Phong shading for shiny Python 3D surface plots

2019-03-25 11:50发布

I'm trying to create aesthetically pleasing 3D plots in Python with specular shading, and thus far have tried using both Matplotlib with 3D axes and surface plots from Mayavi, e.g., from the Mayavi surf examples web page:

enter image description here

The results look good, and in Mayavi there does seem to be reasonable control of the lighting, although I can't seem to achieve a "shiny" appearance.

In Matlab, this can be achieved by using 'Phong' lighting:

enter image description here

see http://www.mathworks.com/matlabcentral/fileexchange/35240-matlab-plot-gallery-change-lighting-to-phong/content/html/Lighting_Phong.html

Therefore, my question is: how can I achieve this Phong-style shiny shading in a Python-based 3D plot?

2条回答
Melony?
2楼-- · 2019-03-25 11:57

Yes, you can do this in Mayavi. In the Mayavi window, click on the little Mayavi icon in the upper left-hand corner to show the advanced menu. Click on the surface in the scene that corresponds to your surface, then click on the "Actor" tab in the menu on the right, scroll down to the box labeled "Property", and click on "More options". You can set the shading to phong shading in the "Interpolation" box.

查看更多
叛逆
3楼-- · 2019-03-25 12:21

As @ben mentioned, you can use Mayavi and then interactively change the lighting. A good idea is to click in the record script button, then you can use those lines of code in your scripts (That's how I did for the Mayavi part here).

Another option is to use Matplotlib. Based on the shading example, I managed to generate a surface with lighting.

See the code below.

import numpy as np
from mayavi import mlab
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.colors import LightSource

## Test data: Matlab `peaks()`
x, y = np.mgrid[-3:3:150j,-3:3:150j]
z =  3*(1 - x)**2 * np.exp(-x**2 - (y + 1)**2) \
   - 10*(x/5 - x**3 - y**5)*np.exp(-x**2 - y**2) \
   - 1./3*np.exp(-(x + 1)**2 - y**2) 

## Mayavi
surf = mlab.surf(x, y, z, colormap='RdYlBu', warp_scale='auto')
# Change the visualization parameters.
surf.actor.property.interpolation = 'phong'
surf.actor.property.specular = 0.1
surf.actor.property.specular_power = 5



## Matplotlib
fig = plt.figure()
ax = fig.gca(projection='3d')

# Create light source object.
ls = LightSource(azdeg=0, altdeg=65)
# Shade data, creating an rgb array.
rgb = ls.shade(z, plt.cm.RdYlBu)
surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, linewidth=0,
                       antialiased=False, facecolors=rgb)
plt.show()
mlab.show()

This gives as results:

  • Mayavi: enter image description here
  • Matplotlib: enter image description here
查看更多
登录 后发表回答