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

如何在单张图中绘制具有不同坐标轴尺度的多个散点图?

在单张图中绘制不同XY轴尺度的多组散点图

问题描述

你需要在同一张图中绘制多组散点图,但每组数据的X、Y轴尺度差异较大,直接使用plt.scatter()依次绘制会导致所有数据被迫适配最后一组的轴尺度,无法清晰展示其他组数据的分布。例如给定以下数据:

a = [0, 1, 2, 3]
b = [10, 20, 30, 40, 50]
c = [1000, 2000, 3000, 4000]
aa = [5, 6, 7, 8]
bb = [50, 60, 70, 80, 90]
cc = [5000, 6000, 7000, 8000]

需要绘制(a, aa)、(b, bb)、(c, cc)三组散点图,避免轴尺度被最后一组覆盖。


解决方案1:使用次坐标轴(保留原始尺度)

通过创建次坐标轴(twinx()/twiny()),为每组数据分配独立的X/Y轴,确保每组数据的原始尺度都能被正确展示,同时所有散点处于同一张图中。

示例代码:

import matplotlib.pyplot as plt

# 定义目标数据
a = [0, 1, 2, 3]
b = [10, 20, 30, 40, 50]
c = [1000, 2000, 3000, 4000]
aa = [5, 6, 7, 8]
bb = [50, 60, 70, 80, 90]
cc = [5000, 6000, 7000, 8000]

# 创建基础坐标轴
fig, ax1 = plt.subplots(figsize=(10, 6))

# 绘制第一组数据 (a, aa)
ax1.scatter(a, aa, color='#ff4444', label='(a, aa)')
ax1.set_xlabel('X轴 - 组1', color='#ff4444', fontsize=10)
ax1.set_ylabel('Y轴 - 组1', color='#ff4444', fontsize=10)
ax1.tick_params(axis='both', labelcolor='#ff4444')

# 创建第二组次坐标轴(X/Y轴)
ax2 = ax1.twinx()
ax2_x = ax1.twiny()

# 绘制第二组数据 (b, bb)
ax2.scatter(b, bb, color='#33b5e5', label='(b, bb)')
ax2.set_ylabel('Y轴 - 组2', color='#33b5e5', fontsize=10)
ax2.tick_params(axis='y', labelcolor='#33b5e5')
ax2_x.set_xlabel('X轴 - 组2', color='#33b5e5', fontsize=10)
ax2_x.tick_params(axis='x', labelcolor='#33b5e5')

# 创建第三组次坐标轴(偏移避免重叠)
ax3 = ax1.twinx()
ax3.spines['right'].set_position(('outward', 60))
ax3_x = ax1.twiny()
ax3_x.spines['top'].set_position(('outward', 60))

# 绘制第三组数据 (c, cc)
ax3.scatter(c, cc, color='#99cc00', label='(c, cc)')
ax3.set_ylabel('Y轴 - 组3', color='#99cc00', fontsize=10)
ax3.tick_params(axis='y', labelcolor='#99cc00')
ax3_x.set_xlabel('X轴 - 组3', color='#99cc00', fontsize=10)
ax3_x.tick_params(axis='x', labelcolor='#99cc00')

# 合并所有图例
handles = ax1.get_legend_handles_labels()[0] + ax2.get_legend_handles_labels()[0] + ax3.get_legend_handles_labels()[0]
labels = ax1.get_legend_handles_labels()[1] + ax2.get_legend_handles_labels()[1] + ax3.get_legend_handles_labels()[1]
ax1.legend(handles, labels, loc='upper left', bbox_to_anchor=(1.2, 1))

plt.title('多组不同尺度散点图(保留原始轴尺度)', fontsize=12)
plt.tight_layout()
plt.show()

解决方案2:数据归一化(展示趋势)

如果不需要保留原始尺度,仅需展示各组数据的分布趋势,可以将所有数据归一化到同一区间(如[0,1]),这样所有散点都能在统一的轴尺度下清晰展示。

示例代码:

import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
import numpy as np

# 定义目标数据
a = [0, 1, 2, 3]
b = [10, 20, 30, 40, 50]
c = [1000, 2000, 3000, 4000]
aa = [5, 6, 7, 8]
bb = [50, 60, 70, 80, 90]
cc = [5000, 6000, 7000, 8000]

# 初始化归一化器
scaler = MinMaxScaler(feature_range=(0, 1))

# 对每组数据的X、Y分别做归一化处理
a_norm = scaler.fit_transform(np.array(a).reshape(-1, 1)).flatten()
aa_norm = scaler.fit_transform(np.array(aa).reshape(-1, 1)).flatten()

b_norm = scaler.fit_transform(np.array(b).reshape(-1, 1)).flatten()
bb_norm = scaler.fit_transform(np.array(bb).reshape(-1, 1)).flatten()

c_norm = scaler.fit_transform(np.array(c).reshape(-1, 1)).flatten()
cc_norm = scaler.fit_transform(np.array(cc).reshape(-1, 1)).flatten()

# 绘制所有归一化后的散点
plt.figure(figsize=(8, 6))
plt.scatter(a_norm, aa_norm, color='#ff4444', label='(a, aa)')
plt.scatter(b_norm, bb_norm, color='#33b5e5', label='(b, bb)')
plt.scatter(c_norm, cc_norm, color='#99cc00', label='(c, cc)')

plt.xlabel('归一化X轴', fontsize=10)
plt.ylabel('归一化Y轴', fontsize=10)
plt.title('多组散点图(归一化后)', fontsize=12)
plt.legend()
plt.grid(alpha=0.3)
plt.show()

针对你提供的30组数据循环代码的调整建议

如果你的循环绘制代码中,30组数据的X/Y尺度差异较大,可参考以下两种调整方式:

  • 若需保留原始尺度:将每组数据分配到独立的次坐标轴(注意过多次坐标轴会导致图表拥挤,可考虑分组展示或使用子图)
  • 若仅需展示趋势:在循环内对每组数据先做归一化再绘制

内容的提问来源于stack exchange,提问作者Reza Bahmani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:05:24