返回介绍

坐标变换

发布于 2024-05-19 17:52:31 字数 6643 浏览 0 评论 0 收藏 0

matplotlib 中有四个坐标系:

  • 用户级的 data 坐标系:坐标转换对象为 ax.transData 。它是用户级坐标系,由 xlimylim 控制
  • Axes 坐标系:坐标转换对象为 ax.transAxes 。它是 Axes 的坐标系, (0,0)Axes 的左下角, (1,1)Axes 的右上角。
  • Figure 坐标系:坐标转换对象为 fig.transFigure 。它是 Figure 的坐标系, (0,0)Figure 的左下角, (1,1)Figure 的右上角。
  • display 坐标系:它没有坐标转换对象。它显示的是 display 的像素坐标系, (0,0)display 的左下角, (width,height)display 的右上角。

前面三个坐标系的坐标转换对象有方法执行坐标转换,这些方法接受输入并产生输出:输入为本坐标系内的坐标点,输出为 display 坐标系中的坐标。(因此 display 坐标系没有坐标转换对象)。当然他们也有相关方法将来自于 display 坐标系中的坐标转换回本坐标系内的坐标。

Artist 的构造函数中传入 transform 关键字参数(其值为坐标转换对象),就能够切换坐标系。如: ax.text(0.05,0.95,label,"This is a Text",transform=ax.transAxes) ,将 Text 放置于 Axes 坐标系中的 (0.05,0.95) 位置处。

通常不建议直接使用 display 坐标系。因为它固定了绝对坐标,导致你 resize 图表时你必须重新定位坐标。所以你必须监听 resize 事件,非常麻烦。

1. 用户的 data 坐标系

当调用 ax.set_xlimit(x_min,x_max) 以及 ax.set_ylimit(y_min,y_max) 时,即建立起了用户 data 坐标系。左下角坐标为 (x_min,y_min) ,右上角坐标为 (x_max,y_max)

有时候你可能并没有显式调用 .set_xlimit() 以及 .set_ylimit() 。其实 matplotlib 会隐式调用它们来设置坐标轴的数据范围。

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)
type(ax.transData)
ax.transData.transform((5, 0))

你可以调用 ax.transData 返回 data 坐标系的坐标转换对象。对该坐标转换对象调用 .transform(point) 方法会返回 pointdisplay 坐标系下的坐标。其中 point 是点在 data 坐标系下的坐标 (x,y) 。你也可以给 .transform() 方法一次传入多个点的坐标,此时输出也是对应于 display 坐标系下的一系列坐标。

你可以对 ax.trandData 返回的坐标转换对象调用 .inverted() 方法。该方法返回的是一个坐标逆转换对象。对该坐标逆转换对象调用 .transform(point) 方法会返回 pointdata 坐标系下的坐标。其中 point 是点在 display 坐标系下的坐标 (x,y) 。你也可以给 .transform() 方法一次传入多个点的坐标,此时输出也是对应于 data 坐标系下的一系列坐标。

当你调用了 ax.set_xlim() 或者 ax.set_ylim() 时,坐标转换对象会实时更新。

用户的 data 坐标系

2. Axes 坐标系

Axes 坐标系中, (0,0) 位于 Axes 的左下角, (1,1) 位于 Axes 的右上角, (0.5,0.5) 位于 Axes 的中心。当然你可以引用位于这之外的点,如 (-0.1,1.1)

通常如果你需要在 Axes 中放置一些文字说明,那么一般都是采用 Axes 坐标系来定位。这样无论图形怎么缩放,这些 Text 都能位于正确的位置。

当然你也可以在 Axes 中通过 Axes 坐标系添加一些 Patch ,但是通常建议在 data 坐标系下添加。因为你在 Axes 中添加的图表当图表缩放时可能会出现问题。

3. 混合坐标系

有时候你需要混合 data 坐标系和 Axes 坐标系。通过 matplotlib.transforms.blended_transform_factory( ax.transData, ax.transAxes) 能够返回一个混合坐标系,该坐标系中: x 坐标为 data 坐标系, y 坐标为 Axes 坐标系。因此该坐标系中 (1,1) 表示的是 data 坐标系中 x=1 但是 y 位于最上方的点。

混合坐标系

有两个函数返回特定的混合坐标系:

  • matplotlib.axes.Axes.get_xaxis_transform() :等价于 matplotlib.transforms.blended_transform_factory(ax.transData, ax.transAxes)x 坐标为 data 坐标系, y 坐标为 Axes 坐标系。常用于绘制 x 轴的 labeltickgridline
  • matplotlib.axes.Axes.get_yaxis_transform(). :等价于 matplotlib.transforms.blended_transform_factory(ax.transAxes,ax.transData)x 坐标为 Axes 坐标系, y 坐标为 data 坐标系。常用于绘制 y 轴的 labeltickgridline

4. 利用坐标变换制造阴影效果

matplotlib.transform.ScaledTranslation(xt, yt, scale_trans) 创建一个新的坐标转换对象,该坐标转换由 xtyt 经过 scale_trans 坐标转换而来。

它创建的是一个偏移对于的坐标变换。偏移的坐标是位于 scale_trans 中的。

  • 制作阴影的时候,将阴影的 zorder 调小,从而使得阴影首先绘制并位于底层

  • scale_transfig.dpi_scale_trans 坐标转换对象时, xt , yt 的单位是像素。还有一个方法也能达到同样的效果: matplotlib.transforms.offset_copy(trans,x=xt,y=yt,units='inches') ,但是该方法返回的坐标转换对象是 trans 合成了偏移之后的效果。

    制造阴影效果

5. 直角坐标系、对数坐标系、极坐标系

a. 设置对数坐标系

通过 Axes.set_xscale(value,**kwargs) / Axes.set_yscale(value,**kwargs) 方法可以设置 x 轴/ y 轴是否对数坐标。其中 value 可以为:

  • linear :线性
  • log :对数。其中 basex | basey 关键字指定对数的基
  • logit :以 2 为底的对数
  • symlog :对数,其中 basex | basey 关键字指定对数的基

你也可以通过 matplotlib.pyplot.xscale()matplotlib.pyplot.yscale() 来设置对数坐标。一定要先添加数据后设置对数坐标。

对数坐标

b. 设置极坐标

通过 Figure.add_axes((left,bottom,width,height), projection='polar') 或者 Figure.add_axes((left,bottom,width,height), polar=True) 方法可以创建一个极坐标的 Axes 。其中 polar 关键字是为了兼容旧代码,新代码推荐用 projection 关键字,因为 projection 关键字不仅可以设置极坐标,还可以设置自定义坐标(它将坐标统一为映射关系)。

Figure.add_subplot(...) 也是同样的设置

级坐标

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文