#python #matplotlib #bar-chart #histogram #color-coding
#python #matplotlib #гистограмма #цветовое кодирование
Вопрос:
Я пытаюсь создать столбчатый график, который выглядит следующим образом:
ось x — это количество совпадающих детекторов (т. Е. Кратность), для каждой кратности у меня есть несколько событий. Ось y содержит среднюю высоту импульса для каждого события.Цвета должны соответствовать количеству попаданий, которые имеют показанные высоты импульсов и появились в событиях с соответствующей кратностью
У меня есть словарь, в котором в качестве ключей указаны кратности, а в качестве значений — массивы средних высот импульсов. :
averages = {2 : [...],
3 : [...],
4 : [...],
5 : [...],
6 : [...],}
for key in averages:
plt.bar(key,averages[key] ,width = 0.8)
я знаю только, как создать простую версию столбчатой диаграммы, которая выглядит следующим образом:
может кто-нибудь сказать мне, как сделать столбцы «сломанными», чтобы показать все высоты импульсов и добавить цветовую кодировку?
Ответ №1:
Не совсем понятно, но я думаю, вы хотите что-то вроде этого
import seaborn as sns
from scipy import stats
import matplotlib as mpl
import matplotlib.pyplot as plt
# Create some fake data that looks roughly like what you have
tips = sns.load_dataset("tips")
weights = stats.gaussian_kde(tips["total_bill"])(tips["total_bill"])
tips = tips.sample(frac=50, weights=weights, replace=True)
days = []
segments = []
counts = []
for day, x in tips["total_bill"].groupby(tips["day"]):
days.append(day)
segments.append(np.sort(x.unique()))
counts.append(x.value_counts().sort_index())
# Map from counts to colors
norm = mpl.colors.Normalize(0, np.concatenate(counts).max())
colors = [mpl.cm.viridis(norm(c)) for c in counts]
f, ax = plt.subplots()
# Draw each horizontal line
events = ax.eventplot(segments, colors=colors, orientation="vertical", zorder=.5)
events[0].set_norm(norm)
f.colorbar(events[0])
# Add the mean/std for each x position
sns.pointplot(data=tips, x="day", y="total_bill", ci="sd", order=days, join=False, color=".1")
Я задал вопрос о том, нужна ли каждая горизонтальная линия для представления каждого значения данных, но если вас устраивает гистограмма, это два вызова функции в seaborn (> = 0.11)
sns.histplot(
data=tips, x="day", y="total_bill",
discrete=(True, False), binwidth=(1, .5),
cmap="viridis", cbar=True, zorder=.5, alpha=.75,
)
sns.pointplot(
data=tips, x="day", y="total_bill",
ci="sd", order=days, join=False, color=".1",
)
Комментарии:
1. Не знал о eventplot . Нужно это проверить. 1
Ответ №2:
Вот решение, которое использует imshow
для создания столбчатых «цветовых гистограмм»:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
# Create dummy data
coincidences = [2, 3, 4, 5, 6]
n_list = [10000, 8000, 6000, 4000, 2000]
mu_list = np.array([200, 300, 400, 500, 600])
scale = 100
averages = {c: np.random.normal(loc=mu_list[i], scale=scale, size=n_list[i])
for i, c in enumerate(coincidences)}
# Calculate histogram for each column
bins = np.linspace(0, 1000, 1000)
hist_img = np.array([np.histogram(averages[c], bins=bins)[0]
for c in coincidences]).T
# Create Normalized colormap
# norm = mpl.colors.Normalize()
norm = mpl.colors.LogNorm(vmin=1, vmax=hist_img.max())
sm = mpl.cm.ScalarMappable(cmap='viridis', norm=norm)
# Use colormap for img_hist and make zeros transparent
hist_img2 = sm.to_rgba(hist_img, bytes=True)
hist_img2[hist_img == 0, 3] = 0
# Plot
fig, ax = plt.subplots()
cc = ax.imshow(hist_img2, aspect='auto', interpolation='none', origin='lower',
extent=[1.5, 6.5, 0, 1000])
plt.colorbar(sm)
mean = [np.mean(averages[c]) for c in coincidences]
std = [np.std(averages[c]) for c in coincidences]
ax.errorbar(coincidences, mean, yerr=std, ls='', c='k', capsize=3, label='std')
ax.plot(coincidences, mean, ls='', marker='o', c='b', label='mean')
ax.legend()
Комментарии:
1. это действительно полезно. Большое вам спасибо!