Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从dict创建饼图并更改箭头_Python_Matplotlib_Pie Chart - Fatal编程技术网

Python 从dict创建饼图并更改箭头

Python 从dict创建饼图并更改箭头,python,matplotlib,pie-chart,Python,Matplotlib,Pie Chart,我在dict中有一些计数数据,如下所示: 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} 我想画一个饼图,像这样: data = {'a_column': 20, '

我在dict中有一些计数数据,如下所示:

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}
我想画一个饼图,像这样:

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()
但这给了我这样的感觉:

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}

如何使箭头像预期的图像一样,并删除标签周围的边框?

我做了两件事

1.计算添加到标签的百分比
2.删除框样式

将numpy导入为np
将matplotlib.pyplot作为plt导入
def组合列名称(列名称、当前值、总和):
百分比=四舍五入(当前值/总和*100,2)
name=“{}{}%.”格式(列名称,百分比)
返回名称
数据={'a_列]:20,'b_列]:130,
“c_列”:140,“d_列”:300,“e_列”:150,
“f_列”:170,“g_列”:10,“h_列”:20,“i_列”:250,“j_列”:54}
base_d=总和(列表(data.values())
final_data={combine_column_names(k,m,base_d):m/base_d*100表示data.items()中的k,m
图,ax=plt.子批次(figsize=(12,5),子批次(aspect=“equal”))
配方=列表(最终数据.keys())
数据=列表(最终数据值())
楔形,text=ax.pie(数据,楔形操作=dict(宽度=0.5),startangle=-40)
kw=dict(arrowprops=dict(arrowstyle=“-”),zorder=0,va=“center”)
对于枚举中的i,p(楔形):
ang=(p.theta2-p.theta1)/2+p、 θ1
y=np.sin(np.deg2rad(ang))
x=np.cos(np.deg2rad(ang))
水平对齐={-1:“右”,1:“左”}[int(np.sign(x))]
connectionstyle=“angle,angleA=0,angleB={}”。格式(ang)
kw[“arrowprops”].update({“connectionstyle”:connectionstyle})
ax.注释(配方[i],xy=(x,y),xytext=(1*np.符号(x),1.4*y),
水平对齐=水平对齐,**千瓦)
plt.show()
第1部分(共3部分)

根据@JohanC的建议,注释掉
#bbox=bbox_props
以移除框,将
1*np.sign(x)
更改为
1.4*np.sign(x)
以沿x更宽地分布标签,计算百分比
perc[i]
,并将其添加到
ax.annotate(…)
内的标签中。最终图片看起来像(图片下面的代码):


最终代码:


第2部分(共3部分)

若你们有很多数据条目,那个么饼图的默认颜色看起来不太好,它只有10-15种独特的颜色。我决定根据彩虹的颜色制作自己的定制颜色。在我的着色中,即使有100个数据条目,所有颜色都是唯一的。在下面的代码中,着色是在
ax.pie(…colors=..)
内部完成的。我制作了彩虹着色的示例图像和代码:


第3部分(共3部分)

还决定改进非常多条目(大约100条条目)的情况。做了下一步的改进:1)沿着X个奇数和偶数条目分开。2) 沿Y方向均匀放置所有标签(在沿角度均匀放置之前)。3) 使字体变小


省略
bbox=bbox_props
如何省略边界框?和
ax.annotate(…,xytext=(1.2*np.符号(x),…),…)
来增加水平距离?
import numpy as np, math, 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,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())
perc = [str(round(e / s * 100., 2)) + '%' for s in (sum(data),) for e in data]
wedges, texts = ax.pie(data, wedgeprops=dict(width=0.5), startangle=-40, radius = 0.8,
    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,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))
    yc = np.arcsin(y) / (np.pi / 2)
    horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
    connectionstyle = f'angle,angleA=0,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()