我正在尝试创建一个四面板的图形,其中左下面板包含散点图,其他三个面板包含直方图。左上角将是散点图x维度上的标准直方图,右下角将是y维度的90°旋转直方图。这两个都可以在matplotlib中轻松完成。
我遇到了第三个直方图的问题,该直方图是该图右上方的45°旋转图,给出了x点和y点之间的差异分布。我之前通过在Illustrator中手动旋转和缩放轴来制作了这样的图形,但是看起来matplotlib 应该能够生成已经使用子图轴上的转换方法旋转的图形。
我认为类似以下的内容可能会起作用:
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()
在这里,我尝试从轴获取转换,对其进行修改,然后将其替换回该轴对象中。但是此代码无效。任何帮助将不胜感激。
根据ImportanceOfBeingErnest在评论中的建议进行了编辑:
我看了一下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()
这使我更接近想要的东西:
我将尝试在这些轴上添加散点图和直方图。
答案 0 :(得分:2)
以下代码实现了我最初想要的功能,除了我正在寻找一种方法来转换右上角的图形,使其更接近左下角的散点图。不过,这是一个较小的问题,因此我可以将其发布为新问题。
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()