时间序列的破折号格式 x 轴不正确

dash formatting x-axis of timeseries incorrectly

我正在尝试使用 plotly/Dash 绘制一些时间序列数据,但图表无法正确显示,尽管 x 轴的类型为 'datetime.date'、'datetime.datetime' 或正确格式化的字符串(没有任何作用......)。 可能 使事情复杂化的是,我使用不同的函数生成了时间序列数据,将其存储到 dcc.Store 对象(如 dict)中,然后将其转换回 Dataframe ......但我不确定。我的代码在下面,但总结了简单的行动计划:

  1. 将资产代码输入输入框,生成字典并存储到 dcc.Store(我想重新使用这个时间序列,因此存储它而不是一次又一次地重复外部 bloomberg 调用)
  2. 立即从 dcc.Store 检索该字典,转换回 Dataframe 并生成简单图

查看每一步生成的数据类型时,我可以看到在使用 df.to_dict() 生成字典后,我得到了以下类型的数据:

{'Date': {0: datetime.date(2017, 1, 1),
  1: datetime.date(2017, 2, 1),
  2: datetime.date(2017, 3, 1),
  3: datetime.date(2017, 4, 1),
.
.
 28: datetime.date(2019, 5, 1)},
 'FD004': {0: 18890.3544,
  1: 18296.9503,
  2: 18667.1757,
.
.
  28: 16697.2425}}

然后在将这个字典转换回 Dataframe 之后我有:

          Date       FD004
0   2017-01-01  18890.3544
1   2017-02-01  18296.9503
2   2017-03-01  18667.1757

其中 df['Date']:

0     2017-01-01
1     2017-02-01
2     2017-03-01
.
.
27    2019-04-01
28    2019-05-01
Name: Date, dtype: object

但我随后使用 to_datetime 或 astype('datetime64[ns]') 转换它,这给了我 'correct' dtype:

0    2017-01-01
1    2017-02-01
2    2017-03-01
.
.
27   2019-04-01
28   2019-05-01
Name: Date, dtype: datetime64[ns]

确实,在检查生成的最终无花果时,我发现 plotly 已将其识别为日期时间对象:

<bound method BaseFigure.show of Figure({
    'data': [{'type': 'scatter',
              'x': array([datetime.datetime(2017, 1, 1, 0, 0),
                          datetime.datetime(2017, 2, 1, 0, 0),
                          datetime.datetime(2017, 3, 1, 0, 0),
                          . . . 
                          datetime.datetime(2019, 3, 1, 0, 0),
                          datetime.datetime(2019, 4, 1, 0, 0),
                          datetime.datetime(2019, 5, 1, 0, 0)], dtype=object),
              'y': array([18890.3544, 18296.9503, 18667.1757, ...
                          13202.488 , 14463.2424, 15025.5053, 16697.2425])}],
    'layout': {'template': '...'}
})>

但仍然...图表显示得像意大利面条:

***** 编辑/更新 *****

当我不存储原始 Dataframe to_dict 时,情节是完美的,所以它看起来好像是关于从 Dataframe 到 dict 并再次转换回来的东西(尽管所有对象 出现 具有正确的数据类型)确实是导致 Date 列被错误解释的原因。那么 to_dict() 函数有什么根本性的错误,或者如何巧妙地解释这个 converted/reverted 数据?

我的代码:

app = dash.Dash()

app.layout = html.Div(children=[
        html.Div(dcc.Input(id='fundTicker', type='text', 
                     debounce=True, placeholder='fundTicker'),
                style={'width':'100%'}), 

        html.Div(dcc.Graph(id='fundGraph'),  
                style={'width':'75%'}),

        dcc.Store(id='fundData'),
        ]
    )

@app.callback(
    Output(component_id='fundData', component_property='data'),
    [Input(component_id='fundTicker', component_property='value')]
    )

def returnFundData(fundTicker):
    fundData = bbg.bbgHistorical(fundTicker, '20170101', '20190501', 'MONTHLY', 'FD004')
    return fundData

@app.callback(
    Output(component_id='fundGraph', component_property='figure'),
    [Input(component_id='fundData', component_property='data')]
    )

def createFundGraph(fundData):

    df = pd.DataFrame.from_dict(fundData)
    df['Date'] = pd.to_datetime(df['Date'])
    fig = go.Figure()

    fig.add_trace(go.Scatter(x=df['Date'], y=df['FD004']))

    return fig    

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

看起来日期并非全部按升序排序,因此 "spaghetti" 看起来(回到过去时)。您打印的数据看起来已排序,所以我不确定,但缺少中心部分,以检查它们是否已排序 运行

np.all(np.sort(df['Date']) == df['Date'])

您可以对数据进行排序(例如使用 np.sortnp.argsort),或者如果您只对点而不是线感到满意,请对散点图使用 mode='markers'(比照 https://plot.ly/python/line-and-scatter/).