首页编程开发Matplotlib【数据可视化(Matplo...

【数据可视化(Matplotlib篇)】42.绘制茎叶图stem()

本系列文章配套代码获取有以下两种途径:

  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/1jG-rGG4QMuZu0t0kEEl7SA?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/Data_Visualization





茎叶图(Stem Plot)由一组从基线延伸的直线(茎)和末端标记(叶)组成,常用于表示小样本离散数据序列,也叫火柴杆图。它结合了离散点图和柱状图的特点,既能显示具体数值,又能保持数据的离散特性。
01

函数语法


Matplotlib barh()函数专门用于绘制茎叶,其函数语法如下:
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()

可视化结果如下图所示:


02

使用示例


  • 示例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/


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

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments