Plotly:如何设置自定义 xticks
Plotly: How to set custom xticks
来自plotly doc:
layout > xaxis > tickvals:
Sets the values at which ticks on this axis
appear. Only has an effect if tickmode
is set to "array". Used with
ticktext
.
layout > xaxis > ticktext:
Sets the text displayed at the
ticks position via tickvals
. Only has an effect if tickmode
is set
to "array". Used with tickvals
.
示例:
import pandas as pd
import numpy as np
np.random.seed(42)
feature = pd.DataFrame({'ds': pd.date_range('20200101', periods=100*24, freq='H'),
'y': np.random.randint(0,20, 100*24) ,
'yhat': np.random.randint(0,20, 100*24) ,
'price': np.random.choice([6600, 7000, 5500, 7800], 100*24)})
import plotly.graph_objects as go
import plotly.offline as py
import plotly.express as px
from plotly.offline import init_notebook_mode
init_notebook_mode(connected=True)
y = feature.set_index('ds').resample('D')['y'].sum()
fig = go.Figure()
fig.add_trace(go.Scatter(x=y.index, y=y))
x_dates = y.index.to_series().dt.strftime('%Y-%m-%d').sort_values().unique()
layout = dict(
xaxis=dict(
tickmode="array",
tickvals=np.arange(0, x_dates.shape[0],2).astype(int),
ticktext=x_dates[::2],
tickformat='%Y-%m-%d',
tickangle=45,
)
)
fig.update_layout(layout)
fig.show()
结果:
因为 x_dates[::2]
的长度是 50,所以 ticknumber 根本不匹配。
我该如何解决它??
我通常使用下面的方法。您应该知道 tickvals
被视为 positional 参数并且最适用于(可能仅适用于)数值而不是日期。使用 ticktext
以您喜欢的格式显示日期。
片段 1:
fig.update_xaxes(tickangle=45,
tickmode = 'array',
tickvals = df_tips['date'][0::40],
ticktext= [d.strftime('%Y-%m-%d') for d in datelist])
情节 1:
现在您可以将 tickvals=np.arange(0, y.shape[0]).astype(int)[0::40]
更改为 tickvals=np.arange(0, y.shape[0]).astype(int)[0::80]
并得到:
地块 2:
那么,为什么这对您第一次不起作用?几个原因:
- 你重采样的pandas系列y有日期作为索引,所以
y.index
被设置为 x 轴值。
y.index
returns 日期
- 当您设置刻度线 positions 到
fig.update_xaxes(tickvals)
时,这对 integer 值更有效。
我做了什么来修复它?
- 我在重新采样后重置了索引,这样
y.index
就不会 return 日期。
- 使用
.to_frame
将 y 更改为数据框。
- 更改为
fig.add_trace(go.Scatter(x=y.index, y=y.y))
否则会失败,因为现在这是一个数据框而不是系列。
- 您的日期现在检索为
x_dates = y.ds
我知道 y=y.y
看起来 真的 很奇怪,但我只是把它留在原处作为一个友好的提醒,让你的 pandas 系列或数据帧更合理名称而不是像 y
这样的单个字母,后者更容易与单个、无索引的数组或列表混淆。
完整代码:
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.offline as py
import plotly.express as px
from plotly.offline import init_notebook_mode
# data
np.random.seed(42)
feature = pd.DataFrame({'ds': pd.date_range('20200101', periods=100*24, freq='H'),
'y': np.random.randint(0,20, 100*24) ,
'yhat': np.random.randint(0,20, 100*24) ,
'price': np.random.choice([6600, 7000, 5500, 7800], 100*24)})
# resampling
y = feature.set_index('ds').resample('D')['y'].sum()#.to_frame()
y=y.to_frame()
y.reset_index(inplace=True)
# plotly setup
fig = go.Figure()
fig.add_trace(go.Scatter(x=y.index, y=y.y))
# x-ticks preparations
x_dates = y.ds
tickvals=np.arange(0, y.shape[0]).astype(int)[0::40]
ticktext=x_dates
# update tickmarks
fig.update_xaxes(tickangle=45,
tickmode = 'array',
tickvals = tickvals,
ticktext=[d.strftime('%Y-%m-%d') for d in ticktext])
fig.show()
来自plotly doc:
layout > xaxis > tickvals:
Sets the values at which ticks on this axis appear. Only has an effect if
tickmode
is set to "array". Used withticktext
.layout > xaxis > ticktext:
Sets the text displayed at the ticks position via
tickvals
. Only has an effect iftickmode
is set to "array". Used withtickvals
.
示例:
import pandas as pd
import numpy as np
np.random.seed(42)
feature = pd.DataFrame({'ds': pd.date_range('20200101', periods=100*24, freq='H'),
'y': np.random.randint(0,20, 100*24) ,
'yhat': np.random.randint(0,20, 100*24) ,
'price': np.random.choice([6600, 7000, 5500, 7800], 100*24)})
import plotly.graph_objects as go
import plotly.offline as py
import plotly.express as px
from plotly.offline import init_notebook_mode
init_notebook_mode(connected=True)
y = feature.set_index('ds').resample('D')['y'].sum()
fig = go.Figure()
fig.add_trace(go.Scatter(x=y.index, y=y))
x_dates = y.index.to_series().dt.strftime('%Y-%m-%d').sort_values().unique()
layout = dict(
xaxis=dict(
tickmode="array",
tickvals=np.arange(0, x_dates.shape[0],2).astype(int),
ticktext=x_dates[::2],
tickformat='%Y-%m-%d',
tickangle=45,
)
)
fig.update_layout(layout)
fig.show()
结果:
因为 x_dates[::2]
的长度是 50,所以 ticknumber 根本不匹配。
我该如何解决它??
我通常使用下面的方法。您应该知道 tickvals
被视为 positional 参数并且最适用于(可能仅适用于)数值而不是日期。使用 ticktext
以您喜欢的格式显示日期。
片段 1:
fig.update_xaxes(tickangle=45,
tickmode = 'array',
tickvals = df_tips['date'][0::40],
ticktext= [d.strftime('%Y-%m-%d') for d in datelist])
情节 1:
现在您可以将 tickvals=np.arange(0, y.shape[0]).astype(int)[0::40]
更改为 tickvals=np.arange(0, y.shape[0]).astype(int)[0::80]
并得到:
地块 2:
那么,为什么这对您第一次不起作用?几个原因:
- 你重采样的pandas系列y有日期作为索引,所以
y.index
被设置为 x 轴值。 y.index
returns 日期- 当您设置刻度线 positions 到
fig.update_xaxes(tickvals)
时,这对 integer 值更有效。
我做了什么来修复它?
- 我在重新采样后重置了索引,这样
y.index
就不会 return 日期。 - 使用
.to_frame
将 y 更改为数据框。 - 更改为
fig.add_trace(go.Scatter(x=y.index, y=y.y))
否则会失败,因为现在这是一个数据框而不是系列。 - 您的日期现在检索为
x_dates = y.ds
我知道 y=y.y
看起来 真的 很奇怪,但我只是把它留在原处作为一个友好的提醒,让你的 pandas 系列或数据帧更合理名称而不是像 y
这样的单个字母,后者更容易与单个、无索引的数组或列表混淆。
完整代码:
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.offline as py
import plotly.express as px
from plotly.offline import init_notebook_mode
# data
np.random.seed(42)
feature = pd.DataFrame({'ds': pd.date_range('20200101', periods=100*24, freq='H'),
'y': np.random.randint(0,20, 100*24) ,
'yhat': np.random.randint(0,20, 100*24) ,
'price': np.random.choice([6600, 7000, 5500, 7800], 100*24)})
# resampling
y = feature.set_index('ds').resample('D')['y'].sum()#.to_frame()
y=y.to_frame()
y.reset_index(inplace=True)
# plotly setup
fig = go.Figure()
fig.add_trace(go.Scatter(x=y.index, y=y.y))
# x-ticks preparations
x_dates = y.ds
tickvals=np.arange(0, y.shape[0]).astype(int)[0::40]
ticktext=x_dates
# update tickmarks
fig.update_xaxes(tickangle=45,
tickmode = 'array',
tickvals = tickvals,
ticktext=[d.strftime('%Y-%m-%d') for d in ticktext])
fig.show()