在matplotlib中抬起灯

发布于 2025-01-30 07:54:34 字数 1322 浏览 2 评论 0原文

我有以下python代码:

import numpy as np
from matplotlib import pyplot as plt
plt.rcParams['figure.figsize'] = [12, 7]

n = 100
m = 100

X = np.arange(-n/2,n/2,1)
Y = np.arange(-m/2,m/2,1)
X, Y = np.meshgrid(X, Y)
    
landscape = np.exp(-0.01 * (X*X + Y*Y) )

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_surface(X, Y, landscape,
                linewidth=0,
                antialiased=False
                )

在笔记本中运行此图像

”在此处输入图像说明”

如果您看起来非常近距离,您会看到高斯峰的左侧比右手轻一些边。但是,这种照明效果几乎看不见,我想增加它,以使3D形状很容易看到。

我知道 matplotlib.colors.colors.lightsource ,但是无论我做什么,我都无法得到我想要的效果。理想情况下,我只是想增加“默认”照明的强度,而不是解决这个问题。但是,如果有人可以解释如何将LightsOrce用于此图像也将有所帮助。

请注意,我不想将高度图应用于图像,也不想在其上绘制网格线 - 我只想在保持表面均匀的颜色的同时增加照明效果。

还值得一提的是,我有点困扰matplotlib,因为我使用 jupyterlite 要与未安装Python的学生分享笔记本,因此我需要一个解决方案的解决方案。

I have the following Python code:

import numpy as np
from matplotlib import pyplot as plt
plt.rcParams['figure.figsize'] = [12, 7]

n = 100
m = 100

X = np.arange(-n/2,n/2,1)
Y = np.arange(-m/2,m/2,1)
X, Y = np.meshgrid(X, Y)
    
landscape = np.exp(-0.01 * (X*X + Y*Y) )

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_surface(X, Y, landscape,
                linewidth=0,
                antialiased=False
                )

Running this in a notebook produces this image

enter image description here

If you look very closely you will see that the left-hand side of the Gaussian peak is very slightly lighter than the right-hand side. This lighting effect is barely visible, though, and I would like to increase it, so that the 3D shape becomes easily visible.

I'm aware of matplotlib.colors.LightSource, but no matter what I do I can't get that to produce the effect I want. Ideally, I'd just like to increase the intensity of the 'default' lighting, rather than fiddling around with this. But if someone can explain how to use LightSource for this image that would help too.

Note that I don't want to apply a height map to the image, and I also don't want to draw grid lines on it - I just want to increase the lighting effect while keeping the surface a uniform colour.

It's also worth mentioning that I'm somewhat stuck with MatPlotLib, because I'm using Jupyterlite to share the notebook with students who don't have Python installed, so I need a solution that works with that.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梓梦 2025-02-06 07:54:34

使用lightsource您可以做

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

plt.rcParams['figure.figsize'] = [12, 7]

n = 100
m = 100

X = np.arange(-n / 2, n / 2, 1)
Y = np.arange(-m / 2, m / 2, 1)
X, Y = np.meshgrid(X, Y)

landscape = np.exp(-0.01 * (X * X + Y * Y))

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

# this is used to set the graph color to blue
blue = np.array([0., 0., 1.])
rgb = np.tile(blue, (landscape.shape[0], landscape.shape[1], 1))

ls = LightSource()
illuminated_surface = ls.shade_rgb(rgb, landscape)

ax.plot_surface(X, Y, landscape,
                linewidth=0,
                antialiased=False,
                facecolors=illuminated_surface)

“在此处输入图像说明”

如果要从右边的灯更改azdeg参数lightsource Creation

ls = LightSource(azdeg=80)

Parameters
    ----------
    azdeg : float, default: 315 degrees (from the northwest)
        The azimuth (0-360, degrees clockwise from North) of the light
        source.
    altdeg : float, default: 45 degrees
        The altitude (0-90, degrees up from horizontal) of the light
        source.

Using LightSource you can do something like

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

plt.rcParams['figure.figsize'] = [12, 7]

n = 100
m = 100

X = np.arange(-n / 2, n / 2, 1)
Y = np.arange(-m / 2, m / 2, 1)
X, Y = np.meshgrid(X, Y)

landscape = np.exp(-0.01 * (X * X + Y * Y))

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

# this is used to set the graph color to blue
blue = np.array([0., 0., 1.])
rgb = np.tile(blue, (landscape.shape[0], landscape.shape[1], 1))

ls = LightSource()
illuminated_surface = ls.shade_rgb(rgb, landscape)

ax.plot_surface(X, Y, landscape,
                linewidth=0,
                antialiased=False,
                facecolors=illuminated_surface)

enter image description here

If you want the light from the right change the azdeg parameter at the LightSource creation

ls = LightSource(azdeg=80)

enter image description here

Parameters
    ----------
    azdeg : float, default: 315 degrees (from the northwest)
        The azimuth (0-360, degrees clockwise from North) of the light
        source.
    altdeg : float, default: 45 degrees
        The altitude (0-90, degrees up from horizontal) of the light
        source.
戏蝶舞 2025-02-06 07:54:34

请记住,Matplotlib的3D功能相当有限,我建议使用其他库。 3D图的更好的库是:

  • plotly :以为我不会将其用于纯色表面,因为它具有一个奇怪的照明解决方案很难读取图。
  • mayavi
  • pyvista
  • k3d-jupyter 内部jupyter笔记本)。

请记住,这些图书馆中的每个图书馆都具有其优势和缺点。

我将使用Mayavi复制您的示例,因为我将其安装在当前环境中:

import numpy as np
from mayavi import mlab

n = 100
m = 100

x, y = np.mgrid[-n/2:n/2:n*1j,-m/2:m/2:m*1j]
z = np.exp(-0.01 * (x**2 + y**2) )

surf = mlab.surf(x, y, z, warp_scale='auto', color=(0, 0.5, 1))
mlab.show()

“在此处输入图像说明”

Keeping in mind that Matplotlib's 3D capabilities are rather limited, I would suggest to use a different library. Better libraries for 3D plots are:

  • Plotly: thought I wouldn't use it for solid color surfaces, as it has a strange lighting solution which creates hard to read plots.
  • Mayavi
  • PyVista
  • K3D-Jupyter (only works inside Jupyter Notebook).

Keep in mind that each one of those libraries come with their advantages and disadvantages.

I'm going to replicate your example with Mayavi, since I have it installed in the current environment:

import numpy as np
from mayavi import mlab

n = 100
m = 100

x, y = np.mgrid[-n/2:n/2:n*1j,-m/2:m/2:m*1j]
z = np.exp(-0.01 * (x**2 + y**2) )

surf = mlab.surf(x, y, z, warp_scale='auto', color=(0, 0.5, 1))
mlab.show()

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文