8000 matplotlib to canvas tag example · evolution99/pyscript@d464f4f · GitHub
[go: up one dir, main page]

Skip to content

Commit d464f4f

Browse files
committed
matplotlib to canvas tag example
1 parent 4a2057b commit d464f4f

File tree

2 files changed

+231
-0
lines changed

2 files changed

+231
-0
lines changed

pyscriptjs/examples/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,8 @@ <h2 class="text-2xl font-bold text-blue-600"><a href="./todo.html" target=”_bl
6868

6969
<h2 class="text-2xl font-bold text-blue-600"><a href="./webgl/raycaster/index.html" target=”_blank”>Webgl Icosahedron Example</a></h2>
7070
<p>Demo showing how a Simple Webgl scene would work in PyScript</code> tag</p>
71+
72+
<h2 class="text-2xl font-bold text-blue-600"><a href="./webgl/raycaster/index.html" target=”_blank”>Matplotlib to Canvas Tag</a></h2>
73+
<p>Demo showing a programmatically generated matplotlib graphic inserted into an HTML canvas tag</p>
7174
</body>
7275
</html>

pyscriptjs/examples/plot_display.html

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
<!DOCTYPE html>
2+
<html lang="en-US">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>py-script demos: matplotlib display</title>
7+
<!-- Styles //-->
8+
<link href="https://fonts.googleapis.com/css2?family=Red+Hat+Text:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
9+
<link rel="stylesheet" href="static/pyscript.css" />
10+
<style type="text/css">
11+
body {
12+
font-family: "Red Hat Text", sans-serif;
13+
font-size: 18px;
14+
font-weight: 400;
15+
line-height: 1.618;
16+
}
17+
18+
#app {
19+
margin: 1em auto;
20+
width: 1000px;
21+
}
22+
23+
.loading {
24+
display: inline-block;
25+
width: 100px;
26+
height: 100px;
27+
border: 3px solid rgba(255, 255, 255, 0.3);
28+
border-radius: 50%;
29+
border-top-color: black;
30+
animation: spin 1s ease-in-out infinite;
31+
}
32+
33+
.loading-container {
34+
margin: 5em 0 0;
35+
text-align: center;
36+
}
37+
38+
@keyframes spin {
39+
to {
40+
transform: rotate(360deg);
41+
}
42+
}
43+
44+
a {color: #43B029;}
45+
46+
ul#project_list {
47+
margin: 1em 0;
48+
}
49+
50+
ul#project_list li {
51+
list-style: disc;
52+
margin-left: 1.25em;
53+
}
54+
55+
#upload_form, #entry_form {
56+
border-left: 3px solid #777;
57+
display: none;
58+
margin: 1.618em 0;
59+
padding-left: 1em;
60+
}
61+
62+
legend {
63+
display: block;
64+
font-size: 1.25em;
65+
margin: 0.5em 0;
66+
}
67+
68+
input[type=submit], button {
69+
background: #43B029;
70+
border-radius: 3px;
71+
color: white;
72+
padding: 0.35em 1.25em;
73+
}
74+
75+
label {
76+
display: block;
77+
}
78+
79+
textarea {
80+
border: 1px solid #777;
81+
padding: 0.75em;
82+
width: 40em;
83+
height: 10em;
84+
}
85+
86+
table {
87+
border-collapse: collapse;
88+
margin: 1em 0;
89+
}
90+
91+
th, td {
92+
border: 1px solid #777;
93+
padding: 0.35em 0.75em;
94+
}
95+
96+
th {
97+
background: #eee;
98+
font-weight: normal;
99+
}
100+
</style>
101+
102+
<!-- pyscript -->
103+
<script defer src="static/pyscript.js"></script>
104+
</head>
105+
<body>
106+
<div id="app">
107+
<!-- Header //-->
108+
<header>
109+
<h1>py-script Demos: matplotlib plot to <code>&lt;canvas&gt;</code.</h1>
110+
</header>
111+
112+
<main>
113+
<div class="loading-container">
114+
<div class="loading"></div>
115+
</div>
116+
117+
<!-- py-script and py-env -->
118+
119+
<py-env>
120+
- matplotlib
121+
</py-env>
122+
123+
<py-script>
124+
from js import (
125+
alert,
126+
document,
127+
Image
128+
)
129+
130+
import base64
131+
from io import BytesIO
132+
133+
import matplotlib.pyplot as plt
134+
135+
data = [
136+
["Day#", "Value"],
137+
[1, 0.4871],
138+
[2, 0.5105],
139+
[3, 0.5338],
140+
[4, 0.3105],
141+
[5, 0.3018],
142+
[6, 0.2931],
143+
[7, 0.2844],
144+
[8, 0.3453],
145+
[9, 0.4062],
146+
[10, 0.4671],
147+
[11, 0.4126],
148+
[12, 0.3581],
149+
[13, 0.4432],
150+
[14, 0.5283],
151+
[15, 0.6134],
152+
[16, 0.6985],
153+
[17, 0.6438],
154+
[18, 0.5892],
155+
[19, 0.5346],
156+
[20, 0.6585],
157+
[21, 0.6133],
158+
[22, 0.5681],
159+
[23, 0.5228],
160+
[24, 0.4776],
161+
]
162+
163+
# Extract plotting data and info from `data`
164+
165+
labels = data.pop(0)
166+
xlabel, ylabel = labels
167+
x = [row[0] for row in data]
168+
y = [row[1] for row in data]
169+
170+
# Create plt
171+
172+
fig, ax = plt.subplots(dpi=100, figsize=(8, 4)) # 800 x 400
173+
ax.bar(x, y)
174+
ax.set_xlabel("Day #")
175+
ax.set_ylabel("Value")
176+
177+
# Save plt to io buffer and encode data for <img> tag
178+
179+
buffer = BytesIO()
180+
fig.savefig(buffer, format="png")
181+
img_data = base64.b64encode(buffer.getbuffer()).decode("ascii")
182+
plt.close() # `pyplot` can cause memory leaks - explicitly close
183+
buffer.close()
184+
185+
# Remove "loading" animation
186+
187+
# Set up canvas and image
188+
189+
def draw(target_img):
190+
<!-- target_img = document.getElementsByTagName("img")[0] -->
191+
<!-- target_img.id = "canvas-plot" -->
192+
canvas = document.getElementById("canvas")
193+
ctx = canvas.getContext("2d")
194+
canvas.width = 820
195+
canvas.height = 420
196+
ctx.drawImage(target_img, 0, 0)
197+
loading = document.getElementsByClassName("loading-container")[0]
198+
loading.style.display = "none"
199+
200+
img = Image.new()
201+
img.style.width = "800px"
202+
img.style.height = "400px"
203+
img.style.display = "block"
204+
img.style.visibility = "visible"
205+
img.src = "data:image/png;base64," + img_data
206+
207+
await asyncio.sleep(0.5)
208+
209+
draw(img)
210+
211+
</py-script>
212+
213+
<!-- end py-script and py-env -->
214+
215+
<!-- Output -->
216+
217+
<div id="container">
218+
<canvas id="canvas" width="820" height="420"></canvas>
219+
<div id="dropbox"></div>
220+
</div>
221+
222+
223+
<!-- End output -->
224+
</main>
225+
</div>
226+
<!-- Scripts //-->
227+
</body>
228+
</html>

0 commit comments

Comments
 (0)
0