从字典创建饼图并更改箭头

如何解决从字典创建饼图并更改箭头

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

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}

我想绘制一个饼图,如下所示:

enter image description here

我尝试过的:

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()

但这给了我这样的:

enter image description here

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

解决方法

我做了两件事。

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(...) 内。最终图片看起来像(图片下方的代码):

enter image description here


最终代码:

Try it online!

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 = ....) 内完成的。我为彩虹着色制作了示例图像和代码:

enter image description here

Try it online!

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) 缩小字体。

enter image description here

Try it online!

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 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-