在pyplot中编辑饼图

Editing a pie chart in pyplot

我正在尝试创建类似于下图的饼图:

我不太在意颜色,但是有几件事让我很纠结。

  1. 如何删除某些楔形的楔形标签,即 'Other'
  2. 左侧的楔形标签
  3. 如何将文本放入 'Other' 楔形
  4. 如何设置标签,使其他标签水平,其他标签朝向楔形旋转?

我是否需要多次重新渲染图表才能获得我想要的结果?我已经查看了文档,但我仍在为图表的实现而苦苦挣扎。

这是我当前的输出:

这是我当前的代码:

exp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1]
    colList = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red',
               'tab:purple', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']
    pct = '%1.0f%%'
    fdict = {
        'size': 20,
        'weight': 'heavy',
        'family': 'serif',


    }

    plt.figure(figsize=(8, 6), dpi=100)
    plt.pie(data, labels=labels, explode=exp, colors=colList, pctdistance=0.8,
            autopct=pct, startangle=142, rotatelabels=True)
    plt.title(title, fontdict=fdict)
    plt.show()

绘制饼图时,您会得到三个对象列表:patchestextsautotexts。在我们的上下文中,它是 wedgeslabelspercentage_labels 的列表,与您 labels.

的索引相同

您首先需要知道您要更改的标签的索引是什么。您可以轻松地做到这一点: label_index = labels.index('OTHER')
基于此索引,您可以对任何列表中的相应对象进行操作。

要删除任何标签,只需将其文本设置为“”即可。

这是使 OTHER 标签水平,而其他标签保持垂直的示例代码。还添加带有文本描述的新文本标签,并将其位置设置在百分比标签下方。我还从 OTHER 标签左侧的图中删除了前两个百分比标签。我使用的是修改后的 matplotlib 官方饼图示例,但对于您更复杂的情况,逻辑是相同的。

import matplotlib.pyplot as plt

# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = 'Frogs', 'Hogs', 'Dogs', 'OTHER'
sizes = [10, 30, 30, 30]
explode = (0, 0, 0, 0.1)  # only "explode" the 2nd slice (i.e. 'Hogs')

pct = '%1.0f%%'
fdict = {
    'size': 20,
    'weight': 'heavy',
    'family': 'serif',
}

fig1, ax1 = plt.subplots()
startangle = 142
wedges_lst, labels_lst, percentage_labels_lst = ax1.pie(sizes, explode=explode, labels=labels, pctdistance=0.8,
                                                        autopct=pct,
                                                        startangle=startangle, rotatelabels=True)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

# Get label index
label_index = labels.index('OTHER')
# Get the label text object from the list
label = labels_lst[label_index]

# Set rotation to 0 degrees and center text horizontally
label.update({"rotation": 0, "horizontalalignment": "center"})

# Get percentage label
percentage_label = percentage_labels_lst[label_index]
# Get X, Y position of the percentage label
percentage_label_pos = percentage_label.get_position()

# Create new text label and move it under percentage label
new_label = ax1.text(s="Many specialized technologies \nwere reported only once", x=percentage_label_pos[0],
                     y=percentage_label_pos[1] - 0.2, horizontalalignment="center", verticalalignment="center")

# Remove percentage labels for first two labels
for label in percentage_labels_lst[:2]:
    label.update({"text": ""})

plt.show()

这是结果: