时间序列的破折号格式 x 轴不正确
dash formatting x-axis of timeseries incorrectly
我正在尝试使用 plotly/Dash 绘制一些时间序列数据,但图表无法正确显示,尽管 x 轴的类型为 'datetime.date'、'datetime.datetime' 或正确格式化的字符串(没有任何作用......)。 可能 使事情复杂化的是,我使用不同的函数生成了时间序列数据,将其存储到 dcc.Store 对象(如 dict)中,然后将其转换回 Dataframe ......但我不确定。我的代码在下面,但总结了简单的行动计划:
- 将资产代码输入输入框,生成字典并存储到 dcc.Store(我想重新使用这个时间序列,因此存储它而不是一次又一次地重复外部 bloomberg 调用)
- 立即从 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.sort
和 np.argsort
),或者如果您只对点而不是线感到满意,请对散点图使用 mode='markers'
(比照 https://plot.ly/python/line-and-scatter/).
我正在尝试使用 plotly/Dash 绘制一些时间序列数据,但图表无法正确显示,尽管 x 轴的类型为 'datetime.date'、'datetime.datetime' 或正确格式化的字符串(没有任何作用......)。 可能 使事情复杂化的是,我使用不同的函数生成了时间序列数据,将其存储到 dcc.Store 对象(如 dict)中,然后将其转换回 Dataframe ......但我不确定。我的代码在下面,但总结了简单的行动计划:
- 将资产代码输入输入框,生成字典并存储到 dcc.Store(我想重新使用这个时间序列,因此存储它而不是一次又一次地重复外部 bloomberg 调用)
- 立即从 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.sort
和 np.argsort
),或者如果您只对点而不是线感到满意,请对散点图使用 mode='markers'
(比照 https://plot.ly/python/line-and-scatter/).