【问题标题】:How Add Average Values to a Categorical Plot in Python如何在 Python 中将平均值添加到分类图中
【发布时间】:2022-01-19 23:19:18
【问题描述】:

尝试将平均值添加到图中的每个类别。我一直在尝试按类别独立添加这些平均值,但没有成功。有没有一种方法可以让 catplot 平均数据集中的值并用不同的颜色绘制额外的值?我的目标是将平均值与单个值相加并加以区分,以便直观地识别。

plt.rcParams["figure.figsize"] = [5.50, 5.50]
plt.rcParams["figure.autolayout"] = True

ax = sns.catplot(x="Sample Set", y="Values [%]", data=df)
ax.set_xticklabels(rotation=90)
ax.despine(right=True, top=True)

sp = 100
delta = 5
plt.axhline(y=sp, color='gray', linestyle='--', label='Target')

plt.axhline(y=sp*((100+(delta*2))/100), color='r', linestyle='--', label='10%')
plt.axhline(y=sp*((100-(delta*2))/100), color='r', linestyle='--')

plt.ylim(80, 120)
plt.title('Sample Location[enter image description here][1]', fontsize = 14, y=1.05)
    
plt.legend(frameon=False, loc ="lower right")
plt.savefig(outputFileName, dpi=300, bbox_inches = 'tight')
plt.show()
plt.draw()

【问题讨论】:

  • 您可以创建一个排除平均值的catplot,然后叠加平均值
  • @DerekO 喜欢这个想法,在实施您的建议后,我现在唯一的限制是添加一个说明虚线、单个值和平均值的图例。任何帮助将不胜感激。
  • 我没有足够的时间认真尝试解决方案,所以我将我的想法作为评论留下,希望能帮助您或其他人开始解决方案。当我有更多时间时,我很乐意重新审视您的问题,看看我是否可以提供进一步的帮助
  • @DerekO,谢谢!

标签: python matplotlib seaborn catplot


【解决方案1】:

您可能会遇到奇怪的错误消息,因为您将sns.catplot 的返回值命名为axsns.catplot 是一个"figure-level" 函数并返回一个FacetGrid,通常分配给一个名为g 的变量。图形级函数可以有一个或多个子图,可通过g.axes 访问。当只有一个子图时,g.ax 指向该子图。

还要注意catplot 的 figsize 不是通过rcParams 设置的。图形大小来自height= 参数(一个子图的高度,以英寸为单位)和aspect= 参数(子图的宽高比)乘以子图的行数/列数。

此外,您似乎正在混合 "object-oriented" 和 matplotlib 的 pyplot 接口。为了可读性和代码维护,最好坚持一个界面。

为了表示均值,可能适合使用不带置信区间的sns.pointplotax.axhspan 可用于可视化目标周围的范围。

这里是从 seaborn 的 iris 数据集开始的一些示例代码。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

iris = sns.load_dataset('iris')

g = sns.catplot(data=iris, x="species", y="sepal_length", height=5.50, aspect=1)
ax = g.ax
ax.tick_params(axis='x', rotation=0, length=0)
sns.pointplot(data=iris, x="species", y="sepal_length", estimator=np.mean,
              join=False, ci=None, markers=['D'], color='black', size=20, zorder=3, ax=ax)
sns.despine(right=True, top=True)

sp = 6
delta = 10
ax.axhline(y=sp, color='gray', linestyle='--', label='Target')
ax.axhspan(ymin=sp * (100 - delta) / 100, ymax=sp * (100 + delta) / 100,
           color='r', alpha=0.15, linestyle='--', label='10%')

ax.collections[-1].set_label('Mean')
ax.legend(frameon=False, loc="lower right")
# plt.savefig(outputFileName, dpi=300, bbox_inches='tight')
plt.tight_layout()
plt.show()

【讨论】:

  • 感谢您的帮助和建议。非常感谢!
  • 我会的,因为它确实解决了上述问题。但是,唯一缺少的部分是如何为平均值添加图例。我一直在尝试在点图函数中使用标签方法,但没有奏效。
  • Seaborn 和图例通常很复杂,因为典型的函数结合了许多 matplotlib 元素。在这种情况下,ax.collections[-1].set_label('Mean') 将标签添加到包含均值的集合中。
  • 感谢您的帮助 JohanC!效果很好。
【解决方案2】:

根据plotting with seaborn using the matplotlib object-oriented interfacecatplotFigure-level类型的图,与其他一些类型的图相比,这样做会困难得多。

第二组函数(图形级)的区别在于 事实上,结果图可能包括几个轴 它们总是以“有意义”的方式组织起来。这意味着 函数需要完全控制图形,所以它不是 例如,可以将 lmplot 绘制到已经存在的 lmplot 上。打电话 该函数始终初始化一个图形并将其设置为 它正在绘制的具体情节。

【讨论】:

    猜你喜欢
    • 2015-01-13
    • 2011-09-27
    • 1970-01-01
    • 2021-08-09
    • 2020-11-22
    • 1970-01-01
    • 2016-06-12
    • 2022-01-12
    相关资源
    最近更新 更多