解决Matplotlib中fill_betweenx按类别填充时的间隙问题
解决Matplotlib中fill_betweenx按类别填充时的间隙问题
嗨,我完全懂你遇到的麻烦——用fill_betweenx按类别给填充图上色时,类别切换的地方总会出现讨厌的间隙,明明想让颜色无缝衔接,结果却断成好几块,太闹心了!
先复盘下你的场景:你有按类别分组的海拔(elev)和强度(strength)数据,一开始没区分类别画出来是完整的,但尝试用np.where给不同类别设nan分别填充后,就出现了间隙。你希望这些间隙能被前一个类别的颜色填满,达到完全无缝的效果。
其实问题出在np.where生成的数组里,类别切换的位置是nan,填充的时候就会断开。要解决这个,我们只需要给每个类别的数据“补个尾巴”,让它刚好衔接下一个类别的起始点就行,具体做法如下:
解决方案步骤
- 按类别分组数据:先把每个类别对应的elev和strength单独提取出来;
- 扩展类别数据区间:给每个类别(除了最后一个)添加下一个类别的最高海拔值,同时用当前类别的最后一个强度值来对应这个新增的点,这样填充的时候就能覆盖到两个类别之间的间隙;
- 逐个类别填充绘图:用处理后的数据分别调用
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
相关产品推荐
相关产品推荐

