如何解决从字典创建饼图并更改箭头
我在字典中有一些计数数据,如下所示:
data = {'a_column': 20,'b_column': 130,'c_column': 140,'d_column': 300,'e_column': 150,'f_column': 170,'g_column': 10,'h_column': 20,'i_column': 250,'j_column': 54}
我想绘制一个饼图,如下所示:
我尝试过的:
base_d = sum(list(data.values()))
final_data = {k:m/base_d*100 for k,m in data.items()}
final_data
import numpy as np
import matplotlib.pyplot as plt
fig,ax = plt.subplots(figsize=(12,5),subplot_kw=dict(aspect="equal"))
recipe = list(final_data.keys())
data = list(final_data.values())
wedges,texts = ax.pie(data,wedgeprops=dict(width=0.5),startangle=-40)
bbox_props = dict(boxstyle="square,pad=0.3",fc="w",ec="k",lw=0.72)
kw = dict(arrowprops=dict(arrowstyle="-"),bbox=bbox_props,zorder=0,va="center")
for i,p in enumerate(wedges):
ang = (p.theta2 - p.theta1)/2. + p.theta1
y = np.sin(np.deg2rad(ang))
x = np.cos(np.deg2rad(ang))
horizontalalignment = {-1: "right",1: "left"}[int(np.sign(x))]
connectionstyle = "angle,angleA=0,angleB={}".format(ang)
kw["arrowprops"].update({"connectionstyle": connectionstyle})
ax.annotate(recipe[i],xy=(x,y),xytext=(1*np.sign(x),1.4*y),horizontalalignment=horizontalalignment,**kw)
plt.show()
但这给了我这样的:
如何使箭头像预期的图像一样并删除标签周围的边框?
解决方法
我做了两件事。
1.计算添加到标签的百分比
2.去掉盒子样式
import numpy as np
import matplotlib.pyplot as plt
def combine_column_names(column_name,cur_value,sums):
percentage = round(cur_value/sums*100,2)
name = "{} {}%".format(column_name,percentage)
return name
data = {'a_column': 20,'b_column': 130,'c_column': 140,'d_column': 300,'e_column': 150,'f_column': 170,'g_column': 10,'h_column': 20,'i_column': 250,'j_column': 54}
base_d = sum(list(data.values()))
final_data = {combine_column_names(k,m,base_d):m/base_d*100 for k,m in data.items()}
fig,ax = plt.subplots(figsize=(12,5),subplot_kw=dict(aspect="equal"))
recipe = list(final_data.keys())
data = list(final_data.values())
wedges,texts = ax.pie(data,wedgeprops=dict(width=0.5),startangle=-40)
kw = dict(arrowprops=dict(arrowstyle="-"),zorder=0,va="center")
for i,p in enumerate(wedges):
ang = (p.theta2 - p.theta1)/2. + p.theta1
y = np.sin(np.deg2rad(ang))
x = np.cos(np.deg2rad(ang))
horizontalalignment = {-1: "right",1: "left"}[int(np.sign(x))]
connectionstyle = "angle,angleA=0,angleB={}".format(ang)
kw["arrowprops"].update({"connectionstyle": connectionstyle})
ax.annotate(recipe[i],xy=(x,y),xytext=(1*np.sign(x),1.4*y),horizontalalignment=horizontalalignment,**kw)
plt.show()
,
第 1 部分(共 3 个)
正如@JohanC 所建议的,注释掉 #bbox=bbox_props
以删除框,将 1*np.sign(x)
更改为 1.4*np.sign(x)
以沿 X 扩展标签,计算百分比 perc[i]
并将它们添加到标签ax.annotate(...)
内。最终图片看起来像(图片下方的代码):
最终代码:
data = {'a_column': 20,'j_column': 54}
base_d = sum(list(data.values()))
final_data = {k:m/base_d*100 for k,m in data.items()}
final_data
import numpy as np
import matplotlib.pyplot as plt
fig,subplot_kw=dict(aspect="equal"))
recipe = list(final_data.keys())
data = list(final_data.values())
perc = [str(round(e / s * 100.,1)) + '%' for s in (sum(data),) for e in data]
wedges,startangle=-40)
bbox_props = dict(boxstyle="square,pad=0.3",fc="w",ec="k",lw=0.72)
kw = dict(arrowprops=dict(arrowstyle="-"),#bbox=bbox_props,angleB={}".format(ang)
kw["arrowprops"].update({"connectionstyle": connectionstyle})
ax.annotate(recipe[i] + ' ' + perc[i],xytext=(1.4*np.sign(x),**kw)
plt.show()
第 2 部分(共 3 个)
如果您有非常多的数据条目,则饼图的默认颜色看起来不太好,它只有 10-15 种独特的颜色。我决定根据彩虹色制作自己的自定义颜色。在我的着色中,即使您有 100 个数据条目,所有颜色也是唯一的。在下面的代码中,着色是在 ax.pie(... colors = ....)
内完成的。我为彩虹着色制作了示例图像和代码:
import numpy as np,math,random
import matplotlib.pyplot as plt
random.seed(0)
data = {f'dat_{str(i).zfill(2)}' : random.random() for i in range(49)}
base_d = sum(list(data.values()))
final_data = {k:m/base_d*100 for k,m in data.items()}
fig,startangle=-40,colors = (lambda C = 7: [plt.cm.gist_rainbow((i % C) / C + i // C * 1 / C / math.ceil(len(data) / C)) for i in range(len(data))])())
bbox_props = dict(boxstyle="square,**kw)
plt.show()
第 3 部分(共 3 个)
还决定改进非常多条目(大约 100 个条目)的情况。进行了下一步改进:1) 沿 X 个奇数和偶数条目分开。 2)将所有标签沿Y均匀放置(在它们沿角度均匀之前)。 3) 缩小字体。
import numpy as np,random
import matplotlib.pyplot as plt
np.random.seed(0)
random.seed(0)
data = {f'dat_{str(i).zfill(2)}' : random.random() for i in range(98)}
base_d = sum(list(data.values()))
final_data = {k:m/base_d*100 for k,2)) + '%' for s in (sum(data),radius = 0.8,p in enumerate(wedges):
ang = (p.theta2 - p.theta1) / 2. + p.theta1
y = np.sin(np.deg2rad(ang))
x = np.cos(np.deg2rad(ang))
yc = np.arcsin(y) / (np.pi / 2)
horizontalalignment = {-1: "right",1: "left"}[int(np.sign(x))]
connectionstyle = f'angle,angleB={ang}'
kw["arrowprops"].update({"connectionstyle": connectionstyle})
ax.annotate(recipe[i] + ' ' + perc[i],xy = (0.8 * x,0.8 * y),xytext = ((1.0 + (i % 2) * 0.4) * np.sign(x),1.4 * yc),horizontalalignment = horizontalalignment,fontsize = 'x-small',**kw)
plt.show()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。