Skip to content

Adding multiple X axes to the same line #3948

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
carluqcor opened this issue Nov 10, 2022 · 13 comments
Closed

Adding multiple X axes to the same line #3948

carluqcor opened this issue Nov 10, 2022 · 13 comments

Comments

@carluqcor
Copy link

carluqcor commented Nov 10, 2022

Hey there,

I'm trying to create a plot in python using Plotly that allows me to add 2 x axis to a single plot. I just tried but every single tutorial and documentation add a second trace to the plot with y and x data, but if you do that it will generate a second line and I just want a line that represents both axis. I mean de mainly x axis will be the bottom one and the secondary can be the upper one. The plot will be generated using y and x data (from the mainly x axis).

I already have this, but as you can see is not very clear...
image

fig = go.Figure()

for percentile, color in zip(percentiles_m, colors_m):
        fig.add_trace(
            go.Scatter(
                y=curves_df[percentile],
                x=[curves_df.index, remaining_patients],
                name=percentile + "th",
                mode="lines+markers",
                textposition="top center",
                line=dict(color=color),
            )
        )

fig.update_xaxes(title_text="Remaining patients/Repetition", tickangle=0, tickfont=dict(size=11), dividerwidth=1)

fig.update_yaxes(title_text=feature_selected, tickfont=dict(size=11))

any idea? Thanks!

@empet
Copy link

empet commented Nov 10, 2022

This example on plotly forum can suggest how to reference a chart to the second xaxis ( the top one), and the default yaxis:
https://community.plotly.com/t/can-plotly-support-2-x-axis-and-2-y-axis-in-one-graph/38303

@carluqcor
Copy link
Author

Thanks for your quick answer @empet.
I already had seen this post. But in my case I don't want to add a second trace, because it will generate other trace. I want 2 X axes linked to one trace.

@empet
Copy link

empet commented Nov 10, 2022

In this case you should add that trace twice. fig.data[0] is referenced to xaxis, yaxis, and fig data[1] to xaxis2, yaxis.

@carluqcor
Copy link
Author

carluqcor commented Nov 10, 2022

Do you mean like this? @empet

for percentile, color in zip(percentiles_m, colors_m):
        fig.add_trace(
            go.Scatter(
                y=curves_df[percentile],
                x=curves_df[percentile].index,
                name=percentile + "th",
                mode="lines+markers",
                textposition="top center",
                line=dict(color=color),
            )
        )

        fig.add_trace(
            go.Bar(
                y=curves_df[percentile],
                x=remaining_patients,
                xaxis="x2",
                showlegend=False,
            )
        )

but if I do that, just changing the x data, it will generate other trace.

Maybe I'm not understanding you.

@empet
Copy link

empet commented Nov 10, 2022

Without data I cannot run your code.

@carluqcor
Copy link
Author

carluqcor commented Nov 11, 2022

Try this one @empet, thanks

percentiles_m = [
        "5",
        "10",
         "25",
    ]

curves_df = pd.DataFrame([[1.63, 1.56, 1.85], [1.5, 1.24, 1.76]], columns = percentiles_m)

remaining_patients = [66, 57, 52]

fig = go.Figure()

for percentile, color in zip(percentiles_m, colors_m):
        fig.add_trace(
            go.Scatter(
                y=curves_df[percentile],
                x=curves_df[percentile].index,
                name=percentile + "th",
                mode="lines+markers",
                textposition="top center",
                line=dict(color=color),
            )
        )

        fig.add_trace(
            go.Bar(
                y=curves_df[percentile],
                x=remaining_patients,
                xaxis="x2",
                showlegend=False,
            )
        )

@empet
Copy link

empet commented Nov 11, 2022

If you want to get help, please post a working code. And also add the line:

fig.update_layout(xaxis2= {'anchor': 'y', 'overlaying': 'x', 'side': 'top'})        

Your code in the last cell, above, throws a lot of errors.

@carluqcor
Copy link
Author

Hi there @empet,

sorry for the last comment.

This is a working example.

percentiles_m = [
        "5",
        "10",
        "25",
    ]

colors_m = [
        "#bfbfbf",
        "#a9a9a9",
        "#939393",
    ]

curves_df = pd.DataFrame([[1.63, 1.56, 1.85], [1.5, 1.24, 1.76], [1.23, 3.22, 5.23], [2, 1.2, 1.3]], columns = percentiles_m)

remaining_patients = [66, 57, 52, 50, 45]

fig = go.Figure()

for percentile, color in zip(percentiles_m, colors_m):
        fig.add_trace(
            go.Scatter(
                y=curves_df[percentile],
                x=list(curves_df.index),
                name=percentile + "th",
                mode="lines+markers",
                textposition="top center",
                line=dict(color=color),
            )
        )

        fig.add_trace(
            go.Scatter(
                y=curves_df[percentile],
                x=remaining_patients,
                xaxis="x2",
                showlegend=False,
            )
        )

fig.update_layout(xaxis2= {'anchor': 'y', 'overlaying': 'x1', 'side': 'top'})        

fig.show()

As u can see when I add the second trace, it generates the coloured lines. I would want to have just the first trace added with the two axis without more lines added to them is that possible?
Also, the second trace reversed the remaining patient values as you can see on the top of the graph
image

@empet
Copy link

empet commented Nov 14, 2022

You question related to referencing a trace to two xaxes is so fuzzy that I cannot understand why do you want to be displayed only the first trace.
The reference system (xaxis2, yaxis) cannot exist as long as you don't reference a trace to it.

Please create a manual plot of what you want to get, and post here a CLEAR EXPLANATION of your data, and of this odd requirement to display two xaxes for a single trace.

@nicolaskruchten
Copy link
Contributor

It's not such an odd request IMO. A simple example would be that I have a temperature curve in celsius but I also want a farenheit axis. Totally reasonable and easy to grok. One trace, two axes.

Plotly's model is simply too rigid to allow for this right now because of the one-axis-per-trace model and the one-trace-per-axis requirement to display an axis.

@empet
Copy link

empet commented Nov 14, 2022

@nicolaskruchten You are right with temperature, but in tens years of math I haven't seen a graph represented with respect to two xaxes, because the graph of a function consists in the points
(x, f(x)), with x in a fixed range, [a, b].

@AaronStiff
Copy link
Contributor

Closing as a duplicate of plotly/plotly.js#5076

@AaronStiff AaronStiff closed this as not planned Won't fix, can't repro, duplicate, stale Feb 24, 2023
@mhangaard
Copy link

This Stackoverflow post is about exactly this. It contains a visualization made in matplotlib, which clearly shows the case:
https://stackoverflow.com/questions/27334585/in-plotly-how-do-i-create-a-linked-x-axis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants