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

如何在Matplotlib孪生轴的同x值对应点间绘制垂直线?

孪生轴(twinx)上同x值两点间绘制垂直线的实现方法

已知在同一坐标轴上可以实现两点间垂直线的绘制,但当两组点分别位于**孪生轴(twinx)**上时,由于两个轴的y轴刻度独立,直接绘制会出现坐标不匹配的问题。以下是给定的基础绘图代码:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

num_points = 100

# Generate x-values 
x_values = np.arange(num_points)

# Create a decreasing linear function
slope = -0.1
intercept = 5
y_values = slope * x_values + intercept

# Add random noise 
noise_scale = 0.5
y_values += np.random.normal(0, noise_scale, num_points)

# Create the numpy arrays
random_points = np.column_stack((x_values, y_values))
random_numbers = np.random.uniform(-0.5, 0.5, num_points)

# Creat DF
df = pd.DataFrame(data={'x': x_values, 'y0': y_values, 'y1': random_numbers})

# Plot the points
ax = df.plot.scatter(x='x', y='y0', c='b', marker='o', label='y0')
ax.legend().set_visible(False)
ax1 = ax.twinx()
ax1.scatter(df['x'], df['y1'], color='darkorange', marker='o', label='y1')
ax1.legend().set_visible(False)
plt.show()

核心思路

孪生轴的y轴坐标空间是独立的,因此需要将其中一个轴的y坐标转换到另一个轴的坐标系统中,再进行直线绘制。具体步骤为:

  1. 将孪生轴(ax1)上的点坐标转换为屏幕显示坐标;
  2. 将屏幕显示坐标转换为主轴(ax)的坐标系统;
  3. 使用主轴绘制两点间的垂直线。

修改后的完整代码

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

num_points = 100

# Generate x-values 
x_values = np.arange(num_points)

# Create a decreasing linear function
slope = -0.1
intercept = 5
y_values = slope * x_values + intercept

# Add random noise 
noise_scale = 0.5
y_values += np.random.normal(0, noise_scale, num_points)

# Create the numpy arrays
random_points = np.column_stack((x_values, y_values))
random_numbers = np.random.uniform(-0.5, 0.5, num_points)

# Creat DF
df = pd.DataFrame(data={'x': x_values, 'y0': y_values, 'y1': random_numbers})

# Plot the points
ax = df.plot.scatter(x='x', y='y0', c='b', marker='o', label='y0')
ax.legend().set_visible(False)
ax1 = ax.twinx()
ax1.scatter(df['x'], df['y1'], color='darkorange', marker='o', label='y1')
ax1.legend().set_visible(False)

# 绘制同一x值下孪生轴两点间的垂直线
for x, y0, y1 in zip(df['x'], df['y0'], df['y1']):
    # 将ax1上的(x, y1)转换为屏幕坐标
    screen_point = ax1.transData.transform((x, y1))
    # 将屏幕坐标转换回ax的数据坐标
    ax_y1 = ax.transData.inverted().transform(screen_point)[1]
    # 在ax上绘制垂直线
    ax.plot([x, x], [y0, ax_y1], color='gray', linestyle='--', linewidth=0.8)

plt.show()

代码说明

  • ax1.transData.transform((x, y1)):将ax1坐标系下的数据点转换为屏幕像素坐标;
  • ax.transData.inverted().transform(screen_point):将屏幕坐标转换回ax坐标系下的数据坐标,提取y值即为ax中对应y1的位置;
  • 最后用ax.plot绘制从y0到转换后y值的垂直线,可根据需求调整线条颜色、样式和宽度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:50:11