Dash Graph -- Two graphs Xaxis out of synch

Using Dash I’m placing two graphs on the same x-axis with time values in the range 00:00 - 24:00

The x values do not always match completely for the two graphs. In some cases the graph places a point all the way of the left and then retraces. See image below:

Using Dash 1.11 and Plotly 4.6.0

Source code and data files available if helpful.

Live demo. Click on Actual to “hide” that line and see the proper graph for Imports


I suspect that you need to sort your data before plotting it. Plotly’s line charts plot lines in the order that they are provided, rather than sorting your data for you (and that’s intentional, because some line charts, even time series, do indeed “loop back”).

Just curious, what did you try googling to find and answer to this question? We’d like to have a better page in our documentation explaining this, but we’re not quite sure which search terms we should be matching.

The two sets of data are sorted. Most of times (hh:mm) in the two data sets are exact matches, but some are missing. The general program usually works (99% of the time), but certain sets of data fail. I pulled this simplified one out as an example. This is the ‘bad actor.’

I’ve written a dozen Dash programs with time series for years, months, or hour:minutes. I’ve read most of the Plotly web pages on this. I assumed the data should be sorted – as it is. The documentation is OK.

You’ll notice in the live demo example, that the data really does not “loop back” because if you “hide” the Actual graph, then the Imports graphs as expected.

I do have an awkward work-around to fix this. I create a dummy ‘base’ scatter for every minute from 00:00 to 23:59. Then all works fine. I want to remove this kludge.

Thanks for Dash and checking into this. – Warren Van Wyck, Vermont, USA

Hm interesting. Could you print the figure right before it gets plotted and share it here?

(Vermont represent! I grew up in VT… Burlington!)

I’m using a callback to populate

html.Div(id=‘load-graph’, children=dcc.Graph(id=‘dummy2’)

This is the figure data printed out:

Graph(id='load-vs-time', figure={'data': [Scatter({
    'line': {'color': 'rgb(255, 127, 14)', 'width': 1},
    'mode': 'lines',
    'name': 'Actual',
    'opacity': 0.7,
    'x': array(['00:00', '00:05', '00:10', ..., '23:45', '23:50', '23:55'], dtype=object),
    'y': array([10483.27 , 10479.188, 10401.329, ..., 10133.323, 10064.778, 10030.881])
}), Scatter({
    'line': {'color': '#403203', 'width': 1},
    'mode': 'lines',
    'name': 'Imports',
    'opacity': 0.7,
    'x': array(['00:00', '00:05', '00:10', ..., '23:45', '23:50', '23:55'], dtype=object),
    'y': array([3079.325, 3032.271, 3082.541, ..., 2972.527, 2956.981, 2855.838])
})], 'layout': Layout({
    'hovermode': 'closest',
    'legend': {'x': -0.3, 'y': 1},
    'margin': {'b': 40, 'l': 140, 'r': 100, 't': 100},
    'title': {'text': 'Tuesday, April 28, 2020'},
    'xaxis': {'mirror': True,
              'showgrid': True,
              'tickmode': 'array',
              'ticktext': [  , 1a, 2a, 3a, 4a, 5a, 6a, 7a, 8a, 9a, 10a, 11a, noon,
                           1p, 2p, 3p, 4p, 5p, 6p, 7p, 8p, 9p, 10p, 11p, ],
              'tickvals': [00:00, 01:00, 02:00, 03:00, 04:00, 05:00, 06:00, 07:00,
                           08:00, 09:00, 10:00, 11:00, 12:00, 13:00, 14:00, 15:00,
                           16:00, 17:00, 18:00, 19:00, 20:00, 21:00, 22:00, 23:00,
              'title': {'text': 'Time'}},
    'yaxis': {'mirror': True,
              'range': [0, 14100],
              'showline': True,
              'ticks': 'outside',
              'title': {'text': 'MegaWatts (MW)'},
              'zeroline': True}

The x, y data are only partially displayed. ‘Actual’ has 280 items and ‘Imports’ has 276 items.

I worked at UVM for thirty years … Waterman building.

1 Like

Are the values sorted with respect to x? Are some values missing (otherwise I don’t see how you can have same start/end and interval but different length)?

Yes, both sets of values are sorted in ascending sequence.
And the difference is:

< 10:35
< 10:40
< 10:45
< 10:50
< 15:45
> 16:25

In the unlikely case that anyone wants to see the input time series data, here’s the two CSV files:




Or if you prefer Jupyter Lab and Plotly Express here is a simple program and the result.


import plotly.io as pio
pio.renderers.default = "browser"
import plotly.express as px
import pandas as pd
df_actual = pd.read_csv('http://wvwelectric.com/data/run_actual_f_1_2.csv')
df_external = pd.read_csv('http://wvwelectric.com/data/run_external_f_1_2.csv')
fig_line = px.line(df_actual, x="hour_min", y="NativeLoad")
fig2_line = px.line(df_external, x="hour_min", y="import_power")

The result:

The same issue. Obviously not really a Dash issue … I’ll leave the subject as is.

Thanks @wvw for the reproducible example!

Hey @Emmanuelle - Could you check this out when you get a chance? Curious if this looks like a bug to you, or some other issue with the data.

(@vwv, on another note, I admired your application’s databars with the /bar_99.png embedded image trick! http://wvwelectric.com/rank_states/ Just wanted to make you aware of an alternative way to make these embedded bar charts in datatables that I pushed up tonight: 📣 DataTable Conditional Formatting Documentation)

Hi @www, the issue arises from the fact that the hour_min column is considered as categorical variables by plotly here, so when there is an x value in the second trace which is not present in the first trace, it is put at the end. You can convert the column to a numerical type or to pandas datetime object to remove the problem

import plotly.express as px
import pandas as pd
df_actual = pd.read_csv('http://wvwelectric.com/data/run_actual_f_1_2.csv')
df_actual["hour_min"] = pd.to_datetime(df_actual["hour_min"] )
df_external = pd.read_csv('http://wvwelectric.com/data/run_external_f_1_2.csv')
df_external["hour_min"] = pd.to_datetime(df_external["hour_min"] )
fig_line = px.line(df_actual, x="hour_min", y="NativeLoad")
fig2_line = px.line(df_external, x="hour_min", y="import_power")
1 Like

Hi @Emmanuelle thanks, ‘pd.to_datetime’ fixes the problem. This also explains some other similar issues I’ve had.

1 Like

Hi, @chriddyp Thanks for the tip on " Data Bars! Bar Chart Embedded within the DataTable " That’s what I wanted to do. Again, thanks to all for this amazing product – I started using it a year ago.

1 Like

Though I need both blue for positive and red for negative.