Skip to content

Commit 049a382

Browse files
committed
updated docs with more examples
1 parent ffcab63 commit 049a382

10 files changed

Lines changed: 2446 additions & 0 deletions

File tree

docs/gallery/3d.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# 3D Visualizations
2+
3+
ggplotly provides geoms for creating interactive 3D plots powered by Plotly's WebGL renderer.
4+
5+
## 3D Scatter Plots
6+
7+
### Basic 3D Scatter
8+
9+
```python
10+
import numpy as np
11+
import pandas as pd
12+
from ggplotly import *
13+
14+
df = pd.DataFrame({
15+
'x': np.random.randn(200),
16+
'y': np.random.randn(200),
17+
'z': np.random.randn(200)
18+
})
19+
20+
ggplot(df, aes(x='x', y='y', z='z')) + geom_point_3d()
21+
```
22+
23+
### Colored by Group
24+
25+
```python
26+
df = pd.DataFrame({
27+
'x': np.random.randn(200),
28+
'y': np.random.randn(200),
29+
'z': np.random.randn(200),
30+
'group': np.random.choice(['A', 'B', 'C'], 200)
31+
})
32+
33+
ggplot(df, aes(x='x', y='y', z='z', color='group')) + geom_point_3d(size=6)
34+
```
35+
36+
### Colored by Continuous Variable
37+
38+
```python
39+
df = pd.DataFrame({
40+
'x': np.random.randn(200),
41+
'y': np.random.randn(200),
42+
'z': np.random.randn(200),
43+
'value': np.random.rand(200) * 100
44+
})
45+
46+
(ggplot(df, aes(x='x', y='y', z='z', color='value'))
47+
+ geom_point_3d(size=5)
48+
+ scale_color_gradient(low='blue', high='red'))
49+
```
50+
51+
## 3D Surfaces
52+
53+
### Creating Surface Data
54+
55+
Surfaces require gridded data. Here's a helper function:
56+
57+
```python
58+
def make_surface(func, x_range=(-5, 5), y_range=(-5, 5), resolution=50):
59+
"""Generate surface data from a function z = f(x, y)."""
60+
x = np.linspace(x_range[0], x_range[1], resolution)
61+
y = np.linspace(y_range[0], y_range[1], resolution)
62+
X, Y = np.meshgrid(x, y)
63+
Z = func(X, Y)
64+
return pd.DataFrame({
65+
'x': X.flatten(),
66+
'y': Y.flatten(),
67+
'z': Z.flatten()
68+
})
69+
```
70+
71+
### Paraboloid
72+
73+
```python
74+
df = make_surface(lambda x, y: x**2 + y**2)
75+
ggplot(df, aes(x='x', y='y', z='z')) + geom_surface(colorscale='Viridis')
76+
```
77+
78+
### Saddle Surface (Hyperbolic Paraboloid)
79+
80+
```python
81+
df = make_surface(lambda x, y: x**2 - y**2)
82+
83+
(ggplot(df, aes(x='x', y='y', z='z'))
84+
+ geom_surface(colorscale='RdBu')
85+
+ labs(title='Saddle Surface'))
86+
```
87+
88+
### Sinc Function (2D)
89+
90+
```python
91+
def sinc_2d(x, y):
92+
r = np.sqrt(x**2 + y**2)
93+
return np.where(r == 0, 1, np.sin(r) / r)
94+
95+
df = make_surface(sinc_2d, x_range=(-10, 10), y_range=(-10, 10), resolution=80)
96+
97+
(ggplot(df, aes(x='x', y='y', z='z'))
98+
+ geom_surface(colorscale='Plasma')
99+
+ labs(title='2D Sinc Function'))
100+
```
101+
102+
### Trigonometric Surface
103+
104+
```python
105+
df = make_surface(lambda x, y: np.sin(x) * np.cos(y))
106+
107+
(ggplot(df, aes(x='x', y='y', z='z'))
108+
+ geom_surface(colorscale='Viridis')
109+
+ labs(title='sin(x) * cos(y)'))
110+
```
111+
112+
### Surface Colorscales
113+
114+
Available colorscales for `geom_surface`:
115+
116+
- **Sequential**: `Viridis`, `Plasma`, `Inferno`, `Magma`, `Cividis`, `Blues`, `Greens`, `Reds`, `YlOrRd`, `YlGnBu`
117+
- **Diverging**: `RdBu`, `RdYlBu`, `RdYlGn`, `BrBG`, `PiYG`, `PRGn`, `Spectral`
118+
- **Other**: `Jet`, `Hot`, `Electric`, `Blackbody`, `Earth`, `Picnic`, `Portland`
119+
120+
## Wireframe Plots
121+
122+
Wireframes show the surface structure without solid fills:
123+
124+
```python
125+
df = make_surface(lambda x, y: np.sin(x) * np.cos(y), resolution=30)
126+
127+
(ggplot(df, aes(x='x', y='y', z='z'))
128+
+ geom_wireframe(color='steelblue', linewidth=1)
129+
+ labs(title='Wireframe Plot'))
130+
```
131+
132+
### Wireframe Parameters
133+
134+
| Parameter | Default | Description |
135+
|-----------|---------|-------------|
136+
| `color` | 'steelblue' | Line color |
137+
| `linewidth` | 1 | Line width |
138+
| `opacity` | 1.0 | Transparency (0-1) |
139+
140+
## Combining 3D Geoms
141+
142+
You can layer 3D geoms:
143+
144+
```python
145+
# Surface with scatter points
146+
df_surface = make_surface(lambda x, y: np.sin(x) * np.cos(y))
147+
148+
# Sample points on the surface
149+
sample_idx = np.random.choice(len(df_surface), 50, replace=False)
150+
df_points = df_surface.iloc[sample_idx].copy()
151+
df_points['z'] += 0.1 # Offset slightly above surface
152+
153+
(ggplot(df_surface, aes(x='x', y='y', z='z'))
154+
+ geom_surface(colorscale='Viridis', opacity=0.7)
155+
+ geom_point_3d(data=df_points, color='red', size=5))
156+
```
157+
158+
## Mathematical Visualizations
159+
160+
### Gaussian (Bell Curve) in 3D
161+
162+
```python
163+
def gaussian_2d(x, y, sigma=1):
164+
return np.exp(-(x**2 + y**2) / (2 * sigma**2))
165+
166+
df = make_surface(gaussian_2d, x_range=(-3, 3), y_range=(-3, 3), resolution=60)
167+
168+
(ggplot(df, aes(x='x', y='y', z='z'))
169+
+ geom_surface(colorscale='Viridis')
170+
+ labs(title='2D Gaussian Distribution'))
171+
```
172+
173+
### Ripple Effect
174+
175+
```python
176+
def ripple(x, y):
177+
r = np.sqrt(x**2 + y**2)
178+
return np.sin(3 * r) * np.exp(-0.3 * r)
179+
180+
df = make_surface(ripple, x_range=(-5, 5), y_range=(-5, 5), resolution=80)
181+
182+
(ggplot(df, aes(x='x', y='y', z='z'))
183+
+ geom_surface(colorscale='RdBu')
184+
+ labs(title='Ripple Effect'))
185+
```
186+
187+
### Rosenbrock Function (Optimization Test)
188+
189+
```python
190+
def rosenbrock(x, y, a=1, b=100):
191+
return (a - x)**2 + b * (y - x**2)**2
192+
193+
df = make_surface(rosenbrock, x_range=(-2, 2), y_range=(-1, 3), resolution=60)
194+
195+
(ggplot(df, aes(x='x', y='y', z='z'))
196+
+ geom_surface(colorscale='Hot')
197+
+ labs(title='Rosenbrock Function'))
198+
```
199+
200+
## Interactivity
201+
202+
All 3D plots support:
203+
204+
- **Rotation**: Click and drag to rotate
205+
- **Zoom**: Scroll wheel or pinch
206+
- **Pan**: Shift + drag
207+
- **Reset**: Double-click
208+
209+
The 3D camera position is automatically saved when you interact, so subsequent renders maintain your viewpoint.

0 commit comments

Comments
 (0)