You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Matplotlib中fill_betweenx按类别填充时的间隙问题

解决Matplotlib中fill_betweenx按类别填充时的间隙问题

嗨,我完全懂你遇到的麻烦——用fill_betweenx按类别给填充图上色时,类别切换的地方总会出现讨厌的间隙,明明想让颜色无缝衔接,结果却断成好几块,太闹心了!

先复盘下你的场景:你有按类别分组的海拔(elev)和强度(strength)数据,一开始没区分类别画出来是完整的,但尝试用np.where给不同类别设nan分别填充后,就出现了间隙。你希望这些间隙能被前一个类别的颜色填满,达到完全无缝的效果。

其实问题出在np.where生成的数组里,类别切换的位置是nan,填充的时候就会断开。要解决这个,我们只需要给每个类别的数据“补个尾巴”,让它刚好衔接下一个类别的起始点就行,具体做法如下:

解决方案步骤

  1. 按类别分组数据:先把每个类别对应的elev和strength单独提取出来;
  2. 扩展类别数据区间:给每个类别(除了最后一个)添加下一个类别的最高海拔值,同时用当前类别的最后一个强度值来对应这个新增的点,这样填充的时候就能覆盖到两个类别之间的间隙;
  3. 逐个类别填充绘图:用处理后的数据分别调用fill_betweenx,就能得到无缝的填充效果了。

完整代码示例

import numpy as np
import matplotlib.pyplot as plt

# 原始数据
category = np.array(['A','A','A','B','B','B','C','C','C'])
elev = np.array([100,90,80,70,60,50,40,30,20])
strength = np.array([8,8,7,6,6,6,9,10,10])

# 按类别分组存储数据
groups = {}
for cat in np.unique(category):
    mask = category == cat
    groups[cat] = {
        'elev': elev[mask].copy(),
        'strength': strength[mask].copy()
    }

# 按海拔从高到低确定类别顺序(避免手动指定的局限)
unique_cats = list(groups.keys())
cat_max_elev = {cat: groups[cat]['elev'].max() for cat in unique_cats}
cat_order = sorted(unique_cats, key=lambda x: cat_max_elev[x], reverse=True)

# 给每个类别扩展数据,衔接下一个类别
for i in range(len(cat_order)):
    current_cat = cat_order[i]
    current_group = groups[current_cat]
    if i < len(cat_order) - 1:
        next_cat = cat_order[i+1]
        next_group = groups[next_cat]
        # 添加下一个类别的最高海拔到当前类别末尾
        current_group['elev'] = np.append(current_group['elev'], next_group['elev'][0])
        # 添加当前类别的最后一个强度值,保证填充连续
        current_group['strength'] = np.append(current_group['strength'], current_group['strength'][-1])

# 逐个类别填充绘图
plt.fill_betweenx(groups['A']['elev'], groups['A']['strength'], step='mid', color='firebrick')
plt.fill_betweenx(groups['B']['elev'], groups['B']['strength'], step='mid', color='royalblue')
plt.fill_betweenx(groups['C']['elev'], groups['C']['strength'], step='mid', color='seagreen')

# 添加标签和标题
plt.xlabel('Strength')
plt.ylabel('Elevation')
plt.title('Category-wise Filled Plot (No Gaps!)')
plt.show()

为什么这个方法有效?

我们给每个类别额外添加了一个点,这个点刚好是下一个类别的起始海拔,并且用当前类别的最后一个强度值来填充。这样fill_betweenx在使用step='mid'绘制时,就会把两个类别之间的空隙完全覆盖,不会再出现断开的间隙,完美实现你想要的无缝效果。

备注:内容来源于stack exchange,提问作者user30104652

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 20:14:27