首页 > 编程问答 >使用 python matplotlib 和 metpy 添加辅助 y 轴

使用 python matplotlib 和 metpy 添加辅助 y 轴

时间:2024-07-28 11:02:23浏览次数:11  
标签:python python-3.x matplotlib plot metpy

我知道这个问题似乎与这里的许多其他问题类似,但我已经尝试过它们,不幸的是它们都没有解决我在尝试添加辅助 y 轴时当前面临的问题。

问题是很简单,但我找不到任何可以修复它的东西: 在 SkewT 图上添加辅助 y 轴会更改图的 y 限制,而不仅仅是添加轴。

基本上,我希望添加辅助 y 轴,因为高度是使用 SkewT 内的压力水平来表示的,但也应该可以以公里为单位显示该高度。我想告诉第二个 y 轴:

  1. 它应该在 1015 到 100hPa 之间缩放(就像原始 y 轴一样);
  2. 我只想显示 0, 1, 3, 6, 9, 12 ,辅助 y 轴上的 15 公里(简单的气压 (hPa) 到高度 (km) 转换);
  3. 我希望 0 公里从第一个气压水平开始,并从那里开始缩放;
  4. 辅助 y 轴还应该在 Y 中使用对数缩放。

这是辅助轴的示例,您可以看到与第一个轴相比缩放是否关闭: enter image description here

这是我添加的代码位更改,尽管仅添加第一行会更改图表:

twin = skew.ax.twinx()
twin.set_yscale('log')
twin.spines['right'].set_position(('axes', 0))
twin.set_frame_on(True)
twin.patch.set_visible(False)
twin.set_ylim(skew.ax.get_ylim())

这是一个更简单的示例,因此您可以使用 Metpy 的简单发声代码示例自行测试它 此处

import matplotlib.pyplot as plt
import pandas as pd

import metpy.calc as mpcalc
from metpy.cbook import get_test_data
from metpy.plots import SkewT
from metpy.units import units

plt.rcParams['figure.figsize'] = (9, 9)

col_names = ['pressure', 'height', 'temperature', 'dewpoint', 'direction', 'speed']

df = pd.read_fwf(get_test_data('jan20_sounding.txt', as_file_obj=False),
                 skiprows=5, usecols=[0, 1, 2, 3, 6, 7], names=col_names)

# Drop any rows with all NaN values for T, Td, winds
df = df.dropna(subset=('temperature', 'dewpoint', 'direction', 'speed'
                       ), how='all').reset_index(drop=True)

p = df['pressure'].values * units.hPa
T = df['temperature'].values * units.degC
Td = df['dewpoint'].values * units.degC
wind_speed = df['speed'].values * units.knots
wind_dir = df['direction'].values * units.degrees
u, v = mpcalc.wind_components(wind_speed, wind_dir)

skew = SkewT()

# Plot the data using normal plotting functions, in this case using
# log scaling in Y, as dictated by the typical meteorological plot
skew.plot(p, T, 'r')
skew.plot(p, Td, 'g')
skew.plot_barbs(p, u, v)

# Add the relevant special lines
skew.plot_dry_adiabats()
skew.plot_moist_adiabats()
skew.plot_mixing_lines()
skew.ax.set_ylim(1000, 100)
# twin = skew.ax.twinx()
# twin.set_yscale('log')
# twin.spines['right'].set_position(('axes', 0))
# twin.set_frame_on(True)
# twin.patch.set_visible(False)
# twin.set_ylim(skew.ax.get_ylim())

plt.savefig("metpy_base.png")

它可能只是一个简单的错误,或者 Metpy 本身可能有什么东西导致了这种情况 twinx() 并且喜欢的人没有做我希望他们做的事情。我正在尝试找到一种解决方案,让我拥有第二个 y 轴,其压力值和缩放比例与第一个轴完全相同,然后我可以仅显示某些刻度并将这些刻度标签替换为相应的公里等效值。

谢谢!


问题在于,正在使用对数刻度创建第二个 y 轴,但试图设置的限制与线性刻度相同。为了解决这个问题,需要将限制转换为它们的对数等效值。

以下是如何修改代码以添加辅助 y 轴的方法,该轴以对数刻度显示以公里为单位的高度:

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

import metpy.calc as mpcalc
from metpy.cbook import get_test_data
from metpy.plots import SkewT
from metpy.units import units

plt.rcParams['figure.figsize'] = (9, 9)

col_names = ['pressure', 'height', 'temperature', 'dewpoint', 'direction', 'speed']

df = pd.read_fwf(get_test_data('jan20_sounding.txt', as_file_obj=False),
                 skiprows=5, usecols=[0, 1, 2, 3, 6, 7], names=col_names)

# Drop any rows with all NaN values for T, Td, winds
df = df.dropna(subset=('temperature', 'dewpoint', 'direction', 'speed'
                       ), how='all').reset_index(drop=True)

p = df['pressure'].values * units.hPa
T = df['temperature'].values * units.degC
Td = df['dewpoint'].values * units.degC
wind_speed = df['speed'].values * units.knots
wind_dir = df['direction'].values * units.degrees
u, v = mpcalc.wind_components(wind_speed, wind_dir)

skew = SkewT()

# Plot the data using normal plotting functions, in this case using
# log scaling in Y, as dictated by the typical meteorological plot
skew.plot(p, T, 'r')
skew.plot(p, Td, 'g')
skew.plot_barbs(p, u, v)

# Add the relevant special lines
skew.plot_dry_adiabats()
skew.plot_moist_adiabats()
skew.plot_mixing_lines()
skew.ax.set_ylim(1000, 100)

# Create twin axis and set limits to be the same as the primary y-axis, but in log scale
twin = skew.ax.twinx()
twin.set_yscale('log')
twin.set_ylim(skew.ax.get_ylim())

# Set ticks and labels for the secondary y-axis
# Calculate heights corresponding to desired pressure levels
heights = mpcalc.pressure_to_height_std(units.Quantity(np.array([1015, 1000, 800, 600, 400, 200, 100]), 'hPa'))
# Convert heights to km
heights_km = heights.to('km').magnitude
# Set ticks and labels
twin.set_yticks(np.array([1015, 1000, 800, 600, 400, 200, 100]))
twin.set_yticklabels([f'{h:.0f}' for h in heights_km])
twin.set_ylabel('Height (km)')

plt.savefig("metpy_modified.png")

在此代码中:

  1. 我们使用 twinx() 创建了一个辅助 y 轴。
  2. 我们将辅助轴的刻度设置为对数( twin.set_yscale('log') )。
  3. 我们使用 twin.set_ylim(skew.ax.get_ylim()) 设置了辅助轴的限制,以匹配主 y 轴的限制。
  4. 我们使用 metpy.calc.pressure_to_height_std 函数计算了对应于所需压力水平的高度。
  5. 我们将高度转换为公里。
  6. 我们使用计算出的高度值(以公里为单位)设置了辅助轴的刻度和标签。

这些更改将创建一个辅助 y 轴,该轴以对数刻度显示以公里为单位的高度,并与主压力轴正确对齐。

标签:python,python-3.x,matplotlib,plot,metpy
From: 72772697

相关文章