Plotly绘制折线图时线条未从左侧y轴起始的问题咨询
Plotly折线图从左边缘y轴起始的实现方法
问题描述
现有一段可正常生成折线图的示例代码,输入数据特征、绘图逻辑均与本地复现的异常情况完全一致,但生成结果存在差异:正常效果下折线会从左侧y轴位置起始,异常效果下折线未从左侧y轴起始,前置存在空白间距。
示例代码如下:
# 运行前需补充导入以下依赖模块 import plotly.graph_objects as go import plotly.io from datetime import date, timedelta from pandas.tseries.offsets import DateOffset import pandas as pd sdate = date(2021,1,31) edate = date(2021,8,30) date_range = pd.date_range(sdate,edate-timedelta(days=1),freq='m') df_test = pd.DataFrame({ 'Datum': date_range}) df_test.loc[len(df_test)+1,'Datum']=(df_test['Datum'].min()-DateOffset(months=1)) df_test=df_test.sort_values(by='Datum',ignore_index=True) df_test['indexed'] = [1,2,3,4,5,6,7,7] df_test['index'] = [5,5,3,4,5,6,7,7] data = df_test sdate=data['Datum'].min() title = 'Gesamtperformance' font ='Helvetica' fig = go.Figure() fig.add_trace(go.Scatter(x=data['Datum'], y=data['indexed'], line = dict(color='blue', width=4), mode='lines', name=title)) fig.add_trace(go.Scatter(x=data['Datum'], y=data['index'], line=dict(color='black', width=4, dash='dot'), mode='lines', name=title)) fig.layout = go.Layout(yaxis=dict(tickformat=".0%")) fig.update_layout(font_family=font, font=dict( family=font, size=30), legend=dict(font=dict(family=font, size=30, color="black"))) fig.update_layout(yaxis_title="Performance", margin=dict(l=100, r=0, t=0, b=120), plot_bgcolor='grey', legend=dict( orientation="h", yanchor="top", y=-0.065, xanchor="auto", x=0.5) ) fig.update_xaxes(dtick="M6", tickformat="%b %Y") fig.update_layout(xaxis=dict(tick0=sdate)) fig.update_layout(width=1485, height=1100) plotly.io.write_image(fig, file='test_line.png', format='png')
问题原因
Plotly默认对连续型坐标轴(含时间类x轴)自动添加左右边距,不会将坐标轴边缘直接对齐到数据集的最小、最大坐标点,因此会出现折线未贴住左边缘y轴的空白问题。
解决方法
只需调整x轴的配置参数,即可消除自动边距,实现折线从左边缘起始:
- 方案1:手动指定x轴范围,将x轴左右边界完全绑定到数据集的最小、最大日期,严格对齐数据范围
- 方案2:取消坐标轴自动边距设置,仅消除左右两侧的默认留白
方案1代码修改示例
替换原有fig.update_xaxes的代码段即可:
fig.update_xaxes( dtick="M6", tickformat="%b %Y", range=[data['Datum'].min(), data['Datum'].max()], tick0=sdate )
方案2代码修改示例
同样替换原有fig.update_xaxes的代码段:
fig.update_xaxes( dtick="M6", tickformat="%b %Y", range_padding=0, tick0=sdate )
可优化的代码细节
- 原代码未导入依赖模块,直接运行会报错,已在示例代码开头补充了必要的导入语句
- 原代码中新增数据行的逻辑
df_test.loc[len(df_test)+1,'Datum']会生成空索引行,若需严格按行数赋值,可改为df_test.loc[len(df_test),'Datum']
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

