Skip to content

Commit 8b10297

Browse files
davidbrochartmartinRenou
authored andcommitted
Add 3D plot example
1 parent 657333e commit 8b10297

File tree

2 files changed

+167
-0
lines changed

2 files changed

+167
-0
lines changed

environment.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ dependencies:
55
- branca
66
- ipycanvas=0.7.0
77
- ipyevents
8+
- numpy
9+
- matplotlib

examples/plot3d.ipynb

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"import matplotlib.pyplot as plt\n",
10+
"from mpl_toolkits.mplot3d import Axes3D, proj3d\n",
11+
"import numpy as np\n",
12+
"from ipycanvas import Canvas, hold_canvas\n",
13+
"from ipywidgets import FloatSlider, Output\n",
14+
"from math import pi"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": null,
20+
"metadata": {},
21+
"outputs": [],
22+
"source": [
23+
"out = Output(layout={'border': '1px solid black'})"
24+
]
25+
},
26+
{
27+
"cell_type": "code",
28+
"execution_count": null,
29+
"metadata": {},
30+
"outputs": [],
31+
"source": [
32+
"class Plot3d(Canvas):\n",
33+
" def __init__(self):\n",
34+
" super(Plot3d, self).__init__(size=(500, 500))\n",
35+
" \n",
36+
" self.width = 500\n",
37+
" self.height = 500\n",
38+
" \n",
39+
" plt.ioff()\n",
40+
" fig = plt.figure()\n",
41+
" self.ax = Axes3D(fig)\n",
42+
"\n",
43+
" self.dragging = False\n",
44+
" self.n = 200\n",
45+
" self.x = np.random.rand(self.n)\n",
46+
" self.y = np.random.rand(self.n)\n",
47+
" self.z = np.random.rand(self.n)\n",
48+
" \n",
49+
" self.zoom = 4\n",
50+
" self.dx = 0\n",
51+
" self.dy = 0\n",
52+
" self.ax.view_init(elev=self.dx, azim=self.dy)\n",
53+
" self.x2, self.y2, _ = proj3d.proj_transform(self.x, self.y, self.z, self.ax.get_proj())\n",
54+
" self.draw()\n",
55+
" \n",
56+
" self.on_mouse_down(self.mouse_down_handler)\n",
57+
" self.on_mouse_move(self.mouse_move_handler)\n",
58+
" self.on_mouse_up(self.mouse_up_handler)\n",
59+
" self.on_mouse_out(self.mouse_out_handler)\n",
60+
"\n",
61+
" #@out.capture()\n",
62+
" def draw(self):\n",
63+
" x = self.x2 * self.width * self.zoom + self.width / 2\n",
64+
" y = self.y2 * self.width * self.zoom + self.height / 2\n",
65+
" with hold_canvas(self):\n",
66+
" self.clear()\n",
67+
" self.save()\n",
68+
" for i in range(self.n):\n",
69+
" self.fill_arc(x[i], y[i], self.zoom, 0, 2*pi)\n",
70+
" self.stroke_arc(x[i], y[i], self.zoom, 0, 2*pi)\n",
71+
" self.restore()\n",
72+
"\n",
73+
" def mouse_down_handler(self, pixel_x, pixel_y):\n",
74+
" self.dragging = True\n",
75+
" self.x_mouse = pixel_x\n",
76+
" self.y_mouse = pixel_y\n",
77+
"\n",
78+
" def mouse_move_handler(self, pixel_x, pixel_y):\n",
79+
" if self.dragging:\n",
80+
" self.dx_new = self.dx + pixel_x - self.x_mouse\n",
81+
" self.dy_new = self.dy + pixel_y - self.y_mouse\n",
82+
" self.ax.view_init(elev=self.dy_new, azim=self.dx_new)\n",
83+
" self.x2, self.y2, _ = proj3d.proj_transform(self.x, self.y, self.z, self.ax.get_proj())\n",
84+
" self.draw()\n",
85+
" \n",
86+
" def mouse_up_handler(self, pixel_x, pixel_y):\n",
87+
" if self.dragging:\n",
88+
" self.dragging = False\n",
89+
" self.dx = self.dx_new\n",
90+
" self.dy = self.dy_new\n",
91+
" \n",
92+
" def mouse_out_handler(self, pixel_x, pixel_y):\n",
93+
" if self.dragging:\n",
94+
" self.dragging = False\n",
95+
" self.dx = self.dx_new\n",
96+
" self.dy = self.dy_new"
97+
]
98+
},
99+
{
100+
"cell_type": "code",
101+
"execution_count": null,
102+
"metadata": {
103+
"scrolled": false
104+
},
105+
"outputs": [],
106+
"source": [
107+
"p = Plot3d()\n",
108+
"p"
109+
]
110+
},
111+
{
112+
"cell_type": "code",
113+
"execution_count": null,
114+
"metadata": {},
115+
"outputs": [],
116+
"source": [
117+
"slider = FloatSlider(description='Zoom:', value=p.zoom, min=1, max=10)\n",
118+
"\n",
119+
"def on_slider_change(change):\n",
120+
" p.zoom = slider.value\n",
121+
" p.draw()\n",
122+
"\n",
123+
"slider.observe(on_slider_change, 'value')\n",
124+
"slider"
125+
]
126+
},
127+
{
128+
"cell_type": "markdown",
129+
"metadata": {},
130+
"source": [
131+
"## Drag the figure with the mouse to rotate, use the slider to zoom"
132+
]
133+
},
134+
{
135+
"cell_type": "code",
136+
"execution_count": null,
137+
"metadata": {},
138+
"outputs": [],
139+
"source": [
140+
"out"
141+
]
142+
}
143+
],
144+
"metadata": {
145+
"kernelspec": {
146+
"display_name": "Python 3",
147+
"language": "python",
148+
"name": "python3"
149+
},
150+
"language_info": {
151+
"codemirror_mode": {
152+
"name": "ipython",
153+
"version": 3
154+
},
155+
"file_extension": ".py",
156+
"mimetype": "text/x-python",
157+
"name": "python",
158+
"nbconvert_exporter": "python",
159+
"pygments_lexer": "ipython3",
160+
"version": "3.8.5"
161+
}
162+
},
163+
"nbformat": 4,
164+
"nbformat_minor": 2
165+
}

0 commit comments

Comments
 (0)