You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plotly Graph Objects中强制显示所有月份X轴刻度的方法问询

解决Plotly X轴刻度按需显示问题

问题描述

使用plotly.graph_objects生成内嵌数据的HTML图表时,整体体验良好,但存在X轴刻度显示问题:部分场景下刻度无法全部显示,仅在放大视图时才会展示全部刻度(此为放大后的期望行为)。需要实现:

  • 展示月份维度数据时,强制显示所有X轴刻度
  • 展示全年数据时,不显示所有日刻度(避免过于密集)

当前代码如下:

import pandas               as pd
import plotly.graph_objects as go

list_data_mb    =   [
                        ('2023-01-01',10 ,'dat') , ('2023-01-15',15 ,'dat'),('2023-01-01',10 ,'ind') , ('2023-01-15',15 ,'ind'),
                        ('2023-02-01',20 ,'dat') , ('2023-02-15',25 ,'dat'),('2023-02-01',20 ,'ind') , ('2023-02-15',25 ,'ind'),
                        ('2023-03-01',30 ,'dat') , ('2023-03-15',35 ,'dat'),('2023-03-01',30 ,'ind') , ('2023-03-15',35 ,'ind'),
                        ('2023-04-01',40 ,'dat') , ('2023-04-15',45 ,'dat'),('2023-04-01',40 ,'ind') , ('2023-04-15',45 ,'ind'),
                        ('2023-05-01',50 ,'dat') , ('2023-05-15',55 ,'dat'),('2023-05-01',50 ,'ind') , ('2023-05-15',55 ,'ind'),
                        ('2023-06-01',60 ,'dat') , ('2023-06-15',65 ,'dat'),('2023-06-01',60 ,'ind') , ('2023-06-15',65 ,'ind'),
                        ('2023-07-01',70 ,'dat') , ('2023-07-15',75 ,'dat'),('2023-07-01',70 ,'ind') , ('2023-07-15',75 ,'ind'),
                        ('2023-08-01',80 ,'dat') , ('2023-08-15',85 ,'dat'),('2023-08-01',80 ,'ind') , ('2023-08-15',85 ,'ind'),
                        ('2023-09-01',90 ,'dat') , ('2023-09-15',95 ,'dat'),('2023-09-01',90 ,'ind') , ('2023-09-15',95 ,'ind'),
                        ('2023-10-01',100,'dat') , ('2023-10-15',102,'dat'),('2023-10-01',100,'ind') , ('2023-10-15',102,'ind'),
                        ('2023-11-01',104,'dat') , ('2023-11-15',106,'dat'),('2023-11-01',104,'ind') , ('2023-11-15',106,'ind'),
                        ('2023-12-01',108,'dat') , ('2023-12-15',110,'dat'),('2023-12-01',108,'ind') , ('2023-12-15',108,'ind'),
                        ('2024-01-01',112,'dat') , ('2024-01-15',114,'dat'),('2024-01-01',112,'ind') , ('2024-01-15',114,'ind'),
                    ]
df              =   pd.DataFrame(list_data_mb,columns=['date','size','tbs'])
df['date']      =   pd.to_datetime(df['date'], format="%Y-%m-%d")

data            =   [go.Bar(name=tbs, x=dfg['date'], y=dfg['size']) for tbs,dfg in df.groupby(by='tbs')]
fig             =   go.Figure(data)
fig.update_layout(
                    barmode     =   'stack', 
                    title       =   'Tablespaces size over time', 
                    xaxis_title =   'Date', 
                )
fig.update_xaxes(
    rangeslider_visible=True,
    tickmode='array', #linear: too many values. And for "1d", it will not display hours
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1d" , step="day",   stepmode="backward"),
            dict(count=1, label="1m" , step="month", stepmode="backward"),
            dict(count=6, label="6m" , step="month", stepmode="backward"),
            dict(count=1, label="1y" , step="year",  stepmode="backward"),
            dict(count=1, label="YTD", step="year",  stepmode="todate"  ),
            dict(                      step="all"                       )
        ])
    )
)
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='white')
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='white')
fig.write_html("./aux_0.html")

解决方案

要实现按需显示刻度的需求,关键是自定义X轴的刻度值数组,并让Plotly根据当前视图范围自动筛选显示的刻度,具体修改如下:

  1. 提取所有唯一日期作为刻度值:从数据中获取不重复的日期并排序,作为X轴的候选刻度
  2. 配置刻度文本与显示参数:设置刻度文本格式,旋转标签避免重叠,同时限制最大显示刻度数,确保大范围视图不会过于密集

修改后的核心代码部分:

# 提取并排序所有唯一日期
unique_dates = sorted(df['date'].unique())

