Skip to content

[BUG] X-axis order does not work in subplots #1163

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
slazicoicr opened this issue Mar 25, 2020 · 4 comments
Closed

[BUG] X-axis order does not work in subplots #1163

slazicoicr opened this issue Mar 25, 2020 · 4 comments

Comments

@slazicoicr
Copy link

Describe your context

dash (1.9.1)
dash-core-components (1.8.1)
dash-html-components (1.0.2)
dash-renderer (1.2.4)
dash-table (4.6.1)

Describe the bug
I have set up a subplot and a normal plot, where the input x-axis is reversed when the button is clicked. It displays correctly in the single plot, but the subplot fails to change axis order:

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
from dash.dependencies import Input, Output, State
from plotly.subplots import make_subplots


d = {'col1': ['a', 'b'], 'col2': [3, 4], 'col3': [6, 7]}
df = pd.DataFrame(data=d)

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[
    dcc.Dropdown(
        id='sel_ts',
        options=[
            {'label': 'Ascending', 'value': 'asc'},
            {'label': 'Descending', 'value': 'des'},
        ],
        value='asc'
    ),

    html.Button("Update", id='button'),

    dcc.Graph(
        id='graph_ts',
        figure={}
    ),

    dcc.Graph(
        id="single",
        figure={}
    )
])


@app.callback([Output("graph_ts", "figure"), Output("single", "figure")],
              [Input("button", "n_clicks")],
              [State("sel_ts", "value")])
def update_graph_multi_timeseries(_clicks, ts_selected):
    fig = make_subplots(
        rows=2,
        cols=1,
        shared_xaxes=True,
        shared_yaxes=False,
    )

    if ts_selected == "asc":
        plot = df.copy().sort_values('col1', ascending=True)
    else:
        plot = df.copy().sort_values('col1', ascending=False)

    x = list(plot['col1'])
    y1 = list(plot['col2'])
    y2 = list(plot['col3'])

    print(x)

    fig.append_trace(
        {'x': x,
         'y': y1,
         'mode': 'markers',
         'name': 'single_trace'},
        1, 1
    )
    fig.append_trace(
        {'x': x,
         'y': y2,
         'mode': 'markers',
         'name': 'single_trace'},
        2, 1
    )

    fig["layout"].update(
        autosize=True,
        template="plotly_white",
    )

    return fig, {'data': [
        {'x': x,
         'y': y1,
         'mode': 'markers',
         'name': 'single_trace'}
    ]}


if __name__ == '__main__':
    app.run_server(debug=True)

Expected behavior
Subplot should respect the x-axis order supplied by the traces.

Screenshots
Initial state of app:
image

Subplot retains initial state, whereas single plot correctly changes order:
image

@alexcjohnson
Copy link
Collaborator

Hi @slazicoicr - looks like you've uncovered a bug in plotly.js - thanks for the report!

Until we get that fixed, can I suggest you use autorange: True | 'reversed' (and always sort the data ascending) to make this change?

def update_graph_multi_timeseries(_clicks, ts_selected):
    fig = make_subplots(
        rows=2,
        cols=1,
        shared_xaxes=True,
        shared_yaxes=False,
    )

    autorange = True if ts_selected == "asc" else "reversed"
    plot = df.copy().sort_values('col1', ascending=True)

    x = list(plot['col1'])
    y1 = list(plot['col2'])
    y2 = list(plot['col3'])

    print(x)

    fig.append_trace(
        {'x': x,
         'y': y1,
         'mode': 'markers',
         'name': 'single_trace'},
        1, 1
    )
    fig.append_trace(
        {'x': x,
         'y': y2,
         'mode': 'markers',
         'name': 'single_trace'},
        2, 1
    )

    fig["layout"].update(
        autosize=True,
        template="plotly_white"
    )

    fig.update_xaxes(autorange=autorange)

    return fig, {
        'data': [
            {'x': x,
             'y': y1,
             'mode': 'markers',
             'name': 'single_trace'}
        ],
        'layout': {
            'xaxis': {'autorange': autorange}
        }
    }

Unfortunately that won't work if the change you're making is any more granular than a reversal (sorting on some other attribute, for example) and this bug is still present even if you explicitly specify the categoryorder.

@alexcjohnson
Copy link
Collaborator

@archmoj this looks like a Plotly.react bug with ax._categories not clearing correctly on matches axes. Can you try to reproduce in a codepen and then move this to plotly.js?

@archmoj
Copy link
Contributor

archmoj commented Apr 1, 2020

Tracked in plotly/plotly.js#4718.

@gvwilson
Copy link
Contributor

Hi - we are tidying up stale issues and PRs in Plotly's public repositories so that we can focus on things that are most important to our community. If this issue is still a concern, please add a comment letting us know what recent version of our software you've checked it with so that I can reopen it and add it to our backlog. (Please note that we will give priority to reports that include a short reproducible example.) If you'd like to submit a PR, we'd be happy to prioritize a review, and if it's a request for tech support, please post in our community forum. Thank you - @gvwilson

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

4 participants