2

I am working on a calculation in Python which calculates the physical properties of an object for angles in the range 0 < θ < π/2 and 0 < φ < π/2 (i.e. the first octant). To visualize the properties I am currently plotting them as color values on a 3D unit sphere. Producing this plot for reasonable resolution is a fairly resource intensive process, but I have no interest in being able to look at the plot from any other angle.

What I would like to create instead is a 2D image plot similar to what imshow would create except that it should have the triangular outline of a sphere octant being projected into 2D. Note that I am not asking how to project the 3D data into 2D, but rather how to display the 2D data in a manner which looks similar to a sphere octant viewed from θ = π/4, φ = π/4.

My current code is below. The specifics may not be that relevant to an answer, but it gives an idea of what I am trying to do.

'''
The code above this point produces three arrays stored in a dictionary 
called phs with the three entries using the keys 'I', 'II', 'III.  Each 
array is a function of theta and phi where 
theta = np.linspace( 0, 90, nPoints)
phi = np.linspace( 0, 90, nPoints)
also 
types = ('I', 'II', 'III')  
'''

# Colormaps
mx = np.maximum( np.maximum( phs['I'], phs['II']), phs['III'])
cmap = cm.ScalarMappable( cmap='BuPu')
cmap.set_array( mx)
clrs = dict()
for type in types:
    clrs[type] = cmap.to_rgba( phs[type])

# Convert to Cartesian coordinates with unit radius
xM, yM, zM = plotCartesianFixedR( thetaM, phiM)

# Plot
fig = plt.figure( figsize=(16,7))
ax = dict()
ax['I'] = plt.subplot( 131, projection='3d')
ax['II'] = plt.subplot( 132, projection='3d')
ax['III'] = plt.subplot( 133, projection='3d')
surf = dict()
for type in types:
    surf[type] = ax[type].plot_surface( xM, yM, zM, rstride=1, cstride=1, 
            facecolors=clrs[type], shade=False)
    # Set axis properties
    ax[type].set_xticklabels([])
    ax[type].set_yticklabels([])
    ax[type].set_zticklabels([])
    ax[type].view_init(elev=45, azim=45)

# Colorbar
plt.colorbar( cmap, shrink=1)
ax['I'].set_title( 'Log$_{10}(|\Delta k|)$ Type I (ssf)')
ax['II'].set_title( 'Log$_{10}(|\Delta k|)$ Type II (sff)')
ax['III'].set_title( 'Log$_{10}(|\Delta k|)$ Type III (fsf)')

# Add title
if title:
    plt.suptitle(title)

The output looks like:

Output of above code

Just to restate the problem; I would like to reproduce this plot almost exactly but in 2D without including the background axes.

Chris Mueller
  • 6,490
  • 5
  • 29
  • 35
  • Do you have a specific question regarding your project? Also, note that there won't be one single "right" solution, as there are [many possibilities to do the spere -> triangle projection](http://en.wikipedia.org/wiki/Map_projection). – Carsten Apr 20 '15 at 13:22
  • @Carsten Calculating the projection isn't my issue. The issue is how to show it as a 2D plot in python because it no longer has a rectangular grid such as would be expected by `imshow` or similar routines. The outline of the 'image' is a bulging triangle like you see in the plots above. – Chris Mueller Apr 20 '15 at 13:26
  • Would you please rephrase the question to address your actual problem (i.e. _plotting non-rectangular data using matplotlib_)? Because an answer to your question, as it is stated now, requires doing the projection as well. – Carsten Apr 20 '15 at 13:42
  • @Carsten Good suggestion. Better now? – Chris Mueller Apr 20 '15 at 13:48
  • It's still unclear to me what you want. To make the axis background invisible? To use 2D plotting? Would the polar projection be a good enough approximation? matplotlib can plot just a [wedge](http://matplotlib.org/examples/axes_grid/demo_floating_axes.html) of a polar projection. – cphlewis Apr 20 '15 at 17:03
  • @cphlewis I want to reproduce the plot shown without using the resources required to do it in 3D. I.E., I want only the view from θ=π/4, φ=π/4 as a 2D scaled image. I am capable of doing the mathematical transformation to get the points as a function of x and y coordinates instead of theta and phi, but I don't know how to get matplotlib to plot it as a bulging triangle with curved boundaries. – Chris Mueller Apr 20 '15 at 17:13
  • 3
    Make a transparent (or white, etc) bitmap and slap your x,y coordinate values into it, then `imshow` that. – cphlewis Apr 20 '15 at 17:19
  • I had thought of doing something similar, but I didn't think of setting the background to be transparent. Thanks, I'll give it a try. – Chris Mueller Apr 20 '15 at 18:14
  • I will be a little surprised if this is faster than letting a 3d program do the work for a fixed-view image -- most of the work is the same. – cphlewis Apr 22 '15 at 00:35

0 Answers0