如何移除Seaborn图表中水平箭头上方的顶部边界线?
移除Seaborn绘图中水平箭头上方的顶部边界线
当前用Seaborn绘制的柱状图里,水平箭头上方存在一条多余的顶部边界线,需要将其消除。
原代码
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from matplotlib.patches import FancyArrowPatch sns.set(style="ticks", font_scale=1.2) np.random.seed(42) num_values = 4 data = { 'TR': [chr(ord('A') + i) for i in range(num_values)], 'Value': np.random.randint(10, 30, size=num_values) } df = pd.DataFrame(data) fig, ax = plt.subplots(figsize=(5, 7)) i = 'Value' palette = sns.color_palette("Set1", len(df)) g = sns.barplot(x='TR', y=i, palette=palette, edgecolor="white", errcolor="black", errorbar='sd', zorder=10, data=df) ax.set_ylim([0.9*df[i].min(), 1.1*df[i].max()]) sns.despine(ax=ax) height = 30 bar1 = g.containers[0][0] bar2 = g.containers[0][2] arrow = FancyArrowPatch((bar1.get_x() + bar1.get_width()/2, height), (bar2.get_x() + bar2.get_width()/2, height), arrowstyle='|-|', mutation_scale=10, linewidth=1.5, color='black', connectionstyle='angle, angleA=90, angleB=0, rad=0') ax.add_patch(arrow) plt.tight_layout() plt.show()
问题根源
原代码里箭头高度设为30,超过了设置的Y轴上限(1.1倍数据最大值,约28.6),Matplotlib为了显示完整箭头自动扩大了轴范围,导致原本被sns.despine()移除的顶部边框重新显示。
解决办法
办法一:调整箭头高度至轴范围内
不用固定写30,根据数据最大值动态设置高度,比如设为最大值的1.05倍,既能保证箭头在轴的显示范围内,又和柱子保持足够间距:
# 替换原height=30的行 height = 1.05 * df[i].max()
办法二:强制隐藏顶部轴脊
不管箭头是否超出轴范围,直接强制让顶部轴脊消失,在sns.despine(ax=ax)之后添加一行代码:
ax.spines['top'].set_visible(False)
修改后的完整代码(以办法二为例)
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from matplotlib.patches import FancyArrowPatch sns.set(style="ticks", font_scale=1.2) np.random.seed(42) num_values = 4 data = { 'TR': [chr(ord('A') + i) for i in range(num_values)], 'Value': np.random.randint(10, 30, size=num_values) } df = pd.DataFrame(data) fig, ax = plt.subplots(figsize=(5, 7)) i = 'Value' palette = sns.color_palette("Set1", len(df)) g = sns.barplot(x='TR', y=i, palette=palette, edgecolor="white", errcolor="black", errorbar='sd', zorder=10, data=df) ax.set_ylim([0.9*df[i].min(), 1.1*df[i].max()]) sns.despine(ax=ax) # 强制隐藏顶部轴脊 ax.spines['top'].set_visible(False) height = 30 bar1 = g.containers[0][0] bar2 = g.containers[0][2] arrow = FancyArrowPatch((bar1.get_x() + bar1.get_width()/2, height), (bar2.get_x() + bar2.get_width()/2, height), arrowstyle='|-|', mutation_scale=10, linewidth=1.5, color='black', connectionstyle='angle, angleA=90, angleB=0, rad=0') ax.add_patch(arrow) plt.tight_layout() plt.show()
预期效果
修改后图表将不再显示顶部边界线,箭头清晰展示在柱状图上方。
内容的提问来源于stack exchange,提问作者Sant
相关产品推荐
相关产品推荐

