首页 > 解决方案 > 绘制直方图,其中条形图根据第二个值列表着色

问题描述

例如,我可以使用 matplotlib 在 Python 中绘制直方图:

from matplotlib import pyplot as plt
x = [3,5,12,7,8,6,4,6]
plt.hist(x)

但是我有第二个数组y = [4,6,8,2,4,5,8,7],其中每个值对应于x. 现在我想创建一个直方图,其中每个条形的高度由 定义x,但每个条形的颜色由y属于其x值的值定义。你也可以说我有元组,list(zip(x,y))因为第一个值应该用于直方图本身,每个 bin 中第二个元组值的平均值应该决定颜色。

标签: pythonnumpymatplotlib

解决方案


np.unique(x, return_counts=True)返回具有唯一值x及其计数的数组。

将所有内容转换为 numpy 数组,在每个位置选择等于y[x == val]的子集。 获取这些值的平均值。调用会给出与该值对应的颜色。和可用于创建颜色条。yxvaly[x == val].mean()cmap(norm(...))cmapnorm

这是一些示例代码,包括用于更改刻度、边距和刺的装饰:

import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from matplotlib.cm import ScalarMappable
import numpy as np

x = np.array([3, 5, 12, 7, 8, 6, 4, 6])
y = np.array([4, 6, 8, 2, 4, 5, 8, 7])

values, counts = np.unique(x, return_counts=True)
cmap = plt.get_cmap('inferno')
norm = plt.Normalize(0, y.max())  # or plt.Normalize(y.min(), y.max())
colors = [cmap(norm(y[x == val].mean())) for val in values]
fig, ax = plt.subplots()
ax.bar(values, counts, color=colors, edgecolor='black')
ax.yaxis.set_major_locator(MultipleLocator(1))
ax.xaxis.set_major_locator(MultipleLocator(1))
ax.set_ylabel('Count')
ax.margins(x=0.02, y=0)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.colorbar(ScalarMappable(cmap=cmap, norm=norm), pad=0.02, ax=ax)
plt.show()

具有来自其他数组的颜色的直方图

这是另一个示例,使用 seaborn 的tips数据集,x 轴为四舍五入的 total_bill,y 轴为计数,并通过小费金额着色。

import seaborn as sns

tips = sns.load_dataset('tips')
x = np.round(tips['total_bill'])
y = np.array(tips['tip'])

values, counts = np.unique(x, return_counts=True)
cmap = plt.get_cmap('turbo')

x 上的 total_amount 直方图,按提示着色

PS:正如@Arne 的回答中提到的,seaborn 可用于将 norm 和颜色分配替换为 seaborn's hue。如果没有修饰,代码将如下所示:

import numpy as np
import seaborn as sns

x = np.array([3, 5, 12, 7, 8, 6, 4, 6])
y = np.array([4, 6, 8, 2, 4, 5, 8, 7])

values, counts = np.unique(x, return_counts=True)
sns.set_style('darkgrid')
ax = sns.barplot(x=values, y=counts, hue=[y[x == val].mean() for val in values],
                 palette='inferno', dodge=False)

seaborn 条形图


推荐阅读