Python- 压缩 contourf 图中 y 轴的下端

Python- compress lower end of y-axis in contourf plot

问题

我有一个用 pandas 数据框绘制的 contourf 图,它绘制了一些二维值,x 轴为时间,y 轴为垂直压力水平。我提取的场、时间和压力数据全部来自 netCDF 文件。我可以很好地绘制它,但我想缩放 y 轴以更好地代表真实的气氛。 (默认缩放比例是线性的,但文件中的压力水平暗示了不同的缩放比例。)基本上,它应该看起来像下面 y 轴上的图。它就像对数刻度,但压缩轴的底部而不是顶部。 (我不知道这个术语...像对数刻度但倒置?)它不需要精确。

工作示例(用 Jupyter notebook 编写)

#modules
import numpy             as np
import pandas            as pd
import matplotlib.pyplot as plt
from   matplotlib        import ticker, colors

#data
time = np.arange(0,10)
lev  = np.array([900,800,650,400,100])
df = pd.DataFrame(np.arange(50).reshape(5,10),index=lev,columns=time)
df.index.name = 'Level'
print(df)
        0   1   2   3   4   5   6   7   8   9
Level                                        
900     0   1   2   3   4   5   6   7   8   9
800    10  11  12  13  14  15  16  17  18  19
650    20  21  22  23  24  25  26  27  28  29
400    30  31  32  33  34  35  36  37  38  39
100    40  41  42  43  44  45  46  47  48  49
#lists for plotting
levtick = np.arange(len(lev))
clevels = np.arange(0,55,5)

#Main plot
fig, ax = plt.subplots(figsize=(10, 5))
im      = ax.contourf(df,levels=clevels,cmap='RdBu_r')

#x-axis customization
plt.xticks(time)
ax.set_xticklabels(time)
ax.set_xlabel('Time')

#y-axis customization
plt.yticks(levtick)
ax.set_yticklabels(lev)
ax.set_ylabel('Pressure')

#title and colorbar
ax.set_title('Some mean time series')
cbar = plt.colorbar(im,values=clevels,pad=0.01)
tick_locator = ticker.MaxNLocator(nbins=11)
cbar.locator = tick_locator
cbar.update_ticks()

问题

如何缩放 y 轴,以便压缩靠近底部 (900, 800) 的值,同时扩展靠近顶部 (200) 的值并提供更多绘图 space,如示例中所示在我的代码之上?我尝试使用 ax.set_yscale('function', functions=(forward, inverse)) 但不明白它是如何工作的。我也简单地尝试了 ax.set_yscale('log'),但日志不是我需要的。

您可以按照您的建议对 ax.set_yscale('function', functions=(forward, inverse)) 使用自定义缩放转换。来自 documentation:

forward and inverse are callables that return the scale transform and its inverse.

在这种情况下,在 forward() 中定义您想要的函数,例如对数函数的反函数,或者您需要的更自定义的函数。在自定义 y 轴之前调用此函数。

def forward(x):
    return 2**x

def inverse(x):
    return np.log2(x)

ax.set_yscale('function', functions=(forward,inverse))