Spaces:
Running
Running
Easy Matplotlib output.
Browse files
examples/matplotlib_example.py
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# From https://matplotlib.org/stable/gallery/images_contours_and_fields/contour_corner_mask.html
|
2 |
+
import matplotlib.pyplot as plt
|
3 |
+
import numpy as np
|
4 |
+
from lynxkite.core.ops import op
|
5 |
+
|
6 |
+
|
7 |
+
@op("LynxKite Graph Analytics", "Matplotlib example", view="matplotlib")
|
8 |
+
def example():
|
9 |
+
# Data to plot.
|
10 |
+
x, y = np.meshgrid(np.arange(7), np.arange(10))
|
11 |
+
z = np.sin(0.5 * x) * np.cos(0.52 * y)
|
12 |
+
|
13 |
+
# Mask various z values.
|
14 |
+
mask = np.zeros_like(z, dtype=bool)
|
15 |
+
mask[2, 3:5] = True
|
16 |
+
mask[3:5, 4] = True
|
17 |
+
mask[7, 2] = True
|
18 |
+
mask[5, 0] = True
|
19 |
+
mask[0, 6] = True
|
20 |
+
z = np.ma.array(z, mask=mask)
|
21 |
+
print(z)
|
22 |
+
|
23 |
+
corner_masks = [False, True]
|
24 |
+
fig, axs = plt.subplots(ncols=2)
|
25 |
+
for ax, corner_mask in zip(axs, corner_masks):
|
26 |
+
cs = ax.contourf(x, y, z, corner_mask=corner_mask)
|
27 |
+
ax.contour(cs, colors="k")
|
28 |
+
ax.set_title(f"{corner_mask=}")
|
29 |
+
|
30 |
+
# Plot grid.
|
31 |
+
ax.grid(c="k", ls="-", alpha=0.3)
|
32 |
+
|
33 |
+
# Indicate masked points with red circles.
|
34 |
+
ax.plot(np.ma.array(x, mask=~mask), y, "ro")
|
examples/requirements.txt
CHANGED
@@ -1,2 +1,3 @@
|
|
1 |
# Example of a requirements.txt file. LynxKite will automatically install anything you put here.
|
2 |
faker
|
|
|
|
1 |
# Example of a requirements.txt file. LynxKite will automatically install anything you put here.
|
2 |
faker
|
3 |
+
matplotlib
|
lynxkite-core/src/lynxkite/core/ops.py
CHANGED
@@ -221,13 +221,17 @@ def op(env: str, name: str, *, view="basic", outputs=None, params=None, slow=Fal
|
|
221 |
_outputs = {name: Output(name=name, type=None) for name in outputs}
|
222 |
else:
|
223 |
_outputs = {"output": Output(name="output", type=None)} if view == "basic" else {}
|
|
|
|
|
|
|
|
|
224 |
op = Op(
|
225 |
func=func,
|
226 |
name=name,
|
227 |
params=_params,
|
228 |
inputs=inputs,
|
229 |
outputs=_outputs,
|
230 |
-
type=
|
231 |
)
|
232 |
CATALOGS.setdefault(env, {})
|
233 |
CATALOGS[env][name] = op
|
@@ -237,6 +241,23 @@ def op(env: str, name: str, *, view="basic", outputs=None, params=None, slow=Fal
|
|
237 |
return decorator
|
238 |
|
239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
def input_position(**kwargs):
|
241 |
"""Decorator for specifying unusual positions for the inputs."""
|
242 |
|
|
|
221 |
_outputs = {name: Output(name=name, type=None) for name in outputs}
|
222 |
else:
|
223 |
_outputs = {"output": Output(name="output", type=None)} if view == "basic" else {}
|
224 |
+
_view = view
|
225 |
+
if view == "matplotlib":
|
226 |
+
_view = "image"
|
227 |
+
func = matplotlib_to_image(func)
|
228 |
op = Op(
|
229 |
func=func,
|
230 |
name=name,
|
231 |
params=_params,
|
232 |
inputs=inputs,
|
233 |
outputs=_outputs,
|
234 |
+
type=_view,
|
235 |
)
|
236 |
CATALOGS.setdefault(env, {})
|
237 |
CATALOGS[env][name] = op
|
|
|
241 |
return decorator
|
242 |
|
243 |
|
244 |
+
def matplotlib_to_image(func):
|
245 |
+
import matplotlib.pyplot as plt
|
246 |
+
import base64
|
247 |
+
import io
|
248 |
+
|
249 |
+
@functools.wraps(func)
|
250 |
+
def wrapper(*args, **kwargs):
|
251 |
+
func(*args, **kwargs)
|
252 |
+
buf = io.BytesIO()
|
253 |
+
plt.savefig(buf, format="png")
|
254 |
+
buf.seek(0)
|
255 |
+
image_base64 = base64.b64encode(buf.read()).decode("utf-8")
|
256 |
+
return f"data:image/png;base64,{image_base64}"
|
257 |
+
|
258 |
+
return wrapper
|
259 |
+
|
260 |
+
|
261 |
def input_position(**kwargs):
|
262 |
"""Decorator for specifying unusual positions for the inputs."""
|
263 |
|