如何使用字典创建华夫饼图?

3

我正在通过Jupyter lab学习Python,遇到了Waffle chart的问题。

我有以下字典,想要将其显示为Waffle图表:

import pandas as pd 
import matplotlib.pyplot as plt
from pywaffle import Waffle

dic = {'Xemay':150,'Xedap':20,'Oto':180,'Maybay':80,'Tauthuy':135,'Xelua':5}
df = pd.DataFrame.from_dict(dic, orient='index')

plt.figure(FigureClass=Waffle,rows=5,values=dic,legend={'loc': 'upper left', 'bbox_to_anchor': (1, 1)})
plt.title('Số lượng xe bán được của một công ty')
plt.show()

然而,结果却出乎意料:

Screenshot1

相反,图表应该像这样。我做错了什么?

Screenshot2


3
你是否使用PyWaffle创建图表?如果你明确包含导入包的话,可以帮助人们回答问题。 - Robert King
是的,我已经导入了以下库: import numpy as np import pandas as pd import seaborn as sns from matplotlib import pyplot as plt from pywaffle import Waffle import collections from wordcloud import WordCloud, STOPWORDS from PIL import Image import folium import geopandas as gpd import math import re from folium import plugins - Tuyen Duong
2
这个回答解决了你的问题吗?如何在Python中制作华夫饼图(正方形饼图)? - rpanai
1
另外在项目页面也可以看到不错的介绍。 - JohanC
2个回答

3

实际上,您的代码是正确的,Waffle正确显示了您的数据(缩放图表以查看方块...)

但是,要实现所需的输出,您需要调整“行”和“列”参数,这些参数指定了您的华夫饼图的尺寸。

nRows=5
countsPerBlock=10  # 1 block = 10 counts
plt.figure(FigureClass=Waffle,
           rows=nRows,
           columns=int(np.ceil(sum(dic.values())/nRows/countsPerBlock)),
           values=dic,
           legend={'loc': 'upper left', 'bbox_to_anchor': (1, 1.1)})
plt.show()

Screenshot solution 2

请注意,华夫饼干内部应用了一些舍入(参见参数 rounding_rule),因此除非您自己调整数据的比例,否则countsPerBlock不是完全准确的。要精确地重现所需的输出,请使用以下代码:
nRows = 5
countsPerBlock = 10
keys = ['Xemay', 'Xedap', 'Oto', 'Maybay', 'Tauthuy', 'Xelua']
vals = np.array([150, 20, 180, 80, 135, 5])
vals = np.ceil(vals/countsPerBlock)
data = dict(zip(keys, vals))

plt.figure(FigureClass=Waffle,
           rows=5,
           values=data,
           legend={'loc': 'upper left', 'bbox_to_anchor': (1, 1)})
plt.show()

Screenshot solution final

或者,您可以将数据标准化,使值的总和为100。在一个5x20的方格中,一个方格将代表您数据的1%。

# Create a dict of normalized data. There are plenty of 
# ways to do this. Here is one approach:
keys = ['Xemay', 'Xedap', 'Oto', 'Maybay', 'Tauthuy', 'Xelua']
vals = np.array([150, 20, 180, 80, 135, 5])
vals = vals/vals.sum()*100
data = dict(zip(keys, vals))
nRows = 5
# ...

Screenshot solution final


我们可以按照正常值来做,而不是按百分比吗? - Tuyen Duong
如果您想让1计数由1个块表示,请参阅我的答案的第二部分。 - normanius
1
还可以查看文档获取更多示例。 - normanius
@TuyenDuong 不客气 :) 我在我的回答中添加了另一个更新,以完全重现您的输出。我注意到‘Waffle’进行了一些内部舍入。 - normanius

0

这两个代码选项可以解决我的问题:

1. 来自Mr.Normanius的贡献:

nRows = 5
countsPerBlock = 10
keys = ['Xemay', 'Xedap', 'Oto', 'Maybay', 'Tauthuy', 'Xelua']
vals = np.array([150, 20, 180, 80, 135, 5])
vals = np.ceil(vals/countsPerBlock)
data = dict(zip(keys, vals))

plt.figure(FigureClass=Waffle,
           rows=5,
           values=data,
           legend={'loc': 'upper left', 'bbox_to_anchor': (1, 1)})
plt.show()

2. 从我所学到的:

fig = plt.figure(
    FigureClass=Waffle, 
    rows=5, 
    values=df[0]/10, 
    title={'label': 'So luong xe duoc ban cua mot cong ty', 'loc': 'left'},
    labels=df.index.tolist(),
    legend={'loc': 'lower right', 'bbox_to_anchor': (1, 0.5)}
)
plt.show()

以下是结果: 在此输入图像描述

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接