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

时间:2015-09-15 13:28:29

标签: python matplotlib transform

使用(x1, y1)(x2, y2)中的两个点MatplotlibLine2D之间绘制一条直线非常简单:

Line2D(xdata=(x1, x2), ydata=(y1, y2))

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

2 个答案:

答案 0 :(得分:5)

正如@tom所提到的,关键是transform kwarg。如果您希望艺术家的数据被解释为在"像素"坐标,指定transform=IdentityTransform()

使用转换

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

如果您还没有看过,请快速阅读matplotlib transforms tutorial。我将假设熟悉该教程的前几段,所以如果你

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

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()

enter image description here

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

以像素绘制

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

任何时候你想在" raw"像素,为艺术家指定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()

enter image description here

撰写变换

关于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()

enter image description here

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

enter image description here

这也可以很容易地定义像图#右边的" 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()

enter image description here

答案 1 :(得分:2)

您可以使用transform关键字在数据坐标(默认)和轴坐标之间切换。例如:

import matplotlib.pyplot as plt
import matplotlib.lines as lines

plt.plot(range(10),range(10),'ro-')

myline = lines.Line2D((0,0.5,1),(0.5,0.5,0),color='b') # data coords

plt.gca().add_artist(myline)

mynewline = lines.Line2D((0,0.5,1),(0.5,0.5,0),color='g',transform=plt.gca().transAxes) # Axes coordinates

plt.gca().add_artist(mynewline)

plt.show()

enter image description here