简体   繁体   English

在子图中的matplotlib轴上旋转变换

[英]Rotate transformation on matplotlib axis in subplot

I am trying to create a four-panel figure where the bottom-left panel contains a scatter plot, and the other three panels contain histograms. 我正在尝试创建一个四面板图,其中左下图包含散点图,其他三个图包含直方图。 The top-left will be a standard histogram across the x-dimension of the scatter, the bottom-right will be a 90° rotated histogram for the y-dimension. 左上角将是散点图x维度上的标准直方图,右下角将是y维度的90°旋转直方图。 Both of these are easy to do in matplotlib. 两者在matplotlib中都很容易实现。

I am running into problems with the third histogram, which is to be a 45° rotated plot in the top-right of the figure giving the distribution of the differences between the x and y points. 我遇到了第三个直方图的问题,该直方图是该图右上方的45°旋转图,给出了x点和y点之间的差异分布。 I have made such figures before by manually rotating and rescaling the axes in Illustrator, but it seems like matplotlib should be able to produce figures that are already rotated using the transformation methods on the subplot axes. 我之前已经通过在Illustrator中手动旋转和缩放轴来制作了这些图形,但是看起来matplotlib 应该能够生成已经使用子图轴上的转换方法旋转过的图形。

I thought something like the following might work: 我认为以下内容可能会起作用:

import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D

fig, ax = plt.subplots(nrows=2, ncols=2, squeeze=True, sharex=False, 
                       sharey=False, figsize=(8,8))
ax[0,1].text(0.5,0.5,'I should be rotated',ha='center',va='center')
t = ax[0,1].get_transform()
ax[0,1].set_transform(t.transform(Affine2D().rotate_deg(45)))

plt.show()

Here I am attempting to get the transform from the axis, modify it, and then replace it back into the axis object. 在这里,我尝试从轴获取变换,对其进行修改,然后将其替换回到轴对象中。 This code has no effect however. 但是此代码无效。 Any help would be greatly appreciated. 任何帮助将不胜感激。

Edited based on suggestion from ImportanceOfBeingErnest in comments: 根据ImportanceOfBeingErnest在评论中的建议进行编辑:

I have taken a look at the Floating Axes demo, and now have this: 我看了一下Floating Axes演示,现在有这个:

from matplotlib.transforms import Affine2D
import mpl_toolkits.axisartist.floating_axes as floating_axes
import matplotlib.pyplot as plt

def setup_axes(fig, rect, rotation, axisScale):
    tr = Affine2D().scale(axisScale[0], axisScale[1]).rotate_deg(rotation)

    grid_helper = floating_axes.GridHelperCurveLinear(tr, extremes=(-0.5, 3.5, 0, 4))

    ax = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper)
    fig.add_subplot(ax)
    aux_ax = ax.get_aux_axes(tr)

    return ax, aux_ax

fig  = plt.figure(1, figsize=(8, 8))
axes = []
axisOrientation = [0, 0, 270, -45]
axisScale = [[1,1],[2,1],[2,1],[2,1]]
axisPosition = [223,221,224,222]

for i in range(0, len(axisOrientation)):
    ax, aux_ax = setup_axes(fig, axisPosition[i], axisOrientation[i], axisScale[i])
    axes.append(aux_ax)
fig.subplots_adjust(wspace=-0.2, hspace=-0.2, left=0.00, right=0.99, top=0.99, bottom=0.0)
plt.show()

This has me closer to what I want: 这使我更接近想要的东西:

情节示范

I will take a shot at adding in the scatter plot and histograms to these axes. 我将尝试在这些轴上添加散点图和直方图。

The following code achieves what I originally wanted, except I am looking for a way to translate the top-right figure to be closer to the scatter plot in the bottom-left. 以下代码实现了我最初想要的功能, 但是我正在寻找一种方法来转换右上角的图形,使其更接近左下角的散点图。 This is a smaller problem though, so I may post it as a new question. 不过,这是一个较小的问题,因此我可以将其发布为新问题。

from matplotlib.transforms import Affine2D
import mpl_toolkits.axisartist.floating_axes as floating_axes
import matplotlib.pyplot as plt

def setup_axes(fig, rect, rotation, axisScale, axisLimits, doShift):
    tr_rot = Affine2D().scale(axisScale[0], axisScale[1]).rotate_deg(rotation)

    # This seems to do nothing
    if doShift:
        tr_trn = Affine2D().translate(-90,-5)
    else:
        tr_trn = Affine2D().translate(0,0)

    tr = tr_rot + tr_trn

    grid_helper = floating_axes.GridHelperCurveLinear(tr, extremes=axisLimits)

    ax = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper)
    fig.add_subplot(ax)
    aux_ax = ax.get_aux_axes(tr)

    return ax, aux_ax

fig  = plt.figure(1, figsize=(8, 8))
axes = []
axisOrientation = [0, 0, 270, -45]
axisScale = [[1,1],[6,1],[6,1],[6,1]]
axisPosition = [223,221,224,222]
axisLimits = [(-0.5, 4.5, -0.5, 4.5),
              (-0.5, 4.5, 0, 12),
              (-0.5, 4.5, 0, 12),
              (-3.5, 3.5, 0, 12)]
doShift = [False, False, False, True]

label_axes = []
for i in range(0, len(axisOrientation)):
    ax, aux_ax = setup_axes(fig, axisPosition[i], axisOrientation[i], 
                            axisScale[i], axisLimits[i], doShift[i])
    axes.append(aux_ax)
    label_axes.append(ax)

numPoints = 100
x = []
y = []
for i in range(0,numPoints):
    x.append(np.random.rand() + i/100.0)
    y.append(np.random.rand() + i/100.0 + np.mod(i,2)*2)

axes[0].plot(x,y,ls='none',marker='x')
label_axes[0].axis["bottom"].label.set_text('Variable 1')
label_axes[0].axis["left"].label.set_text('Variable 2')

b = np.linspace(-0.5,4.5,50)
axes[1].hist(x, bins = b)
axes[2].hist(y, bins = b)
b = np.linspace(-3.5,3.5,50)
axes[3].hist(np.array(x)-np.array(y), bins=b)

for i in range(1,len(label_axes)):
    for axisLoc in ['top','left','right']:
        label_axes[i].axis[axisLoc].set_visible(False)
    label_axes[i].axis['bottom'].toggle(ticklabels=False)    

fig.subplots_adjust(wspace=-0.30, hspace=-0.30, left=0.00, right=0.99, top=0.99, bottom=0.0)
plt.show()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM