Python:为什么 plot_surface 是透明的?

标签 python matplotlib transparency

我尝试使用 Python 3 创建曲面图,现在我想知道为什么它是透明的?有任何想法吗?我希望它看起来像我使用相同数据集使用 MATLAB 创建的图 ETOPO1 .第二个问题,使用 plot_surface 改变纵横比是不可能的,对吧?

最好的,马丁

import numpy as np
from matplotlib import cm
import matplotlib.pyplot as plt
from matplotlib.colors import LightSource

ETOPO1 = np.flipud(ETOPO1)

lon = np.arange(30,60+1/60,1/60)
lat = np.arange(-20,20+1/60,1/60)
LON,LAT = np.meshgrid(lon,lat)

fig, ax2 = plt.subplots(subplot_kw={"projection": "3d"})
ls = LightSource(270,45)
rgb = ls.shade(ETOPO1,
        cmap=cm.gist_earth,
        vert_exag=0.1,
        blend_mode='hsv')
ax2.plot_surface(LON,LAT,ETOPO1,
        rstride=1, cstride=1,
        linewidth=0,
        facecolors=rgb,
        antialiased=True,
        shade=True)
ax2.view_init(60, 20-90)
ax2.tick_params(axis='both', labelsize=6)
ax2.grid(False)
plt.show()

3D surface from python

3D surface from matlab

编辑 2021 年 12 月 1 日

这里有几个相关的问题:

  1. 如果我使用 rstride=5、cstride=5,上面的代码需要 15 秒,但如果我使用全分辨率 rstride=1、cstride=1,则需要 318 秒 = 5.3 分钟。这是令人惊讶的,因为 MATLAB 需要 0.14 秒才能获得完整分辨率——为什么?

  2. 我尝试使用以下方法在曲面顶部添加轮廓

    v = np.array([500,1000,2000,3000])
    ax2.contour(LON,LAT,ETOPO1+1,
         levels=v,linewidths=0.3,
         colors='r',linestyles='solid')
    

    但是,尽管向 ETOPO1 添加 1、10 或 100,它们总是被表面隐藏。

  3. 我尝试使用 ETOPO1 保存图形,我

    plt.savefig('etopo1_python.png',dpi=300)

    但在 PNG 文件中得到一个空图像。有什么想法吗?

  4. antialiased=True

    导致透明,问题来了,是不是bug?

最佳答案

根据 this answer这是 plot_surface() 函数的一个已知问题。

This other answer建议在 plot_surface() 中设置 antialiased=False,这对我对您的数据有效。但是,我没有仔细查看它是否引起任何问题。

如下所示,您可以通过添加类似 ax.set_box_aspect((1, 1, 0.1)) 的内容来调整纵横比(下面我计算了 Z 参数实现一些所需的近似垂直夸大,但你明白了)。

import numpy as np
from matplotlib import cm
from matplotlib.colors import LightSource
import matplotlib.pyplot as plt

url = 'http://141.89.112.21/wp-content/uploads/2021/11/etopo1_data_python.txt'
ETOPO1 = np.loadtxt(np.DataSource().open(url), skiprows=5)

h, w = ETOPO1.shape
lon = np.linspace( 30,  60, w)  # linspace recommended for non-integer intervals.
lat = np.linspace( 20, -20, h)  # Reverse this instead of flipping the array.
LON, LAT = np.meshgrid(lon, lat)

fig, ax = plt.subplots(figsize=(20, 15),
                       subplot_kw={"projection": "3d"})

ve = 200  # Approx. vertical exaggeration.
ax.set_box_aspect((1, 1, ve/1850))

rgb = LightSource(270, 45).shade(ETOPO1,
                                 cmap=cm.Blues_r,
                                 blend_mode='soft',
                                 vert_exag=ve/1850)

ax.plot_surface(LON, LAT, ETOPO1,
                rstride=2, cstride=2,
                facecolors=rgb,
                antialiased=False)

ax.view_init(20, -70)
ax.tick_params(axis='both', labelsize=6)
ax.grid(False)
plt.show()

这会产生:

The result of the code

关于Python:为什么 plot_surface 是透明的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70136084/

相关文章:

java - 有什么方法可以禁用 JButton 的默认单击动画吗?

python - Python。向字典中的键添加多个项目

python - TensorFlow random_shuffle_queue 已关闭且元素不足

python - 字典: how to compare values and merge if values are the same?

python - 带阴影线的 matplotlib 自定义图例

python - 运行时错误: main thread is not in main loop using Matplotlib with Django

python - 单词 ngrams 的最大长度与上下文窗口大小之间的差异

python - Matplotlib:索引颜色图

user-interface - Java Swing - 半透明组件

java - 制作一个按钮 - java