【问题标题】:How to make multiple scatter subplots with sharing one-axis?如何通过共享一个轴制作多个散点图?
【发布时间】:2021-04-24 03:12:43
【问题描述】:
date name amount
1 harry 100
1 joe 20
2 harry 50
3 joe 60
3 lee 25
4 lee 60
4 harry 200
4 joe 90

我试图与 432 人名共享“日期”轴(x 轴)。图片太大,无法显示。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

dec=pd.read_csv('december.csv')
sns.lmplot(x='date', y='amount',
           data= dec, fit_reg=False, hue='name', legend=True, palette='Set1')

这段代码给出了一个 432 色相的图表。但我想要 432 个图表。怎么做?

【问题讨论】:

标签: python pandas matplotlib seaborn


【解决方案1】:

使用您编写的相同代码,但不是输入hue='name',而是输入col='name',它应该会给您预期的行为:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

dec = pd.DataFrame(
    [
        [1,'harry',100],
        [1,'joe',20],
        [2,'harry',50],
        [3,'joe',60],
        [3,'lee',25],
        [4,'lee',60],
        [4,'harry',200],
        [4,'joe',90],        
    ],
    columns=['date','name','amount'],
)

sns.lmplot(
    x='date',
    y='amount',
    data= dec,
    fit_reg=False,
    col='name',
    legend=True,
    palette='Set1',
)

如果要分行,可以使用col_wrap(每行的绘图数)定义列包装:

sns.lmplot(
    x='date',
    y='amount',
    data= dec,
    fit_reg=False,
    col='name',
    col_wrap=1,
    legend=True,
    palette='Set1',
)

编辑:使用groupby() 方法,您可以轻松获得聚合,例如每个图的点数和每组的总量。 主要思想是按名称对dec 数据框中的记录进行分组(是否已在上图中隐式完成)。

继续上面的代码,您可以使用describe 方法预览groupby 操作:

dec.groupby('name').describe()

Out[2]: 
       date                                                amount                                                          
      count      mean       std  min   25%  50%   75%  max  count        mean        std   min    25%    50%     75%    max
name                                                                                                                       
harry   3.0  2.333333  1.527525  1.0  1.50  2.0  3.00  4.0    3.0  116.666667  76.376262  50.0  75.00  100.0  150.00  200.0
joe     3.0  2.666667  1.527525  1.0  2.00  3.0  3.50  4.0    3.0   56.666667  35.118846  20.0  40.00   60.0   75.00   90.0
lee     2.0  3.500000  0.707107  3.0  3.25  3.5  3.75  4.0    2.0   42.500000  24.748737  25.0  33.75   42.5   51.25   60.0

使用 pandas groupby 方法,我们按 'name' 对记录进行分组并选择任意列(此处为:'amount')来获取计数(计数对于每一列都是相同的聚合,因为它计算每个单独的出现每个不同的'name'):

counts = dec.groupby('name')['amount'].count()
counts

Out[3]: 
name
harry    3
joe      3
lee      2
Name: amount, dtype: int64

要获得总金额,我们也这样做,我们选择'amount' 列并调用sum() 方法而不是count() 方法:

total_amounts = dec.groupby('name')['amount'].sum()
total_amounts

Out[4]: 
name
harry    350
joe      170
lee       85
Name: amount, dtype: int64

我们现在有两个由'name' 索引的系列,其中包含我们想要的信息:countstotal_amounts。 我们将使用这两个系列为每个子情节建立一个标题:

plot = sns.lmplot(
    x='date',
    y='amount',
    data=dec,
    fit_reg=False,
    col='name',
    legend=True,
    palette='Set1',
)

for name in plot.axes_dict:
    sublot_title = f'name = {name}, number of dots = {counts[name]}, total amount = {total_amounts[name]}'
    plot.axes_dict[name].set_title(sublot_title)

plot.fig

打印出来:

【讨论】:

  • 谢谢! @apaolilo 如果我还想用名字显示计数怎么办?
  • “计数”是指每个名称的amount 值的总和吗?或者它在数据框中出现的次数(每个子图上的点数)?
  • @apaolilo 你能告诉我怎么做吗?
  • @ShashwatAwasthi 我编辑了答案以解释如何做到这两点
猜你喜欢
  • 2023-03-14
  • 2019-11-26
  • 2021-12-15
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多