Plotly:如何设置自定义 x 轴刻度

12

来自Plotly文档:

layout > xaxis > tickvals:

设置此轴上刻度出现的位置。仅在tickmode设置为"array"时才有效。与ticktext一起使用。

layout > xaxis > ticktext:

通过tickvals设置在刻度位置显示的文本。仅在tickmode设置为"array"时才有效。与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,刻度数完全不匹配。 我该怎么解决?


我不确定问题的意图是什么,但是您是说您想要每100个数据有50个x轴标签吗? - r-beginners
@r-beginners 我只想设置自定义的xticks。我知道在这种情况下nticks可以做类似的事情,但问题是为什么tickmode="array"不起作用。 - Mithril
你正在创建一个 layout 的字典。但是你没有将它传递给 fig 对象。 - CypherX
1个回答

21
我通常使用以下方法。你应该知道tickvals被视为一个位置参数,并且最好(也许只能)与数值一起使用,而不是日期。使用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:

enter image description here

现在你可以将 tickvals=np.arange(0, y.shape[0]).astype(int)[0::40] 更改为 tickvals=np.arange(0, y.shape[0]).astype(int)[0::80] 来得到:

情节2:

plot2

那么第一次为什么不起作用呢?有许多原因:

  1. 您重新采样的 pandas series y 的索引是日期,因此 y.index 被设置为 x 轴值。
  2. y.index 返回 dates
  3. 当您通过 fig.update_xaxes(tickvals) 设置刻度标记 位置 时,这与 整数 值更搭配。

我做了什么来修复它呢?

  1. 我在重新采样后重置了索引,以便 y.index 不返回日期。
  2. 使用 .to_frame 将 y 更改为数据框。
  3. 更改为 fig.add_trace(go.Scatter(x=y.index, y=y.y)),否则会失败,因为现在这是一个数据框而不是系列。
  4. 您的日期现在通过 x_dates = y.ds 检索

我知道 y=y.y 看起来非常奇怪,但我只是把它留下作为友好提醒,要给你的 pandas series 或数据框取更明智的名称,而不是像 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()

奇怪,你的代码在我的环境中是正确的,我的代码仍然显示错误的 xticks,请你运行我的代码来进行测试吗? - Mithril
将整数值提供给xtickvals,即正确点。我没有尝试过这个,因为类似的代码在matplotlib中运行良好。所以看起来plotly在处理dtype { 'x' : date, tickvals: int } 和 dtype { 'x' : date, tickvals: date }时存在一些问题,后者也不起作用,所以我没有尝试 { 'x' : int, tickvals: int }。我想我会去打扰plotly开发人员:)。谢谢你指出这个问题。 - Mithril

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接