Skip to content

Commit 00f8048

Browse files
committed
add back matplotlib example
1 parent 886e990 commit 00f8048

6 files changed

Lines changed: 158 additions & 24 deletions

File tree

docs/source/examples.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ Slow internet may cause inconsistent frame pacing 😅
108108
.. interactive-widget:: snake_game
109109

110110

111+
Matplotlib Plot
112+
---------------
113+
114+
.. literalinclude:: examples/matplotlib_plot.py
115+
116+
Pick the polynomial coefficients (seperate each coefficient by a space) 🔢:
117+
118+
.. interactive-widget:: matplotlib_plot
119+
120+
111121
Simple Dashboard
112122
----------------
113123

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from io import BytesIO
2+
3+
import matplotlib.pyplot as plt
4+
5+
import idom
6+
from idom.widgets.html import image
7+
8+
9+
@idom.element
10+
async def PolynomialPlot():
11+
coefficients, set_coefficients = idom.hooks.use_state([0])
12+
13+
x = [n for n in linspace(-1, 1, 50)]
14+
y = [polynomial(value, coefficients) for value in x]
15+
16+
return idom.html.div(
17+
plot(f"{len(coefficients)} Term Polynomial", x, y),
18+
ExpandableNumberInputs(coefficients, set_coefficients),
19+
)
20+
21+
22+
@idom.element
23+
async def ExpandableNumberInputs(values, set_values):
24+
inputs = []
25+
for i in range(len(values)):
26+
27+
def set_value_at_index(event, index=i):
28+
new_value = float(event["value"] or 0)
29+
set_values(values[:index] + [new_value] + values[index + 1 :])
30+
31+
inputs.append(poly_coef_input(i, set_value_at_index))
32+
33+
def add_input():
34+
set_values(values + [0])
35+
36+
def del_input():
37+
set_values(values[:-1])
38+
39+
return idom.html.div(
40+
idom.html.div(
41+
"add/remove term:",
42+
idom.html.button({"onClick": lambda event: add_input()}, "+"),
43+
idom.html.button({"onClick": lambda event: del_input()}, "-"),
44+
),
45+
inputs,
46+
)
47+
48+
49+
def plot(title, x, y):
50+
fig, axes = plt.subplots()
51+
axes.plot(x, y)
52+
axes.set_title(title)
53+
buffer = BytesIO()
54+
fig.savefig(buffer, format="png")
55+
plt.close(fig)
56+
return image("png", buffer.getvalue())
57+
58+
59+
def poly_coef_input(index, callback):
60+
return idom.html.div(
61+
{"style": {"margin-top": "5px"}},
62+
idom.html.label(
63+
"C",
64+
idom.html.sub(index),
65+
" × X",
66+
idom.html.sup(index),
67+
),
68+
idom.html.input(
69+
{
70+
"type": "number",
71+
"onChange": callback,
72+
},
73+
),
74+
)
75+
76+
77+
def polynomial(x, coefficients):
78+
return sum(c * (x ** i) for i, c in enumerate(coefficients))
79+
80+
81+
def linspace(start, stop, n):
82+
if n == 1:
83+
yield stop
84+
return
85+
h = (stop - start) / (n - 1)
86+
for i in range(n):
87+
yield start + h * i
88+
89+
90+
display(PolynomialPlot)

docs/source/examples/simple_dashboard.py

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,23 @@ async def RandomWalk():
1414
mu = idom.hooks.use_ref(0)
1515
sigma = idom.hooks.use_ref(1)
1616

17-
mu_inputs = number_inputs("Mean", mu.current, mu.set, (-1, 1, 0.01))
18-
sigma_inputs = number_inputs(
19-
"Standard Deviation", sigma.current, sigma.set, (0, 1, 0.01)
17+
return idom.html.div(
18+
RandomWalkGraph(mu, sigma),
19+
idom.html.style(
20+
"""
21+
.number-input-container {margin-bottom: 20px}
22+
.number-input-container input {width: 48%;float: left}
23+
.number-input-container input + input {margin-left: 4%}
24+
"""
25+
),
26+
NumberInput("Mean", mu.current, mu.set, (-1, 1, 0.01)),
27+
NumberInput("Standard Deviation", sigma.current, sigma.set, (0, 1, 0.01)),
2028
)
2129

22-
interval = use_interval(0.4)
30+
31+
@idom.element
32+
async def RandomWalkGraph(mu, sigma):
33+
interval = use_interval(0.5)
2334
data, set_data = idom.hooks.use_state([{"x": 0, "y": 0}] * 50)
2435

2536
@use_async_effect
@@ -32,35 +43,22 @@ async def animate():
3243
}
3344
set_data(data[1:] + [next_data_point])
3445

35-
style = idom.html.style(
36-
[
37-
"""
38-
.number-inputs {margin-bottom: 20px}
39-
.number-inputs input {width: 48%;float: left}
40-
.number-inputs input + input {margin-left: 4%}
41-
"""
42-
]
43-
)
46+
return VictoryLine({"data": data, "style": {"parent": {"width": "500px"}}})
4447

45-
return idom.html.div(
46-
VictoryLine({"data": data, "style": {"parent": {"width": "500px"}}}),
47-
style,
48-
mu_inputs,
49-
sigma_inputs,
50-
)
5148

49+
@idom.element
50+
async def NumberInput(label, value, set_value_callback, domain):
51+
minimum, maximum, step = domain
52+
attrs = {"min": minimum, "max": maximum, "step": step}
5253

53-
def number_inputs(label, value, callback, domain):
5454
value, set_value = idom.hooks.use_state(value)
5555

5656
def update_value(value):
5757
set_value(value)
58-
callback(value)
58+
set_value_callback(value)
5959

60-
minimum, maximum, step = domain
61-
attrs = {"min": minimum, "max": maximum, "step": step}
6260
return idom.html.fieldset(
63-
{"class": "number-inputs"},
61+
{"class": "number-input-container"},
6462
[idom.html.legend({"style": {"font-size": "medium"}}, label)],
6563
Input(update_value, "number", value, attributes=attrs, cast=float),
6664
Input(update_value, "range", value, attributes=attrs, cast=float),

scripts/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Scripts
2+
3+
All scripts should be run from the repository root.
File renamed without changes.

scripts/run_doc_example.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import sys
2+
from pathlib import Path
3+
4+
from idom.widgets.utils import hotswap
5+
from idom.server.sanic import PerClientStateServer
6+
7+
here = Path(__file__).parent
8+
examples_dir = here.parent / "docs" / "source" / "examples"
9+
sys.path.insert(0, str(examples_dir))
10+
11+
for file in examples_dir.iterdir():
12+
if not file.is_file() or not file.suffix == ".py" or file.stem.startswith("_"):
13+
continue
14+
15+
16+
if __name__ == "__main__":
17+
ex_name = sys.argv[1]
18+
example_file = examples_dir / (ex_name + ".py")
19+
20+
mount, element = hotswap()
21+
server = PerClientStateServer(element)
22+
23+
with example_file.open() as f:
24+
exec(
25+
f.read(),
26+
{
27+
"display": mount,
28+
"__file__": str(file),
29+
"__name__": f"widgets.{file.stem}",
30+
},
31+
)
32+
33+
server.run("127.0.0.1", 5000)

0 commit comments

Comments
 (0)