Вертикальный «сломанный» столбчатый график с массивами в виде высоты столбцов и цветовой кодировки

#python #matplotlib #bar-chart #histogram #color-coding

#python #matplotlib #гистограмма #цветовое кодирование

Вопрос:

Я пытаюсь создать столбчатый график, который выглядит следующим образом:

1

ось x — это количество совпадающих детекторов (т. Е. Кратность), для каждой кратности у меня есть несколько событий. Ось y содержит среднюю высоту импульса для каждого события.Цвета должны соответствовать количеству попаданий, которые имеют показанные высоты импульсов и появились в событиях с соответствующей кратностью

У меня есть словарь, в котором в качестве ключей указаны кратности, а в качестве значений — массивы средних высот импульсов. :

 averages = {2 : [...],
        3 : [...],
        4 : [...],
        5 : [...],
        6 : [...],}

for key in averages:
plt.bar(key,averages[key] ,width = 0.8)
  

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

2

может кто-нибудь сказать мне, как сделать столбцы «сломанными», чтобы показать все высоты импульсов и добавить цветовую кодировку?

Ответ №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. это действительно полезно. Большое вам спасибо!