本系列文章配套代码获取有以下两种途径:
-
通过百度网盘获取:
链接:https://pan.baidu.com/s/1jG-rGG4QMuZu0t0kEEl7SA?pwd=mnsj
提取码:mnsj
-
前往GitHub获取:
https://github.com/returu/Data_Visualization
函数语法:
plt.stem(*args, linefmt=None, markerfmt=None, basefmt=None,
bottom=0, label=None, orientation='vertical',
data=None)
-
定位参数:
-
locs:茎线位置序列(x轴或y轴); -
heads:茎的高度值序列(y轴或x轴);
-
样式控制参数:
-
linefmt:茎的线条样式(如‘r–‘表示红色虚线); -
markerfmt:末端标记的格式字符串(如‘go’表示绿色圆点); -
basefmt:基线格式字符串(如‘k:’表示黑色点线);
-
布局控制参数:
-
bottom:基线位置偏移量;
-
label:图表标签(用于图例显示);
-
orientation:‘vertical’(默认)或‘horizontal’,交换x/y后可省略。
通过调整这些参数,可以灵活控制茎叶图的视觉效果。
# 创建示例数据
time = np.linspace(0, 10, 50)
signal = np.sin(time) + np.random.normal(0, 0.1, 50)
# 创建茎叶图
plt.stem(time,
signal,
linefmt='-k', # 茎:红色实线
markerfmt='ob', # 标记点:蓝色圆形
basefmt='--r', # 基线:黑色虚线
label='信号强度', # 标签(用于图例)
bottom=-0.5, # 调整基线位置
orientation='horizontal'# 明确指定水平方向(可选,交换x/y后可省略)
)
plt.title("传感器脉冲信号图")
plt.xlabel("时间 (秒)")
plt.ylabel("信号强度")
plt.grid(alpha=0.3) # 添加网格
plt.show()
可视化结果如下图所示:

使用示例:
-
示例1:自定义茎叶图样式
在使用stem()函数时,会返回一个特殊的StemContainer对象,这个对象封装了茎叶图的三个核心组成部分:
markerline, stemlines, baseline = plt.stem(...)
-
markerline:代表茎叶图顶端的标记点(”叶” 的部分),是一个Line2D对象;
-
stemlines:代表连接基线和标记点的茎线段,是一个LineCollection对象;
-
baseline:代表基线,是一个Line2D对象。
通过对上述三个组件进行二次编辑,可以实现比stem()函数参数更细致的样式控制,主要有以下两种方法:
-
方法 1:直接调用对象的属性设置方法:通过对象自带的 set_xxx() 系列方法(如 set_color()、set_markersize() 等),直接对元素样式进行修改。 -
方法 2:使用 plt.setp() 函数批量设置属性:通过 Matplotlib 提供的 plt.setp() 工具函数,批量为对象设置多个属性。
# 创建示例数据
x = np.arange(0, 10, 0.5)
y = np.sin(x)
# 创建茎叶图并获取三个核心组件
markerline, stemlines, baseline = plt.stem(
x, y,
linefmt='--g', # 茎线样式:绿色虚线
markerfmt='or', # 叶标记样式:红色圆圈
basefmt='k-', # 基线样式:黑色实线
)
# ============获取返回对象进行二次编辑=====================
# 修改茎头(标记点)样式
markerline.set_markersize(10) # 设置标记点大小
markerline.set_markerfacecolor('crimson') # 设置标记点填充色
markerline.set_markeredgecolor('black') # 设置标记点边缘色
# 修改茎线样式
colors = plt.cm.viridis(np.linspace(0, 1, len(x))) # 创建颜色映射
# 遍历所有茎线段(通过get_segments()获取线段集合)
for i, segment in enumerate(stemlines.get_segments()):
# 为每条茎线设置对应的渐变颜色
stemlines.set_color(colors[i])
# 修改基线样式(使用plt.setp()批量设置属性)
plt.setp(baseline, color='green', linewidth=2)
plt.title('自定义样式茎叶图')
plt.xlabel('时间')
plt.ylabel('振幅')
plt.grid(True)
plt.show()

-
示例2:分组茎叶图
绘制分组茎叶图(多组数据对比的茎叶图)的核心思路是通过多次调用plt.stem()函数并合理设置样式与位置,实现多组数据的清晰展示。
另外,当多组数据共享同一 x 轴基准时,直接绘制会导致茎叶重叠,可以通过微调 x 坐标实现分组区分。
# 创建分组数据
days = np.arange(1, 8) # 横坐标:1-7天
product_a = np.array([120, 150, 130, 180, 160, 190, 200]) # A产品销量
product_b = np.array([90, 110, 100, 140, 130, 160, 170]) # B产品销量
product_c = np.array([150, 170, 160, 210, 190, 220, 230]) # C产品销量
plt.figure(figsize=(12, 7))
# 绘制多组茎叶图(不同样式区分)
plt.stem(days, product_a, linefmt='-r', markerfmt='or', basefmt='-', label='产品A')
plt.stem(days, product_b, linefmt='-g', markerfmt='og', basefmt='-', label='产品B')
plt.stem(days + 0.1, product_c, linefmt='-b', markerfmt='ob', basefmt='-', label='产品C')
# 添加图表元素
plt.title('3款产品一周销量波动对比(茎叶图)', fontsize=14, pad=20)
plt.xlabel('日期(天)', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.xticks(days) # x轴刻度:显示1-7天
plt.legend(fontsize=10)
plt.grid(alpha=0.3, axis='y') # 仅显示y轴网格
plt.show()

更多内容可以前往官网查看:
https://matplotlib.org/stable/


本篇文章来源于微信公众号: 码农设计师