【问题标题】:Produce pie chart subplots for unique results in groupby?为 groupby 中的独特结果生成饼图子图?
【发布时间】:2018-12-13 08:16:32
【问题描述】:

为 Dataframe 中的唯一值生成饼图的最佳方法是什么?

我有一个按县显示服务数量的 DataFrame。我想为每个县制作一组饼图,显示该县的服务数量。我尝试了各种不同的方法,但都没有成功。

这是我的数据

打印(mdfgroup)

    County     Service    ServiceCt
0   Alamance    Literacy          1
1   Alamance   Technical          1
2   Alamance  Vocational          4
3    Chatham    Literacy          3
4    Chatham   Technical          2
5    Chatham  Vocational          1
6     Durham    Literacy          1
7     Durham   Technical          1
8     Durham  Vocational          1
9     Orange    Literacy          1
10      Wake    Literacy          2
11      Wake   Technical          2

因此,Alamance 将有一张图表,其中包含读写能力、技术、职业方面的切片; Chatham、Durham 等图表。切片大小将基于 ServiceCt。

我一直在尝试很多不同的方法,但我不确定哪种方法最有效。我试过了,但在它下面并没有真正按县划分,也没有产生任何图表。

for i, row in enumerate(mdfgroup.itertuples(),1):
       plt.figure()
       plt.pie(row.ServiceCt,labels=row.Service,
       startangle=90,frame=True, explode=0.2,radius=3)
plt.show()

这会引发错误:

TypeError: len() of unsized object

然后产生一个空白的绘图框

(我还不能嵌入图片,所以这里是链接) Blank Plot Box

理想情况下,我希望它们都成为次要情节,但在这个阶段,我会拍摄一系列单独的情节。我发现的其他示例不处理键(县)的唯一值。

【问题讨论】:

  • 什么是mdfgroup?您可能想阅读minimal reproducible example。
  • 糟糕。 mdfgroup 是列出的数据框。更新了帖子以澄清。

标签: python matplotlib pie-chart


【解决方案1】:

使用 matplotlib

一种常见的方法是遍历列的groupby。这里要迭代的列是"Country"。您可以首先创建一个子图网格,其中子图的数量至少与您拥有的独特国家/地区一样多。然后您可以同时迭代子图和组。
最后可能会有一些空的子图;这些可以设置为不可见。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"Country" : list("AAACCCDDDOWW"),
                   "Service" : list("LTV")*4,
                   "ServiceCt" : list(map(int, "114321111122"))})

cols = 3
g = df.groupby("Country")
rows = int(np.ceil(len(g)/cols))

fig, axes = plt.subplots(ncols=cols, nrows=rows)

for (c, grp), ax in zip(g, axes.flat):
    ax.pie(grp.ServiceCt, labels=grp.Service)
    ax.set_title(c)

if len(g) < cols*rows:    
    for ax in axes.flatten()[len(g):]:
        ax.axis("off")
        
plt.show()

使用 seaborn

这个案例其实很适合和seaborn的FacetGrid一起使用。

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

df = pd.DataFrame({"Country" : list("AAACCCDDDOWW"),
                   "Service" : list("LTV")*4,
                   "ServiceCt" : list(map(int, "114321111122"))})

def pie(v, l, color=None):
    plt.pie(v, labels=l.values)
g = sns.FacetGrid(df, col="Country")
g.map(pie, "ServiceCt", "Service" )
        
plt.show()

使用熊猫

最后,使用 pandas 可以在一行中完成所有操作。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"Country" : list("AAACCCDDDOWW"),
                   "Service" : list("LTV")*4,
                   "ServiceCt" : list(map(int, "114321111122"))})


df.pivot("Service", "Country", "ServiceCt").plot.pie(subplots=True, legend=False)
        
plt.show()

【讨论】:

  • 混蛋,又被打得落花流水!
  • 好的,我添加了一些其他选项来让这些答案有所不同。
【解决方案2】:

这是你的想法吗?

Ncounties = len(mdfgroup.County.unique())
fig, axs = plt.subplots(1, Ncounties, figsize=(3*Ncounties,3), subplot_kw={'aspect':'equal'})
for ax,(groupname,subdf) in zip(axs,mdfgroup.groupby('County')):
    ax.pie(subdf.ServiceCt, labels=subdf.Service)
    ax.set_title(groupname)

【讨论】:

  • 是的!谢谢。看到它写出来,现在完全有道理。确定有多少个独特的县,制作许多子图,然后循环并绘制它们。
  • 在我的例子中,数据点在不同的组中分布均匀。由于 aspect:equal 参数,它确实设法使我的散点图保持可读性,但与其他两个子图相比,它会将子图的大小更改为一个小矩形。如何解决这个问题?
  • 如何调整两个级别的 groupby 以便有 6 种组合,并且我希望子图的形状为 (2,3)?
猜你喜欢
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 2022-01-16
  • 2019-12-28
相关资源
最近更新 更多