Как закрасить выбранный диапазон гистограммы matplotlib? - PullRequest
0 голосов
/ 23 января 2020

У меня есть данные с именем prices, и я использую prices.tail(1) для построения гистограммы.

Также у меня есть некоторые переменные: left_border = 341.086, right_border = 437.177, line_length = 1099.

И следующий код:

plt.figure(figsize=(9,6))
plt.hist(prices.tail(1), bins = 400)
x2 = [left_border,left_border] 
y2 = [0, line_length]
plt.plot(x2, y2, color = 'green')
x3 = [right_border, right_border] 
y3 = [0, line_length]
plt.plot(x3, y3, color = 'green')

plt.show()

Произведите вывод:

enter image description here

Как я могу раскрасить часть гистограммы что между зелеными границами отличается от части за зелеными границами, градиентно? Также выбрать ящики, которые находятся почти у зеленых границ и превратить их в другой цвет?

Спасибо.

1 Ответ

2 голосов
/ 23 января 2020

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

  • hist возвращает значения каждого бина, пределы бинов и патчи, которые были нарисованы; Вы можете раскрасить участки в зависимости от их среднего значения x-position
  • , чтобы создать эффект, подобный градиенту, самый простой способ - это линейная интерполяция между двумя цветами; функция, такая как sqrt, может использоваться для ускорения запуска эффекта
  • axvspan может нарисовать вертикальный промежуток между двумя данными координатами x; установите zorder=0, чтобы убедиться, что диапазон остается за гистограммой; или установите alpha=0.3, чтобы нарисовать его в виде прозрачного слоя над полосами
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np

prices_np = 14*np.random.normal(5, 1, 10000)**2

left_border = 341.086
right_border = 437.177
# line_length = 1099
divisor_tickness = 10
main_color = mcolors.to_rgb('dodgerblue')
highlight_color = mcolors.to_rgb('limegreen')
divisor_color = mcolors.to_rgb('crimson')

binvals, bins, patches = plt.hist(prices_np, bins = 400, color=main_color)

bin_centers = 0.5 * (bins[:-1] + bins[1:])

for p, x in zip(patches, bin_centers):
    #x, _ = p.get_xy()
    #w = p.get_width()
    if left_border < x  < right_border:
        f = 2*min(x-left_border, right_border-x) / (right_border - left_border)
        f = f ** 0.5
        p.set_facecolor([ (h_rgb*f + m_rgb * (1-f))  for m_rgb, h_rgb in zip(main_color, highlight_color)] )
    elif left_border-divisor_tickness < x <= left_border or right_border <= x < right_border + divisor_tickness:
        p.set_facecolor(divisor_color)

plt.axvspan(left_border, right_border, color='lightgoldenrodyellow', zorder=0)
plt.show()

result

Чтобы получить плавный градиент в зависимости от высота штанги, гауссовский кде может быть полезным:

kde = gaussian_kde(prices_np)
max_kde = max([kde(x)[0] for x in bin_centers])
for x, p in zip(bin_centers, patches):
    p.set_facecolor(plt.cm.viridis((kde(x)[0] / max_kde) ))

using gaussian kde for color

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