Dash Graph Dates offset from the data associated with it

Hello.

I have a time series graph where month/year dates along the X axis and sales/predicted sales along the Y axis. I’m noticing the points are offset from their actual dates. See below.

This is the code used to produce the above graph:

fig = go.Figure()
    fig = make_subplots(rows=2, cols=1,shared_xaxes=True,subplot_titles=(item+" Predictions by Home Delivery", item+" Predictions by Shop Sales"))
    for name, color in zip(names, colors):
        fig.add_traces(go.Scatter(x=df_[(df_['model']==name) & (df_['location_type'] =='home_delivery')]['dmand_yr_mo'],
                    y = df_[(df_['model']==name) & (df_['location_type'] =='home_delivery')]['predicted_sales'],
                    #    hovertemplate="%{x|%m/%Y} value: %{y}",
                   xperiod="M1",
                   name=name, marker_color=color,
                   showlegend=True,
                   legendgroup=name,
                   mode='markers'),
                   rows=1, cols=1)
        fig.add_traces(go.Scatter(x=df_[(df_['model']==name) & (df_['location_type'] =='home_delivery')]['dmand_yr_mo'],
                    y = df_[(df_['model']==name) & (df_['location_type'] =='home_delivery')]['sales_dollars'],
                    #    hovertemplate="%{x|%m/%Y} value: %{y}",
                   xperiod="M1",
                   name='actual_sales', marker_color='purple',
                   showlegend=False,
                   mode='lines'),
                   rows=1, cols=1,
                )
        fig.add_traces(go.Scatter(x=df_[(df_['model']==name) & (df_['location_type'] =='shop_sales')]['dmand_yr_mo'],
                    y = df_[(df_['model']==name) & (df_['location_type'] =='shop_sales')]['predicted_sales'],
                    #    hovertemplate="%{x|%m/%Y} value: %{y}",
                   xperiod="M1",
                   

How can I get the points to align with the dates correctly?

What is the dtype of this column?

Date

Jordan

The xperiod=M1 seems to be the problem, I don’t know why. If used, it reproduces the behavior you describe, check out the MRE.

import plotly.graph_objs as go
import pandas as pd

data = {'date':['2022-01', '2022-02', '2022-03', '2022-04'], 'val1':[20, 21, 19, 18]}
df = pd.DataFrame(data)
df.date = pd.to_datetime(df.date)

fig = go.Figure(
    data=go.Scatter(
        x=df['date'], 
        y=df['val1'],
        #xperiod="M1"
    )
)

fig.update_layout(
    xaxis=dict(
        range=['2021-12', '2022-05'], 
        tickformat='%Y-%m', 
        tickvals=['2022-01', '2022-02', '2022-03', '2022-04']
    )
)
fig.show()

hi @jbh1128d1 hi @AIMPED
So I looked more into this and talked to some of our engineers.

xperiod appears to be working just as it should. For example, in a dataframe with a Date column of many years, months and days, using xperiod="M1" should collapse the days into months, giving an average of the data for every month. This is usually used with bar charts.

We can see this happening with @AIMPED 's example where the scatter markers fall in the middle of each month, indicating the presumed average for each month.

import plotly.graph_objs as go
import pandas as pd

data = {'date':['2022-01', '2022-02', '2022-03', '2022-04'], 'val1':[20, 21, 19, 18]}
df = pd.DataFrame(data)
df.date = pd.to_datetime(df.date)

fig = go.Figure(
    data=go.Scatter(
        x=df['date'],
        y=df['val1'],
        xperiod="M1"
    )
)

fig.update_layout(
    xaxis=dict(
        range=['2021-12', '2022-05'],
        tickformat='%Y-%m',
        tickvals=['2022-01', '2022-02', '2022-03', '2022-04']
    )
)
fig.show()

Thanks for the clarification @adamschroeder

So for this use case I would just not use xperiod then :wink:

I got pulled to another fire to put out and just getting back to this. I took out “x-period”. I did take out the “range” and “tickvals” parameters from the xaxis parameters due to the fact that those values are driven by a drop down menu. So this is what the menu looks like:

fig = go.Figure()
    fig = make_subplots(rows=2, cols=1,shared_xaxes=True,subplot_titles=(item+" Predictions by Home Delivery", item+" Predictions by Shop Sales"))
    for name, color in zip(names, colors):
        fig.add_traces(go.Scatter(x=df_[(df_['model']==name) & (df_['location_type'] =='home_delivery')]['dmand_yr_mo'],
                    y = df_[(df_['model']==name) & (df_['location_type'] =='home_delivery')]['predicted_sales'],
                   name=name, marker_color=color,
                   showlegend=True,
                   legendgroup=name,
                   mode='markers'),
                   rows=1, cols=1)
        fig.add_traces(go.Scatter(x=df_[(df_['model']==name) & (df_['location_type'] =='home_delivery')]['dmand_yr_mo'],
                    y = df_[(df_['model']==name) & (df_['location_type'] =='home_delivery')]['sales_dollars'],
                   name='actual_sales', marker_color='purple',
                   showlegend=False,
                   mode='lines'),
                   rows=1, cols=1,
                )
        fig.add_traces(go.Scatter(x=df_[(df_['model']==name) & (df_['location_type'] =='shop_sales')]['dmand_yr_mo'],
                    y = df_[(df_['model']==name) & (df_['location_type'] =='shop_sales')]['predicted_sales'],
                   name=name, marker_color=color,
                   showlegend=False,
                   legendgroup=name,mode='markers',
                ),
                   rows=2, cols=1)
        fig.add_traces(go.Scatter(x=df_[(df_['model']==name) & (df_['location_type'] =='shop_sales')]['dmand_yr_mo'],
                    y = df_[(df_['model']==name) & (df_['location_type'] =='shop_sales')]['sales_dollars'],
                   name='actual_sales', marker_color='purple',
                   showlegend=False,mode='lines'),
                   rows=2, cols=1,
                )

        fig.update_layout(
        xaxis=dict(
        tickformat='%Y-%m', 
    )
)

But the values are still not aligning. If you look below, you’ll see the X-axis states March of 2021 but the data (according to the tool tip) is from February:

I mean technically, the 28th of February is should not be aligned with the March tick…am I missing something?

The dates driving those are all aligned to the last day of the month but represent the entire month (they are that way for joining purposes). So I would like the month/year to be aligned despite the day.

In this case, I would like data from February 28th, 2021 has Feb 2021 directly under the it on the x-axis and the same for the rest of the months.

Apologies if I wasn’t clear before.

hi @jbh1128d1
We might be able to align Feb 28 more to the left, but what happens with data points in May, for example? I see you have data for mid-May and for end of May on the graph. Would you like to artificially move those left as well?

Plotly is creating the graph correctly, by putting the scatter markers exactly over their respective date. It seems to me that you’re trying to get Plotly to plot the data in a less accurate way and show Feb 28 data above Feb ~15. Is that what you’re trying?

Would it be easier to make a copy of the data and modify the dates instead of modifying the Plotly graph?

Ha…I actually don’t have two data points for May. It just so happens that there are no sales (and thus data) for April so the graph ends up looking like it does above.

Yes, this issue is that my data is a monthly aggregation with each month represented as the last day in the month. Maybe when I pull the data, I just need to pythonically extract the Month/Year out of that date column and use that for the X-axis.

1 Like