4141)
4242from spatialdata_plot .pl .utils import (
4343 _get_cs_contents ,
44+ _get_valid_cs ,
4445 _maybe_set_colors ,
4546 _mpl_ax_contains_elements ,
4647 _prepare_cmap_norm ,
@@ -318,6 +319,7 @@ def render_images(
318319 palette : str | list [str ] | None = None ,
319320 alpha : float = 1.0 ,
320321 quantiles_for_norm : tuple [float | None , float | None ] = (None , None ),
322+ scale : str | list [str ] | None = None ,
321323 ** kwargs : Any ,
322324 ) -> sd .SpatialData :
323325 """
@@ -340,6 +342,15 @@ def render_images(
340342 Alpha value for the shapes.
341343 quantiles_for_norm
342344 Tuple of (pmin, pmax) which will be used for quantile normalization.
345+ scale
346+ Influences the resolution of the rendering. Possibilities for setting this parameter:
347+ 1) None (default). The image is rasterized to fit the canvas size. For multiscale images, the best scale
348+ is selected before the rasterization step.
349+ 2) Name of one of the scales in the multiscale image to be rendered. This scale is rendered as it is
350+ (exception: a dpi is specified in `show()`. Then the image is rasterized to fit the canvas and dpi).
351+ 3) "full": render the full image without rasterization. In the case of a multiscale image, the scale
352+ with the highest resolution is selected. This can lead to long computing times for large images!
353+ 4) List that is matched to the list of elements (can contain `None`, scale names or "full").
343354 kwargs
344355 Additional arguments to be passed to cmap and norm.
345356
@@ -383,6 +394,7 @@ def render_images(
383394 palette = palette ,
384395 alpha = alpha ,
385396 quantiles_for_norm = quantiles_for_norm ,
397+ scale = scale ,
386398 )
387399
388400 return sdata
@@ -401,6 +413,7 @@ def render_labels(
401413 na_color : str | tuple [float , ...] | None = (0.0 , 0.0 , 0.0 , 0.0 ),
402414 outline_alpha : float = 1.0 ,
403415 fill_alpha : float = 0.3 ,
416+ scale : str | list [str ] | None = None ,
404417 ** kwargs : Any ,
405418 ) -> sd .SpatialData :
406419 """
@@ -433,6 +446,15 @@ def render_labels(
433446 Color to be used for NAs values, if present.
434447 alpha
435448 Alpha value for the labels.
449+ scale
450+ Influences the resolution of the rendering. Possibilities for setting this parameter:
451+ 1) None (default). The image is rasterized to fit the canvas size. For multiscale images, the best scale
452+ is selected before the rasterization step.
453+ 2) Name of one of the scales in the multiscale image to be rendered. This scale is rendered as it is
454+ (exception: a dpi is specified in `show()`. Then the image is rasterized to fit the canvas and dpi).
455+ 3) "full": render the full image without rasterization. In the case of a multiscale image, the scale
456+ with the highest resolution is selected. This can lead to long computing times for large images!
457+ 4) List that is matched to the list of elements (can contain `None`, scale names or "full").
436458 kwargs
437459 Additional arguments to be passed to cmap and norm.
438460
@@ -470,6 +492,7 @@ def render_labels(
470492 outline_alpha = outline_alpha ,
471493 fill_alpha = fill_alpha ,
472494 transfunc = kwargs .get ("transfunc" , None ),
495+ scale = scale ,
473496 )
474497
475498 return sdata
@@ -502,15 +525,22 @@ def show(
502525
503526 Parameters
504527 ----------
528+ coordinate_systems :
529+ Name(s) of the coordinate system(s) to be plotted. If None, all coordinate systems are plotted.
530+ If a coordinate system doesn't contain any relevant elements (as specified in the render_* calls),
531+ it is automatically not plotted.
532+ figsize :
533+ Size of the figure (width, height) in inches. The size of the actual canvas may deviate from this,
534+ depending on the dpi! In matplotlib, the actual figure size (in pixels) is dpi * figsize.
535+ If None, the default of matlotlib is used (6.4, 4.8)
536+ dpi :
537+ Resolution of the plot in dots per inch (as in matplotlib).
538+ If None, the default of matplotlib is used (100.0).
505539 ax :
506540 Matplotlib axes object to plot on. If None, a new figure is created.
507541 Works only if there is one image in the SpatialData object.
508542 ncols :
509543 Number of columns in the figure. Default is 4.
510- width :
511- Width of each subplot. Default is 4.
512- height :
513- Height of each subplot. Default is 3.
514544
515545 Returns
516546 -------
@@ -576,6 +606,42 @@ def show(
576606 if cs not in sdata .coordinate_systems :
577607 raise ValueError (f"Unknown coordinate system '{ cs } ', valid choices are: { sdata .coordinate_systems } " )
578608
609+ # Check if user specified only certain elements to be plotted
610+ cs_contents = _get_cs_contents (sdata )
611+ elements_to_be_rendered = []
612+ for cmd , params in render_cmds .items ():
613+ if cmd == "render_images" and cs_contents .query (f"cs == '{ cs } '" )["has_images" ][0 ]: # noqa: SIM114
614+ if params .elements is not None :
615+ elements_to_be_rendered += (
616+ [params .elements ] if isinstance (params .elements , str ) else params .elements
617+ )
618+ elif cmd == "render_shapes" and cs_contents .query (f"cs == '{ cs } '" )["has_shapes" ][0 ]: # noqa: SIM114
619+ if params .elements is not None :
620+ elements_to_be_rendered += (
621+ [params .elements ] if isinstance (params .elements , str ) else params .elements
622+ )
623+ elif cmd == "render_points" and cs_contents .query (f"cs == '{ cs } '" )["has_points" ][0 ]: # noqa: SIM114
624+ if params .elements is not None :
625+ elements_to_be_rendered += (
626+ [params .elements ] if isinstance (params .elements , str ) else params .elements
627+ )
628+ elif cmd == "render_labels" and cs_contents .query (f"cs == '{ cs } '" )["has_labels" ][0 ]: # noqa: SIM102
629+ if params .elements is not None :
630+ elements_to_be_rendered += (
631+ [params .elements ] if isinstance (params .elements , str ) else params .elements
632+ )
633+
634+ # filter out cs without relevant elements
635+ coordinate_systems = _get_valid_cs (
636+ sdata = sdata ,
637+ coordinate_systems = coordinate_systems ,
638+ render_images = "render_images" in render_cmds ,
639+ render_labels = "render_labels" in render_cmds ,
640+ render_points = "render_points" in render_cmds ,
641+ render_shapes = "render_shapes" in render_cmds ,
642+ elements = elements_to_be_rendered ,
643+ )
644+
579645 # set up canvas
580646 fig_params , scalebar_params = _prepare_params_plot (
581647 num_panels = len (coordinate_systems ),
@@ -616,64 +682,70 @@ def show(
616682
617683 for cmd , params in render_cmds .items ():
618684 if cmd == "render_images" and has_images :
619- _render_images (
620- sdata = sdata ,
621- render_params = params ,
622- coordinate_system = cs ,
623- ax = ax ,
624- fig_params = fig_params ,
625- scalebar_params = scalebar_params ,
626- legend_params = legend_params ,
627- )
628685 wants_images = True
629686 wanted_images = params .elements if params .elements is not None else list (sdata .images .keys ())
630- wanted_elements .extend (
631- [
632- image
633- for image in wanted_images
634- if cs in set (get_transformation (sdata .images [image ], get_all = True ).keys ())
635- ]
636- )
687+ wanted_images_on_this_cs = [
688+ image
689+ for image in wanted_images
690+ if cs in set (get_transformation (sdata .images [image ], get_all = True ).keys ())
691+ ]
692+ wanted_elements .extend (wanted_images_on_this_cs )
693+ if len (wanted_images_on_this_cs ) > 0 :
694+ rasterize = (params .scale is None ) or (
695+ isinstance (params .scale , str )
696+ and params .scale != "full"
697+ and (dpi is not None or figsize is not None )
698+ )
699+ _render_images (
700+ sdata = sdata ,
701+ render_params = params ,
702+ coordinate_system = cs ,
703+ ax = ax ,
704+ fig_params = fig_params ,
705+ scalebar_params = scalebar_params ,
706+ legend_params = legend_params ,
707+ rasterize = rasterize ,
708+ )
637709
638710 elif cmd == "render_shapes" and has_shapes :
639- _render_shapes (
640- sdata = sdata ,
641- render_params = params ,
642- coordinate_system = cs ,
643- ax = ax ,
644- fig_params = fig_params ,
645- scalebar_params = scalebar_params ,
646- legend_params = legend_params ,
647- )
648711 wants_shapes = True
649712 wanted_shapes = params .elements if params .elements is not None else list (sdata .shapes .keys ())
650- wanted_elements .extend (
651- [
652- shape
653- for shape in wanted_shapes
654- if cs in set (get_transformation (sdata .shapes [shape ], get_all = True ).keys ())
655- ]
656- )
713+ wanted_shapes_on_this_cs = [
714+ shape
715+ for shape in wanted_shapes
716+ if cs in set (get_transformation (sdata .shapes [shape ], get_all = True ).keys ())
717+ ]
718+ wanted_elements .extend (wanted_shapes_on_this_cs )
719+ if len (wanted_shapes_on_this_cs ) > 0 :
720+ _render_shapes (
721+ sdata = sdata ,
722+ render_params = params ,
723+ coordinate_system = cs ,
724+ ax = ax ,
725+ fig_params = fig_params ,
726+ scalebar_params = scalebar_params ,
727+ legend_params = legend_params ,
728+ )
657729
658730 elif cmd == "render_points" and has_points :
659- _render_points (
660- sdata = sdata ,
661- render_params = params ,
662- coordinate_system = cs ,
663- ax = ax ,
664- fig_params = fig_params ,
665- scalebar_params = scalebar_params ,
666- legend_params = legend_params ,
667- )
668731 wants_points = True
669732 wanted_points = params .elements if params .elements is not None else list (sdata .points .keys ())
670- wanted_elements .extend (
671- [
672- point
673- for point in wanted_points
674- if cs in set (get_transformation (sdata .points [point ], get_all = True ).keys ())
675- ]
676- )
733+ wanted_points_on_this_cs = [
734+ point
735+ for point in wanted_points
736+ if cs in set (get_transformation (sdata .points [point ], get_all = True ).keys ())
737+ ]
738+ wanted_elements .extend (wanted_points_on_this_cs )
739+ if len (wanted_points_on_this_cs ) > 0 :
740+ _render_points (
741+ sdata = sdata ,
742+ render_params = params ,
743+ coordinate_system = cs ,
744+ ax = ax ,
745+ fig_params = fig_params ,
746+ scalebar_params = scalebar_params ,
747+ legend_params = legend_params ,
748+ )
677749
678750 elif cmd == "render_labels" and has_labels :
679751 if sdata .table is not None and isinstance (params .color , str ):
@@ -685,24 +757,30 @@ def show(
685757 key = params .color ,
686758 palette = params .palette ,
687759 )
688- _render_labels (
689- sdata = sdata ,
690- render_params = params ,
691- coordinate_system = cs ,
692- ax = ax ,
693- fig_params = fig_params ,
694- scalebar_params = scalebar_params ,
695- legend_params = legend_params ,
696- )
697760 wants_labels = True
698761 wanted_labels = params .elements if params .elements is not None else list (sdata .labels .keys ())
699- wanted_elements .extend (
700- [
701- label
702- for label in wanted_labels
703- if cs in set (get_transformation (sdata .labels [label ], get_all = True ).keys ())
704- ]
705- )
762+ wanted_labels_on_this_cs = [
763+ label
764+ for label in wanted_labels
765+ if cs in set (get_transformation (sdata .labels [label ], get_all = True ).keys ())
766+ ]
767+ wanted_elements .extend (wanted_labels_on_this_cs )
768+ if len (wanted_labels_on_this_cs ) > 0 :
769+ rasterize = (params .scale is None ) or (
770+ isinstance (params .scale , str )
771+ and params .scale != "full"
772+ and (dpi is not None or figsize is not None )
773+ )
774+ _render_labels (
775+ sdata = sdata ,
776+ render_params = params ,
777+ coordinate_system = cs ,
778+ ax = ax ,
779+ fig_params = fig_params ,
780+ scalebar_params = scalebar_params ,
781+ legend_params = legend_params ,
782+ rasterize = rasterize ,
783+ )
706784
707785 if title is None :
708786 t = cs
0 commit comments