我正在尝试绘制一系列波形,以使它们沿y轴均匀分布。我相信matplotlib.transforms
是必经之路。使用此代码,我需要一些基本的工作:
import matplotlib.transforms
import matplotlib as mp
import numpy as np
import pylab as pl
%matplotlib inline
ax = pl.gca()
n_levels = 10
t = np.arange(1000)/1000
offset_step = 1/(n_levels + 1)
for i in range(n_levels):
offset = offset_step * (i + 1)
o = mp.transforms.ScaledTranslation(0, offset, ax.transAxes)
trans = mp.transforms.blended_transform_factory(ax.transData, ax.transData + o)
y = np.sin(t*2*np.pi*10*i)
p, = ax.plot(t, y, 'k-', transform=trans)
ax.axis(ymin=0, ymax=25)
这将创建以下图。
即使以轴坐标为单位的实际偏移量为0.09 0.18 ... 0.82 0.91,这些线也显然不会出现在这些精确偏移量处!我在做什么错了?
编辑:要回答一些有关为什么我不能只在数据空间中应用偏移而不是使用变换的问题。这是我需要做的更复杂的变换的一种简单形式,我希望能够缩放单个行的幅度而不必调整y轴限制。为此,实际的y转换为:
boxin = mp.transforms.Bbox([[0, 0], [1, 1]])
boxout = mp.transforms.Bbox([[0, 0], [1, 1]])
y_trans = mp.transforms.BboxTransform(boxin, boxout) + \
axes.transData + \
mp.transforms.ScaledTranslation(0, offset_step * (i + 1), axes.transAxes)
然后,在我的交互式应用程序中,我可以使用以下命令修改每个单独波形的缩放比例:
scale = 2
box = np.array([[0, 0], [scale, scale]])
boxout.set_points(box)
figure.canvas.redraw()
效果很好。但是,对于n_levels
的不同选择,我需要在生成图时首先调整ymin和ymax,以确保线沿y轴相等隔开。理想的结果是:
答案 0 :(得分:1)
由于这里显然不关心y轴比例,因此您可以逐步遵循变换链
offset_step
的虚拟盒子。i*offset_step
翻译此框(可能在底部添加一些空间)完整示例:
import matplotlib.transforms as mtrans
import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
ax = plt.gca()
n_levels = 10
t = np.arange(1000)/1000
T = t*2*np.pi*10
offset_step = 1/(n_levels+1)
space = 1.25 # set to 1 to have no space between lines
# Transform from a virtual box around the sine (-1 .. 1 in y direction)
tfrom = mtrans.BboxTransformFrom(mtrans.Bbox([[0, -1*space],[1, 1*space]]))
# Transform to a box (0 .. offset_step)
tto = mtrans.BboxTransformTo(mtrans.Bbox([[0, 0],[1,offset_step]]))
for i in range(n_levels):
# offset = steps + half the remainder to full axes
offset = offset_step * i + (1-n_levels*offset_step)/2.
# Translate by offset
translate = mtrans.Affine2D().translate(0,offset)
# chain all transforms
y_trans = tfrom + tto + translate + ax.transAxes
trans = mpl.transforms.blended_transform_factory(ax.transData, y_trans)
# plot
p, = ax.plot(t, np.sin(T*i), transform=trans)
plt.show()
答案 1 :(得分:0)
问题是transData
已经合并了transAxes
,所以当我创建缩放转换时,我被transAxes
转换了两次。诀窍是将y转换设置为transLimits
+ transScale
+缩放转换:
import matplotlib.transforms
import matplotlib as mp
import numpy as np
import pylab as pl
%matplotlib inline
ax = pl.gca()
n_levels = 10
t = np.arange(1000)/1000
offset_step = 1/(n_levels + 1)
for i in range(n_levels):
offset = offset_step * (i + 1)
o = mp.transforms.ScaledTranslation(0, offset, ax.transAxes)
y_trans = ax.transLimits + ax.transScale + o
trans = mp.transforms.blended_transform_factory(ax.transData, y_trans)
y = np.sin(t*2*np.pi*10*i)
p, = ax.plot(t, y, 'k-', transform=trans)
这将生成:
这正是我想要的。