Python Matplotlib 2个子批次,1个颜色条

Python Matplotlib 2个子批次,1个颜色条,python,matplotlib,subplot,colorbar,Python,Matplotlib,Subplot,Colorbar,我花了太长时间研究如何在Matplotlib中使两个子图共享同一y轴,并在两个子图之间共享一个颜色条 所发生的事情是,当我在subplot1或subplot2中调用colorbar()函数时,它会自动缩放绘图,这样colorbar加上绘图就可以放在“subplot”边界框中,导致两个并排绘图的大小非常不同 为了解决这个问题,我尝试创建第三个子图,然后对其进行黑客攻击,使其仅呈现一个色条,而不呈现任何绘图。 唯一的问题是,现在两幅图的高度和宽度都不均匀,我不知道如何使它看起来好 这是我的密码: f

我花了太长时间研究如何在Matplotlib中使两个子图共享同一y轴,并在两个子图之间共享一个颜色条

所发生的事情是,当我在
subplot1
subplot2
中调用
colorbar()
函数时,它会自动缩放绘图,这样colorbar加上绘图就可以放在“subplot”边界框中,导致两个并排绘图的大小非常不同

为了解决这个问题,我尝试创建第三个子图,然后对其进行黑客攻击,使其仅呈现一个色条,而不呈现任何绘图。 唯一的问题是,现在两幅图的高度和宽度都不均匀,我不知道如何使它看起来好

这是我的密码:

from __future__ import division
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches
from matplotlib.ticker import NullFormatter

# SIS Functions
TE = 1 # Einstein radius
g1 = lambda x,y: (TE/2) * (y**2-x**2)/((x**2+y**2)**(3/2)) 
g2 = lambda x,y: -1*TE*x*y / ((x**2+y**2)**(3/2))
kappa = lambda x,y: TE / (2*np.sqrt(x**2+y**2))

coords = np.linspace(-2,2,400)
X,Y = np.meshgrid(coords,coords)
g1out = g1(X,Y)
g2out = g2(X,Y)
kappaout = kappa(X,Y)
for i in range(len(coords)):
    for j in range(len(coords)):
        if np.sqrt(coords[i]**2+coords[j]**2) <= TE:
            g1out[i][j]=0
            g2out[i][j]=0

fig = plt.figure()
fig.subplots_adjust(wspace=0,hspace=0)

# subplot number 1
ax1 = fig.add_subplot(1,2,1,aspect='equal',xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{1}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
plt.ylabel(r"y ($\theta_{E}$)",rotation='horizontal',fontsize="15")
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.imshow(g1out,extent=(-2,2,-2,2))
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
e1 = patches.Ellipse((0,0),2,2,color='white')
ax1.add_patch(e1)

# subplot number 2
ax2 = fig.add_subplot(1,2,2,sharey=ax1,xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{2}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
ax2.yaxis.set_major_formatter( NullFormatter() )
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
plt.imshow(g2out,extent=(-2,2,-2,2))
e2 = patches.Ellipse((0,0),2,2,color='white')
ax2.add_patch(e2)

# subplot for colorbar
ax3 = fig.add_subplot(1,1,1)
ax3.axis('off')
cbar = plt.colorbar(ax=ax2)

plt.show()
来自未来进口部的

将matplotlib.pyplot作为plt导入
将numpy作为np导入
从matplotlib导入修补程序
从matplotlib.ticker导入NullFormatter
#SIS功能
TE=1#爱因斯坦半径
g1=λx,y:(TE/2)*(y**2-x**2)/(x**2+y**2)**(3/2))
g2=λx,y:-1*TE*x*y/((x**2+y**2)***(3/2))
kappa=λx,y:TE/(2*np.sqrt(x**2+y**2))
coords=np.linspace(-2,2400)
十、 Y=np.meshgrid(坐标系,坐标系)
g1out=g1(X,Y)
g2out=g2(X,Y)
kappaout=kappa(X,Y)
对于范围内的i(len(coords)):
对于范围内的j(len(coords)):

如果np.sqrt(coords[i]**2+coords[j]**2)只需将颜色条放置在其自身的轴上,并使用
子批次调整
为其腾出空间

举个简单的例子:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(im, cax=cbar_ax)

plt.show()


请注意,即使值的范围由
vmin
vmax
设置,颜色范围也将由最后绘制的图像(产生
im
)设置。例如,如果另一个绘图具有更高的最大值,则值高于最大值的点将以统一的颜色显示。

只需将颜色条放置在其自身的轴上,并使用
子绘图调整
为其腾出空间即可

举个简单的例子:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(im, cax=cbar_ax)

plt.show()


请注意,即使值的范围由
vmin
vmax
设置,颜色范围也将由最后绘制的图像(产生
im
)设置。例如,如果另一个绘图具有更高的最大值,则值高于
im
最大值的点将以统一颜色显示。

使用
make_轴
更容易,并给出更好的结果。它还提供了定制颜色条位置的可能性。 还要注意
子批次
选项以共享x轴和y轴

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

fig, axes = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

cax,kw = mpl.colorbar.make_axes([ax for ax in axes.flat])
plt.colorbar(im, cax=cax, **kw)

plt.show()

使用
生成轴
更简单,效果更好。它还提供了定制颜色条位置的可能性。 还要注意
子批次
选项以共享x轴和y轴

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

fig, axes = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

cax,kw = mpl.colorbar.make_axes([ax for ax in axes.flat])
plt.colorbar(im, cax=cax, **kw)

plt.show()

您可以使用
figure.colorbar()
ax
参数和轴列表简化Joe Kington的代码。 发件人:

斧头

无|将从中盗取新色条轴空间的父轴对象。如果给出了轴列表,它们都将调整大小,以便为颜色条轴留出空间


您可以使用
figure.colorbar()
ax
参数和轴列表简化Joe Kington的代码。 发件人:

斧头

无|将从中盗取新色条轴空间的父轴对象。如果给出了轴列表,它们都将调整大小,以便为颜色条轴留出空间


abevieiramota使用轴列表的解决方案非常有效,直到您仅使用一行图像,如注释中所指出。为
figsize
使用合理的纵横比会有所帮助,但还远远不够完美。例如:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9.75, 3))
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.colorbar(im, ax=axes.ravel().tolist())

