如何在 Python 的 Matplotlib 中绘制嵌套饼图?

问题描述 投票:0回答:3

我在 Python 的 Matplotlib 中绘制嵌套饼图时遇到问题。我写了一些代码来处理这个过程,但我有一个与设计和标签相关的问题

我想画一种嵌套饼图。 (从嵌套的最上层到最里层是SEX,ALIGN覆盖他们的计数)

这是我的数据框,如下所示。

ALIGN   SEX count
2   Bad Characters  Male Characters 1542
5   Good Characters Male Characters 1419
3   Good Characters Female Characters   714
0   Bad Characters  Female Characters   419
8   Neutral Characters  Male Characters 254
6   Neutral Characters  Female Characters   138
1   Bad Characters  Genderless Characters   9
4   Good Characters Genderless Characters   4
7   Neutral Characters  Genderless Characters   3
9   Reformed Criminals  Male Characters 2

这是我与显示嵌套饼图相关的代码片段,如下所示。

fig, ax = plt.subplots(figsize=(24,12))
size = 0.3

ax.pie(dc_df_ALIGN_SEX.groupby('SEX')['count'].sum(), radius=1,
       labels=dc_df_ALIGN_SEX['SEX'].drop_duplicates(),
       autopct='%1.1f%%',
       wedgeprops=dict(width=size, edgecolor='w'))

ax.pie(dc_df_ALIGN_SEX['count'], radius=1-size, labels = dc_df_ALIGN_SEX["ALIGN"],
       wedgeprops=dict(width=size, edgecolor='w'))

ax.set(aspect="equal", title='Pie plot with `ax.pie`')
plt.show()

我如何设计 4 行和 4 列,并将每一个放在每个插槽中,并在图例区域显示标签?

python pandas matplotlib pie-chart
3个回答
6
投票

由于问题已更改,我发布了一个新答案。

首先,我稍微简化了你的 DataFrame:

import pandas as pd

df = pd.DataFrame([['Bad', 'Male', 1542],
                   ['Good', 'Male', 1419],
                   ['Good', 'Female', 714],
                   ['Bad', 'Female', 419],
                   ['Neutral', 'Male', 254],
                   ['Neutral', 'Female', 138], 
                   ['Bad', 'Genderless', 9], 
                   ['Good', 'Genderless', 4],
                   ['Neutral', 'Genderless', 3], 
                   ['Reformed', 'Male', 2]])
df.columns = ['ALIGN', 'SEX', 'n']

对于外圈的数字,我们可以像你一样使用简单的

groupby

outer = df.groupby('SEX').sum()

但是对于内环中的数字,我们需要按两个分类变量进行分组,这会产生一个 MultiIndex:

inner = df.groupby(['SEX', 'ALIGN']).sum()
inner
                     n
SEX         ALIGN   
Female      Bad      419
            Good     714
            Neutral  138
Genderless  Bad        9
            Good       4
            Neutral    3
Male        Bad     1542
            Good    1419
            Neutral  254
            Reformed   2

我们可以使用它的

get_level_values()
方法从MultiIndex中提取适当的标签:

inner_labels = inner.index.get_level_values(1)

现在您可以将上述值转换为一维数组并将它们插入您的绘图调用中:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(figsize=(24,12))
size = 0.3

ax.pie(outer.values.flatten(), radius=1,
       labels=outer.index,
       autopct='%1.1f%%',
       wedgeprops=dict(width=size, edgecolor='w'))

ax.pie(inner.values.flatten(), radius=1-size, 
       labels = inner_labels,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.set(aspect="equal", title='Pie plot with `ax.pie`')
plt.show()


0
投票

你定义函数

percentage_growth(l)
的方式假设它的参数
l
是一个列表(或其他一些一维对象)。但是然后(分配
colors
)你在
dc_df_ALIGN_SEX
上调用这个函数,这显然是你的DataFrame。因此函数(在其循环的第一次迭代中)尝试评估
dc_df_ALIGN_SEX[0]
,这会抛出关键错误,因为这不是索引 DataFrame 的正确方法。

也许你想做像

percentage_growth(dc_df_ALIGN_SEX['count'])
这样的事情?


0
投票

你能试试一个名为 omniplot 的 python 模块吗?它使用 matplotlib。它有一个名为“nested_piechart”的方法,可以从 pandas 数据框中绘制嵌套饼图,如下所示。

import pandas as pd
import omniplot.plot as op
import matplotlib.pyplot as plt

df = pd.DataFrame([['Bad', 'Female', 419],
                   ['Good', 'Male', 1419],
                   ['Bad', 'Male', 1542],
                   ['Good', 'Genderless', 4],
                   ['Good', 'Female', 714],
                   ['Neutral', 'Female', 138], 
                   ['Neutral', 'Male', 254],
                   
                   ['Bad', 'Genderless', 9], 
                   
                   ['Neutral', 'Genderless', 3], 
                   ['Reformed', 'Male', 2]])
df.columns = ['ALIGN', 'SEX', 'n']
op.nested_piechart(df=df, category=['ALIGN', 'SEX'], variable="n")
# optionally plt.savefig("test.png") or plt.show()

The result

它也可以对标签进行排序。

op.nested_piechart(df=df, category=['ALIGN', 'SEX'], variable="n", show_percentage=True, order="largest")

The result2

© www.soinside.com 2019 - 2024. All rights reserved.