如何用指示时间段到下一个时间段的百分比变化的连接线制作海图的条形图?

时间:2020-10-23 13:15:00

标签: matplotlib seaborn

我在网上可以找到的唯一参考文献是在条形图here的顶部放置一个百分比,但没有一条带有连接线的文字,并且在连接线的中心的条之间放置了一些文本。

当前我的图表如下:

enter image description here

df_revenue = compiled_data[compiled_data['Fee Name'] == "Item Price Credit"]
df_revenue = df_revenue.groupby(['Year']).sum()
df_revenue = df_revenue.reset_index()

sns.set_theme(font_scale=1.5, style="whitegrid")
g = sns.catplot(data=df_revenue, x='Year', y='Amount', kind='bar', height=6, aspect=12/6)
g.set(title="Yearly Revenues", xlabel = 'Year', ylabel='Amount')
sns.despine(left=True)

for ax in g.axes[:,0]:
    ax.yaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
plt.show()

但是我希望它看起来像这样,我不确定该如何处理:

enter image description here

1 个答案:

答案 0 :(得分:2)

您可以遍历条形图,提取其尺寸并将其用于线条和文本:

import seaborn as sns
import pandas as pd
from matplotlib import ticker
from matplotlib import pyplot as plt

df_revenue = pd.DataFrame({'Year': [2018, 2019, 2020], 'Amount': [100000, 1200000, 3200000]})

sns.set_theme(font_scale=1.5, style="whitegrid")
g = sns.catplot(data=df_revenue, x='Year', y='Amount', kind='bar', height=6, aspect=12 / 6)
g.set(title="Yearly Revenues", xlabel='Year', ylabel='Amount')
sns.despine(left=True)

for ax in g.axes[:, 0]:
    ax.yaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
for ax in g.axes.ravel():
    for bar_group in ax.containers:
        prev = None
        for bar in bar_group:
            if prev != None:
                x0 = prev.get_x() + prev.get_width()
                x1 = bar.get_x()
                y0 = prev.get_y() + prev.get_height()
                y1 = bar.get_y() + bar.get_height()
                ax.plot([x0, x1], [y0, y1], color='black', lw=2)
                if y0 > 0 and y0 != y1:
                    ax.text((x0 + x1) / 2, (y0 + y1) / 2, f' {(y1 - y0) / y0 * 100:.1f} % ',
                            ha='right' if y0 < y1 else 'left', va='center')
            prev = bar
plt.tight_layout()
plt.show()

example plot