plt.show()
fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.75)

提供了
收缩
参数,该参数是颜色条轴大小的比例因子。它确实需要一些手动尝试和错误。例如:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9.75, 3))
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.colorbar(im, ax=axes.ravel().tolist())

plt.show()
fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.75)

abevieiramota使用轴列表的解决方案非常有效,直到您仅使用一行图像,如注释中所指出。为
figsize
使用合理的纵横比会有所帮助,但还远远不够完美。例如:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9.75, 3))
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.colorbar(im, ax=axes.ravel().tolist())

plt.show()
fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.75)

提供了
收缩
参数,该参数是颜色条轴大小的比例因子。它确实需要一些手动尝试和错误。例如:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9.75, 3))
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.colorbar(im, ax=axes.ravel().tolist())

plt.show()
fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.75)

此解决方案不需要手动调整轴位置或色条大小,适用于多行和单行布局,也适用于
紧密布局()。它使用matplotlib的
ImageGrid
从a改编而来


此解决方案不需要手动调整轴位置或色条大小,适用于多行和单行布局,也适用于
紧密布局()。它使用matplotlib的
ImageGrid
从a改编而来


作为一个偶然发现这条线索的初学者,我想添加一个python for Dummie,以适应abevieiramota非常简洁的答案(因为我已经到了必须查找“ravel”才能了解他们的代码的程度):


更不用说蟒蛇了,像我这样的疯子更容易看到这里到底发生了什么

作为一个偶然发现这条线索的初学者,我想添加一个python for Dummie改编自abevieiramota的非常简洁的答案(因为我已经到了必须查找“ravel”才能了解他们的代码的程度):


更不用说蟒蛇了,像我这样的疯子更容易看到这里到底发生了什么

正如在其他答案中指出的那样,这个想法通常是为色条定义一个要驻留的轴。这样做的方式多种多样;一个尚未提及的问题是,使用
plt.subplot()
在子地块创建时直接指定颜色条轴。其优点是,轴位置不需要手动设置,并且在所有情况下都需要手动设置
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.gridspec import GridSpec

# Define number of rows and columns you want in your figure
nrow = 2
ncol = 3

# Make a new figure
fig = plt.figure(constrained_layout=True)

# Design your figure properties
widths = [3,4,5,1]
gs = GridSpec(nrow, ncol + 1, figure=fig, width_ratios=widths)

# Fill your figure with desired plots
axes = []
for i in range(nrow):
    for j in range(ncol):
        axes.append(fig.add_subplot(gs[i, j]))
        im = axes[-1].pcolormesh(np.random.random((10,10)))

# Shared colorbar    
axes.append(fig.add_subplot(gs[:, ncol]))
fig.colorbar(im, cax=axes[-1])

plt.show()