Кольцевая диаграмма Python matplotlib с меньшей шириной на одном клине

Я пытаюсь воссоздать кольцевую диаграмму, где последний клин тоньше остальных, например:

введите здесь описание изображения

Но я не могу найти способ уменьшить ширину последнего клина. Поэтому я попытался сделать так, чтобы последний клин был того же цвета, что и фон, и нарисовал сверху серый кружок. Но я не могу нарисовать круг под клиньями и сделать слои выше прозрачными в нужных местах.

Есть ли способ сделать один клин прозрачным или иным образом решить мою проблему?

Вот мой код:

import matplotlib.pyplot as plt
donut = [150,10,20,20,30,40]
total = sum(donut)
grey_circle = plt.Circle((0,0),0.965,color='#CCCCCC', lw=1, fill=False)
centre_circle = plt.Circle((0,0),0.93,fc='white')
fig, ax = plt.subplots(figsize=(2, 2), subplot_kw=dict(aspect="equal"))
colors = ['#F8F5EB','#50E3C2','#FF9100','#002776','#C94096','#0071CD' ]
wedges, texts = ax.pie(donut, colors=colors, wedgeprops=dict(width=0.1), startangle=90)
fig.gca().add_artist(grey_circle)
fig.gca().add_artist(centre_circle)
fig.set_facecolor('#F8F5EB')
fig = plt.gcf()
plt.savefig('cirle.png',facecolor=fig.get_facecolor(), edgecolor='none', dpi=300)

plt.show() 

И мой результат:

введите здесь описание изображения


person Ullsokk    schedule 23.01.2020    source источник
comment
[stackoverflow.com/questions/20551477/ вы можете найти способ получить доступ к клиньям. Затем вы можете динамически изменять ширину по своему желанию.   -  person Cowflu    schedule 23.01.2020


Ответы (1)


Самый простой способ — нарисовать диаграмму дважды, один раз для толстых клиньев, один раз для тонких. Для цветов клиньев, которые не нужно рисовать, установлено значение «нет». Установка явного радиуса создаст правильный размер для тонких клиньев.

При таком подходе круги не нужны, чтобы что-то скрывать. Вы все еще можете добавить круг, чтобы получить другой цвет в центре. Просто добавьте zorder=0, чтобы убедиться, что круг находится за кругом.

Некоторый код для иллюстрации концепций:

import matplotlib.pyplot as plt

donut = [150, 10, 20, 20, 30, 40]

thin_indices = [0]  # indices of all wedges that should be thin
colors = ['#CCCCCC', '#50E3C2', '#FF9100', '#002776', '#C94096', '#0071CD']
colors_thin = [c if i in thin_indices else 'none' for i, c in enumerate(colors)]
colors_thick = [c if i not in thin_indices else 'none' for i, c in enumerate(colors)]
radius = 1
thick_width = 0.1
thin_width = 0.05
radius_thin = radius - 0.5 * (thick_width - thin_width)

fig, ax = plt.subplots(figsize=(2, 2), subplot_kw=dict(aspect="equal"))
ax.pie(donut, radius=radius, colors=colors_thick, wedgeprops=dict(width=thick_width), startangle=90)
ax.pie(donut, radius=radius_thin, colors=colors_thin, wedgeprops=dict(width=thin_width), startangle=90)
centre_circle = plt.Circle((0, 0), radius - thick_width/2, fc='white', zorder=0)
ax.add_artist(centre_circle)

fig.set_facecolor('#F8F5EB')
plt.savefig('cirle.png', facecolor=fig.get_facecolor(), edgecolor='none', dpi=300)

plt.show()

результирующий пончик

person JohanC    schedule 23.01.2020
comment
Фантастика, огромное спасибо! Моя единственная проблема сейчас в том, что центр имеет тот же цвет, что и мой фон, но он должен быть белым. Пробовал снова поставить белый кружок сверху, но он просто зажимает клинья. Есть ли способ воспроизвести белый интерьер моего первого изображения, а снаружи цветной? - person Ullsokk; 23.01.2020
comment
Да, это так! Безуспешно пробовал что-то подобное, не знал про zorder = 0, но в этом есть смысл! Еще раз спасибо - person Ullsokk; 23.01.2020