# 更新X轴配置
fig.update_xaxes(
    rangeslider_visible=True,
    tickmode='array',
    tickvals=unique_dates,  # 设置候选刻度值
    ticktext=[d.strftime('%Y-%m-%d') for d in unique_dates],  # 格式化刻度文本
    tickangle=45,  # 旋转刻度标签,避免重叠
    nticks=12,  # 控制最大显示刻度数,全年视图时自动合并
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1d" , step="day",   stepmode="backward"),
            dict(count=1, label="1m" , step="month", stepmode="backward"),
            dict(count=6, label="6m" , step="month", stepmode="backward"),
            dict(count=1, label="1y" , step="year",  stepmode="backward"),
            dict(count=1, label="YTD", step="year",  stepmode="todate"  ),
            dict(                      step="all"                       )
        ])
    )
)

完整修改后代码

import pandas               as pd
import plotly.graph_objects as go

list_data_mb    =   [
                        ('2023-01-01',10 ,'dat') , ('2023-01-15',15 ,'dat'),('2023-01-01',10 ,'ind') , ('2023-01-15',15 ,'ind'),
                        ('2023-02-01',20 ,'dat') , ('2023-02-15',25 ,'dat'),('2023-02-01',20 ,'ind') , ('2023-02-15',25 ,'ind'),
                        ('2023-03-01',30 ,'dat') , ('2023-03-15',35 ,'dat'),('2023-03-01',30 ,'ind') , ('2023-03-15',35 ,'ind'),
                        ('2023-04-01',40 ,'dat') , ('2023-04-15',45 ,'dat'),('2023-04-01',40 ,'ind') , ('2023-04-15',45 ,'ind'),
                        ('2023-05-01',50 ,'dat') , ('2023-05-15',55 ,'dat'),('2023-05-01',50 ,'ind') , ('2023-05-15',55 ,'ind'),
                        ('2023-06-01',60 ,'dat') , ('2023-06-15',65 ,'dat'),('2023-06-01',60 ,'ind') , ('2023-06-15',65 ,'ind'),
                        ('2023-07-01',70 ,'dat') , ('2023-07-15',75 ,'dat'),('2023-07-01',70 ,'ind') , ('2023-07-15',75 ,'ind'),
                        ('2023-08-01',80 ,'dat') , ('2023-08-15',85 ,'dat'),('2023-08-01',80 ,'ind') , ('2023-08-15',85 ,'ind'),
                        ('2023-09-01',90 ,'dat') , ('2023-09-15',95 ,'dat'),('2023-09-01',90 ,'ind') , ('2023-09-15',95 ,'ind'),
                        ('2023-10-01',100,'dat') , ('2023-10-15',102,'dat'),('2023-10-01',100,'ind') , ('2023-10-15',102,'ind'),
                        ('2023-11-01',104,'dat') , ('2023-11-15',106,'dat'),('2023-11-01',104,'ind') , ('2023-11-15',106,'ind'),
                        ('2023-12-01',108,'dat') , ('2023-12-15',110,'dat'),('2023-12-01',108,'ind') , ('2023-12-15',108,'ind'),
                        ('2024-01-01',112,'dat') , ('2024-01-15',114,'dat'),('2024-01-01',112,'ind') , ('2024-01-15',114,'ind'),
                    ])
df              =   pd.DataFrame(list_data_mb,columns=['date','size','tbs'])
df['date']      =   pd.to_datetime(df['date'], format="%Y-%m-%d")

data            =   [go.Bar(name=tbs, x=dfg['date'], y=dfg['size']) for tbs,dfg in df.groupby(by='tbs')]
fig             =   go.Figure(data)
fig.update_layout(
                    barmode     =   'stack', 
                    title       =   'Tablespaces size over time', 
                    xaxis_title =   'Date', 
                )

# 提取并排序所有唯一日期
unique_dates = sorted(df['date'].unique())

fig.update_xaxes(
    rangeslider_visible=True,
    tickmode='array',
    tickvals=unique_dates,
    ticktext=[d.strftime('%Y-%m-%d') for d in unique_dates],
    tickangle=45,
    nticks=12,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1d" , step="day",   stepmode="backward"),
            dict(count=1, label="1m" , step="month", stepmode="backward"),
            dict(count=6, label="6m" , step="month", stepmode="backward"),
            dict(count=1, label="1y" , step="year",  stepmode="backward"),
            dict(count=1, label="YTD", step="year",  stepmode="todate"  ),
            dict(                      step="all"                       )
        ])
    )
)
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='white')
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='white')
fig.write_html("./aux_0.html")

效果说明

  • 当选择1m(1个月)视图时,X轴会自动显示该月的所有刻度(1号和15号)
  • 当选择全年或6m视图时,Plotly会根据nticks参数自动筛选显示的刻度,避免日刻度过于密集,仅展示关键日期或合并为月份级别的刻度
  • 旋转刻度标签(tickangle=45)可以避免标签重叠,提升可读性

内容的提问来源于stack exchange,提问作者glezo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 12:54:56