Matplotlib:变换¶
日期 | 2010-06-16(最后修改),2006-01-22(创建) |
---|
无论何时将坐标传递给 matplotlib,都会出现一个问题,即您指的是哪种坐标。考虑以下示例
axes.text(x,y, "my label")
在坐标 x,y 处向轴添加一个标签“my label”,或者更准确地说:文本放置在数据点 (x,y) 的理论位置。因此,我们称之为“数据坐标”。但是,还可以考虑其他坐标。例如,您可能希望将标签放在图形的正中间。如果您使用上述方法指定它,那么您需要确定 x 和 y 的最小值和最大值以确定中间位置。但是,使用变换,您可以简单地使用
axes.text(0.5, 0.5, "middle of graph", transform=axes.transAxes)
有四种内置变换,您应该了解它们(让 ax 是一个 Axes 实例,fig 是一个 Figure 实例)
matplotlib.transforms.identity_transform() # display coords
ax.transData # data coords
ax.transAxes # 0,0 is bottom,left of axes and 1,1 is top,right
fig.transFigure # 0,0 is bottom,left of figure and 1,1 is top,right
这些变换可用于任何类型的 Artist,而不仅仅是文本对象。
ax.text 的默认变换是 ax.transData,fig.text 的默认变换是 fig.transFigure。
当然,您可以定义更通用的变换,例如 matplotlib.transforms.Affine,但上面列出的四种变换在许多应用程序中出现。
xy_tup() 函数已不再使用。请参阅 Matplotlib 官方文档 http://matplotlib.sourceforge.net/users/transforms_tutorial.html 以获取更多参考。
示例:类似注释的刻度标签¶
如果您发现 Matplotlib 的内置刻度标签不足以满足您的需求,可以使用变换来实现类似的功能。以下示例在刻度标签下方绘制注释,并使用变换来确保注释的 x 坐标与绘图的 x 坐标一致,但 y 坐标位于固定位置,与绘图的比例无关。
import matplotlib as M
import Numeric as N
import pylab as P
blend = M.transforms.blend_xy_sep_transform
def doplot(fig, subplot, function):
ax = fig.add_subplot(subplot)
x = N.arange(0, 2*N.pi, 0.05)
ax.plot(x, function(x))
trans = blend(ax.transData, ax.transAxes)
for x,text in [(0.0, '|'), (N.pi/2, r'$\rm{zero\ to\ }\pi$'),
(N.pi, '|'), (N.pi*1.5, r'$\pi\rm{\ to\ }2\pi$'),
(2*N.pi, '|')]:
ax.text(x, -0.1, text, transform=trans,
horizontalalignment='center')
fig = P.figure()
doplot(fig, 121, N.sin)
doplot(fig, 122, lambda x: 10*N.sin(x))
P.show()
示例:向数据坐标添加像素偏移量¶
有时您希望指定标签显示在对应数据点的固定像素偏移量处,无论缩放如何。以下是一种方法;尝试在交互式后端运行此代码,并缩放和平移图形。
此方法的工作原理是首先对 `transData` 进行浅拷贝,然后向其添加偏移量。所有变换都可以具有偏移量,可以通过 `set_offset` 进行修改,并且进行拷贝是为了避免修改数据本身的变换。较新版本的 matplotlib(目前仅限 svn 版本)具有 `offset_copy` 函数,可以自动执行此操作。
import matplotlib
import matplotlib.transforms
from pylab import figure, show
# New enough versions have offset_copy by Eric Firing:
if 'offset_copy' in dir(matplotlib.transforms):
from matplotlib.transforms import offset_copy
def offset(ax, x, y):
return offset_copy(ax.transData, x=x, y=y, units='dots')
else: # Without offset_copy we have to do some black transform magic
from matplotlib.transforms import blend_xy_sep_transform, identity_transform
def offset(ax, x, y):
# This trick makes a shallow copy of ax.transData (but fails for polar plots):
trans = blend_xy_sep_transform(ax.transData, ax.transData)
# Now we set the offset in pixels
trans.set_offset((x,y), identity_transform())
return trans
fig=figure()
ax=fig.add_subplot(111)
# plot some data
x = (3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3)
y = (2,7,1,8,2,8,1,8,2,8,4,5,9,0,4,5)
ax.plot(x,y,'.')
# add labels
trans=offset(ax, 10, 5)
for a,b in zip(x,y):
ax.text(a, b, '(%d,%d)'%(a,b), transform=trans)
show()
章节作者:AndrewStraw、Unknown[115]、Unknown[77]、GaelVaroquaux、Unknown[116]