基于Pandas列值为绘图区间添加分段着色背景的实现方法
为散点图添加分段背景色的实现方案
你手头的DataFrame包含分段标识segment、样本编号sample和数据值data_value,需要绘制sample与data_value的散点图,并给不同segment对应的x轴区间添加不同颜色的背景,同时显示对应图例。你已经实现了散点图绘制,想知道是否能用fill_between()实现背景分段着色——答案是肯定的,下面是具体实现步骤:
1. 准备数据与自动获取分段区间
先通过分组计算,自动获取每个segment对应的sample区间,避免硬编码适配数据变化:
import pandas as pd # 构建示例DataFrame data = { 'segment': ['first', 'first', 'first', 'second', 'second', 'second', 'third', 'third', 'third'], 'sample': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'data_value': [28, 53, 19, 50, 39, 61, 22, 49, 34] } df = pd.DataFrame(data) # 计算每个segment的sample最小/最大值,得到区间 segment_ranges = df.groupby('segment')['sample'].agg(['min', 'max']).reset_index()
2. 定义分段颜色映射
给每个segment分配对应背景色:
color_map = { 'first': '#63aaff', # 蓝色 'second': '#70d675', # 绿色 'third': '#ff9e64' # 橙色 }
3. 使用fill_between()绘制背景色块
利用fill_between()填充x轴区间内的y轴范围,设置透明度避免遮挡散点:
import matplotlib.pyplot as plt # 设置y轴范围(给数据上下留5个单位的边距) y_min = df['data_value'].min() - 5 y_max = df['data_value'].max() + 5 fig, ax = plt.subplots(figsize=(8, 5)) # 遍历每个分段,绘制背景色块 for _, row in segment_ranges.iterrows(): seg = row['segment'] # 让色块覆盖sample的完整区间(比如sample=1对应x从0.5到1.5) x_start = row['min'] - 0.5 x_end = row['max'] + 0.5 ax.fill_between([x_start, x_end], y_min, y_max, color=color_map[seg], alpha=0.2)
4. 绘制散点图并添加图例
通过zorder确保散点在背景之上,手动创建图例项来对应分段背景色:
from matplotlib.patches import Patch # 绘制散点图,zorder设置为2让散点在背景(默认zorder=1)之上 ax.scatter(df['sample'], df['data_value'], color='black', zorder=2) # 创建背景色块对应的图例元素 legend_elements = [Patch(facecolor=color_map[seg], alpha=0.2, label=seg) for seg in color_map.keys()] ax.legend(handles=legend_elements, title='Segment') # 设置轴标签与标题 ax.set_xlabel('Sample') ax.set_ylabel('Data Value') ax.set_title('Scatter Plot with Segment Backgrounds') # 显示所有sample的x轴刻度 ax.set_xticks(df['sample']) plt.tight_layout() plt.show()
完整代码整合
import pandas as pd import matplotlib.pyplot as plt from matplotlib.patches import Patch # 构建示例DataFrame data = { 'segment': ['first', 'first', 'first', 'second', 'second', 'second', 'third', 'third', 'third'], 'sample': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'data_value': [28, 53, 19, 50, 39, 61, 22, 49, 34] } df = pd.DataFrame(data) # 计算每个segment的sample区间 segment_ranges = df.groupby('segment')['sample'].agg(['min', 'max']).reset_index() # 定义颜色映射 color_map = { 'first': '#63aaff', 'second': '#70d675', 'third': '#ff9e64' } # 设置y轴范围 y_min = df['data_value'].min() - 5 y_max = df['data_value'].max() + 5 fig, ax = plt.subplots(figsize=(8, 5)) # 绘制分段背景 for _, row in segment_ranges.iterrows(): seg = row['segment'] x_start = row['min'] - 0.5 x_end = row['max'] + 0.5 ax.fill_between([x_start, x_end], y_min, y_max, color=color_map[seg], alpha=0.2) # 绘制散点图 ax.scatter(df['sample'], df['data_value'], color='black', zorder=2) # 添加图例 legend_elements = [Patch(facecolor=color_map[seg], alpha=0.2, label=seg) for seg in color_map.keys()] ax.legend(handles=legend_elements, title='Segment') # 设置轴标签和标题 ax.set_xlabel('Sample') ax.set_ylabel('Data Value') ax.set_title('Scatter Plot with Segment Backgrounds') ax.set_xticks(df['sample']) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者MAtennis9
相关产品推荐
相关产品推荐

