Python Matplotlib子批次:轴共享的等轴

Python Matplotlib子批次:轴共享的等轴,python,matplotlib,Python,Matplotlib,我知道这个话题已经在几个matplotlib博客中讨论过了,但我仍然找不到解决这个问题的方法。我想创建一个如下图: (根据@ImportanceOfBeingErnest的答案绘制) 这是两个子地块,它们共享相同的y轴,具有我定义的y极限。x轴的单位应该与y轴相同,这意味着如果我画一个圆,它实际上就是一个圆 现在,我还想指定x限制,并希望子批次大小能够调整到该限制,但我无法使其工作。一般的问题似乎是matplotlib始终保持不同子批次的fig大小 下面是一个简单的工作示例: import m

我知道这个话题已经在几个matplotlib博客中讨论过了,但我仍然找不到解决这个问题的方法。我想创建一个如下图:

(根据@ImportanceOfBeingErnest的答案绘制)

这是两个子地块,它们共享相同的y轴,具有我定义的y极限。x轴的单位应该与y轴相同,这意味着如果我画一个圆,它实际上就是一个圆

现在,我还想指定x限制,并希望子批次大小能够调整到该限制,但我无法使其工作。一般的问题似乎是matplotlib始终保持不同子批次的fig大小

下面是一个简单的工作示例:

import matplotlib.pyplot as plt
import numpy as np

fig=plt.figure()
ax1=fig.add_subplot(1,2,1,aspect='equal')
ax2=fig.add_subplot(1,2,2,aspect='equal',sharey=ax1)

def create_data(xmin,xmax):
    delta = 0.025
----
    x = np.arange(xmin, xmax, delta)
    y = np.arange(-3,3,delta)
    X, Y = np.meshgrid(x, y)
    Z1 = plt.mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
    Z2 = plt.mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
    Z = 10 * (Z1 - Z2)
----
    nr, nc = Z.shape
----
    # put NaNs in one corner:
    Z[-nr//6:, -nc//6:] = np.nan
    # contourf will convert these to masked
----
----
    Z = np.ma.array(Z)
    # mask another corner:
    Z[:nr//6, :nc//6] = np.ma.masked
----
    # mask a circle in the middle:
    interior = np.sqrt((X**2) + (Y**2)) < 0.5
    Z[interior] = np.ma.masked
    return X,Y,Z

X,Y,Z=create_data(-2,4)
ax1.contourf(X,Y,Z)
ax1.set_ylim(-1,1)
ax1.set_xlim(-2,4)
X,Y,Z=create_data(-1,0)
ax2.contourf(X,Y,Z)
ax2.set_ylim(-1,1)
ax2.set_xlim(-1,0)
plt.show()

似乎有效,但需要手动编辑收缩参数。

由于两个绘图的x极限范围之间的比率为1/6,如果这些绘图应保持相同的高度,则这些绘图的大小也需要相差6倍

(请注意,matplotlib的早期版本中可能存在一个bug,这使得下面的代码无法按预期工作;但是,它在matplotlib 2.2中运行良好)

导入matplotlib.pyplot作为plt
将numpy作为np导入
图(ax1,ax2)=plt.子批次(ncols=2,sharey=True,
子地块_kw=dict(纵横比=相等),
gridspec_kw=dict(宽度比=[6,1]))
def创建_数据(xmin,xmax):
增量=0.025
x=np.arange(xmin,xmax,delta)
y=np.arange(-3,3,δ)
十、 Y=np.meshgrid(X,Y)
Z1=plt.mlab.二元正态(X,Y,1.0,1.0,0.0,0.0)
Z2=plt.mlab.二元正态(X,Y,1.5,0.5,1,1)
Z=10*(Z1-Z2)
nr,nc=Z形
#把南放在一个角落里:
Z[-nr//6:,-nc//6:]=np.nan
#contourf将这些转换为蒙版
Z=np.ma.数组(Z)
#遮住另一个角落:
Z[:nr//6,:nc//6]=np.ma.masked
#在中间遮罩一个圆:
内部=np.sqrt((X**2)+(Y**2))<0.5
Z[内部]=np.ma.屏蔽
返回X,Y,Z
十、 Y,Z=创建_数据(-2,4)
ax1.f(X,Y,Z)
ax1.set_ylim(-1,1)
ax1.set_xlim(-2,4)
十、 Y,Z=创建_数据(-1,0)
ax2.f(X,Y,Z)
ax2.set_ylim(-1,1)
ax2.set_xlim(-1,0)
plt.show()

我想我不理解这个要求。如果两个子图的纵横比相等,并且将一个图的x限制设置为另一个图的六分之一,那么最终的图应该是什么样子的。这至少与您显示的图片不匹配,其中比率似乎为一半。它应该与@ImportanceOfBeingErnest显示的完全相同,但是我无法复制他的情节。谢谢!不知何故,即使运行相同的python代码,我也无法再现您的情节。这是版本问题吗?我得到了这个图:我使用的是Matplotlib 2.0.2你的意思是你复制并粘贴了这个答案的代码,得到了一个不同的图?在这种情况下,可能是版本问题,我使用的是matplotlib 2.2rc1。是的,我刚刚复制了您的代码,让我用最新版本再试一次,我马上回来。用版本2.2.0测试就可以了!再次感谢!我在上面的问题中使用了你的情节只是为了让问题更清楚。只是出于兴趣,你在更新之前使用了哪个版本?
fig.colorbar(CS, ax=ax,shrink=xx)
import matplotlib.pyplot as plt
import numpy as np


fig, (ax1,ax2) = plt.subplots(ncols=2, sharey=True, 
                              subplot_kw=dict(aspect='equal'),
                              gridspec_kw=dict(width_ratios=[6,1]))

def create_data(xmin,xmax):
    delta = 0.025

    x = np.arange(xmin, xmax, delta)
    y = np.arange(-3,3,delta)
    X, Y = np.meshgrid(x, y)
    Z1 = plt.mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
    Z2 = plt.mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
    Z = 10 * (Z1 - Z2)

    nr, nc = Z.shape

    # put NaNs in one corner:
    Z[-nr//6:, -nc//6:] = np.nan
    # contourf will convert these to masked


    Z = np.ma.array(Z)
    # mask another corner:
    Z[:nr//6, :nc//6] = np.ma.masked

    # mask a circle in the middle:
    interior = np.sqrt((X**2) + (Y**2)) < 0.5
    Z[interior] = np.ma.masked
    return X,Y,Z

X,Y,Z=create_data(-2,4)
ax1.contourf(X,Y,Z)
ax1.set_ylim(-1,1)
ax1.set_xlim(-2,4)
X,Y,Z=create_data(-1,0)
ax2.contourf(X,Y,Z)
ax2.set_ylim(-1,1)
ax2.set_xlim(-1,0)
plt.show()