如何基于自定义重复X轴刻度绘制非等间距数据
问题描述
已知同类问题通常直接用数据X值作为X轴刻度,但本次需求存在核心差异:
- 数据点的X值非等间距
- 需要基于固定重复的X轴序列绘图,该序列为测量窗口从3.5到4.9再返回3.5,示例:
range = [3.5, 3.6,...,4.8, 4.9, 4.8,..., 3.6, 3.5] - 要求在单个坐标轴内呈现类似目标图的往返效果
尝试以下方法均未解决问题:
- 使用
plt.xticks设置自定义重复刻度,出现4.8到3.6的刻度重复问题 - 手动拆分数据绘图,结合
ax.set_xticks和ax.set_xticklabels也无法实现需求
附相关内容
data_df数据示例
[[4.2, 416394000.0], [4.55, 417501000.0], ..., [3.41905, 328130000.0]]
尝试代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt data_df = ... # 创建刻度 ticks = np.arange(3.5, 4.9, 0.1) ticks = np.append(ticks, np.arange(4.8, 3.5, -0.1)) # 绘图 fig = plt.figure(figsize=(10,7.5)) ax = plt.subplot() plt.xticks(ticks) ax.scatter(data_df.x, data_df.y) plt.show()
最小复现代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt data_df = pd.DataFrame([[1.0, 3], [1.1, 4], ..., [1.2, 4]], columns = ['x', 'y']) xticks = np.arange(1, 2, 0.1) xticks = np.append(xticks, np.arange(2, 0.9, -0.1)) fig = plt.figure() ax = plt.subplot() plt.xticks(xticks) ax.scatter(data_df.x, data_df.y) plt.show()
解决方案
核心思路:将重复的X轴序列映射为连续索引作为绘图的实际X坐标,再用原序列值作为刻度标签,从底层避免刻度重复冲突,同时呈现往返效果。
步骤1:生成目标往返X轴序列
# 生成3.5到4.9的正向序列(步长0.1,用5.0确保包含4.9) forward = np.arange(3.5, 5.0, 0.1) # 生成4.8到3.5的反向序列(步长-0.1) backward = np.arange(4.8, 3.4, -0.1) # 合并为完整往返序列 target_x = np.concatenate([forward, backward])
步骤2:匹配数据点到目标序列的索引
如果数据X值与目标序列不完全一致,通过找最接近值的方式匹配索引:
# 为每个数据点添加绘图用的X索引列 data_df['plot_x'] = [np.argmin(np.abs(target_x - x)) for x in data_df['x']]
步骤3:绘图并设置刻度
用索引作为实际X坐标绘图,再将目标序列值设为刻度标签:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 加载data_df(此处省略数据加载代码) # 生成目标X序列 forward = np.arange(3.5, 5.0, 0.1) backward = np.arange(4.8, 3.4, -0.1) target_x = np.concatenate([forward, backward]) # 匹配索引 data_df['plot_x'] = [np.argmin(np.abs(target_x - x)) for x in data_df['x']] # 绘图 fig, ax = plt.subplots(figsize=(10,7.5)) ax.scatter(data_df['plot_x'], data_df['y']) # 设置刻度:索引位置对应目标序列数值 ax.set_xticks(np.arange(len(target_x))) ax.set_xticklabels([f'{x:.1f}' for x in target_x]) # 可选:旋转刻度避免重叠 plt.xticks(rotation=45) plt.tight_layout() plt.show()
最小复现代码适配
将目标序列替换为示例中的1.0到2.0往返序列即可:
import pandas as pd import numpy as np import matplotlib.pyplot as plt data_df = pd.DataFrame([[1.0, 3], [1.1, 4], [1.2, 4], [1.9, 5], [1.8, 4], [1.0, 3]], columns = ['x', 'y']) # 生成目标X序列 forward = np.arange(1.0, 2.1, 0.1) backward = np.arange(1.9, 0.9, -0.1) target_x = np.concatenate([forward, backward]) # 匹配索引 data_df['plot_x'] = [np.argmin(np.abs(target_x - x)) for x in data_df['x']] # 绘图 fig, ax = plt.subplots() ax.scatter(data_df['plot_x'], data_df['y']) ax.set_xticks(np.arange(len(target_x))) ax.set_xticklabels([f'{x:.1f}' for x in target_x]) plt.xticks(rotation=45) plt.tight_layout() plt.show()
说明
- 此方法通过索引映射让底层X轴保持连续,彻底解决重复刻度的冲突问题
- 刻度标签显示所需的往返数值,视觉效果符合需求
- 若数据X值与目标序列完全一一对应,可直接用目标序列的索引作为
plot_x,无需找最接近值
内容的提问来源于stack exchange,提问作者jtAxiom
相关产品推荐
相关产品推荐

