Phong shading for shiny Python 3D surface plots
Asked Answered
A

2

12

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?

Afghani answered 30/1, 2015 at 9:32 Comment(4)
Two things spring to mind. In matlab, I noticed that if you switch renderers (from the matlab software renderer to the OpenGL renderer) it goes from shiny looking to much more flat looking. So it might be that matplotlib is using the OpenGL renderer. Secondly, is there a way to change the colour and brightness of the source light in matplotlib. This might allow you to change the "shininess" of your plot.Viki
Thanks. Good suggestion - I wonder how I can change the Mayavi / Matplotlib renderer then to help achieve this please?Afghani
Maybe this will help - changing backends in matplotlib: #3285693 Phong-style lighting would be really nice in python, but I couldn't find anything on it. The only mention was in the context of using Blender python API: blenderartists.org/forum/…Physostomous
For a numpy implementation of blinn-phong, see answer: #54965830Dimitry
M
17

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
Millicentmillie answered 31/7, 2015 at 20:26 Comment(1)
In Mayavi, with specular = 1.0 and specular_power = 100 I get shinier highlights. The trouble with Matplotlib is that it can't draw intersecting objects properly, because it draws one thing at a time. This means that e.g. it's impossible to draw nice contours on surfaces (unless none of them are occluded by other parts of the surface). Also, those banding artifacts visible in the bottom figure become more pronounced for rougher surfaces and there is no workaround.Karrah
F
2

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.

Flageolet answered 17/6, 2015 at 19:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.