pyplot.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import asyncio
  2. import io
  3. import matplotlib.pyplot as plt
  4. from .. import background_tasks, globals
  5. from ..element import Element
  6. class Pyplot(Element):
  7. def __init__(self, *, close: bool = True, **kwargs) -> None:
  8. """Pyplot Context
  9. Create a context to configure a `Matplotlib <https://matplotlib.org/>`_ plot.
  10. :param close: whether the figure should be closed after exiting the context; set to `False` if you want to update it later (default: `True`)
  11. :param kwargs: arguments like `figsize` which should be passed to `pyplot.figure <https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.figure.html>`_
  12. """
  13. super().__init__('div')
  14. self.close = close
  15. self.fig = plt.figure(**kwargs)
  16. self._convert_to_html()
  17. if not self.client.shared:
  18. background_tasks.create(self._auto_close(), name='auto-close plot figure')
  19. def _convert_to_html(self) -> None:
  20. with io.StringIO() as output:
  21. self.fig.savefig(output, format='svg')
  22. self._props['innerHTML'] = output.getvalue()
  23. def __enter__(self):
  24. plt.figure(self.fig)
  25. return self
  26. def __exit__(self, *_):
  27. self._convert_to_html()
  28. if self.close:
  29. plt.close(self.fig)
  30. self.update()
  31. async def _auto_close(self) -> None:
  32. while self.client.id in globals.clients:
  33. await asyncio.sleep(1.0)
  34. plt.close(self.fig)