Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何对Matplotlib面片应用持久坐标变换?_Python_Matplotlib - Fatal编程技术网

Python 如何对Matplotlib面片应用持久坐标变换?

Python 如何对Matplotlib面片应用持久坐标变换?,python,matplotlib,Python,Matplotlib,matplotlib坐标系(在Jupyter笔记本中用于交互式动画)让我有点困惑。如果您创建一个面片,比如说一个圆,然后使用set_transform()对其进行平移,我发现该变换不是持久的,这意味着如果使用相同的(x,y)移位再次应用该变换,则圆将不会移动,因为在变换后圆的位置似乎不会更新,因此,后续变换将应用于相同的原始面片位置。我的问题是,如何应用一个转换,不仅在应用补丁后移动它,而且更新补丁位置?。假设我要应用一系列的平移,那么圆应该四处移动,而不是从原始位置来回摆动。下面是一个示例代码

matplotlib坐标系(在Jupyter笔记本中用于交互式动画)让我有点困惑。如果您创建一个面片,比如说一个圆,然后使用set_transform()对其进行平移,我发现该变换不是持久的,这意味着如果使用相同的(x,y)移位再次应用该变换,则圆将不会移动,因为在变换后圆的位置似乎不会更新,因此,后续变换将应用于相同的原始面片位置。我的问题是,如何应用一个转换,不仅在应用补丁后移动它,而且更新补丁位置?。假设我要应用一系列的平移,那么圆应该四处移动,而不是从原始位置来回摆动。下面是一个示例代码:

%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对象):

我不知道如何对matplotlib修补程序执行相同的操作?

将数据坐标转换为显示坐标

将变换添加到一起时,将从左向右应用变换。所以

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)

或者,您可以计算(或跟踪)偏移序列,并根据需要生成变换,而不是组合变换。有关此方法的示例,请参见


还要注意的是,在呈现补丁之前(例如通过调用
plt.show()
)不会应用变换。这解释了为什么对
c.set\u transform
的多个调用与对
c.set\u transform
的单个调用具有相同的效果。只有最后一个变换应用于面片

补丁程序
c
将单个转换存储在私有属性中,您可以使用
c.get\u transform
访问该属性:

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\u transform
将该私有属性重新指定给新的转换。但是在执行
plt.show()
或其他一些渲染调用(如
plt.savefig
)之前,不会应用任何变换。

阅读了吗?对于问题1的第一部分,
set\u transform
不会附加变换。它重置整个矩阵。这意味着
c.set_transform(ax.transData+mpl.transforms.Affine2D().translate(10,10))
之前的任何内容都将被有效忽略。是的,这是任何想要操作转换的人的必读资料。谢谢。我会读你链接的那一页。这里对我来说最重要的细节是显示与数据(如果我可以这样称呼的话)坐标。但是,如果您确认这些变换仅应用于渲染面片,它们实际上不会更新面片的“位置”或坐标。正确。渲染时应用单个变换(当前变换,由
c.get_transform()
返回的变换)。
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.]])))))))))