@@ -404,7 +404,7 @@ def _normalize_image(data: np.ndarray):
404404 "plasma" : "fire" , # warm sequential (dark→bright)
405405 "inferno" : "kb" , # dark→blue→white
406406 "magma" : "kbc" , # dark→blue→cyan sequential
407- "cividis" : "dimgray " , # accessible, low-chroma sequential
407+ "cividis" : "bgy " , # accessible, blue→green→yellow sequential
408408 "hot" : "fire" ,
409409 "afmhot" : "fire" ,
410410 "jet" : "rainbow4" ,
@@ -805,21 +805,58 @@ def disconnect(self, cid: int) -> None:
805805 # ------------------------------------------------------------------
806806 # View control
807807 # ------------------------------------------------------------------
808- def set_view (self , x0 : float | None = None , x1 : float | None = None ) -> None :
808+ def set_view (self ,
809+ x0 : float | None = None , x1 : float | None = None ,
810+ y0 : float | None = None , y1 : float | None = None ) -> None :
811+ """Set the viewport to a data-space rectangle.
812+
813+ Parameters
814+ ----------
815+ x0, x1 : float, optional
816+ Horizontal data-space range to show. If omitted the full
817+ x-extent is used for zoom calculation.
818+ y0, y1 : float, optional
819+ Vertical data-space range to show. If omitted the full
820+ y-extent is used for zoom calculation.
821+
822+ Translates the requested rectangle into the ``zoom`` / ``center_x``
823+ / ``center_y`` state values used by the 2-D JS renderer.
824+ """
809825 xarr = np .asarray (self ._state ["x_axis" ])
810- if len (xarr ) < 2 :
826+ yarr = np .asarray (self ._state ["y_axis" ])
827+ if len (xarr ) < 2 or len (yarr ) < 2 :
811828 return
829+
812830 xmin , xmax = float (xarr [0 ]), float (xarr [- 1 ])
813- span = xmax - xmin or 1.0
814- f0 = 0.0 if x0 is None else max (0.0 , min (1.0 , (float (x0 )- xmin )/ span ))
815- f1 = 1.0 if x1 is None else max (0.0 , min (1.0 , (float (x1 )- xmin )/ span ))
816- self ._state ["view_x0" ] = f0
817- self ._state ["view_x1" ] = f1
831+ ymin , ymax = float (yarr [0 ]), float (yarr [- 1 ])
832+ x_span = xmax - xmin or 1.0
833+ y_span = ymax - ymin or 1.0
834+
835+ zoom_candidates = []
836+
837+ if x0 is not None and x1 is not None :
838+ fx0 = max (0.0 , min (1.0 , (float (x0 ) - xmin ) / x_span ))
839+ fx1 = max (0.0 , min (1.0 , (float (x1 ) - xmin ) / x_span ))
840+ if fx1 > fx0 :
841+ self ._state ["center_x" ] = (fx0 + fx1 ) / 2.0
842+ zoom_candidates .append (1.0 / (fx1 - fx0 ))
843+
844+ if y0 is not None and y1 is not None :
845+ fy0 = max (0.0 , min (1.0 , (float (y0 ) - ymin ) / y_span ))
846+ fy1 = max (0.0 , min (1.0 , (float (y1 ) - ymin ) / y_span ))
847+ if fy1 > fy0 :
848+ self ._state ["center_y" ] = (fy0 + fy1 ) / 2.0
849+ zoom_candidates .append (1.0 / (fy1 - fy0 ))
850+
851+ if zoom_candidates :
852+ self ._state ["zoom" ] = min (zoom_candidates )
818853 self ._push ()
819854
820855 def reset_view (self ) -> None :
821- self ._state ["view_x0" ] = 0.0
822- self ._state ["view_x1" ] = 1.0
856+ """Reset pan and zoom to show the full image."""
857+ self ._state ["zoom" ] = 1.0
858+ self ._state ["center_x" ] = 0.5
859+ self ._state ["center_y" ] = 0.5
823860 self ._push ()
824861
825862 # ------------------------------------------------------------------
@@ -833,8 +870,8 @@ def add_circles(self, offsets, name=None, *, radius=5,
833870 linewidths = 1.5 , alpha = 0.3 ,
834871 hover_edgecolors = None , hover_facecolors = None ,
835872 labels = None , label = None ) -> "MarkerGroup" : # noqa: F821
836- # On 1-D panels the native type is "points" (radius maps to sizes).
837- return self ._add_marker ("points " , name , offsets = offsets , sizes = radius ,
873+ """Add circle markers at (x, y) positions in data coordinates."""
874+ return self ._add_marker ("circles " , name , offsets = offsets , radius = radius ,
838875 facecolors = facecolors , edgecolors = edgecolors ,
839876 linewidths = linewidths , alpha = alpha ,
840877 hover_edgecolors = hover_edgecolors ,
@@ -847,7 +884,7 @@ def add_points(self, offsets, name=None, *, sizes=5,
847884 hover_edgecolors = None , hover_facecolors = None ,
848885 labels = None , label = None ) -> "MarkerGroup" : # noqa: F821
849886 """Add point markers at (x, y) positions in data coordinates."""
850- return self ._add_marker ("points " , name , offsets = offsets , sizes = sizes ,
887+ return self ._add_marker ("circles " , name , offsets = offsets , radius = sizes ,
851888 edgecolors = color , facecolors = facecolors ,
852889 linewidths = linewidths , alpha = alpha ,
853890 hover_edgecolors = hover_edgecolors ,
@@ -965,6 +1002,12 @@ def list_markers(self) -> list:
9651002 out .append ({"type" : mtype , "name" : name , "n" : g ._count ()})
9661003 return out
9671004
1005+ def __repr__ (self ) -> str :
1006+ w = self ._state .get ("image_width" , "?" )
1007+ h = self ._state .get ("image_height" , "?" )
1008+ cmap = self ._state .get ("colormap_name" , "?" )
1009+ return f"Plot2D({ w } \u00d7 { h } , cmap={ cmap !r} )"
1010+
9681011
9691012# ---------------------------------------------------------------------------
9701013# PlotMesh (pcolormesh-style 2-D panel)
@@ -1323,6 +1366,11 @@ def update(self, x, y, z) -> None:
13231366 })
13241367 self ._push ()
13251368
1369+ def __repr__ (self ) -> str :
1370+ geom = self ._state .get ("geom_type" , "?" )
1371+ n = len (self ._state .get ("vertices" , []))
1372+ return f"Plot3D(geom={ geom !r} , n_vertices={ n } )"
1373+
13261374
13271375# ---------------------------------------------------------------------------
13281376# Plot1D
@@ -1779,6 +1827,11 @@ def list_markers(self) -> list:
17791827 out .append ({"type" : mtype , "name" : name , "n" : g ._count ()})
17801828 return out
17811829
1830+ def __repr__ (self ) -> str :
1831+ n = len (self ._state .get ("data" , []))
1832+ color = self ._state .get ("line_color" , "?" )
1833+ return f"Plot1D(n={ n } , color={ color !r} )"
1834+
17821835
17831836# ---------------------------------------------------------------------------
17841837# _bar_x_axis helper
0 commit comments