python画图|堆叠直方图绘制

前述文章里,我们已经探索了如何画直方图,以及如何设置图例、颜色等。具体可通过下述链接找到:

https://mp.csdn.net/mp_blog/creation/editor/141830709

https://mp.csdn.net/mp_blog/creation/editor/141894225 

本期文章,我们继续探索: 堆叠直方图

【1】官网教程

直方图堆叠是常见的数据表达方式,有助于大家表达两种及以上类别的累积影响。

在python中绘制直方图,需要在常规的坐标轴上,增加设置底座直方图(地基)和叠加多层(建楼)两个操作。

打开官网https://matplotlib.org/stable/gallery/lines_bars_and_markers/index.html

我们看到Bar Label Demo和Stacked bar chart模块都显示了堆叠直方图。

图1

分别点进 Bar Label Demo和Stacked bar chart模块,发现后者是前者的一部分,但前者内容更多,因此先打开Stacked bar chart。由此进入学习模式。

【2】代码解读

代码前两行,引入计算模块numpy用于数值运算,画图模块matplotlib用于绘图。

import matplotlib.pyplot as plt #引入matplotlib模块用于绘图
import numpy as np #引入numpy模块用于数值计算

之后开始定义直方图的类别:

species = ( #定义species数组,作为直方图的类别
    "Adelie\n $\\mu=$3700.66g",
    "Chinstrap\n $\\mu=$3733.09g",
    "Gentoo\n $\\mu=5076.02g$",
)

之后定义直方图各类别对应数值:

 

weight_counts = { #定义weight_counts数组,这个数组包括两个子数组,直方图叠加依据这两组数
    "Below": np.array([70, 31, 58]), #直方图第一层的依据数据
    "Above": np.array([82, 37, 66]), #直方图第二层的依据数据
}

然后定义了图形的基本属性:

width = 0.5 #定义width常数,用于设置直方图间距

fig, ax = plt.subplots() #定义一个带坐标轴的图,坐标轴属性用ax控制

实际上width=0.5出现略早,因为图形还没开始定义,上述代码交换一下位置更合适。不过当前这种先后顺序不会影响实际输出效果,所以无需深究。
之后定义了bottom = np.zeros(3) ,定义了一个1X3的全0矩阵。

bottom = np.zeros(3) #定义1X3的全0矩阵

在后续运行中将会发现,叠加矩阵的第一层需要设置是从y=0开始画方块。

也即,堆叠直方图需要明确“地基”起点。

 此后定义了画图函数,使用for循环反复输出:

for boolean, weight_count in weight_counts.items(): #for函数用于遍历weight_counts内部分布尔型数组
    p = ax.bar(species, weight_count, width, label=boolean, bottom=bottom) #以species为类别,weight_count为数值, width为不同方块间距, label=boolean图例为boolean, bottom=bottom为方块底部对应Y值
    bottom += weight_count #用bottom+weight_count赋值旧的bottom,即bottom =bottom+weight_count,新的bottom是新的一轮直方图起点

 这里需要注意的是:bottom += weight_count。

它代表的意思是,上一轮直方图行绘制完毕,其顶部对应y值,应该是下一轮直方图绘制的起点。

这里需要注意的是这是实现堆叠的根本原因。

最后:设置了图名、图例名,并要求输出了图形。

ax.set_title("Number of penguins with above average body mass") #设置图名
ax.legend(loc="upper right") #设置图例名

plt.show() #输出图形

图2

【3】代码改写-增加堆叠层数

官网代码绘制出了两层堆叠图,我们尝试绘制三层,将weight_counts部分增加一个数组,改后为:

weight_counts = { #定义weight_counts数组,这个数组包括两个子数组,直方图叠加依据这两组数
    "Below": np.array([70, 31, 58]),
    "Above": np.array([82, 37, 66]),
    "add": np.array([90, 70, 80]), #新增对叠层
}

此时的输出图形如下:

图3

完整代码为;

import matplotlib.pyplot as plt #引入matplotlib模块用于绘图
import numpy as np #引入numpy模块用于数值计算

# data from https://allisonhorst.github.io/palmerpenguins/


species = ( #定义species数组,作为直方图的类别
    "Adelie\n $\\mu=$3700.66g",
    "Chinstrap\n $\\mu=$3733.09g",
    "Gentoo\n $\\mu=5076.02g$",
)
weight_counts = { #定义weight_counts数组,这个数组包括两个子数组,直方图叠加依据这两组数
    "Below": np.array([70, 31, 58]),
    "Above": np.array([82, 37, 66]),
    "Add": np.array([70, 90, 80]),  #新增对叠层
}
width = 0.5 #定义width常数,用于设置直方图间距
fig, ax = plt.subplots() #定义一个带坐标轴的图,坐标轴属性用ax控制
bottom = np.zeros(3) #定义1X3的全0矩阵

