Как скруглить углы гистограмм в matplotlib python?

Хочу скруглить углы у баров в графике matplotlib у гистограмм. Так же хотел бы добавить вертикальный градиент и тоже не смог найти решение под мой график.

Скрипт:

import matplotlib.pyplot as plt

data = [4636, 7877, 10492, 6926, 5399, 3244, 2583, 1530, 4259, 5546, 6495, 5533, 5799, 4330, 8257, 8008, 3505, 941, 1656, 4564]

# размеры графика
fig, ax = plt.subplots(figsize=(10,6), facecolor='white', dpi=100)
# размеры оси Y
max_value = max(data)
ax.set_ylim((-max_value/100*5, max_value+max_value/100*10))
# колонки
ax.vlines(x=range(len(data)), ymin=0, ymax=data, colors=('#8197fa','#5770e7'), alpha=1, linewidth=20)

# текст
ax.set_title(f'Статистика за последние {len(data)} дней', fontdict={'size':18})
ax.set(ylabel='Количество новой аудитории')
# текст значений
for i, cty in enumerate(data):
    ax.text(i, cty+200, round(cty, 1), horizontalalignment='center')

# колоноки
plt.xticks(range(len(data)), data, rotation=60, horizontalalignment='center', fontsize=12)

# сетка
ax.grid(axis='y', linewidth=1/2)

plt.tight_layout()
plt.show()

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


Ответы (1 шт):

Автор решения: passant

Давайте разобьём вашу задачу на две.

Задача 1. Как добавить вертикальный градиент.

Для этого вертикальную линию надо строить не методом vlines, а методом построения вертикальных столбиков - bar. Кроме того, сама градиентная заливка добавляется отдельной функцией, которую придется прописывать самостоятельно (нашел у себя в записях, наверняка откуда-то из интернет)

import matplotlib.pyplot as plt
import numpy as np
data = [4636, 7877, 10492, 6926, 5399, 3244, 2583, 1530, 4259, 5546, 6495, 5533, 5799, 4330, 8257, 8008, 3505, 941, 1656, 4564]
# размеры графика
fig, ax = plt.subplots(figsize=(10,6), facecolor='white', dpi=100)
# размеры оси Y
max_value = max(data)
ax.set_ylim((-max_value/100*5, max_value+max_value/100*10))
################################################################
def gradientbars(bars):
    grad = np.atleast_2d(np.linspace(0,0.1,256)).T
    ax = bars[0].axes
    lim = ax.get_xlim()+ax.get_ylim()
    for bar in bars:
        bar.set_zorder(1)
        bar.set_facecolor('none')
        x,y = bar.get_xy()
        w, h = bar.get_width(), bar.get_height()
        ax.imshow(grad, extent=[x,x+w,y,y+h], cmap='winter',aspect='auto')
    ax.axis(lim)
br=ax.bar([i for i in range(len(data))],data)
gradientbars(br)   
################################################################     
# текст
ax.set_title(f'Статистика за последние {len(data)} дней', fontdict={'size':18})
ax.set(ylabel='Количество новой аудитории')
# текст значений
for i, cty in enumerate(data):
    ax.text(i, cty+200, round(cty, 1), horizontalalignment='center')   
# колоноки
plt.xticks(range(len(data)), data, rotation=60, horizontalalignment='center', fontsize=12)    
# сетка
ax.grid(axis='y', linewidth=1/2)   
plt.tight_layout()
plt.show()

Результат: введите сюда описание изображения

Красоту, надеюсь, сможете навести самостоятельно, включая выбор цветовой шкалы. Для справки можно глянуть вот тут:

https://matplotlib.org/3.5.0/tutorials/colors/colormaps.html
  1. Что касается скругленных углов, то на сколько я знаю, нарисовать такую картинку в рамках matplotlib не удастся. Это все-же не инструмент для рисования, а инструмент для отображения результатов исследований, и до таких "дизайнерских изысков" он еще не дотянулся.
→ Ссылка