Matplotlib Sankey图合并后箭头方向反转问题求助
问题:Matplotlib Sankey合并绘图后小流量箭头方向反转
问题现象
使用Matplotlib的Sankey模块绘制桑基图时:
- 单独绘制两个子图,数值为44的绿色箭头方向正常(与预期一致)
- 合并到同一个Sankey实例绘制后,该箭头方向完全反转
原因分析
- 多图连接的流量逻辑冲突:通过
prior和connect参数连接多个桑基图时,Sankey会根据前一个图的连接点流量方向自动调整当前图的流量符号逻辑,小流量的方向判断容易被干扰。 - 过大的
tolerance参数:设置tolerance=6000时,小流量(44)会被视为布局误差,导致方向判断被强制反转。 - 统一
scale参数的影响:合并时统一使用scale=0.0000006,与第一个图单独绘制时的scale=0.0000003差异较大,改变了小流量的布局计算规则。
修复方案
关键修复点
- 调小
tolerance参数,避免小流量被误判为布局误差 - 反转小流量的符号,匹配多图连接后的流量逻辑
- 同步调整对应
orientations值,确保箭头指向符合预期
修复后的完整代码
from matplotlib.sankey import Sankey from matplotlib import pyplot as plt a = [1008590.0368940466, -368142.35465001286, -34409.668598874494, -369212.57399895444, -236736.40069105377, -89.03895515092165] b = [199910.4894048177, 15518.603443203947, 143514.46418879204, 231094.9357130916, 44.28348931634303, -590082.7762392217] fig = plt.figure(figsize=[10,5], dpi=330) ax = fig.add_subplot(1,1,1) # 调小tolerance,避免小流量被误判 sankey = Sankey(ax=ax, scale=0.0000006, offset=0, format='%d', shoulder=0.02, tolerance=100) # 第一个桑基图保持原有设置 sankey.add(flows=a, labels=['Input', 'Low', 'Medium', 'High', 'Remote (Forest)', 'Other'], orientations=[0, -1, -1, -1, 0, 1], pathlengths=[0.05,0.1,0.3,0.2,0.1,0.1], trunklength=0.5, edgecolor='#2b8cbe', facecolor='#2b8cbe') # 第二个桑基图:修改小流量符号并匹配方向 modified_b = b.copy() modified_b[4] = -modified_b[4] # 反转44的流量符号,匹配连接逻辑 sankey.add(flows=modified_b, labels=['Low', 'Medium', 'High', 'Remote (Forest)-I', 'Other', 'Forest-Resilience'], orientations=[-1, -1, -1, 0, -1, 0], # 同步调整方向参数 pathlengths=[0.2,0.42,0.6,0.1,0.1,0.1], trunklength=0.5, prior=0, connect=(4,3), edgecolor='#2ca25f', facecolor='#2ca25f') # 第三个桑基图保持原有设置 sankey.add(flows=[b[0],-b[0]], orientations=[1,1], pathlengths=[0.1,0.1], trunklength=0.27, prior=1, connect=(0,1), edgecolor=None, facecolor='#99d8c9', hatch='....', zorder=-2, alpha=0.2) diagrams = sankey.finish() # 调整文本位置 diagrams[0].texts[4].set_position(xy=[1.1, 0.4]) diagrams[1].texts[3].set_position(xy=[1.55, 0.23]) diagrams[2].texts[0].set_position(xy=[1.55,-0.2]) # 设置字体大小 for diagram in diagrams: for text in diagram.texts: text.set_fontsize(10) plt.axis("off") plt.show()
内容的提问来源于stack exchange,提问作者Ep1c1aN
相关产品推荐
相关产品推荐

