pandas 如何为每个面添加水平中线和注解

y4ekin9u  于 2023-09-29  发布在  其他
关注(0)|答案(2)|浏览(109)

我有一个简单的FacetGrid的2行和1列的线图表示不同类别的方面-图片如下。

# lineplot for each Category over the last three years
g = sns.FacetGrid(df, row="Category", sharey=False, sharex=False, height=2.5, aspect = 3)
g = g.map(plt.plot, 'Date', 'Count')

如何添加显示每个面的平均计数的参考线和注解?

示例数据

  • 读取示例 Dataframe
import pandas as pd

data = {'Category': ['Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1',
                     'Group 1', 'Group 1', 'Group 1', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2',
                     'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2', 'Group 2'],
        'Date': ['2017-01-31', '2017-02-28', '2017-03-31', '2017-04-30', '2017-05-31', '2017-06-30', '2017-07-31', '2017-08-31', '2017-09-30', '2017-10-31', '2017-11-30', '2017-12-31', '2018-01-31', '2018-02-28', '2018-03-31', '2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31', '2018-11-30', '2018-12-31',
                 '2019-01-31', '2019-02-28', '2019-03-31', '2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31', '2019-08-31', '2019-09-30', '2017-01-31', '2017-02-28', '2017-03-31', '2017-04-30', '2017-05-31', '2017-06-30', '2017-07-31', '2017-08-31', '2017-09-30', '2017-10-31', '2017-11-30', '2017-12-31', '2018-01-31', '2018-02-28', '2018-03-31',
                 '2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31', '2018-11-30', '2018-12-31', '2019-01-31', '2019-02-28', '2019-03-31', '2019-04-30', '2019-05-31', '2019-06-30', '2019-07-31', '2019-08-31', '2019-09-30'],
        'Count': [226, 235, 236, 221, 187, 218, 225, 221, 248, 224, 204, 224, 218, 241, 196, 246, 256, 217, 229, 230, 222, 215, 226, 227, 232, 233, 224, 214, 243, 214, 235, 218, 208, 208, 254, 223, 227, 245, 222, 226, 235, 225, 226, 258, 234, 257, 224, 228, 222, 227, 256, 217, 243, 230, 250, 197, 232, 248, 232, 259, 259, 229, 228, 234, 218, 231]}

df = pd.DataFrame(data)
df.Date = pd.to_datetime(df.Date)

df.head()

Category       Date  Count
0  Group 1 2017-01-31    226
1  Group 1 2017-02-28    235
2  Group 1 2017-03-31    236
3  Group 1 2017-04-30    221
4  Group 1 2017-05-31    187
inb24sb2

inb24sb21#

g = sns.relplot(data=df, kind='line', x='Date', y='Count', row='Category', height=2.5, aspect=3, facet_kws={'sharey': True, 'sharex': False})
g.fig.tight_layout()

def custom(y, **kwargs):
    ym = y.mean()
    plt.axhline(ym, color="orange", linestyle="dashed")
    plt.annotate(f"mean: {y.mean():.3f}", xy=(1,ym), 
                 xycoords=plt.gca().get_yaxis_transform(), ha="right")
    

g = g.map(custom, 'Count')

只要一句台词就够了

g = sns.FacetGrid(df, row="Category", sharey=False, sharex=False, height=2.5, aspect = 3)
g = g.map(plt.plot, 'Date', 'Count')

# add this to get a horizontal line
g = g.map(lambda y, **kw: plt.axhline(y.mean(), color="k"), 'Count')

要使线条变为橙子和虚线并添加注解,可以执行以下操作

def custom(y, **kwargs):
    ym = y.mean()
    plt.axhline(ym, color="orange", linestyle="dashed")
    plt.annotate(f"mean: {y.mean():.3f}", xy=(1,ym), 
                 xycoords=plt.gca().get_yaxis_transform(), ha="right")
    

g = sns.FacetGrid(df, row="Category", sharey=False, sharex=False, height=2.5, aspect = 3)
g = g.map(plt.plot, 'Date', 'Count')
    
g = g.map(custom, 'Count')

0h4hbjxa

0h4hbjxa2#

g = sns.relplot(data=df, kind='line', x='Date', y='Count', row='Category', height=2.5, aspect=3, facet_kws={'sharey': True, 'sharex': False})
g.fig.tight_layout()

# draw lines:
for m, ax in zip(df.groupby('Category').Count.mean(), g.axes.ravel()):
    ax.hlines(m, *ax.get_xlim())
    ax.annotate(f'Mean: {m:0.0f}', xy=(ax.get_xlim()[1], m))

  • 这也适用于其他图形级别的图,如sns.catplot
g = sns.catplot(data=df, kind='bar', x='Date', y='Count', row='Category', height=2.5, aspect=3)
g.set_xticklabels(rotation=90)

# draw lines:
for m, ax in zip(df.groupby('Category').Count.mean(), g.axes.ravel()):
    ax.hlines(m, *ax.get_xlim())
    ax.annotate(f'Mean: {m:0.0f}', xy=(ax.get_xlim()[1], m))

可以在每个轴上手动绘制水平线:
zip(list1, list2)类似于[(list1[0], list2[0]), (list1[1], list2[1]),...]。在这个代码中,它意味着m是平均值,ax是小平面中的轴。ravel()将n维np.array转换为1D数组,因此您可以zipax.hlines(y_val, x_min, x_max)y_val处画一条从x_minx_max的水平线。这里,两个x值由*ax.get_xlim()提供。

g = sns.FacetGrid(df, row="Category", sharey=False, sharex=False, height=2.5, aspect = 3)
g = g.map(plt.plot, 'Date', 'Count')

# draw lines:
for m,ax in zip(df.groupby('Category').Count.mean(), g.axes.ravel()):
    ax.hlines(m,*ax.get_xlim())

输出量:

相关问题