Plotly中同名索引行的独立堆叠柱状图实现问题
解决Plotly堆叠横向柱状图中同名索引被合并的问题
问题背景
用Python 3.10结合Plotly开发时,有一个约40行的DataFrame(cluster_user_distribution_data),原本以唯一学校名称为索引时,能正常生成按多数聚类分组的堆叠横向柱状图。为实现匿名,将索引重命名为Small school、Medium school等重复类别后,Plotly会自动合并同名索引的行,导致堆叠柱状图数据错误聚合。临时方案是给名称加唯一编号,但希望找到无需修改名称的解决方法。
核心原因
Plotly的Bar图表会根据y参数的标签值进行分组堆叠,当多个trace的y标签相同时,会被合并到同一行,这是堆叠混乱的根本原因。
解决方案
用唯一的数值型y轴标识作为绘图的实际y值,同时通过自定义y轴刻度,将显示的文本替换为需要的匿名类别名称。这样既保证每行数据独立不合并,又能显示预期的匿名标签。
修改后的核心代码
import plotly.graph_objects as go import numpy as np # clusters_with_majority是包含至少一个用户的多数聚类的唯一数组,例如[0,1,3] # cluster_user_distribution_data_largest_cluster是每个用户的多数聚类序列 row_number = 1 for i in np.sort(clusters_with_majority): x_data = cluster_user_distribution_data.loc[cluster_user_distribution_data_largest_cluster == i] # 按降序排序数据用于绘制柱状图 x_data = x_data.sort_values(x_data.columns[i]) # 获取排序后的索引列表和数组格式的数据 y_labels = x_data.index.tolist() # 存储匿名标签(Small school等) x_data_values = x_data.values # 生成唯一的数值型y值(用行的位置索引,保证每个行唯一) unique_y_values = list(range(len(y_labels))) # 将重点聚类移至第一列 x_data_values[:, [0, i]] = x_data_values[:, [i, 0]] for j in range(len(x_data_values[0])): for xd, y_val in zip(x_data_values, unique_y_values): fig.add_trace(go.Bar( x=[xd[j]], y=[y_val], # 使用唯一数值作为y值,避免合并 orientation='h', marker=dict( color=colors_loop[j], line=dict(color='black', width=bar_plot_line_width) ), showlegend=False, ), row=row_number, col=1, ) # 配置当前子图的y轴刻度,显示匿名标签 fig.update_yaxes( tickvals=unique_y_values, ticktext=y_labels, row=row_number, col=1 ) row_number += 1
关键改动说明
- 生成
unique_y_values:用行的位置索引(0,1,2...)作为每个行的唯一标识,确保Plotly不会合并相同y值的trace - 更新y轴配置:通过
tickvals指定实际的数值y值,ticktext替换为需要显示的匿名类别名称,实现“实际值唯一,显示值匿名”的效果 - 绘图时使用
y=[y_val]替代原来的y=[yd],基于唯一数值定位行
内容的提问来源于stack exchange,提问作者Calle Flygare
相关产品推荐
相关产品推荐