for boolean, weight_count in weight_counts.items(): #for函数用于遍历weight_counts内部分布尔型数组
    p = ax.bar(species, weight_count, width, label=boolean, bottom=bottom) #以species为类别,weight_count为数值, width为不同方块间距, label=boolean图例为boolean, bottom=bottom为方块底部对应Y值
    bottom += weight_count #用bottom+weight_count赋值旧的bottom,即bottom =bottom+weight_count
ax.set_title("Number of penguins with above average body mass") #设置图名
ax.legend(loc="upper right") #设置图例名

plt.show() #输出图形

【4】代码改写-增加各对堆叠层对应数据

各队叠层如果只是图形,虽然直观,但是各部分实际数据如果能一同体现则更好。

直方图是以类别区分,以数据作为画图高度,因此把数据作为标签显示出来即可。

在for循环中增加一行:

ax.bar_label(p, label_type='center') #将各部分数据作为标签输出,至于方块图中间

输出图形为:

图4

由图4可见,各部分数据已经显示。

完整代码如下:

import matplotlib.pyplot as plt #引入matplotlib模块用于绘图
import numpy as np #引入numpy模块用于数值计算

# data from https://allisonhorst.github.io/palmerpenguins/


species = ( #定义species数组,作为直方图的类别
    "Adelie\n $\\mu=$3700.66g",
    "Chinstrap\n $\\mu=$3733.09g",
    "Gentoo\n $\\mu=5076.02g$",
)
weight_counts = { #定义weight_counts数组,这个数组包括两个子数组,直方图叠加依据这两组数
    "Below": np.array([70, 31, 58]),
    "Above": np.array([82, 37, 66]),
    "Add": np.array([70, 90, 80]),  #新增对叠层
}
width = 0.5 #定义width常数,用于设置直方图间距
fig, ax = plt.subplots() #定义一个带坐标轴的图,坐标轴属性用ax控制
bottom = np.zeros(3) #定义1X3的全0矩阵

for boolean, weight_count in weight_counts.items(): #for函数用于遍历weight_counts内部分布尔型数组
    p = ax.bar(species, weight_count, width, label=boolean, bottom=bottom) #以species为类别,weight_count为数值, width为不同方块间距, label=boolean图例为boolean, bottom=bottom为方块底部对应Y值
    bottom += weight_count #用bottom+weight_count赋值旧的bottom,即bottom =bottom+weight_count
    ax.bar_label(p, label_type='center') #将各部分数据作为标签输出,至于方块图中间
ax.set_title("Number of penguins with above average body mass") #设置图名
ax.legend(loc="upper right") #设置图例名

plt.show() #输出图形

【5】总结

本文学习堆叠直方图的画法,包括使用for循环使用对叠层的设置、层数变化和各对叠层数据显示。

 

 

  • 24
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用Python的Matplotlib库中的mpl_toolkits.mplot3d来绘制3D柱状图和直方图,其中ax.bar3d函数可以用于创建3D柱状图。 例如,以下是一个使用ax.bar3d绘制3D柱状图的示例代码: ```python import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 数据 x = np.random.randint(0, 10, 10) y = np.random.randint(0, 10, 10) z = np.random.randint(0, 10, 10) dx = np.ones_like(x) dy = np.ones_like(y) dz = z # 绘制3D柱状图 ax.bar3d(x, y, z, dx, dy, dz) # 添加轴标签 ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') plt.show() ``` 如果您想要绘制3D直方图,可以使用ax.hist3d函数。以下是一个使用ax.hist3d绘制3D直方图的示例代码: ```python import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 数据 x = np.random.randn(100) y = np.random.randn(100) z = np.random.randn(100) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 绘制3D直方图 hist, xedges, yedges = np.histogram2d(x, y, bins=10) xpos, ypos = np.meshgrid(xedges[:-1]+xedges[1:], yedges[:-1]+yedges[1:]) xpos = xpos.flatten()/2. ypos = ypos.flatten()/2. zpos = np.zeros_like(xpos) dx = xedges[1] - xedges[0] dy = yedges[1] - yedges[0] dz = hist.flatten() ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average') # 添加轴标签 ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') plt.show() ``` 希望这能帮到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值