matplotlib画堆叠、并列直方图

在用 matplotlib.pyplot.hist 画分布图时,若总分布由几个分量组成(如高斯混合),想用不同颜色标识出来,方便看到各分量占比,参考 [1]。

效果:

  • 分布由两个分量(x、y)组成;
  • 左上:总分布;
  • 右上:总分布,y 轴用 log scale;
  • 左下:并列展示两个分量分布;
  • 右下:总分布,但堆叠展示两个分量分布,用不同颜色标识。

histogram

Code

  • hist 传多个数组(tuple/list),label、color 也是相应的顺序;
  • stacked=True 是堆叠,False 是并列。
import numpy as np
import matplotlib.pyplot as plt

# 示例分布,分 x、y 两分量,且数量不同(10000 和 20000)
x = np.random.randn(10000) # 正太分布
y = np.random.uniform(low=x.min(), high=x.max(), size=[20000]) # 均匀分布
z = np.concatenate((x, y)) # 总分布

cmap = plt.get_cmap('viridis')

fig, ax = plt.subplots(2, 2, figsize=(15, 15))
# 左上。似乎排在前面的数组会画先,从而出现在底部
ax[0][0].hist(z, bins=100, label="x and y", color=cmap(0.25))
# 右上。y 轴用 log scale
ax[0][1].hist(z, bins=100, label="x and y", color=cmap(0.25), log=True)
# 左下,并列
ax[1][0].hist((x, y), bins=100, label=("x", "y"))
# 右下,堆叠
ax[1][1].hist((x, y), bins=100, label=("x", "y"), stacked=True)

# 图例
for i in range(len(ax)):
    for j in range(len(ax[0])):
        ax[i][j].legend(fancybox=True, framealpha=0) # 透明图例

plt.tight_layout()
fig.savefig("test.png", bbox_inches='tight')
plt.close(fig)

References

  1. The histogram (hist) function with multiple data sets
  2. matplotlib.pyplot.hist
<think>好的,我现在需要帮助用户解决在Python中绘制非重叠直方图的问题。首先,我需要明确用户的需求。用户提到“非重叠直方图”,可能指的是多个直方图在同一个图中并列显示,而不是堆叠在一起,或者在不同的子图中分开显示。根据用户提供的引用,站内资料提到了堆叠直方图并列直方图的绘制方法,用户可能希望了解如何调整直方图的位置,使得它们不互相覆盖。 接下来,我需要回忆Python中常用的绘图库,比如Matplotlib,因为用户提供的引用都是关于Python绘图的。用户提到的引用[1]和[3]分别涉及堆叠并列直方图,这可能与非重叠直方图的绘制方法相关。我需要结合这些引用中的方法,比如设置底座直方图、调整位置、使用for循环等,来设计解决方案。 首先,非重叠直方图可能有几种实现方式:一是将多个直方图并列显示在同一坐标系中,每个直方图的柱子并排排列;另一种是将多个直方图分别绘制在不同的子图中。用户的问题可能更倾向于前者,即在同一图中并列显示,不重叠。 根据引用[3],并列直方图的绘制方法涉及调整每个柱子的位置和宽度,避免重叠。例如,通过循环每个类别,计算每个柱子的x轴位置,并水平移动它们的位置,使得各个直方图的柱子并列排列。例如,对于两个数据集,可以将每个柱子的宽度设为0.4,然后分别将第一个数据集的柱子左移0.2,第二个右移0.2,这样它们并列且不重叠。 另外,引用[2]提到设置x轴的刻度位置,这可能用于调整直方图的标签位置,使得每个并列的柱子下方有对应的标签。例如,使用ax.xaxis.set_ticks来设置刻度的位置,确保每个类别标签位于两个并列柱子的中间。 还需要考虑数据的分组和柱子的颜色区分,避免视觉混淆。可能需要使用不同的颜色或透明度来区分不同的直方图,同时添加图例说明。 现在,我需要将这些思路整理成步骤,并编写相应的示例代码。首先,导入必要的库(如matplotlib.pyplot和numpy)。然后生成示例数据,可能使用numpy.random生成不同分布的数据集。接下来,设置柱子宽度和位置,计算每个柱子的x轴位置,确保它们并列排列。使用plt.bar绘制每个数据集的直方图,调整x参数为计算后的位置。最后,设置x轴刻度和标签,添加图例和标签,显示图形。 在编写代码时,需要注意每个数据集的柱子宽度应适当减小,以留出空间给其他数据集。例如,如果有两个数据集,每个柱子的宽度可以设为0.4,这样总宽度为0.8,剩下的空间作为间隔。然后,第一个数据集的x位置减去宽度的一半,第二个加上,这样它们并列在同一个分类位置的两侧。 此外,需要测试代码是否正确,确保柱子不重叠,标签正确显示。可能还需要处理多个数据集的情况,比如三个或更多,这时需要调整每个柱子的位置和宽度,确保它们均匀分布,不重叠。 最后,根据用户提供的引用,需要在回答中引用相关的资料,比如引用[3]提到的并列直方图的循环法和位置调整,引用[2]的刻度设置方法。因此,在回答中要自然地添加这些引用标识。 总结步骤: 1. 导入必要的库。 2. 生成示例数据。 3. 设置柱子的宽度和位置。 4. 使用循环绘制每个数据集的直方图,调整x轴位置。 5. 设置刻度和标签。 6. 添加图例和标签,显示图形。 现在,将这些步骤转化为具体的代码示例,并确保符合用户的要求,即非重叠直方图。</think>在Python中绘制非重叠的直方图,可以通过调整柱子位置和宽度实现并列显示。以下是具体方法: ### 实现步骤 1. **导入库**:使用`matplotlib`和`numpy` 2. **生成数据**:创建多个数据集(示例含两个正态分布) 3. **设置参数**:定义柱子宽度、位置偏移量 4. **循环绘图**:对每个数据集,计算偏移后的x轴位置,并绘制直方图 5. **坐标轴调整**:设置x轴刻度和标签位置,添加图例 ```python import matplotlib.pyplot as plt import numpy as np # 生成两组示例数据 data1 = np.random.normal(60, 10, 200) data2 = np.random.normal(80, 15, 200) categories = ['A', 'B', 'C', 'D'] # 直方图类别标签 # 设置柱子参数 bar_width = 0.35 # 每个柱子宽度 x = np.arange(len(categories)) # 基础坐标 plt.figure(figsize=(10,6)) # 绘制第一组直方图(左偏移) plt.bar(x - bar_width/2, [data1[data1//20==i].size for i in range(4)], width=bar_width, label='数据集1', alpha=0.7) # 绘制第二组直方图(右偏移) plt.bar(x + bar_width/2, [data2[data2//20==i].size for i in range(4)], width=bar_width, label='数据集2', alpha=0.7) # 设置坐标轴标签 plt.xticks(x, categories) # 引用[2]的刻度设置方法 plt.xlabel('类别') plt.ylabel('频数') plt.title('并列直方图示例') plt.legend() plt.show() ``` ### 关键技巧 1. **位置偏移**:通过`x ± bar_width/2`实现并列显示[^3] 2. **透明度调节**:`alpha`参数提升重叠区域可见性 3. **标签对齐**:使用`plt.xticks()`精确控制标签位置[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值