import asyncio
import io
import os
from typing import Any
from .. import background_tasks, globals # pylint: disable=redefined-builtin
from ..element import Element
try:
if os.environ.get('MATPLOTLIB', 'true').lower() == 'true':
import matplotlib.pyplot as plt
globals.optional_features.add('matplotlib')
except ImportError:
pass
class Pyplot(Element):
def __init__(self, *, close: bool = True, **kwargs: Any) -> None:
"""Pyplot Context
Create a context to configure a `Matplotlib `_ plot.
:param close: whether the figure should be closed after exiting the context; set to `False` if you want to update it later (default: `True`)
:param kwargs: arguments like `figsize` which should be passed to `pyplot.figure `_
"""
if 'matplotlib' not in globals.optional_features:
raise ImportError('Matplotlib is not installed. Please run "pip install matplotlib".')
super().__init__('div')
self.close = close
self.fig = plt.figure(**kwargs)
self._convert_to_html()
if not self.client.shared:
background_tasks.create(self._auto_close(), name='auto-close plot figure')
def _convert_to_html(self) -> None:
with io.StringIO() as output:
self.fig.savefig(output, format='svg')
self._props['innerHTML'] = output.getvalue()
def __enter__(self):
plt.figure(self.fig)
return self
def __exit__(self, *_):
self._convert_to_html()
if self.close:
plt.close(self.fig)
self.update()
async def _auto_close(self) -> None:
while self.client.id in globals.clients:
await asyncio.sleep(1.0)
plt.close(self.fig)