matplotlib 主y轴刻度和次y轴刻度之间不匹配

9vw9lbht  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(131)

我有一个包含3列的数据集:DEPTHTVD_SCS_interpGamma_ray。我想创建一个深度图(在左y轴上),TVD_SCS_interp(右侧y轴)与Gamma_ray(x轴)。我尝试绘制TVD_SCS与Gamma_ray和DEPTH与Gamma_ray的关系图,以确保刻度的位置是否正确(由于Gamma_ray值相同,我预期线会彼此重叠),但DEPTH与相应TVD_SCS_interp值的对齐不一致,如下图所示。
下面是我的代码:

DEPTH = df.DEPTH     
TVD_SCS_interp = df.TVD_SCS_interp     
GAMMA_RAY = df.GR_N 

# Create an array for the x-axis
x = np.array(GAMMA_RAY)

# Create a figure and two axes
fig = plt.figure(figsize=(8, 165))
gs = gridspec.GridSpec(1, 1, width_ratios=[0.4])

# Create subplots within the custom grid
ax1 = plt.subplot(gs[0])
# Create a second y-axis on the right side
ax2 = ax1.twinx()

# Plot 'DEPTH' data on the left y-axis
ax1.plot(x, DEPTH, color='b', label='DEPTH')
ax1.set_ylabel('DEPTH', color='b')
ax1.set_ylim(2180, 4076.5)

# Plot 'DEPTH_TRU' data on the right y-axis
ax2.plot(x, TVD_SCS_interp, color='r', label='TVD_SCS_interp')
ax2.set_ylabel('DEPTH_TRU', color='r')

top = df.loc[df['DEPTH'] == 2180, 'TVD_SCS_interp'].values[0]
bottom = df.loc[df['DEPTH'] == 4076.5, 'TVD_SCS_interp'].values[0]
ax2.set_ylim(top,bottom)
ax2.yaxis.set_major_locator(ticker.MultipleLocator(10))
ax2.yaxis.set_minor_locator(ticker.MultipleLocator(1))
ax1.yaxis.set_major_locator(ticker.MultipleLocator(10))
ax1.yaxis.set_minor_locator(ticker.MultipleLocator(1))

# Set labels and title
ax1.set_xlabel('GAMMA_RAY')
ax1.set_title('Two Y-Axes Plot')

# Show legend
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')

# Display the plot
plt.show()

如何创建具有第二个y轴的图,其刻度标签与第一个y轴相关?

以下是一些样本数据:

{
    "DEPTH": [4398.1, 4398.2, 4398.3, 4398.4, 4398.5, 4398.6, 4398.7],
    "TVD_SCS_interp": [
        4200.23,
        4200.98,
        4201.4,
        4202.12,
        4202.89,
        4203.3,
        4204.21,
    ],
    "Gamma_ray": [150, 155, 161, 145, 165, 137, 153],
}
0g0grzrc

0g0grzrc1#

使用regression来估计双等维轴之间的最佳拟合关系(例如,两个y轴)

→显示 * 对齐的 * 二元数据,相对于共享的相同自变量(x

例如,下面我根据您提供的样本数据生成了一个粗略的外推扩展-其中y维中的两个单调增加的变量在x维中共享相同的值,但在x维中共享不同的尺度和变化率,因此需要进行估计(即回归分析)以最佳地划分和分配它们的tick值,以确保两个数据的对齐。𝒙

import math
import random

import numpy as np
import pandas as pd

import matplotlib.gridspec as gridspec
import matplotlib.pyplot as plt

# Sample data
num_points = 37

linear_values = np.linspace(4200.0, 4500.0, num_points)

# Some noise is introduced to complicate the linear spacing 
noise = np.random.uniform(-2, 2, num_points)
secondary_values = linear_values + noise

# Ensure the secondary y-axis values always have a positive rate of change
for i in range(1, len(secondary_values)):
    if secondary_values[i] <= secondary_values[i - 1]:
        secondary_values[i] = secondary_values[i - 1] + np.abs(noise[i])

data = {
    "DEPTH": np.arange(4398.1, 4398.1 + (num_points * 0.1), 0.1),
    "TVD_SCS_interp": secondary_values,
    "Gamma_ray": random.choices(range(130, 170), k=num_points),
}
df = pd.DataFrame(data)

DEPTH = df.DEPTH
TVD_SCS_interp = df.TVD_SCS_interp
GAMMA_RAY = df.Gamma_ray

# Estimate the relationship between DEPTH and TVD_SCS_interp
# using polynomial regression (least squares fit)
slope, intercept = np.polyfit(DEPTH, TVD_SCS_interp, 1)

### Plotting
fig = plt.figure(figsize=(6, 8), dpi=150)
gs = gridspec.GridSpec(1, 1, width_ratios=[0.4])

ax1 = plt.subplot(gs[0])
ax2 = ax1.twinx()

ax1.plot(
    GAMMA_RAY,
    DEPTH,
    color="b",
    marker="o",
    markersize=6,
    linestyle="-",
    linewidth=3,
    alpha=0.5,
    label="DEPTH",
)
ax1.set_ylabel("DEPTH", color="b")
depth_max = math.ceil(max(DEPTH))
ax1.set_ylim(4398, depth_max)

# Set limits for the secondary y-axis based on the relationship
# & adjust tick locations for the secondary y-axis based on the primary y-axis
ax2.set_ylim(4398 * slope + intercept, depth_max * slope + intercept)
ax2_ticks = [y * slope + intercept for y in ax1.get_yticks()]
ax2.set_yticks(ax2_ticks)

ax2.plot(
    GAMMA_RAY,
    TVD_SCS_interp,
    color="r",
    marker="o",
    markersize=2,
    linestyle="--",
    label="TVD_SCS_interp",
)
ax2.set_ylabel("DEPTH_TRU", color="r")

ax1.set_xlabel("GAMMA_RAY")
ax1.set_title("Two Y-Axes Plot")

ax1.legend(loc="upper left")
ax2.legend(loc="upper right")

plt.grid(True, which='major', color='k', linestyle='--', linewidth=0.6, alpha=0.4)
plt.grid(True, which='minor', color='k', linestyle='--', linewidth=0.5, alpha=0.2)
plt.minorticks_on()

plt.tight_layout()
plt.show()

结果:

相关问题