Круговой барплот в python с процентными метками - PullRequest
0 голосов
/ 10 января 2020

Я новичок ie до python и у меня мало опыта в R.

У меня есть фрейм данных с gut_list и процентом. Я хочу создать круговой сюжет барплота / ипподрома с метками. Я видел сообщение в R ggplot, чтобы создать что-то похожее с центром святого. Но я не уверен, как использовать ggplot в python.

Я хочу вывод, аналогичный приведенному в следующей группе R. Но я хотел бы попробовать пакеты python для создания таких графиков со значениями, помеченными и с легендами.

Создание кругового барплета с полым центром (он же ипподром)

Пример данных:

gut_list = ("Micro1", "Micro2", "Micro3", "Micro4", "Micro5", "Micro6")
percent = (2, 77, 22, 41, 21, 9)

Первоначальное испытание:

import matplotlib.pyplot as plt
from matplotlib import cm
from math import log10

gut_list = ("Micro1", "Micro2", "Micro3", "Micro4", "Micro5", "Micro6") 
percent = [2, 77, 22, 41, 21, 9]
#number of data points
n = len(percent)
#find max value for full ring
k = 10 ** int(log10(max(percent)))
m = k * (1 + max(percent) // k)

#radius of donut chart
r = 1.5
#calculate width of each ring
w = r / n 

#create colors along a chosen colormap
colors = [cm.PuBu(i / n) for i in range(n)]

#create figure, axis
fig, ax = plt.subplots()
ax.axis("equal")

for i in range(n):
    innerring, _ = ax.pie([m - percent[i], percent[i]], radius = r - i * w, startangle = 90, colors = ["white", colors[i]])
    plt.setp(innerring, width = w, edgecolor = "lightgrey")


plt.legend()
plt.show()

Мне все еще не удалось добавить метку или легенды.

Ожидаемый результат: (i.stack.imgur.com/hOv9q.png)enter image description here

1 Ответ

1 голос
/ 11 января 2020

Вот пример кода для создания такой «концентрической c круговой диаграммы» или «концентрическая c кольцевая диаграмма».

Основная идея заключается в использовании массива x pie, чтобы указать, какой круг использовать. И ставьте только один x за раз. документы говорят, что если сумма x меньше 1, она будет взята в процентах (в противном случае все будет суммировано и показано пропорционально сумме, что составит единичное x 100%). counterclock=False будет иметь ar c в нужном направлении. Одиночный x теперь пересчитывается так, что наибольшее значение ar c будет представлять собой процент, установленный в списке процентов.

Важно отметить, что как внешний радиус r, так и внутренний радиус необходимо. В текущем коде внутренний радиус играет роль только для вычисления шага width, который смещает каждый круг.

Диаграмма p ie может отображать метки на самих частях p ie, но в автоматическом режиме c размещение может быть запутанным в нашем случае. Установка labels=['desired label'] переведет ярлык в легенду. Настройка labeldistance=None не будет отображаться на графике. Легенда может быть размещена так, чтобы ее верхний правый угол находился в центре верхней части графика. Поместите его в другое место, если проценты слишком высоки и дуги будут перекрываться.

В качестве альтернативы текст может отображаться непосредственно рядом с дугами. В data coordinates центр кругов находится в 0,0. Таким образом, y=radius-w/2 находится в центре начального края каждого кольца. Текст выравнивается по правому краю и выравнивается по центру.

import matplotlib.pyplot as plt

cathegories = ["Electronics", "Appliances", "Books", "Music", "Clothing", "Cars", "Food/Beverages", "Personal Hygiene",
               "Personal Health/OTC", "Hair Care"]
percent = [81, 77, 70, 69, 69, 68, 62, 62, 61, 60]

# number of data points
n = len(percent)
# percent of circle to draw for the largest circle
percent_circle = max(percent) / 100

r = 1.5  # outer radius of the chart
r_inner = 0.4  # inner radius of the chart
# calculate width of each ring
w = (r - r_inner) / n

# create colors along a chosen colormap
#colors = [plt.cm.plasma(i / n) for i in range(n)]
colors = plt.cm.tab10.colors

# create figure, axis
fig, ax = plt.subplots()
ax.axis("equal")

for i in range(n):
    radius = r - i * w
    ax.pie([percent[i] / max(percent) * percent_circle], radius=radius, startangle=90,
           counterclock=False,
           colors=[colors[i]],
           labels=[f'{cathegories[i]} – {percent[i]}%'], labeldistance=None,
           wedgeprops={'width': w, 'edgecolor': 'white'})
    ax.text(0, radius - w / 2, f'{cathegories[i]} – {percent[i]}% ', ha='right', va='center')

# plt.legend(loc='upper right', bbox_to_anchor=(0.5, 1.1), prop={'size': 12})
plt.tight_layout()
plt.show()

resulting plot

...