Python+Plotly技术实现:通过字典为饼图自定义颜色及图例排序
没问题,这两个需求都能完美实现!咱们一步步来解决你的问题:
1. 实现按等级精准映射颜色
你提出的字典形式颜色映射完全可行,我们只需要定义好覆盖1-10级的完整映射字典,再根据每个等级匹配对应的颜色即可。这里要注意原始数据里的等级是整数,所以需要把它转成字符串来匹配字典的键。
2. 让图例按10→1的顺序排序
直接用原始数据列表生成饼图的话,Plotly会默认按数据出现顺序或数值升序排列图例。要实现10到1的倒序,我们需要先统计每个等级的数量,再手动按指定顺序组织数据,这样图例就会跟着我们设定的顺序排列。
修改后的完整代码
#!/usr/bin/env python # -*- coding: utf-8 -*- import plotly.plotly as py import plotly.graph_objs as go import pandas as pd crit = [1, 10, 2, 6, 1, 2, 2, 3, 1, 4, 6, 6, 9, 10, 5, 8, 3, 8, 5, 4, 9, 2, 8, 7, 1, 1, 7, 3, 9, 9, 6, 6, 8, 9, 6, 7, 5, 9, 8, 4, 4, 5, 6, 2, 9, 9, 4, 6, 9, 9] # 定义1-10级的颜色映射字典,按你需求的对应关系设置 color_map = { '10': '#ff0000', # 10级红色 '9': '#ff5050', # 9级浅红/橙色 '8': '#ff6600', # 8级橙色 '7': '#ff9966', # 7级浅橙色 '6': '#ff6699', # 6级橙红色 '5': '#ff99ff', # 5级浅紫色 '4': '#cc99ff', # 4级紫色 '3': '#ccccff', # 3级浅蓝紫色 '2': '#99ccff', # 2级浅蓝色 '1': '#e6f2ff' # 1级极浅蓝色 } # 统计每个临界度的数量,并强制按10→1的顺序排序 crit_series = pd.Series(crit) sorted_levels = list(range(10, 0, -1)) # 生成10到1的倒序列表 crit_counts = crit_series.value_counts().reindex(sorted_levels, fill_value=0) # 准备饼图所需的标签、数值和颜色列表 labels = [str(level) for level in sorted_levels] values = crit_counts.values.tolist() pie_colors = [color_map[label] for label in labels] fig = { "data": [ { "values": values, "labels": labels, "domain": {"x": [0, .48]}, "name": "Criticality", "marker": {'colors': pie_colors}, # 使用自定义颜色列表 "textinfo":"percent+label", "textfont": {'color': '#FFFFFF', 'size': 15}, "hole": .4, "type": "pie" } ], "layout": { "title":"Criticalities", "annotations": [ { "font": { "size": 25, "color": '#5A5A5A' }, "showarrow": False, "text": "2018", "x": 0.20, "y": 0.5 } ] } } py.iplot(fig, filename='pie-custom-colors-sorted')
关键改动说明
- 颜色映射:通过
color_map字典精准绑定每个等级和颜色,再用列表推导式生成饼图的颜色列表,确保10级永远是红色、9级永远是橙色,以此类推。 - 图例排序:利用pandas的
value_counts统计数量后,通过reindex强制按10到1的顺序排列数据,这样饼图的标签和图例都会严格遵循这个顺序,即使某个等级没有数据也会保留位置(显示0),保证图例完整性。 - 数据适配:把原始的重复数据转换成统计后的聚合数据,避免饼图出现重复的标签,同时让数据展示更清晰。
内容的提问来源于stack exchange,提问作者Olli
相关产品推荐
相关产品推荐

