Python Plotly折线子图图例排序设置无效解决方法
问题说明
使用Plotly绘制双子图折线图时,子图内周末时段添加了灰色半透明填充(对应trace设置了showlegend = False不在图例显示),尝试通过fig.update_layout(legend_traceorder="reversed")反转图例顺序不生效,当前图例B显示在A前方,预期效果为A在前、B在后。
复现代码如下:
import numpy as np import pandas as pd import plotly.graph_objects as go from plotly.subplots import make_subplots rng = pd.date_range('2022-04-09', periods=20, freq='D') np.random.seed(42) first_df = pd.DataFrame({ 'Date': rng, 'Val' : np.random.randn(len(rng))}) first_df['Type'] = 'A' second_df = pd.DataFrame({ 'Date': rng, 'Val' : np.random.randn(len(rng))}) second_df['Type'] = 'B' final_df = pd.concat([first_df,second_df]).sort_values(by = 'Date') final_df['Is_Weekend'] = np.where((final_df['Date'].dt.weekday == 5), 1, 0 ) A_df = final_df[final_df['Type']=='A'] B_df = final_df[final_df['Type']=='B'] fig = make_subplots(rows=2, cols=1, shared_xaxes=True, specs=[[{"secondary_y": True}],[{"secondary_y": True}]]) fig.add_trace(go.Scatter(x=A_df['Date'], y=A_df['Is_Weekend'], fill = 'tonexty', fillcolor = 'rgba(128,128,128, 0.2)', line_shape = 'hv', line_color = 'rgba(0,0,0,0)', showlegend = False ), row = 1, col = 1, secondary_y=True) fig.update_xaxes(showgrid=False, row=1, col=1) fig.update_yaxes(range=[-0,0.1], showgrid=False, tickfont_color = 'rgba(0,0,0,0)', secondary_y=True, row=1, col=1) fig.add_trace(go.Scatter(x=A_df['Date'], y = A_df['Val'], line_color = 'orange', mode = 'lines+markers', showlegend = True, name = "A"), row=1, col=1, secondary_y = False) fig.add_trace(go.Scatter(x=B_df['Date'], y=B_df['Is_Weekend'], fill = 'tonexty', fillcolor = 'rgba(128,128,128, 0.2)', line_shape = 'hv', line_color = 'rgba(0,0,0,0)', showlegend = False ), row=2, col=1, secondary_y=True) fig.update_xaxes(showgrid=False, row=2, col=1) fig.update_yaxes(range=[-0,0.1], showgrid=False, tickfont_color = 'rgba(0,0,0,0)', secondary_y=True, row=2, col=1) fig.add_trace(go.Scatter(x=B_df['Date'], y = B_df['Val'], line_color = 'blue', mode = 'lines+markers', showlegend = True, name = "B"), row=2, col=1, secondary_y = False) fig.update_layout(legend_traceorder="reversed") fig.show()
原因分析
legend_traceorder="reversed"的反转逻辑针对所有trace生效,包括设置了showlegend=False、不在图例中显示的辅助trace,并非仅反转可见图例条目。
当前代码的trace添加顺序为:
- A子图周末灰色填充(隐藏图例)
- A类数据折线(显示图例,名称A)
- B子图周末灰色填充(隐藏图例)
- B类数据折线(显示图例,名称B)
执行全量反转后trace顺序变为B折线→B填充→A折线→A填充,过滤掉隐藏图例的条目后,最终显示顺序就是B在前、A在后,和预期不符。
解决方案
使用legendrank参数手动指定图例排序优先级是最简便的方案,不需要调整现有代码的trace添加顺序,也不会被隐藏的辅助trace干扰排序逻辑:该参数取值越小,对应图例条目的展示位置越靠前。
操作步骤:
- 删除原有无效的
fig.update_layout(legend_traceorder="reversed")配置 - 给名称为A的折线Scatter配置添加
legendrank=1 - 给名称为B的折线Scatter配置添加
legendrank=2
修改后对应代码片段如下:
# A折线配置 fig.add_trace(go.Scatter(x=A_df['Date'], y = A_df['Val'], line_color = 'orange', mode = 'lines+markers', showlegend = True, name = "A", legendrank=1 ), row=1, col=1, secondary_y = False) # B折线配置 fig.add_trace(go.Scatter(x=B_df['Date'], y = B_df['Val'], line_color = 'blue', mode = 'lines+markers', showlegend = True, name = "B", legendrank=2 ), row=2, col=1, secondary_y = False)
运行修改后的代码,图例就会按照A在前、B在后的预期顺序显示。
内容的提问来源于stack exchange,提问作者user9532692
相关产品推荐
相关产品推荐

