Plotly - x轴上多个(三个)标签

3 投票
2 回答
70 浏览
提问于 2025-04-14 18:32

我有一个数据集,里面有周、月和年的列,我想用这些周、月和年作为标签来绘制一个时间变化的图表。请问在Python的plotly库中可以做到这样吗?

这是我想要的标签样式

我已经能用以下代码得到两个标签(周和月)了:df是我的数据框,里面有周、月、年和数值这几列。

fig = go.Figure()
fig.add_trace(go.Scatter(x=[df['month'], df['week']],
                             y=list(df['value'])))
return fig

2 个回答

1

你可以在图表中添加一个辅助的X轴,把每周的刻度和标签放在上面。如果你需要一些特别的年份刻度,也可以把它们放在这个辅助X轴上,位置在图表外面:

import plotly.graph_objects as go
from plotly.graph_objs.layout import YAxis, XAxis
import plotly.express as px

df = px.data.stocks()

# grab some data
df = df.head(60)

# apply the layout with a secondary X-axis
layout = go.Layout(
    title="Plot with ticks for weeks, months, and years on the X-axis",
    # main X-axis with monthly ticks, where each label contains a month and a year 
    xaxis = XAxis(
        ticks="outside",
        ticklabelmode="period", 
        tickcolor="black", 
        ticklen=10,
        dtick="M1",
        tickformat="%m\n%Y"
    ),
    # secondary X-axis having weekly ticks with inside labels, and having huge outside "minor" ticks corresponding to years
    xaxis2 = XAxis(
        overlaying="x",
        ticks="inside",
        ticklabelposition="inside",
        ticklabelmode="period",
        tickcolor="black", 
        ticklen=10,
        dtick=7*24*60*60*1000,
        tickformat="%V",
        griddash="dot",
        gridcolor="white",
        minor=dict(
            ticks="outside",
            ticklen=40,
            dtick="M12"
        )
    ),
    yaxis=dict(
        title="Y values"
    ),
)

# plot data
fig = px.line(df, x="date", y=df.columns,
              title="custom tick labels")

# apply the layout with a secondary X-axis
fig.update_layout(layout)

# place an invisible trace on the secondary X axis, to avoid automatic hiding of the axis
fig.add_trace(
    go.Scatter(x=df["date"], y=df["GOOG"], name="some data", xaxis="x2", opacity=0, showlegend=False),
)

fig.show()

在这个方法中,你需要在辅助X轴上放置一个透明的轨迹,否则Plotly会自动隐藏这个轴。结果如下:

enter image description here

如果你缩放这个包含图片的HTML页面,可能会发现每周的标签变成了竖着的:

enter image description here

如果你把页面压缩得太厉害,标签甚至可能会重叠在一起:

enter image description here

为了避免这种情况,你可能需要调整一下dtick参数,这个参数在这里表示刻度之间的间隔,单位是毫秒。例如,如果你从辅助X轴的布局定义中去掉dtick=7*24*60*60*1000,,那么在辅助X轴上只会显示部分每周的标签:

enter image description here

但是如果你把图放大到一定程度,你会再次看到所有的标签:

enter image description here

2

据我所知,x轴上最多可以有两个层级的层次结构。作为一种解决方法,你可以把年份和月份结合起来,这样就能得到接近你想要的效果。我是根据参考中的散点图代码创建的。

import plotly.express as px
import plotly.graph_objects as go
import datetime
import pandas as pd

df = px.data.stocks()[:30]
df['date'] = pd.to_datetime(df['date'])

df['week'] = df['date'].dt.isocalendar().week
df['month'] = df['date'].dt.month
df['year'] = df['date'].dt.year

fig = go.Figure()
fig.add_trace(go.Scatter(x=[[f'{m:02}<br>{y}' for y,m in zip(df['year'].tolist(),df['month'].tolist())], df['week']], y=list(df['GOOG'])))

fig.show()

enter image description here

撰写回答