强基初中数学&学Python——第277课 数字和数学第三方模块Matplotlib之八:高级教程——转换器教程(2)

混合变换  在将图表域(axes)与数据坐标混合的混合坐标空间中绘制图表的方法非常有用,例如,创建一个水平跨度的区域,突出显示y数据,虽然跨越x轴,但不考虑数据限制、平移或缩放级别等。事实上,这些混合线和跨度区域非常有用,我们有内置的功能使其易于绘制(请参见axhline()axvline()axhspan()axvspan())。但出于本专题的教学目的,我们将在这里使用混合转换来实现水平跨度区域。这个技巧只适用于可分离的变换(即x轴与y轴的变换可分离),就像你在普通笛卡尔坐标系(平面直角坐标系)中看到的那样,但不适用于不可分离的转换,比如PolarTransform

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

import numpy as npimport matplotlib.pyplot as pltimport matplotlib.transforms as transformsimport matplotlib.patches as mpatches
fig, ax = plt.subplots()x = np.random.randn(1000)
ax.hist(x, 30)ax.set_title(r'$\sigma=1 \/ \dots \/ \sigma=2$', fontsize=16)
# the x coords of this transformation are data, and the y coord are axestrans = transforms.blended_transform_factory(    ax.transData, ax.transAxes)# highlight the 1..2 stddev region with a span.# We want x to be in data coordinates and y to span from 0..1 in axes coords.rect = mpatches.Rectangle((1, 0), width=1, height=1, transform=trans,                          color='yellow', alpha=0.5)ax.add_patch(rect)
plt.show()

 

提示:

  x在数据坐标中,y在图表域(axes)坐标中的混合转换非常有用,因此我们有辅助方法来返回Matplotlib内部用于绘制刻度、刻度标签等的版本。这些方法是Matplotlib.aaxes.get_xaxis_transform()matplotlb.axes.get_yaxis_transform()。因此,在上面的示例中,对blended_transform_factory()的调用可以替换为get_xaxis_transform:

· 

trans = ax.get_xaxis_transform()


物理坐标绘图

  有时我们希望一个物体在绘图上具有一定的物理尺寸。在这里,我们画了与上面相同的圆,但使用物理坐标。如果以交互方式完成,可以看到更改图形的大小不会更改圆从左下角的偏移,也不会更改其大小,并且无论图表域的纵横比如何,它都能保持为圆。

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

import numpy as npimport matplotlib.pyplot as pltimport matplotlib.transforms as transformsimport matplotlib.patches as mpatchesfig, ax = plt.subplots(figsize=(5, 4))x, y = 10*np.random.rand(2, 1000)ax.plot(x, y*10., 'go', alpha=0.2)  # plot some data in data coordinates# add a circle in fixed-coordinatescirc = mpatches.Circle((2.5, 2), 1.0, transform=fig.dpi_scale_trans,                       facecolor='blue', alpha=0.75)ax.add_patch(circ)plt.show()

,时长00:20

  如果我们更改图表(figure)大小,则圆不会更改其绝对位置,而是被裁剪。

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

import numpy as npimport matplotlib.pyplot as pltimport matplotlib.transforms as transformsimport matplotlib.patches as mpatchesfig, ax = plt.subplots(figsize=(7, 2))x, y = 10*np.random.rand(2, 1000)ax.plot(x, y*10., 'go', alpha=0.2)  # plot some data in data coordinates# add a circle in fixed-coordinatescirc = mpatches.Circle((2.5, 2), 1.0, transform=fig.dpi_scale_trans,                       facecolor='blue', alpha=0.75)ax.add_patch(circ)plt.show()

 

  另一个用途是在图表域上的数据点周围放置一个具有固定物理尺寸的色斑。这里我们将两个变换相加。第一个设置椭圆应该有多大的比例,第二个设置其位置。先将椭圆放置在原点,然后使用辅助变换ScaledTranslation将其移动到ax.transData坐标系中的正确位置。此辅助程序是用以下代码实例化的:

· 

trans = ScaledTranslation(xt, yt, scale_trans)

其中, 参数xt和yt是转换偏移,scale_trans是偏移之前缩放xt和yt的转换。  请注意在下面的变换中使用加号(+)运算符。这段代码的实际作用:首先应用比例变换fig.dpi_scale_trans使椭圆大小合适,但仍以(0, 0)为中心,然后将它的数据转换为数据空间中的xdata[0]和ydata[0]。  在交互环境中运行时,即使通过缩放更改了图表域的限制,椭圆的大小也保持不变。

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

· 

import numpy as npimport matplotlib.pyplot as pltimport matplotlib.transforms as transformsimport matplotlib.patches as mpatchesfig, ax = plt.subplots()xdata, ydata = (0.2, 0.7), (0.5, 0.5)ax.plot(xdata, ydata, "o")ax.set_xlim((0, 1))
trans = (fig.dpi_scale_trans +         transforms.ScaledTranslation(xdata[0], ydata[0], ax.transData))
# plot an ellipse around the point that is 150 x 130 points in diameter...circle = mpatches.Ellipse((0, 0), 150/72, 130/72, angle=40,                          fill=None, transform=trans)ax.add_patch(circle)plt.show()

,时长00:20

注意:

  转变的顺序很重要。在这里,椭圆首先在显示空间中被赋予正确的尺寸,然后在数据空间中被移动到正确的位置。如果我们先进行ScaledTranslation,那么xdata[0]和ydata[0]将首先被转换为显示坐标(在200 dpi监视器上为[358.4 475.2]),然后这些坐标将通过图.dpi_scale_trans缩放,将椭圆的中心推离屏幕(即[7680。95040.])。

axhline():

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axhline.html#matplotlib.axes.Axes.axhline

axvline():

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axvline.html#matplotlib.axes.Axes.axvline

axhspan():

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axhspan.html#matplotlib.axes.Axes.axhspan

axvspan():

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axvspan.html#matplotlib.axes.Axes.axvspan

PolarTransform:

https://matplotlib.org/stable/api/projections/polar.html#matplotlib.projections.polar.PolarAxes.PolarTransform

matplotlib.axes.Axes.get_xaxis_transform():

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.get_xaxis_transform.html#matplotlib.axes.Axes.get_xaxis_transform

matplotlib.axes.Axes.get_yaxis_transform():

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.get_yaxis_transform.html#matplotlib.axes.Axes.get_yaxis_transform

blended_transform_factory():

https://matplotlib.org/stable/api/transformations.html#matplotlib.transforms.blended_transform_factory

ScaledTranslation:https://matplotlib.org/stable/api/transformations.html#matplotlib.transforms.ScaledTranslation