1515from typing import (
1616 TYPE_CHECKING ,
1717 Any ,
18+ Callable ,
19+ Literal ,
1820 Optional ,
1921 ParamSpec ,
2022 Protocol ,
3436from .. import ui as _ui
3537from .._namespaces import ResolvedId
3638from ..types import ImgData
37- from ._try_render_plot import try_render_matplotlib , try_render_pil , try_render_plotnine
39+ from ._try_render_plot import (
40+ PlotSizeInfo ,
41+ try_render_matplotlib ,
42+ try_render_pil ,
43+ try_render_plotnine ,
44+ )
3845from .transformer import (
3946 TransformerMetadata ,
4047 ValueFn ,
@@ -139,9 +146,6 @@ async def PlotTransformer(
139146 height : Optional [float ] = None ,
140147 ** kwargs : object ,
141148) -> ImgData | None :
142- import matplotlib as mpl
143- import matplotlib .pyplot as plt
144-
145149 is_userfn_async = is_async_callable (_fn )
146150 name = _meta .name
147151 session = _meta .session
@@ -154,18 +158,25 @@ async def PlotTransformer(
154158 pixelratio : float = typing .cast (
155159 float , inputs [ResolvedId (".clientdata_pixelratio" )]()
156160 )
157- if width is None :
158- width = typing .cast (
159- float , inputs [ResolvedId (f".clientdata_output_{ name } _width" )]()
160- )
161- if height is None :
162- height = typing .cast (
163- float , inputs [ResolvedId (f".clientdata_output_{ name } _height" )]()
164- )
165161
166- mpl .rcParams ["figure.dpi" ] = ppi * pixelratio
167- mpl .rcParams ["figure.figsize" ] = [width / ppi , height / ppi ]
168- plt .close () # type: ignore
162+ # Do NOT call this unless you actually are going to respect the container dimension
163+ # you're asking for. It takes a reactive dependency. If the client hasn't reported
164+ # the requested dimension, you'll get a SilentException.
165+ def container_size (dimension : Literal ["width" , "height" ]) -> Callable [[], float ]:
166+ def container_size_fn () -> float :
167+ result = inputs [ResolvedId (f".clientdata_output_{ name } _{ dimension } " )]()
168+ return typing .cast (float , result )
169+
170+ return container_size_fn
171+
172+ plot_size_info = PlotSizeInfo (
173+ container_size_px_fn = (
174+ container_size ("width" ),
175+ container_size ("height" ),
176+ ),
177+ user_specified_size_px = (width , height ),
178+ pixelratio = pixelratio ,
179+ )
169180
170181 # Call the user function to get the plot object.
171182 x = await resolve_value_fn (_fn )
@@ -190,11 +201,8 @@ async def PlotTransformer(
190201 if "plotnine" in sys .modules :
191202 ok , result = try_render_plotnine (
192203 x ,
193- width ,
194- height ,
195- pixelratio ,
196- ppi ,
197- alt ,
204+ plot_size_info = plot_size_info ,
205+ alt = alt ,
198206 ** kwargs ,
199207 )
200208 if ok :
@@ -203,10 +211,7 @@ async def PlotTransformer(
203211 if "matplotlib" in sys .modules :
204212 ok , result = try_render_matplotlib (
205213 x ,
206- width ,
207- height ,
208- pixelratio = pixelratio ,
209- ppi = ppi ,
214+ plot_size_info = plot_size_info ,
210215 allow_global = not is_userfn_async ,
211216 alt = alt ,
212217 ** kwargs ,
@@ -217,11 +222,9 @@ async def PlotTransformer(
217222 if "PIL" in sys .modules :
218223 ok , result = try_render_pil (
219224 x ,
220- width ,
221- height ,
222- pixelratio ,
223- ppi ,
224- alt ,
225+ plot_size_info = plot_size_info ,
226+ ppi = ppi ,
227+ alt = alt ,
225228 ** kwargs ,
226229 )
227230 if ok :
0 commit comments