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

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

此问题在此处已有答案

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小时前关门了。
我有一个条形图,我想包括一个说明在底部。目前的代码如下所示

  1. import pandas as pd
  2. import numpy as np
  3. import seaborn as sns
  4. import matplotlib.pyplot as plt
  5. from matplotlib.ticker import PercentFormatter
  6. data = {
  7. '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],
  8. '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'],
  9. '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']
  10. }
  11. df = pd.DataFrame(data)
  12. df_N = df.groupby(['level']).count().sort_index(ascending = True).reset_index()
  13. df_N['%'] = 100 * df_N['id'] / df_N['id'].sum()
  14. sns.set_style('white')
  15. ax = sns.barplot(data=df_N, x='level', y='%', ci=None,
  16. palette="rainbow")
  17. N = df_N['id'].to_numpy()
  18. N_it = '$\it{N}$'
  19. labels=[f'{np.round(perc,1)}% ({N_it} = {n})'
  20. for perc, n in zip(ax.containers[0].datavalues, N)]
  21. ax.bar_label(ax.containers[0], labels = labels, fontsize = 10)
  22. sns.despine(ax=ax, left=True)
  23. ax.grid(True, axis='y')
  24. ax.yaxis.set_major_formatter(PercentFormatter(100))
  25. ax.set_xlabel('')
  26. ax.set_ylabel('')
  27. ax.margins(y=0.15) # optionally some more free space at the top
  28. plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0)
  29. plt.tight_layout()
  30. plt.show()

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

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

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

axkjgtzd

axkjgtzd1#

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

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

输出:

sshcrbum

sshcrbum2#

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

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

这是我得到的结果图:

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

展开查看全部

相关问题