Skip to content

Commit 4c737d8

Browse files
committed
docs
1 parent 049a382 commit 4c737d8

38 files changed

+6725
-3852
lines changed

.github/workflows/docs.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ jobs:
2929

3030
- name: Install dependencies
3131
run: |
32-
pip install mkdocs mkdocs-material mkdocstrings mkdocstrings-python
33-
pip install -e .
32+
pip install -e ".[all]"
3433
3534
- name: Build docs
3635
run: mkdocs build

docs/gallery/3d.ipynb

Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
{
2+
"nbformat": 4,
3+
"nbformat_minor": 5,
4+
"metadata": {
5+
"kernelspec": {
6+
"display_name": "Python 3",
7+
"language": "python",
8+
"name": "python3"
9+
},
10+
"language_info": {
11+
"name": "python",
12+
"version": "3.12.0"
13+
}
14+
},
15+
"cells": [
16+
{
17+
"cell_type": "markdown",
18+
"metadata": {},
19+
"source": [
20+
"# 3D Visualizations\n",
21+
"\n",
22+
"ggplotly provides geoms for creating interactive 3D plots powered by Plotly's WebGL renderer.\n",
23+
"\n",
24+
"## 3D Scatter Plots\n",
25+
"\n",
26+
"### Basic 3D Scatter"
27+
]
28+
},
29+
{
30+
"cell_type": "code",
31+
"execution_count": null,
32+
"metadata": {},
33+
"outputs": [],
34+
"source": [
35+
"import numpy as np\n",
36+
"import pandas as pd\n",
37+
"from ggplotly import *\n",
38+
"\n",
39+
"df = pd.DataFrame({\n",
40+
" 'x': np.random.randn(200),\n",
41+
" 'y': np.random.randn(200),\n",
42+
" 'z': np.random.randn(200)\n",
43+
"})\n",
44+
"\n",
45+
"ggplot(df, aes(x='x', y='y', z='z')) + geom_point_3d()"
46+
]
47+
},
48+
{
49+
"cell_type": "markdown",
50+
"metadata": {},
51+
"source": [
52+
"### Colored by Group"
53+
]
54+
},
55+
{
56+
"cell_type": "code",
57+
"execution_count": null,
58+
"metadata": {},
59+
"outputs": [],
60+
"source": [
61+
"df = pd.DataFrame({\n",
62+
" 'x': np.random.randn(200),\n",
63+
" 'y': np.random.randn(200),\n",
64+
" 'z': np.random.randn(200),\n",
65+
" 'group': np.random.choice(['A', 'B', 'C'], 200)\n",
66+
"})\n",
67+
"\n",
68+
"ggplot(df, aes(x='x', y='y', z='z', color='group')) + geom_point_3d(size=6)"
69+
]
70+
},
71+
{
72+
"cell_type": "markdown",
73+
"metadata": {},
74+
"source": [
75+
"### Colored by Continuous Variable"
76+
]
77+
},
78+
{
79+
"cell_type": "code",
80+
"execution_count": null,
81+
"metadata": {},
82+
"outputs": [],
83+
"source": [
84+
"df = pd.DataFrame({\n",
85+
" 'x': np.random.randn(200),\n",
86+
" 'y': np.random.randn(200),\n",
87+
" 'z': np.random.randn(200),\n",
88+
" 'value': np.random.rand(200) * 100\n",
89+
"})\n",
90+
"\n",
91+
"(ggplot(df, aes(x='x', y='y', z='z', color='value'))\n",
92+
" + geom_point_3d(size=5)\n",
93+
" + scale_color_gradient(low='blue', high='red'))"
94+
]
95+
},
96+
{
97+
"cell_type": "markdown",
98+
"metadata": {},
99+
"source": [
100+
"## 3D Surfaces\n",
101+
"\n",
102+
"### Creating Surface Data\n",
103+
"\n",
104+
"Surfaces require gridded data. Here's a helper function:"
105+
]
106+
},
107+
{
108+
"cell_type": "code",
109+
"execution_count": null,
110+
"metadata": {},
111+
"outputs": [],
112+
"source": [
113+
"def make_surface(func, x_range=(-5, 5), y_range=(-5, 5), resolution=50):\n",
114+
" \"\"\"Generate surface data from a function z = f(x, y).\"\"\"\n",
115+
" x = np.linspace(x_range[0], x_range[1], resolution)\n",
116+
" y = np.linspace(y_range[0], y_range[1], resolution)\n",
117+
" X, Y = np.meshgrid(x, y)\n",
118+
" Z = func(X, Y)\n",
119+
" return pd.DataFrame({\n",
120+
" 'x': X.flatten(),\n",
121+
" 'y': Y.flatten(),\n",
122+
" 'z': Z.flatten()\n",
123+
" })"
124+
]
125+
},
126+
{
127+
"cell_type": "markdown",
128+
"metadata": {},
129+
"source": [
130+
"### Paraboloid"
131+
]
132+
},
133+
{
134+
"cell_type": "code",
135+
"execution_count": null,
136+
"metadata": {},
137+
"outputs": [],
138+
"source": [
139+
"df = make_surface(lambda x, y: x**2 + y**2)\n",
140+
"ggplot(df, aes(x='x', y='y', z='z')) + geom_surface(colorscale='Viridis')"
141+
]
142+
},
143+
{
144+
"cell_type": "markdown",
145+
"metadata": {},
146+
"source": [
147+
"### Saddle Surface (Hyperbolic Paraboloid)"
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": null,
153+
"metadata": {},
154+
"outputs": [],
155+
"source": [
156+
"df = make_surface(lambda x, y: x**2 - y**2)\n",
157+
"\n",
158+
"(ggplot(df, aes(x='x', y='y', z='z'))\n",
159+
" + geom_surface(colorscale='RdBu')\n",
160+
" + labs(title='Saddle Surface'))"
161+
]
162+
},
163+
{
164+
"cell_type": "markdown",
165+
"metadata": {},
166+
"source": [
167+
"### Sinc Function (2D)"
168+
]
169+
},
170+
{
171+
"cell_type": "code",
172+
"execution_count": null,
173+
"metadata": {},
174+
"outputs": [],
175+
"source": [
176+
"def sinc_2d(x, y):\n",
177+
" r = np.sqrt(x**2 + y**2)\n",
178+
" return np.where(r == 0, 1, np.sin(r) / r)\n",
179+
"\n",
180+
"df = make_surface(sinc_2d, x_range=(-10, 10), y_range=(-10, 10), resolution=80)\n",
181+
"\n",
182+
"(ggplot(df, aes(x='x', y='y', z='z'))\n",
183+
" + geom_surface(colorscale='Plasma')\n",
184+
" + labs(title='2D Sinc Function'))"
185+
]
186+
},
187+
{
188+
"cell_type": "markdown",
189+
"metadata": {},
190+
"source": [
191+
"### Trigonometric Surface"
192+
]
193+
},
194+
{
195+
"cell_type": "code",
196+
"execution_count": null,
197+
"metadata": {},
198+
"outputs": [],
199+
"source": [
200+
"df = make_surface(lambda x, y: np.sin(x) * np.cos(y))\n",
201+
"\n",
202+
"(ggplot(df, aes(x='x', y='y', z='z'))\n",
203+
" + geom_surface(colorscale='Viridis')\n",
204+
" + labs(title='sin(x) * cos(y)'))"
205+
]
206+
},
207+
{
208+
"cell_type": "markdown",
209+
"metadata": {},
210+
"source": [
211+
"### Surface Colorscales\n",
212+
"\n",
213+
"Available colorscales for `geom_surface`:\n",
214+
"\n",
215+
"- **Sequential**: `Viridis`, `Plasma`, `Inferno`, `Magma`, `Cividis`, `Blues`, `Greens`, `Reds`, `YlOrRd`, `YlGnBu`\n",
216+
"- **Diverging**: `RdBu`, `RdYlBu`, `RdYlGn`, `BrBG`, `PiYG`, `PRGn`, `Spectral`\n",
217+
"- **Other**: `Jet`, `Hot`, `Electric`, `Blackbody`, `Earth`, `Picnic`, `Portland`\n",
218+
"\n",
219+
"## Wireframe Plots\n",
220+
"\n",
221+
"Wireframes show the surface structure without solid fills:"
222+
]
223+
},
224+
{
225+
"cell_type": "code",
226+
"execution_count": null,
227+
"metadata": {},
228+
"outputs": [],
229+
"source": [
230+
"df = make_surface(lambda x, y: np.sin(x) * np.cos(y), resolution=30)\n",
231+
"\n",
232+
"(ggplot(df, aes(x='x', y='y', z='z'))\n",
233+
" + geom_wireframe(color='steelblue', linewidth=1)\n",
234+
" + labs(title='Wireframe Plot'))"
235+
]
236+
},
237+
{
238+
"cell_type": "markdown",
239+
"metadata": {},
240+
"source": [
241+
"### Wireframe Parameters\n",
242+
"\n",
243+
"| Parameter | Default | Description |\n",
244+
"|-----------|---------|-------------|\n",
245+
"| `color` | 'steelblue' | Line color |\n",
246+
"| `linewidth` | 1 | Line width |\n",
247+
"| `opacity` | 1.0 | Transparency (0-1) |\n",
248+
"\n",
249+
"## Combining 3D Geoms\n",
250+
"\n",
251+
"You can layer 3D geoms:"
252+
]
253+
},
254+
{
255+
"cell_type": "code",
256+
"execution_count": null,
257+
"metadata": {},
258+
"outputs": [],
259+
"source": [
260+
"# Surface with scatter points\n",
261+
"df_surface = make_surface(lambda x, y: np.sin(x) * np.cos(y))\n",
262+
"\n",
263+
"# Sample points on the surface\n",
264+
"sample_idx = np.random.choice(len(df_surface), 50, replace=False)\n",
265+
"df_points = df_surface.iloc[sample_idx].copy()\n",
266+
"df_points['z'] += 0.1 # Offset slightly above surface\n",
267+
"\n",
268+
"(ggplot(df_surface, aes(x='x', y='y', z='z'))\n",
269+
" + geom_surface(colorscale='Viridis', opacity=0.7)\n",
270+
" + geom_point_3d(data=df_points, color='red', size=5))"
271+
]
272+
},
273+
{
274+
"cell_type": "markdown",
275+
"metadata": {},
276+
"source": [
277+
"## Mathematical Visualizations\n",
278+
"\n",
279+
"### Gaussian (Bell Curve) in 3D"
280+
]
281+
},
282+
{
283+
"cell_type": "code",
284+
"execution_count": null,
285+
"metadata": {},
286+
"outputs": [],
287+
"source": [
288+
"def gaussian_2d(x, y, sigma=1):\n",
289+
" return np.exp(-(x**2 + y**2) / (2 * sigma**2))\n",
290+
"\n",
291+
"df = make_surface(gaussian_2d, x_range=(-3, 3), y_range=(-3, 3), resolution=60)\n",
292+
"\n",
293+
"(ggplot(df, aes(x='x', y='y', z='z'))\n",
294+
" + geom_surface(colorscale='Viridis')\n",
295+
" + labs(title='2D Gaussian Distribution'))"
296+
]
297+
},
298+
{
299+
"cell_type": "markdown",
300+
"metadata": {},
301+
"source": [
302+
"### Ripple Effect"
303+
]
304+
},
305+
{
306+
"cell_type": "code",
307+
"execution_count": null,
308+
"metadata": {},
309+
"outputs": [],
310+
"source": [
311+
"def ripple(x, y):\n",
312+
" r = np.sqrt(x**2 + y**2)\n",
313+
" return np.sin(3 * r) * np.exp(-0.3 * r)\n",
314+
"\n",
315+
"df = make_surface(ripple, x_range=(-5, 5), y_range=(-5, 5), resolution=80)\n",
316+
"\n",
317+
"(ggplot(df, aes(x='x', y='y', z='z'))\n",
318+
" + geom_surface(colorscale='RdBu')\n",
319+
" + labs(title='Ripple Effect'))"
320+
]
321+
},
322+
{
323+
"cell_type": "markdown",
324+
"metadata": {},
325+
"source": [
326+
"### Rosenbrock Function (Optimization Test)"
327+
]
328+
},
329+
{
330+
"cell_type": "code",
331+
"execution_count": null,
332+
"metadata": {},
333+
"outputs": [],
334+
"source": [
335+
"def rosenbrock(x, y, a=1, b=100):\n",
336+
" return (a - x)**2 + b * (y - x**2)**2\n",
337+
"\n",
338+
"df = make_surface(rosenbrock, x_range=(-2, 2), y_range=(-1, 3), resolution=60)\n",
339+
"\n",
340+
"(ggplot(df, aes(x='x', y='y', z='z'))\n",
341+
" + geom_surface(colorscale='Hot')\n",
342+
" + labs(title='Rosenbrock Function'))"
343+
]
344+
},
345+
{
346+
"cell_type": "markdown",
347+
"metadata": {},
348+
"source": [
349+
"## Interactivity\n",
350+
"\n",
351+
"All 3D plots support:\n",
352+
"\n",
353+
"- **Rotation**: Click and drag to rotate\n",
354+
"- **Zoom**: Scroll wheel or pinch\n",
355+
"- **Pan**: Shift + drag\n",
356+
"- **Reset**: Double-click\n",
357+
"\n",
358+
"The 3D camera position is automatically saved when you interact, so subsequent renders maintain your viewpoint."
359+
]
360+
}
361+
]
362+
}

0 commit comments

Comments
 (0)