размещение этикеток на круговой диаграмме - PullRequest
0 голосов
/ 10 ноября 2018

Я пытаюсь сделать следующую круговую диаграмму красивее:

В частности, у меня есть очевидная проблема с ярлыками. Я хочу повернуть их и расположить по центру над соответствующим кусочком пирога, но я могу только повернуть их. Кроме того, вращение требует много настроек, устанавливая pie_properties[1][0].set_rotation(30) с разными значениями градусов для каждой метки.

Есть ли способ сделать это автоматически или хотя бы более простым способом?

Вот мой код:

import matplotlib.pyplot as plt
import numpy as np


fig, ax = plt.subplots()

### Data structure: 
# Network type:
group_names = ['Group 1', 'Group 2', 'Group 3']
group_vals = [43,49,38]
group_colors = ['w']*3

#Information level:
info_names = ['Subgroup 1', 'Subgroup 2', \
              'Subgroup 1', 'Subgroup 2',\
              'SSubgroup 1', 'Subgroup 2']
info_vals = np.array([[27,16],[26,23],[14,24]])
my_blue = [x/255 for x in [30,144,255]]
info_colors = [my_blue,'gray',\
               my_blue,'gray',\
               my_blue,'gray']

corr_vals = np.array([[10,3,7,3,4], [4,4,4,2,2],\
                     [10,5,5,3,3], [10,5,5,1,2],\
                     [4,4,2,2,2], [12,2,2,1,7]])
pale_green = [x/255 for x in [152,251,152]]
pale_red = [x/255 for x in [240,128,128]]
pale_gray = [x/255 for x in [169,169,169]]
corr_colors = ['green',pale_green,pale_gray,pale_red,'red', 'green',pale_green,pale_gray,pale_red,'red',\
               'green',pale_green,pale_gray,pale_red,'red', 'green',pale_green,pale_gray,pale_red,'red',\
               'green',pale_green,pale_gray,pale_red,'red', 'green',pale_green,pale_gray,pale_red,'red',]

#inner layer
pie_properties = ax.pie(group_vals, radius=1, colors=group_colors, 
       labels=group_names, labeldistance=0.7,
       wedgeprops=dict(width=0.3, edgecolor='k'))
pie_properties[1][0].set_rotation(-45) #<===rotation
pie_properties[1][1].set_rotation(90)
pie_properties[1][2].set_rotation(-135)

#middle layer
pie_properties = ax.pie(info_vals.flatten(), radius=1+0.4, colors=info_colors,
       labels=info_names, labeldistance=0.7,
       wedgeprops=dict(width=0.4, edgecolor='w'))
pie_properties[1][0].set_rotation(-45)
pie_properties[1][1].set_rotation(15)
pie_properties[1][2].set_rotation(65)
pie_properties[1][3].set_rotation(125)
pie_properties[1][4].set_rotation(-160)
pie_properties[1][5].set_rotation(-125)

#outer layer
ax.pie(corr_vals.flatten(), radius=1+0.4+0.5, colors=corr_colors,
       wedgeprops=dict(width=0.5, edgecolor='w'))


ax.set(aspect="equal")
plt.show()

1 Ответ

0 голосов
/ 11 ноября 2018

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

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()

group_names = ['Group 1', 'Group 2', 'Group 3']
group_vals = [43,49,38]
group_colors = ['w']*3

info_names = ['Subgroup 1', 'Subgroup 2', \
              'Subgroup 1', 'Subgroup 2',\
              'Subgroup 1', 'Subgroup 2']
info_vals = np.array([[27,16],[26,23],[14,24]])
my_blue = np.array([30,144,255])/255
info_colors = [my_blue,'gray']*3

corr_vals = np.array([[10,3,7,3,4], [4,4,4,2,2],\
                     [10,5,5,3,3], [10,5,5,1,2],\
                     [4,4,2,2,2], [12,2,2,1,7]])
pale_green = np.array([152,251,152])/255
pale_red   = np.array([240,128,128])/255
pale_gray  = np.array([169,169,169])/255
corr_colors = ['green',pale_green,pale_gray,pale_red,'red']*6

def rotatetext(text):
    angle = np.rad2deg(np.arctan2(*text.get_position()[::-1]))
    text.set(rotation = angle - 90*np.sign(angle), 
             rotation_mode="anchor", ha="center", va="center")

#inner layer
pie_properties = ax.pie(group_vals, radius=1/1.9, colors=group_colors, 
       labels=group_names, labeldistance=.8,
       wedgeprops=dict(width=0.3/1.9, edgecolor='k'))

for text in pie_properties[1]:
    rotatetext(text)

#middle layer
pie_properties = ax.pie(info_vals.flatten(), radius=(1+0.4)/1.9, colors=info_colors,
       labels=info_names, labeldistance=.82,
       wedgeprops=dict(width=0.4/1.9, edgecolor='w'))

for text in pie_properties[1]:
    rotatetext(text)

#outer layer
ax.pie(corr_vals.flatten(), radius=(1+0.4+0.5)/1.9, colors=corr_colors,
       wedgeprops=dict(width=0.5/1.9, edgecolor='w'))

ax.set(xlim=(-1,1), ylim=(-1,1))
ax.set(aspect="equal")
plt.show()

enter image description here

Однако лучшая радиальная позициянуждается в ручной настройке.Здесь я выбрал 0,80 и 0,82 соответственно, но это будет зависеть от размера рисунка и шрифта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...