- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 matplotlib 坐标系有点困惑(在 Jupyter notebook 中使用它来制作交互式动画)。如果你创建一个补丁,比如一个圆,并使用 set_transform() 转换它我发现转换不是持久的,这意味着如果你再次应用相同的转换(x,y)移动圆将不会移动,因为 Circle position 似乎在转换后没有得到更新,因此后续转换应用于相同的原始 patch 位置。我的问题是如何应用一个转换,它实际上不仅在应用后移动补丁,而且还更新补丁位置?。假设我想应用一系列翻译,那么圆应该四处移动,而不是从它的原始位置来回摆动。这是一个示例代码:
%import matplotlib
%matplotlib notebook
fig = plt.figure()
ax = fig.add_subplot(111, xlim=(-10, 10), ylim=(-10, 10))
c = ax.add_patch(plt.Circle((x, y), radius=0.5)
c.set_transform(ax.transData + mpl.transforms.Affine2D().translate(-5,-5))
c.set_transform(ax.transData + mpl.transforms.Affine2D().translate(10,10))
如果你运行这个,你会看到注释掉第一个翻译不会影响圆圈的最终位置。我原以为圆心的最终位置是 (5,5) 而不是 (10,10)。这意味着转换实际上并没有更新补丁(圆圈)的位置;它只是在图形/轴中翻译它。
问题 2: 另一件让我感到困惑的事情是,上面的代码生成的圆似乎确实按照要求具有 0.5 的半径,但是在按 (10,10) 应用平移后它图中翻译的少很多!!好像平移移位在应用之前按某种因素缩小了!!我对此没有任何解释,它只是表明我不了解 matplotlib 坐标系和转换。
另一方面,由 plot() 生成的对象是 Line2D 对象,可以通过 set_data() 方法进行转换,该方法更新对象的位置如下(假设上面代码段中的 fig 和 ax 对象):
L, = ax.plot(0, 0, 'ro', ms=8)
sx = 10 # shift in x
sy = 10 # shift in y
L.set_data(L.get_data()[0] + sx, L.get_data()[1] + sy)
我不确定如何为 matplotlib 补丁做同样的事情?
最佳答案
The ax.transData
transform将数据坐标转换为显示坐标。
当您将变换添加在一起时,它们将从左到右应用。所以
ax.transData + mpl.transforms.Affine2D().translate(-5,-5)
首先将数据转换为显示坐标,然后通过偏移量进行转换(-5, -5) 显示坐标(像素)。
相比之下,
mpl.transforms.Affine2D().translate(-5,-5) + ax.transData
会先在数据坐标中移动(-5, -5),然后将数据坐标转换为显示坐标。
因为变换可以通过加法组合,所以更新变换使用
transform = transform + mpl.transforms.Affine2D().translate(...)
例如,
import matplotlib.pyplot as plt
import matplotlib as mpl
fig = plt.figure()
ax = fig.add_subplot(111, xlim=(-10, 10), ylim=(-10, 10))
x, y = 0, 0
c = ax.add_patch(plt.Circle((x, y), radius=5))
transform = mpl.transforms.Affine2D().translate(-5,-5)
transform += mpl.transforms.Affine2D().translate(10,10)
c.set_transform(transform+ax.transData)
ax.set_aspect('equal')
plt.show()
正如预期的那样,圆心位于 (5,5)
,因为 (x,y)+(-5,-5)+(10,10) = (5,5)
。
或者,您可以计算(或跟踪)一系列偏移量,然后根据需要生成变换,而不是组合变换。参见 this post有关此方法的示例。
另请注意,在渲染补丁之前不会应用转换(例如通过调用 plt.show()
)。这解释了为什么多次调用 c.set_transform
与一次调用 c.set_transform
具有相同的效果。只有最后一个变换应用于补丁。
补丁 c
将单个转换存储在您可以使用 c.get_transform
访问的私有(private)属性中:
In [10]: c.get_transform()
Out[15]:
CompositeGenericTransform(Affine2D(array([[ 5., 0., 0.],
[ 0., 5., 0.],
[ 0., 0., 1.]])), CompositeGenericTransform(TransformWrapper(BlendedAffine2D(IdentityTransform(),IdentityTransform())), CompositeGenericTransform(BboxTransformFrom(TransformedBbox(Bbox([[-10.0, -10.0], [10.0, 10.0]]), TransformWrapper(BlendedAffine2D(IdentityTransform(),IdentityTransform())))), BboxTransformTo(TransformedBbox(Bbox([[0.125, 0.09999999999999998], [0.9, 0.9]]), BboxTransformTo(TransformedBbox(Bbox([[0.0, 0.0], [6.4, 4.8]]), Affine2D(array([[ 100., 0., 0.],
[ 0., 100., 0.],
[ 0., 0., 1.]])))))))))
c.set_transform
将该私有(private)属性重新分配给新的转换。但是在 plt.show()
或一些其他渲染调用(如 plt.savefig
被执行之前,不会应用转换。
关于python - 如何将持久坐标转换应用于 Matplotlib 补丁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42493224/
我是一名优秀的程序员,十分优秀!