# Adding a shape to a 3D plot

**URL:** <https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441>\
**Category:** Plotly Fundamentals\
**Created:** [July 1, 2016, 3:30pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441 "2016-07-01T15:30:42Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![rshah](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/rshah/32/377_2.png) [@rshah](https://community.plotly.com/u/rshah)\
**Post date:** [July 1, 2016, 3:30pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/1 "2016-07-01T15:30:42Z")

</div>

Is it possible to add a shape to a 3D plot?  
I am trying to add a “floor” to my 3D plot. I tried using add\_trace with a shape, but not having any luck getting the shape to show up. Should this work? or is there a better approach. Basically, I want to add a little color to the z plane, so its clear which way is up and down in my plot. thanks

---

<div class="post-metadata">

**Author:** ![empet](https://avatars.discourse-cdn.com/v4/letter/e/977dab/32.png) [@empet](https://community.plotly.com/u/empet)\
**Post date:** [July 1, 2016, 10:25pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/2 "2016-07-01T22:25:50Z")

</div>

Shapes can be inserted only in 2D plots.  
But you can plot a colored z-plane, defining it as a surface:

```
import numpy as np 
import plotly.plotly as py
x=np.linspace(0,2, 50)
y=np.linspace(1,3, 50)
x,y=np.meshgrid(x,y)
z_level=1.0#plot a z-plane at height 1
z=z_level*np.ones(x.shape)  
single_color=[[0.0, 'rgb(200,200,200)'], [1.0, 'rgb(200,200,200)']] 
z_plane=dict(type='surface', x=x, y=y, z=z,
                     colorscale=single_color, showscale=False)
fig=dict(data=[z_plane])
py.iplot(fig)

```

![](https://us1.discourse-cdn.com/flex024/uploads/plot/original/1X/b404d130e9db2f62ae4b6a3e1e14ea3838323ebb.png)

---

<div class="post-metadata">

**Author:** ![luca](https://avatars.discourse-cdn.com/v4/letter/l/51bf81/32.png) [@luca](https://community.plotly.com/u/luca)\
**Post date:** [April 24, 2019, 2:53pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/3 "2019-04-24T14:53:56Z")

</div>

is this still impossible, or has this functionality been implemented in the past years?

---

<div class="post-metadata">

**Author:** ![NEGU93](https://avatars.discourse-cdn.com/v4/letter/n/ee59a6/32.png) [@NEGU93](https://community.plotly.com/u/NEGU93)\
**Post date:** [February 27, 2020, 2:27pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/4 "2020-02-27T14:27:17Z")

</div>

My case is similar… but it’s not a square shape. Is there any solution for this existent? My question was made in [stackoverflow](https://stackoverflow.com/questions/60432713/filled-3d-histogram-from-2d-histogram-with-plotly?noredirect=1)

---

<div class="post-metadata">

**Author:** ![empet](https://avatars.discourse-cdn.com/v4/letter/e/977dab/32.png) [@empet](https://community.plotly.com/u/empet)\
**Post date:** [February 27, 2020, 3:07pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/5 "2020-02-27T15:07:50Z")

</div>

@NEGU93  
I do not understand exactly your issue. What is wrong with your plot? The polygons are not filled in?!!  
It seems that the polygon is not closed.

The first and last value in the coordinate lists should coincide.

---

<div class="post-metadata">

**Author:** ![NEGU93](https://avatars.discourse-cdn.com/v4/letter/n/ee59a6/32.png) [@NEGU93](https://community.plotly.com/u/NEGU93)\
**Post date:** [February 28, 2020, 10:01am UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/6 "2020-02-28T10:01:22Z")

</div>

I tried then to “close” the figures using:

```auto
a1.append(a1[0])
a0.append(a0[0])

```

However the result stays the same.

**What is wrong:**  
The original code was [this](https://stackoverflow.com/questions/60398154/plotly-how-to-make-a-3d-stacked-histogram/60403270#60403270), I just wanted to fill the surfaces of the histograms drawn there with the command `surfaceaxis=0` and even though a fill was done, it get’s out of the line contours.  
Original image:

 ![CX7VF](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/b/bdc74c40a527b89e9891ef3fac00e4ab057595bc.png)  
Intent of filling the histograms:  
 ![M8u7r](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/f/f7d3afd2824bc9879e36b4f0bc183aaf40a6b1d6.png)

---

<div class="post-metadata">

**Author:** ![empet](https://avatars.discourse-cdn.com/v4/letter/e/977dab/32.png) [@empet](https://community.plotly.com/u/empet)\
**Post date:** [February 28, 2020, 3:01pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/7 "2020-02-28T15:01:49Z")

</div>

@NEGU93

To fill in your region plotly.js triangulates it by Delaunay triangles [https://en.wikipedia.org/wiki/Delaunay\_triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation).  
But the Delaunay triangulation is a triangulation of the convexhull of the given points (in your case, the points of coordinates (x[i], a1[i], a0[i]) . What is displayed is their convex hull. You needed more points in each region to get the right triangulation.

---

<div class="post-metadata">

**Author:** ![empet](https://avatars.discourse-cdn.com/v4/letter/e/977dab/32.png) [@empet](https://community.plotly.com/u/empet)\
**Post date:** [February 28, 2020, 9:53pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/8 "2020-02-28T21:53:06Z")

</div>

@NEGU93

Update: To avoid the drawback of the Delaunay triangulation, discussed above, I defined a function that triangulates each histogram bar, and now the histogram is an instance of `go.Mesh3d`:

```auto
import numpy as np
import pandas as pd
import plotly.graph_objects as go

def triangulate_histogtam(x, y, z):
   
    if len(x) != len(y) != len(z) :
        raise ValueError("The lists x, y, z, must have the same length")
    n = len(x)
    if n % 2 :
        raise ValueError("The length of lists x, y, z must be an even number") 
    pts3d = np.vstack((x, y, z)).T
    pts3dp = np.array([[x[2*k+1], y[2*k+1], 0] for k in range(1, n//2-1)])
    pts3d = np.vstack((pts3d, pts3dp))
    #triangulate the histogram bars:
    tri = [[0,1,2], [0,2,n]]
    for k, i in zip(list(range(n, n-3+n//2)), list(range(3, n-4, 2))):
        tri.extend([[k, i, i+1], [k, i+1, k+1]])
    tri.extend([[n-3+n//2, n-3, n-2], [n-3+n//2, n-2, n-1]])      
    return pts3d, np.array(tri)

# data
np.random.seed(123)
df = pd.DataFrame(np.random.normal(50, 5, size=(300, 4)), columns=list('ABCD'))

# plotly setup
fig = go.Figure()

# data binning and traces
bins = 10

bar_color = ['#e763fa', '#ab63fa', '#636efa', '#00cc96']
for m, col in enumerate(df.columns):
    a0=np.histogram(df[col], bins=bins, density=False)[0].tolist()
    a0=np.repeat(a0,2).tolist()
    a0.insert(0,0)
    a0.pop()
    a0[-1]=0
    a1=np.histogram(df[col], bins=bins-1, density=False)[1].tolist()
    a1=np.repeat(a1,2)
   
    verts, tri = triangulate_histogtam([m]*len(a0), a1, a0)
    x, y, z = verts.T
    I, J, K = tri.T
    fig.add_traces(go.Mesh3d(x=x, y=y, z=z, i=I, j=J, k=K, color=bar_color[m], opacity=0.7))
                   
fig.update_layout(width=700, height=700, scene_camera_eye_z=0.8)                                       

```

 ![histograms-as-mesh3d](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/5/58b80afd36098f627904e2f4f43de1c745a7b0e6.png)

---

<div class="post-metadata">

**Author:** ![NEGU93](https://avatars.discourse-cdn.com/v4/letter/n/ee59a6/32.png) [@NEGU93](https://community.plotly.com/u/NEGU93)\
**Post date:** [March 2, 2020, 3:51pm UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/9 "2020-03-02T15:51:33Z")

</div>

It works, maybe you can consider doing a PR.

---

<div class="post-metadata">

**Author:** ![mark377](https://avatars.discourse-cdn.com/v4/letter/m/ac8455/32.png) [@mark377](https://community.plotly.com/u/mark377)\
**Post date:** [June 12, 2022, 11:49am UTC](https://community.plotly.com/t/adding-a-shape-to-a-3d-plot/1441/10 "2022-06-12T11:49:58Z")

</div>

This is great, but is there a way to modify this example so that it would work for a regular 2d dataset instead of a histogram? I am looking to plot a simple list of dates and values as x, y in the same way?
