定位颜色条和第二个y轴(matplotlib)

时间:2019-12-06 11:04:43

标签: python matplotlib plot axis-labels colorbar

我正在尝试绘制一个带有两个y轴并在其旁边带有颜色条的图。但是,我的第二个y轴的标签将不会显示,并且在正确设置颜色条时遇到了一些麻烦。我的代码可以在下面找到:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm #colormap
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.transforms import Transform
from matplotlib.ticker import (
    AutoLocator, AutoMinorLocator)

x = np.linspace(-2.5, 2.5, 100)
y = np.linspace(-2.5, 2.5, 100)
xx, yy = np.meshgrid(x, y)

std_x = 1.
std_y = 1.
A = 10
Gaussian = A * np.exp(-(xx**2/(2*std_x**2) + yy**2/(2*std_y**2)))

fig = plt.figure()
ax = plt.subplot(111)
im = plt.imshow(Gaussian)
ax.set_xlabel("[m]")
ax.set_ylabel("[m]")
ax_new = ax.twinx().twiny()
ticks = np.linspace(0, 1, 5)
ticklabels = np.round(np.arctan(ticks*512/1e3)*3600) #hardcoded
plt.xticks(ticks, ticklabels)
plt.yticks(ticks, ticklabels)
ax_new.set_xlabel("arcsec")
ax_new.set_ylabel("arcsec")
ax_new.set_title("Atmosphere Structure", fontsize=20)
divider = make_axes_locatable(ax_new)
# on the figure total in percent [left, bottom, width, height]
cax = fig.add_axes([0.95, 0.1, 0.02, 0.75])
colorbar_1 = fig.colorbar(im, cax=cax)
colorbar_1.set_label('pwv in mm', labelpad=-10, y=1.05, rotation=0)
plt.show()

经过很多微调,该图现在看起来像这样(为简单起见,我使用高斯曲线):

enter image description here

颜色条仍然略有未对准,现在我定位颜色条的方式感觉像是快速修复,而不是好的解决方案。有谁知道如何以“清洁” /更好的方式做到这一点?有人知道如何使ylabel出现在显示权(ax_new.set_ylabel("arcsec"))上吗?

我尝试了Plot multiple y-axis AND colorbar in matplotlib中提出的解决方案,但是以某种方式对我不起作用。

编辑: 当我将cax = fig.add_axes([0.95, 0.1, 0.02, 0.75])替换为cax = divider.append_axes("right", size="4%", pad="10%")时,得到以下图像:

enter image description here

编辑2:

我也尝试过使用secondary_xaxis,可以在下面的代码中看到

def m2deg(x):
    arcsec = np.arctan(x*512/1e3)*180/np.pi
    return arcsec

def deg2m(x):
    m = np.tan(x/(512)*np.pi/180)*1e3
    return m

secax = ax.secondary_xaxis('top', functions=(m2deg, deg2m))
secax2 = ax.secondary_yaxis('right', functions=(m2deg, deg2m))
secax.set_label("degrees")
secax2.set_label("degrees")

它给了我下面的图片: enter image description here

再次

不会显示轴标签,并且刻度线没有正确的值(tan(0 /(512)* pi / 180)* 1e3 = 0,而arctan(0 * 512 / 1e3)* 180 / pi = 0,因此所有0必须对齐)。

1 个答案:

答案 0 :(得分:0)

尝试constrained_layout吗?

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm #colormap

x = np.linspace(-2.5, 2.5, 100)
y = np.linspace(-2.5, 2.5, 100)
xx, yy = np.meshgrid(x, y)

std_x = 1.
std_y = 1.
A = 10
Gaussian = A * np.exp(-(xx**2/(2*std_x**2) + yy**2/(2*std_y**2)))

fig, ax = plt.subplots(constrained_layout=True)
im = ax.imshow(Gaussian)
ax_new = ax.twinx().twiny()
ticks = np.linspace(0, 1, 5)
ticklabels = np.round(np.arctan(ticks*512/1e3)*3600) #hardcoded
plt.xticks(ticks, ticklabels)
plt.yticks(ticks, ticklabels)
ax_new.set_xlabel("arcsec")
ax_new.set_ylabel("arcsec")
ax_new.set_title("Atmosphere Structure", fontsize=20)
colorbar_1 = fig.colorbar(im)
colorbar_1.set_label('pwv in mm', labelpad=-10, y=1.05, rotation=0)
plt.show()

enter image description here