@@ -607,14 +607,33 @@ def center_scene(self, *, zoom: float = 1.0):
607607 if not len (self ._fpl_graphics_scene .children ) > 0 :
608608 return
609609
610- # scale all cameras associated with this controller
611- # else it looks wonky
612- for camera in self .controller .cameras :
613- camera .show_object (self ._fpl_graphics_scene )
610+ if self .parent .__class__ .__name__ .endswith ("Figure" ):
611+ # always use figure._subplots.ravel() in internal fastplotlib code
612+ # otherwise if we use `for subplot in figure`, this could conflict
613+ # with a user's iterator where they are doing `for subplot in figure` !!!
614+ for subplot in self .parent ._subplots .ravel ():
615+ # scale all cameras associated with this controller
616+ if subplot .camera in self .controller .cameras :
617+ # skip if the scene is empty
618+ if len (subplot ._fpl_graphics_scene .children ) < 1 :
619+ continue
620+
621+ # center the camera in the other subplot w.r.t. the scene in that other subplot!
622+ self ._auto_center_scene (
623+ subplot .camera , subplot ._fpl_graphics_scene , zoom
624+ )
625+ else :
626+ # just change for this plot area
627+ # this is probably a dock area
628+ self ._auto_center_scene (self .camera , self ._fpl_graphics_scene , zoom )
614629
615- # camera.show_object can cause the camera width and height to increase so apply a zoom to compensate
616- # probably because camera.show_object uses bounding sphere
617- camera .zoom = zoom
630+ def _auto_center_scene (
631+ self , camera : pygfx .PerspectiveCamera , scene : pygfx .Scene , zoom : float
632+ ):
633+ camera .show_object (scene )
634+ # camera.show_object can cause the camera width and height to increase so apply a zoom to compensate
635+ # probably because camera.show_object uses bounding sphere
636+ camera .zoom = zoom
618637
619638 def auto_scale (
620639 self ,
@@ -642,16 +661,43 @@ def auto_scale(
642661 self .center_scene ()
643662
644663 if maintain_aspect is None : # if not provided keep current setting
664+ # use the same maintain apsect for all other cameras that this controller manages
665+ # I think this make sense for most use cases, even when the other controllers are
666+ # only managing one or 2 axes
645667 maintain_aspect = self .camera .maintain_aspect
646668
647- # scale all cameras associated with this controller else it looks wonky
648- for camera in self .controller .cameras :
649- camera .maintain_aspect = maintain_aspect
669+ if self .parent .__class__ .__name__ .endswith ("Figure" ):
670+ # always use figure._subplots.ravel() in internal fastplotlib code
671+ # otherwise if we use `for subplot in figure`, this could conflict
672+ # with a user's iterator where they are doing `for subplot in figure` !!!
673+ for subplot in self .parent ._subplots .ravel ():
674+ # skip if the scene is empty
675+ if len (subplot ._fpl_graphics_scene .children ) < 1 :
676+ continue
650677
651- if len (self ._fpl_graphics_scene .children ) > 0 :
652- width , height , depth = np .ptp (
653- self ._fpl_graphics_scene .get_world_bounding_box (), axis = 0
678+ # scale the camera in the other subplot w.r.t. the scene in that other subplot!
679+ if subplot .camera in self .controller .cameras :
680+ camera = subplot .camera
681+ self ._auto_scale_scene (
682+ camera , subplot ._fpl_graphics_scene , zoom , maintain_aspect
683+ )
684+ else :
685+ # just change for this plot area, this is probably a dock area
686+ self ._auto_scale_scene (
687+ self .camera , self ._fpl_graphics_scene , zoom , maintain_aspect
654688 )
689+
690+ def _auto_scale_scene (
691+ self ,
692+ camera : pygfx .PerspectiveCamera ,
693+ scene : pygfx .Scene ,
694+ zoom : float ,
695+ maintain_aspect : bool ,
696+ ):
697+ camera .maintain_aspect = maintain_aspect
698+
699+ if len (scene .children ) > 0 :
700+ width , height , depth = np .ptp (scene .get_world_bounding_box (), axis = 0 )
655701 else :
656702 width , height , depth = (1 , 1 , 1 )
657703
@@ -661,12 +707,10 @@ def auto_scale(
661707 if height < 0.01 :
662708 height = 1
663709
664- # scale all cameras associated with this controller else it looks wonky
665- for camera in self .controller .cameras :
666- camera .width = width
667- camera .height = height
710+ camera .width = width
711+ camera .height = height
668712
669- camera .zoom = zoom
713+ camera .zoom = zoom
670714
671715 def remove_graphic (self , graphic : Graphic ):
672716 """
0 commit comments