有没有办法在Python的Matplotlib中用点坐标绘制Line2D?

c00*_*ter 8 python transform matplotlib

这是非常简单的绘制两点之间的直线(x1, y1),并(x2, y2)Matplotlib使用Line2D:

Line2D(xdata=(x1, x2), ydata=(y1, y2))
Run Code Online (Sandbox Code Playgroud)

但在我的特殊情况下,我必须使用全局使用数据坐标的常规图顶部的点坐标绘制Line2D实例.那可能吗?

Joe*_*ton 5

正如@tom所说,关键是transformkwarg.如果您希望将艺术家的数据解释为"像素"坐标,请指定transform=IdentityTransform().

使用变换

变换是matplotlib中的一个关键概念.变换采用艺术家数据所在的坐标并将其转换为显示坐标 - 换句话说,就是屏幕上的像素.

如果您还没有看过它,请快速阅读matplotlib变换教程.我将假设熟悉该教程的前几段,所以如果你是

例如,如果我们想在整个图中画一条线,我们会使用类似的东西:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

# The "clip_on" here specifies that we _don't_ want to clip the line
# to the extent of the axes
ax.plot([0, 1], [0, 1], lw=3, color='salmon', clip_on=False, 
        transform=fig.transFigure)

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


无论我们如何以交互方式调整大小/缩放/平移绘图,此线将始终从图的左下角延伸到右上角.


以像素绘制

您将使用最常见的变换是ax.transData,ax.transAxesfig.transFigure.但是,要绘制点/像素,您实际上根本不需要变换.在这种情况下,你将创建一个什么都不做的新转换实例:IdentityTransform.这指定艺术家的数据是"原始"像素.


任何时候您想要以"原始"像素绘图,请指定transform=IdentityTransform()给艺术家.


如果你想在点上工作,请回想一下有72个点到一英寸,而对于matplotlib来说,它fig.dpi控制着一个"英寸"的像素数(它实际上与物理显示无关).因此,我们可以使用简单的公式将点转换为像素.

举个例子,让我们在图的左下角放置一个标记30点:

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

fig, ax = plt.subplots()

points = 30
pixels = fig.dpi * points / 72.0

ax.plot([pixels], [pixels], marker='o', color='lightblue', ms=20,
        transform=IdentityTransform(), clip_on=False)
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


撰写变换

关于matplotlib变换的一个更有用的事情是可以添加它们来创建一个新的变换.这样可以轻松创建班次.

例如,让我们绘制一条线,然后添加另一条在x方向上移动15个像素的线:

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

fig, ax = plt.subplots()
ax.plot(range(10), color='lightblue', lw=4)

ax.plot(range(10), color='gray', lw=4,
        transform=ax.transData + Affine2D().translate(15, 0))

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

要记住的一件重要事情是增加的顺序很重要.如果我们这样做Affine2D().translate(15, 0) + ax.transData,我们会将事物移动15个数据单位而不是15个像素.添加的变换按顺序被"链接"(组合将是更准确的术语).

在此输入图像描述


这也可以很容易地定义诸如"图中右侧的20个像素"之类的东西.例如:

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

fig, ax = plt.subplots()

ax.plot([1, 1], [0, 1], lw=3, clip_on=False, color='salmon',
        transform=fig.transFigure + Affine2D().translate(-20, 0))

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述