



等高线图可能会隐藏它所代表的曲面的一些细节,因为它只显示“高度”相同的位置,而不显示值是多少,甚至不显示与周围值的关系。在地图上,可以通过将高度输出到某些特定等高线上来解决上述问题。曲面图更具表现力,但将三维对象投影到二维屏幕上的问题本身可能会掩盖一些细节。为了解决这些问题,我们可以自定义三维图(或等高线图)的外观,对图形效果进行增强,并确保我们希望突出显示的细节清晰可见。最简单的方法是更改图形的颜色图,正如我们在前面的示例中看到的那样(默认情况下,Matplotlib会生成单色的曲面图,这使得我们在印刷品上难以看到细节)。在接下来的示例中,我们将探讨一些其他自定义三维曲面绘图的方法,包括更改显示的初始视角和更改颜色图的归一化方法等。
在这个示例中,我们将进一步自定义前面示例中绘制的函数:
和前面的示例一样,我们生成要绘制函数的数据点:
让我们看看如何自定义这些值的三维图。
以下步骤显示了如何自定义三维曲面图的外观。
1.和往常一样,我们的首要任务是创建一个新的图形和坐标轴,然后在它们上面绘图。由于我们要自定义Axes3D对象的属性,因此首先创建一个新图形:
2.现在,我们需要在这个figure对象上添加新的Axes3D对象,除了设置我们之前见过的projection="3d"关键字参数以外,还可以通过设置azim和elev关键字参数来改变初始视角:
3.搞定这些后,我们现在可以绘制这个曲面了。我们将更改归一化的边界,使最大值和最小值不在颜色图的极端位置。我们通过更改vmin和vmax参数来实现这一点:
4.最后,我们可以像往常一样设置坐标轴标签和标题:
生成的图形如图2.9所示。
图2.9 修改归一化和初始视角后的自定义三维曲面图
将图2.6与图2.9进行比较,我们可以看到,后者通常具有更深的色调,并且视角提供了函数达到最小值时所处“盆地”的更好的视图。有更深的色调是由于对颜色图数值应用了归一化,我们使用vmin和vmax关键字参数对其进行了修改。
颜色映射的工作原理是根据比例分配RGB值,即 颜色图 。首先,将值进行归一化,使其介于0和1之间,这通常是通过将最小值取为0、将最大值取为1的线性变换来实现的。然后,将适当的颜色应用于曲面图的每个面(在其他的图中可能是直线)。
在这个示例中,我们使用vmin和vmax关键字参数来人为地改变映射到0和1的值,以达到适应颜色图的目的。实际上,我们改变了应用于图形的颜色范围的端点。
Matplotlib提供了一些内置的颜色图,只需要将颜色图的名称传递给cmap关键字参数即可应用。文档(https://matplotlib.org/tutorials/colors/colormaps.html)中给出了这些颜色图的列表,还提供了相应的反转变体,在所选颜色图名称后添加_r后缀就可以实现。
三维图的视角由两个角度描述: 方位角 和 俯仰角 。方位角是在参考平面(这里是指由 x-y 轴确定的平面)内测量的角度;俯仰角是相对参考平面的角度。Axes3D的默认视角是:方位角为-60°和俯仰角为30°。在这个示例中,我们使用plot_surface的azim关键字参数将初始方位角更改为-80°(几乎沿 y 轴负方向),并使用elev参数将初始俯仰角设置为22°。
应用颜色图时的归一化步骤是由从Normalize类派生的对象执行的。Matplotlib提供了许多标准的归一化例程,包括LogNorm和PowerNorm。当然,你也可以创建自己的Normalize子类来执行归一化。可以使用plot_surface或其他绘图函数的norm关键字添加备选的Normalize子类。
对于更高级的用途,Matplotlib提供了一个接口,用于使用光源创建自定义的阴影。该接口通过从matplotlib.colors包导入LightSource类,然后使用该类的实例根据 z 值对曲面元素产生阴影。这是使用LightSource对象的shade方法实现的:
如果你想了解更多内容,可以在Matplotlib库中找到完整的示例。
除了视角之外,我们还可以改变用于将三维数据表示为二维图像的投影类型。默认情况下是透视投影,但我们也可以通过将proj_type关键字参数设置为“ortho”来使用正交投影。