使用Plotly在Python中绘制马赛克图的条形间隙问题求助
解决Plotly马赛克图条形间隙问题
问题描述
使用Plotly在Python中生成马赛克(Marimekko)图时,条形之间出现无法消除的间隙,尝试fig.update_layout(bargap=0)无效。
带间隙的图表:
问题原因
- x轴范围设置错误:原代码中
fig1.update_xaxes(range=[0, widths])传入的widths是数组,实际应设置为宽度总和sum(widths),导致x轴范围未覆盖全部条形,视觉上产生间隙。 - 未覆盖分组间隙参数:仅设置
bargap=0不足以消除所有间隙,由于使用barmode='stack',还需设置bargroupgap=0来清除组内堆叠条形的间隙。
修复后的代码
import pandas as pd import numpy as np import plotly.graph_objects as go # Dataframe creation/formatting df = pd.DataFrame( [ [5755, 6221, 5424, 7261, 1158, 7075, 6780], [6103, 3143, 7094, 9212, 3175, 9956, 9655], [2810, 3047, 5938, 2067, 2189, 8892, 2380], ], columns=['X1','X2','X3','X4','X5','X6','X7'] ) df = df.T labels = ['Group1','Group2','Group3'] df.columns = labels for c in df.columns: df[c + '_%'] = df[c].apply(lambda x: (x/df.loc[:,c].sum()) * 100) widths = np.array([sum(df['Group1']),sum(df['Group2']),sum(df['Group3'])]) total_width = sum(widths) # 计算所有条形的总宽度 marker_colors = { 'X1':'darkblue', 'X2':'darkgreen', 'X3':'crimson', 'X4':'green', 'X5':'blue', 'X6':'red', 'X7':'orange' } fig1 = go.Figure() for idx in df.index: dff = df.filter(items=[idx], axis=0) fig1.add_trace(go.Bar( x=np.cumsum(widths) - widths, y=dff[dff.columns[3:]].values[0], width=widths, marker_color=marker_colors[idx], text=['{:.2f}%'.format(x) for x in dff[dff.columns[3:]].values[0]], name=idx ) ) # 将x轴刻度调整到每个条形的中间位置,更符合马赛克图的展示逻辑 fig1.update_xaxes( tickvals=np.cumsum(widths) - widths/2, ticktext= ["%s<br>%d" % (l, w) for l, w in zip(labels, widths)] ) # 修正x轴范围为总宽度,确保覆盖所有条形 fig1.update_xaxes(range=[0, total_width]) fig1.update_yaxes(range=[0, 100]) # 同时设置bargap和bargroupgap为0,彻底消除间隙 fig1.update_layout( barmode='stack', bargap=0, bargroupgap=0 ) fig1.show()
关键改动说明
- 修正x轴范围:将
range=[0, widths]改为range=[0, total_width],确保x轴完全覆盖所有条形的总宽度,避免因范围不足导致的视觉间隙。 - 双间隙参数设置:在
update_layout中同时添加bargap=0和bargroupgap=0,清除堆叠条形之间的所有间隙。 - 优化刻度位置:将
tickvals调整为np.cumsum(widths) - widths/2,让刻度显示在每个条形的中间,提升图表的可读性。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

