Python: гистограмма с диапазоном, но распределение рассчитывается для всего набора
Я использую matplotlib, чтобы нарисовать гистограмму в формате PDF, и мне нужно использовать переменную диапазона из-за появления графика. Получил максимум в начале и в конце, вероятность вероятности намного выше для этих пиков, поэтому остальная часть графика не видна, поэтому мне нужно использовать диапазон для "увеличения". Но когда используется диапазон, вероятность плотность будет учитывать только данные в пределах диапазона.
Есть ли способ продолжить использование диапазона, но плотность вероятности рассчитывается не только с данными в данном диапазоне, но и со всеми данными?
Заранее спасибо!
Изменить: я строю PDF размеров пакетов для набора данных. График имеет пики в нижней области ~100 байт и в верхней области ~1450 байт. Чтобы показать распределение в середине набора данных, я использую диапазон для увеличения различных областей, что дает более детальную информацию о распределении.
ax.hist(x=list_of_pkt_sizes,bins=25,density=True,range=[500,1000])
Это пример фрагмента кода, используемого для построения одного из увеличенных областей. Как сказано выше, теперь он показывает только распределение для данного диапазона. Я хочу общее распространение.
2 ответа
Не самое элегантное решение, но вы легко можете нормализовать вручную:
import numpy as np
# Convert list to numpy array for convenience
pkt_arr = np.array(list_of_pkt_sizes)
# Set range variables
min_range, max_range = 500, 1000
# Filter out elements not in range to new array
pkt_arr_in_range = pkt_arr[(pkt_arr > min_range) & (pkt_arr < max_range)]
# Get normalisers - bin size and total number of elements
num_elem_norm = pkt_arr.shape[0]
counts, bins = np.histogram(x=pkt_arr_in_range, bins=25)
bin_width = bins[1] - bins[0]
# Get x coordinates of LHS of bins
xs = bins[:-1]
# Normalise counts (prob density per unit of input)
counts_norm = counts / (num_elem_norm * bin_width)
# Use bar chart
ax.bar(xs, counts_norm, width=bin_width, align='edge')
ОБНОВЛЕНИЕ: @DizietAsahi делает лучшее предложение в своем комментарии:
min_range, max_range = 500, 1000
min_all, max_all = min(list_of_pkt_sizes), max(list_of_pkt_sizes)
range_ratio = (max_all - min_all) / (max_range - min_range)
ax.hist(list_of_pkt_sizes, bins=int(round(25 * range_ratio)), density=True)
plt.xlim(min_range, max_range)
Вот как я бы решил эту проблему. Я создал фальшивый дистрибутив с большим количеством низких и высоких значений согласно вашей информации
plt.figure()
plt.hist(l1, density=True, bins=25)
Я использую numpy.histogram
Функция для получения распределения плотности. Обратите внимание, что я использую обычай bins=
Аргумент: я запрашиваю одну ячейку от 0-500, 25 корзин от 500 до 1000 и 1 ячейку от 1000 до 2000
p,b = np.histogram(l1, density=True, bins=[0]+list(np.linspace(500,1000,25+1))+[2000])
Наконец, я использую Matplotlib's bar()
функция для построения результирующей гистограммы, но я просто опускаю первый и последний бин
plt.figure()
plt.bar(x=b[1:-2], height=p[1:-1], width=20, align='edge')