darabos commited on
Commit
dce04fe
·
1 Parent(s): 8fcb185

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=view,
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