matplotlib 在海运条形图中包括注解[重复]

cig3rfwq  于 2023-03-19  发布在  其他
关注(0)|答案(2)|浏览(138)

此问题在此处已有答案

How to add a footnote under the x-axis of a plot(2个答案)
Displaying a line of text outside of a plot(1个答案)
How to display a text with matplotlib(2个答案)
5小时前关门了。
我有一个条形图,我想包括一个说明在底部。目前的代码如下所示

import pandas as pd
import numpy as np
import seaborn as sns

import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter

data = {
'id': [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22],
'survey': ['baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline', 'baseline', 'endline'],
'level': ['low', 'high', 'medium', 'low', 'high', 'medium', 'medium', 'high', 'low', 'low', 'medium', 'high', 'low', 'medium', 'low', 'high', 'low', 'low', 'medium', 'high', 'high', 'high', 'high', 'medium', 'low', 'low', 'medium', 'high', 'low', 'medium', 'high', 'medium', 'low', 'high', 'high', 'medium', 'medium', 'low', 'high', 'low', 'low', 'low', 'low', 'low']
}

df = pd.DataFrame(data)

df_N = df.groupby(['level']).count().sort_index(ascending = True).reset_index()
df_N['%'] = 100 * df_N['id'] / df_N['id'].sum()

sns.set_style('white')
ax = sns.barplot(data=df_N, x='level', y='%', ci=None,
                 palette="rainbow")

N = df_N['id'].to_numpy()
N_it = '$\it{N}$'
labels=[f'{np.round(perc,1)}% ({N_it} = {n})' 
        for perc, n in zip(ax.containers[0].datavalues, N)]

ax.bar_label(ax.containers[0], labels = labels, fontsize = 10)

sns.despine(ax=ax, left=True)
ax.grid(True, axis='y')
ax.yaxis.set_major_formatter(PercentFormatter(100))
ax.set_xlabel('')
ax.set_ylabel('')
ax.margins(y=0.15)  # optionally some more free space at the top
plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0)
plt.tight_layout()
plt.show()

我想在下文中加入一个基于分类的说明

df_N = df.groupby(['survey', 'level']).count().sort_index(ascending = True).reset_index()
df_N

具体而言:
注:基线:高- 6、低- 10、中- 6底线:高-8、低-8、中-6

axkjgtzd

axkjgtzd1#

您可以使用annotate函数将注解定位在图下方,如下所示:

note = "Note: " + ", ".join([f"{row['survey'].capitalize()}: {row['level']} - {row['id']}" for _, row in df_N_disagg.iterrows()])
    
ax.annotate(
    note,
    xy=(-0.1, -0.2),
    xycoords="axes fraction",
    bbox=dict(boxstyle="round,pad=0.3", edgecolor="black", facecolor="aliceblue")
)

输出:

sshcrbum

sshcrbum2#

您可以使用seaborn模块中的text()

df_N = df.groupby(['survey', 'level']).count().sort_index(ascending = True).reset_index()
u_values = df_N['survey'].unique()
txt = ""
for val in u_values:
    txt += val + ": "
    a = df_N[df_N['survey'] == val][['level','id']].values.flatten().tolist()
    for i, j in enumerate(a):
        if i % 2 == 0:
                txt += str(j) + " - "
        else:
                txt += str(j) + ", "
txt = txt[:-2]
ax.text(-0.4, -5, txt, fontsize=10)

这是我得到的结果图:

注意:上述代码添加在代码中plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0)行之前。

相关问题