#!/usr/bin/env python # coding: utf-8 # #### New to Plotly? # Plotly's Python library is free and open source! [Get started](https://plot.ly/python/getting-started/) by downloading the client and [reading the primer](https://plot.ly/python/getting-started/). #
You can set up Plotly to work in [online](https://plot.ly/python/getting-started/#initialization-for-online-plotting) or [offline](https://plot.ly/python/getting-started/#initialization-for-offline-plotting) mode, or in [jupyter notebooks](https://plot.ly/python/getting-started/#start-plotting-online). #
We also have a quick-reference [cheatsheet](https://images.plot.ly/plotly-documentation/images/python_cheat_sheet.pdf) (new!) to help you get started! # # #### Projections of a 3d surface onto planes # This example will demonstrate how to create heatmaps of projections of a 3d surface onto planes perpendicular to the z, x, respectively y-direction. Usually surfaces in the 3d space are colored with a colormap associated to the normalized range of the z coordinates of points on that surface. # Recently, Plotly devised a method to color a surface according to a custom color function. # # Namely, if $x, y, z$ are numpy arrays of shape (m, n), defined by a discretization (via a meshgrid) of a surface z=f(x,y) or in parametric form, $x=x(u,v), y=y(u,v), z=z(u,v)$, then a custom function, `Color(x,y,z)`, returns a numpy array `C`, of the same shape as z, and the surface is colored by a colormap, according to the values in `C`. # This method allows to project a surface onto planes perpendicular to the z, x or y-direction in the 3d space # and interpret the projection as a planar surface colored according to the z, x or y value at each point # of the coresponding plane. # # First, define the surface and its discretization: # In[1]: import plotly.plotly as py import plotly.graph_objs as go import numpy as np xx=np.linspace(-3.5, 3.5, 100) yy=np.linspace(-3.5, 3.5, 100) x,y=np.meshgrid(xx, yy) z=np.exp(-(x-1)**2-y**2)-10*(x**3+y**4-x/5)*np.exp(-(x**2+y**2)) # #### Color according to normalized z-values # In[2]: colorscale=[[0.0, 'rgb(20,29,67)'], [0.1, 'rgb(28,76,96)'], [0.2, 'rgb(16,125,121)'], [0.3, 'rgb(92,166,133)'], [0.4, 'rgb(182,202,175)'], [0.5, 'rgb(253,245,243)'], [0.6, 'rgb(230,183,162)'], [0.7, 'rgb(211,118,105)'], [0.8, 'rgb(174,63,95)'], [0.9, 'rgb(116,25,93)'], [1.0, 'rgb(51,13,53)']] # #### Add hover text for the surface: # In[3]: textz = [['x: '+'{:0.5f}'.format(x[i][j])+'
y: '+'{:0.5f}'.format(y[i][j])+ '
z: '+'{:0.5f}'.format(z[i][j]) for j in range(z.shape[1])] for i in range(z.shape[0])] trace1= go.Surface( x=tuple(x), y=tuple(y), z=tuple(z), colorscale=colorscale, text=textz, hoverinfo='text', ) # #### Set Plot Layout: # In[4]: axis = dict( showbackground=True, backgroundcolor="rgb(230, 230,230)", showgrid=False, zeroline=False, showline=False) ztickvals=list(range(-6,4)) layout = go.Layout(title="Projections of a surface onto coordinate planes" , autosize=False, width=700, height=600, scene=dict(xaxis=dict(axis, range=[-3.5, 3.5]), yaxis=dict(axis, range=[-3.5, 3.5]), zaxis=dict(axis , tickvals=ztickvals), aspectratio=dict(x=1, y=1, z=0.95) ) ) # #### Discretization of each Plane # The surface projections will be plotted in the planes of equations # `Z=np.min(z)-2`, `X=np.min(xx)`, respectively `Y=np.min(yy)`. # In[5]: z_offset=(np.min(z)-2)*np.ones(z.shape)# x_offset=np.min(xx)*np.ones(z.shape) y_offset=np.min(yy)*np.ones(z.shape) # Define the color functions and the color numpy arrays, `C_z`, `C_x`, `C_y`, corresponding to each plane:
# Define the 3-tuples of coordinates to be displayed at hovering the mouse over the projections. # The first two coordinates give the position in the projection plane, whereas the third one is used # for assigning the color, just in the same way the coordinate z is used for the z-direction projection. # In[7]: proj_z=lambda x, y, z: z#projection in the z-direction colorsurfz=proj_z(x,y,z) proj_x=lambda x, y, z: x colorsurfx=proj_z(x,y,z) proj_y=lambda x, y, z: y colorsurfy=proj_z(x,y,z) textx=[['y: '+'{:0.5f}'.format(y[i][j])+'
z: '+'{:0.5f}'.format(z[i][j])+ '
x: '+'{:0.5f}'.format(x[i][j]) for j in range(z.shape[1])] for i in range(z.shape[0])] texty=[['x: '+'{:0.5f}'.format(x[i][j])+'
z: '+'{:0.5f}'.format(z[i][j]) + '
y: '+'{:0.5f}'.format(y[i][j]) for j in range(z.shape[1])] for i in range(z.shape[0])] tracex = go.Surface(z=list(z), x=list(x_offset), y=list(y), colorscale=colorscale, showlegend=False, showscale=False, surfacecolor=colorsurfx, text=textx, hoverinfo='text' ) tracey = go.Surface(z=list(z), x=list(x), y=list(y_offset), colorscale=colorscale, showlegend=False, showscale=False, surfacecolor=colorsurfy, text=texty, hoverinfo='text' ) tracez = go.Surface(z=list(z_offset), x=list(x), y=list(y), colorscale=colorscale, showlegend=False, showscale=False, surfacecolor=colorsurfx, text=textz, hoverinfo='text' ) data=[trace1, tracex, tracey, tracez] fig = go.Figure(data=data, layout=layout) py.iplot(fig) # In[2]: from IPython.display import display, HTML display(HTML('')) display(HTML('')) get_ipython().system(' pip install git+https://github.com/plotly/publisher.git --upgrade') import publisher publisher.publish( 'Plotly-project-3d-onto-a-plane.ipynb', 'python/2d-projection-of-3d-surface/', 'Projection of 3D Surface', 'How to project 3D Surface plots in 2D with Plotly.', title = '2D Projection of 3D surface | plotly', has_thumbnail='true', thumbnail='thumbnail/projection-3d.jpg', language='python', display_as='3d_charts', order=19, ipynb= '~notebook_demo/79') # In[ ]: