diff --git a/tidy3d/components/base_sim/simulation.py b/tidy3d/components/base_sim/simulation.py index f6f0e8c903..38bf795f19 100644 --- a/tidy3d/components/base_sim/simulation.py +++ b/tidy3d/components/base_sim/simulation.py @@ -9,7 +9,7 @@ import pydantic.v1 as pd from tidy3d.components.base import cached_property, skip_if_fields_missing -from tidy3d.components.geometry.base import Box +from tidy3d.components.geometry.base import Box, Geometry from tidy3d.components.medium import Medium, MediumType3D from tidy3d.components.scene import Scene from tidy3d.components.structure import Structure @@ -251,6 +251,7 @@ def plot( hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, fill_structures: bool = True, + transpose: bool = False, **patch_kwargs, ) -> Ax: """Plot each of simulation's components on a plane defined by one nonzero x,y,z coordinate. @@ -275,6 +276,9 @@ def plot( The z range if plotting on xz or yz planes, y plane if plotting on xy plane. fill_structures : bool = True Whether to fill structures with color or just draw outlines. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. + Returns ------- matplotlib.axes._subplots.Axes @@ -282,25 +286,25 @@ def plot( """ hlim, vlim = Scene._get_plot_lims( - bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) ax = self.scene.plot_structures( - ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, fill=fill_structures + ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, fill=fill_structures, transpose=transpose ) - ax = self.plot_sources(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=source_alpha) - ax = self.plot_monitors(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=monitor_alpha) + ax = self.plot_sources(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=source_alpha, transpose=transpose) + ax = self.plot_monitors(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=monitor_alpha, transpose=transpose) ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) - ax = self.plot_boundaries(ax=ax, x=x, y=y, z=z) - ax = self.plot_symmetries(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + ax = self.plot_boundaries(ax=ax, x=x, y=y, z=z, transpose=transpose) + ax = self.plot_symmetries(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose) # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) - + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if NEEDED return ax @equal_aspect @@ -314,6 +318,7 @@ def plot_sources( vlim: Optional[tuple[float, float]] = None, alpha: Optional[float] = None, ax: Ax = None, + transpose: bool = False, ) -> Ax: """Plot each of simulation's sources on a plane defined by one nonzero x,y,z coordinate. @@ -333,6 +338,8 @@ def plot_sources( Opacity of the sources, If ``None`` uses Tidy3d default. ax : matplotlib.axes._subplots.Axes = None Matplotlib axes to plot on, if not specified, one is created. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. Returns ------- @@ -343,12 +350,13 @@ def plot_sources( for source in self.sources: ax = source.plot(x=x, y=y, z=z, alpha=alpha, ax=ax, sim_bounds=bounds) ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax @equal_aspect @@ -362,6 +370,7 @@ def plot_monitors( vlim: Optional[tuple[float, float]] = None, alpha: Optional[float] = None, ax: Ax = None, + transpose: bool = False, ) -> Ax: """Plot each of simulation's monitors on a plane defined by one nonzero x,y,z coordinate. @@ -381,6 +390,8 @@ def plot_monitors( Opacity of the sources, If ``None`` uses Tidy3d default. ax : matplotlib.axes._subplots.Axes = None Matplotlib axes to plot on, if not specified, one is created. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. Returns ------- @@ -389,14 +400,15 @@ def plot_monitors( """ bounds = self.bounds for monitor in self.monitors: - ax = monitor.plot(x=x, y=y, z=z, alpha=alpha, ax=ax, sim_bounds=bounds) + ax = monitor.plot(x=x, y=y, z=z, alpha=alpha, ax=ax, sim_bounds=bounds, transpose=transpose) ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax @equal_aspect @@ -409,6 +421,7 @@ def plot_symmetries( hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, ax: Ax = None, + transpose: bool = False, ) -> Ax: """Plot each of simulation's symmetries on a plane defined by one nonzero x,y,z coordinate. @@ -426,6 +439,8 @@ def plot_symmetries( The z range if plotting on xz or yz planes, y plane if plotting on xy plane. ax : matplotlib.axes._subplots.Axes = None Matplotlib axes to plot on, if not specified, one is created. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. Returns ------- @@ -442,12 +457,13 @@ def plot_symmetries( plot_params = self._make_symmetry_plot_params(sym_value=sym_value) ax = sym_box.plot(x=x, y=y, z=z, ax=ax, **plot_params.to_kwargs()) ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax def _make_symmetry_plot_params(self, sym_value: Symmetry) -> PlotParams: @@ -519,6 +535,7 @@ def plot_structures( hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, fill: bool = True, + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of simulation's structures on a plane defined by one nonzero x,y,z coordinate. @@ -545,11 +562,11 @@ def plot_structures( """ hlim_new, vlim_new = Scene._get_plot_lims( - bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) return self.scene.plot_structures( - x=x, y=y, z=z, ax=ax, hlim=hlim_new, vlim=vlim_new, fill=fill + x=x, y=y, z=z, ax=ax, hlim=hlim_new, vlim=vlim_new, fill=fill #, transpose=transpose CONTINUEHERE ) @equal_aspect @@ -566,6 +583,7 @@ def plot_structures_eps( ax: Ax = None, hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of simulation's structures on a plane defined by one nonzero x,y,z coordinate. The permittivity is plotted in grayscale based on its value at the specified frequency. @@ -603,7 +621,7 @@ def plot_structures_eps( """ hlim, vlim = Scene._get_plot_lims( - bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) return self.scene.plot_structures_eps( @@ -617,6 +635,7 @@ def plot_structures_eps( hlim=hlim, vlim=vlim, reverse=reverse, + # transpose=transpose CONTINUEHERE ) @equal_aspect @@ -632,6 +651,7 @@ def plot_structures_heat_conductivity( ax: Ax = None, hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + # transpose: bool, CONTINUEHERE ) -> Ax: """Plot each of simulation's structures on a plane defined by one nonzero x,y,z coordinate. The permittivity is plotted in grayscale based on its value at the specified frequency. @@ -669,7 +689,7 @@ def plot_structures_heat_conductivity( """ hlim, vlim = Scene._get_plot_lims( - bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) return self.scene.plot_structures_heat_conductivity( @@ -682,6 +702,7 @@ def plot_structures_heat_conductivity( hlim=hlim, vlim=vlim, reverse=reverse, + # transpose=transpose CONTINUEHERE ) @classmethod diff --git a/tidy3d/components/geometry/base.py b/tidy3d/components/geometry/base.py index 4e6e7d2b20..8ef4a11491 100644 --- a/tidy3d/components/geometry/base.py +++ b/tidy3d/components/geometry/base.py @@ -13,7 +13,7 @@ import xarray as xr try: - from matplotlib import patches + from matplotlib import patches, transforms except ImportError: pass @@ -485,6 +485,29 @@ def _update_from_bounds(self, bounds: tuple[float, float], axis: Axis) -> Geomet raise NotImplementedError( "'_update_from_bounds' is not compatible with this geometry class." ) + + @staticmethod + def transpose_axis_info( + ax: Ax = None, + swap_axis_labels: bool = False, + swap_axis_limits: bool = False, + ) -> None: + """Swaps matplotlib axis-labels and limits, but does not alter geometry (contents) of a plot.""" + if swap_axis_labels: + # Swap the axis labels? + xlabel_orig = ax.get_xlabel() + ylabel_orig = ax.get_ylabel() + ax.set_xlabel(ylabel_orig) + ax.set_ylabel(xlabel_orig) + if swap_axis_limits: + # Do we want to swap the graph boundaries/limits? + xlim_orig = ax.get_xlim() + ylim_orig = ax.get_ylim() + ax.set_xlim(ylim_orig) + ax.set_ylim(xlim_orig) + # Now recalculate automatic tick locations based on new limits: + ax.relim() + ax.autoscale_view() @equal_aspect @add_ax_if_none @@ -496,6 +519,7 @@ def plot( ax: Ax = None, plot_length_units: LengthUnit = None, viz_spec: VisualizationSpec = None, + transpose: bool = False, **patch_kwargs, ) -> Ax: """Plot geometry cross section at single (x,y,z) coordinate. @@ -514,6 +538,8 @@ def plot( Specify units to use for axis labels, tick labels, and the title. viz_spec : VisualizationSpec = None Plotting parameters associated with a medium to use instead of defaults. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. **patch_kwargs Optional keyword arguments passed to the matplotlib patch plotting of structure. For details on accepted values, refer to @@ -536,17 +562,27 @@ def plot( # for each intersection, plot the shape for shape in shapes_intersect: - ax = self.plot_shape(shape, plot_params=plot_params, ax=ax) + ax = self.plot_shape(shape, plot_params=plot_params, ax=ax, transpose=transpose) # clean up the axis display ax = self.add_ax_lims(axis=axis, ax=ax) ax.set_aspect("equal") # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title(ax=ax, x=x, y=y, z=z, plot_length_units=plot_length_units) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax - def plot_shape(self, shape: Shapely, plot_params: PlotParams, ax: Ax) -> Ax: - """Defines how a shape is plotted on a matplotlib axes.""" + def plot_shape( + self, + shape: Shapely, + plot_params: PlotParams, + ax: Ax, + transpose: bool = False, + ) -> Ax: + """ + Defines how a shape is plotted on a matplotlib axes. + If transpose==True, the horizontal and vertical coordinates are swapped. + """ if shape.geom_type in ( "MultiPoint", "MultiLineString", @@ -555,19 +591,39 @@ def plot_shape(self, shape: Shapely, plot_params: PlotParams, ax: Ax) -> Ax: ): for sub_shape in shape.geoms: ax = self.plot_shape(shape=sub_shape, plot_params=plot_params, ax=ax) - return ax _shape = Geometry.evaluate_inf_shape(shape) if _shape.geom_type == "LineString": xs, ys = zip(*_shape.coords) - ax.plot(xs, ys, color=plot_params.facecolor, linewidth=plot_params.linewidth) + if transpose: + ax.plot(ys, xs, color=plot_params.facecolor, linewidth=plot_params.linewidth) + else: + ax.plot(xs, ys, color=plot_params.facecolor, linewidth=plot_params.linewidth) elif _shape.geom_type == "Point": - ax.scatter(shape.x, shape.y, color=plot_params.facecolor) + if transpose: + ax.scatter(shape.y, shape.x, color=plot_params.facecolor) + else: + ax.scatter(shape.x, shape.y, color=plot_params.facecolor) else: patch = polygon_patch(_shape, **plot_params.to_kwargs()) + if transpose: + # Define a transformation which swaps horizal<-->vertical coordinates. + transpose_xy = transforms.Affine2D() + transpose_xy.set_matrix( + np.array( + [[0, 1, 0], # Swap the X and Y axes. + [1, 0, 0], + [0, 0, 1]] + ) + ) + # Apply this transformation to the coordinates of the patch. + patch.set_transform(transpose_xy + ax.transData) ax.add_artist(patch) + # If transpose==True, I also update the axis labels (if any). In practice, this + # seems to have no effect (since they get overwritten elsewhere), but I do it anway. + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) return ax @staticmethod @@ -2200,6 +2256,7 @@ def _plot_arrow( both_dirs: bool = False, ax: Ax = None, arrow_base: Coordinate = None, + transpose: bool = False, ) -> Ax: """Adds an arrow to the axis if with options if certain conditions met. @@ -2225,6 +2282,8 @@ def _plot_arrow( If True, plots an arrow pointing in direction and one in -direction. arrow_base : :class:`.Coordinate` = None Custom base of the arrow. Uses the geometry's center if not provided. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. Returns ------- @@ -2260,6 +2319,10 @@ def _plot_arrow( v_x = (xmax - xmin) / 10 v_y = (ymax - ymin) / 10 + if transpose: + x0, y0 = y0, x0 + v_x, v_y = v_y, v_x + directions = (1.0, -1.0) if both_dirs else (1.0,) for sign in directions: arrow = patches.FancyArrowPatch( diff --git a/tidy3d/components/monitor.py b/tidy3d/components/monitor.py index 1ad5cef331..31d9d9730b 100644 --- a/tidy3d/components/monitor.py +++ b/tidy3d/components/monitor.py @@ -358,11 +358,12 @@ def plot( y: Optional[float] = None, z: Optional[float] = None, ax: Ax = None, + transpose: bool = False, **patch_kwargs, ) -> Ax: """Plot this monitor.""" # call the monitor.plot() function first - ax = super().plot(x=x, y=y, z=z, ax=ax, **patch_kwargs) + ax = super().plot(x=x, y=y, z=z, ax=ax, transpose=transpose, **patch_kwargs) kwargs_alpha = patch_kwargs.get("alpha") arrow_alpha = ARROW_ALPHA if kwargs_alpha is None else kwargs_alpha @@ -384,6 +385,7 @@ def plot( color=ARROW_COLOR_MONITOR, alpha=arrow_alpha, both_dirs=True, + transpose=transpose, ) return ax diff --git a/tidy3d/components/scene.py b/tidy3d/components/scene.py index 17752120a4..cf97449047 100644 --- a/tidy3d/components/scene.py +++ b/tidy3d/components/scene.py @@ -34,7 +34,7 @@ TriangularGridDataset, UnstructuredGridDataset, ) -from .geometry.base import Box, ClipOperation, GeometryGroup +from .geometry.base import Box, ClipOperation, GeometryGroup, Geometry from .geometry.utils import flatten_groups, merging_geometries_on_plane, traverse_geometries from .grid.grid import Coords, Grid from .material.multi_physics import MultiPhysicsMedium @@ -366,11 +366,17 @@ def _get_plot_lims( z: Optional[float] = None, hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + transpose: bool = False, ) -> tuple[tuple[float, float], tuple[float, float]]: # if no hlim and/or vlim given, the bounds will then be the usual pml bounds axis, _ = Box.parse_xyz_kwargs(x=x, y=y, z=z) _, (hmin, vmin) = Box.pop_axis(bounds[0], axis=axis) _, (hmax, vmax) = Box.pop_axis(bounds[1], axis=axis) + if transpose: + # Swap the default horizontal and vertical plot limits. (Note: If + # the user manually specified hlim, vlim, then we do not swap them.) + hmin, vmin = vmin, hmin + hmax, vmax = vmax, hmax # account for unordered limits if hlim is None: @@ -396,6 +402,7 @@ def plot( hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, fill_structures: bool = True, + transpose: bool = False, **patch_kwargs, ) -> Ax: """Plot each of scene's components on a plane defined by one nonzero x,y,z coordinate. @@ -416,17 +423,26 @@ def plot( The z range if plotting on xz or yz planes, y plane if plotting on xy plane. fill_structures : bool = True Whether to fill structures with color or just draw outlines. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. Returns ------- matplotlib.axes._subplots.Axes The supplied or created matplotlib axes. """ - hlim, vlim = Scene._get_plot_lims(bounds=self.bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim) - - ax = self.plot_structures(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, fill=fill_structures) - ax = self._set_plot_bounds(bounds=self.bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + ax = self.plot_structures( + ax=ax, + x=x, + y=y, + z=z, + hlim=hlim, + vlim=vlim, + fill=fill_structures, + transpose=transpose, + ) + ax = self._set_plot_bounds(bounds=self.bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose) return ax @equal_aspect @@ -440,6 +456,7 @@ def plot_structures( hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, fill: bool = True, + transpose: bool = False, ) -> Ax: """Plot each of scene's structures on a plane defined by one nonzero x,y,z coordinate. @@ -478,16 +495,18 @@ def plot_structures( shape=shape, ax=ax, fill=fill, + transpose=transpose, ) # clean up the axis display axis, _ = Box.parse_xyz_kwargs(x=x, y=y, z=z) ax = self.box.add_ax_lims(axis=axis, ax=ax) - ax = self._set_plot_bounds(bounds=self.bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + ax = self._set_plot_bounds(bounds=self.bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose) # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax def _plot_shape_structure( @@ -497,6 +516,7 @@ def _plot_shape_structure( shape: Shapely, ax: Ax, fill: bool = True, + transpose: bool = False, ) -> Ax: """Plot a structure's cross section shape for a given medium.""" plot_params_struct = self._get_structure_plot_params( @@ -504,7 +524,7 @@ def _plot_shape_structure( mat_index=mat_index, fill=fill, ) - ax = self.box.plot_shape(shape=shape, plot_params=plot_params_struct, ax=ax) + ax = self.box.plot_shape(shape=shape, plot_params=plot_params_struct, ax=ax, transpose=transpose) return ax def _get_structure_plot_params( @@ -580,6 +600,7 @@ def _set_plot_bounds( z: Optional[float] = None, hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + transpose: bool = False, ) -> Ax: """Sets the xy limits of the scene at a plane, useful after plotting. @@ -597,13 +618,16 @@ def _set_plot_bounds( The x range if plotting on xy or xz planes, y range if plotting on yz plane. vlim : Tuple[float, float] = None The z range if plotting on xz or yz planes, y plane if plotting on xy plane. + transpose: bool = False + Optional: Swap the default horizontal and vertical axes (when hlim==None or vlim==None). + Returns ------- matplotlib.axes._subplots.Axes The axes after setting the boundaries. """ - hlim, vlim = Scene._get_plot_lims(bounds=bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + hlim, vlim = Scene._get_plot_lims(bounds=bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose) ax.set_xlim(hlim) ax.set_ylim(vlim) return ax @@ -616,6 +640,7 @@ def _get_structures_2dbox( z: Optional[float] = None, hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + # transpose: bool = False, CONTINUEHERE ) -> list[tuple[Medium, Shapely]]: """Compute list of shapes to plot on 2d box specified by (x_min, x_max), (y_min, y_max). @@ -766,12 +791,12 @@ def plot_eps( The supplied or created matplotlib axes. """ - hlim, vlim = Scene._get_plot_lims(bounds=self.bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + hlim, vlim = Scene._get_plot_lims(bounds=self.bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim) #, transpose=transpose CONTINUEHERE ax = self.plot_structures_eps( - freq=freq, cbar=True, alpha=alpha, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + freq=freq, cbar=True, alpha=alpha, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) - ax = self._set_plot_bounds(bounds=self.bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + ax = self._set_plot_bounds(bounds=self.bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) #, transpose=transpose CONTINUEHERE return ax @equal_aspect @@ -791,6 +816,7 @@ def plot_structures_eps( vlim: Optional[tuple[float, float]] = None, grid: Grid = None, eps_component: Optional[PermittivityComponent] = None, + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of scene's structures on a plane defined by one nonzero x,y,z coordinate. The permittivity is plotted in grayscale based on its value at the specified frequency. @@ -848,6 +874,7 @@ def plot_structures_eps( grid=grid, property="eps", eps_component=eps_component, + # transpose=transpose, CONTINUEHERE ) @equal_aspect @@ -868,6 +895,7 @@ def plot_structures_property( grid: Grid = None, property: Literal["eps", "doping", "N_a", "N_d"] = "eps", eps_component: Optional[PermittivityComponent] = None, + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of scene's structures on a plane defined by one nonzero x,y,z coordinate. The permittivity is plotted in grayscale based on its value at the specified frequency. @@ -941,7 +969,7 @@ def plot_structures_property( else: structures = [self.background_structure, *list(structures)] medium_shapes = self._get_structures_2dbox( - structures=structures, x=x, y=y, z=z, hlim=hlim, vlim=vlim + structures=structures, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) property_min, property_max = limits @@ -978,11 +1006,11 @@ def plot_structures_property( reverse=reverse, shape=shape, ax=ax, - property="doping", + property="doping", #, transpose=transpose CONTINUEHERE ) else: self._pcolormesh_shape_doping_box( - x, y, z, alpha, medium, property_min, property_max, shape, ax, property + x, y, z, alpha, medium, property_min, property_max, shape, ax, property #, transpose=transpose CONTINUEHERE ) else: # if the background medium is custom medium, it needs to be rendered separately @@ -999,7 +1027,7 @@ def plot_structures_property( reverse=reverse, shape=shape, ax=ax, - eps_component=eps_component, + eps_component=eps_component, #, transpose=transpose CONTINUEHERE ) else: # For custom medium, apply pcolormesh clipped by the shape. @@ -1016,7 +1044,7 @@ def plot_structures_property( shape, ax, grid, - eps_component=eps_component, + eps_component=eps_component, #, transpose=transpose CONTINUEHERE ) if cbar: @@ -1036,11 +1064,12 @@ def plot_structures_property( # clean up the axis display axis, _ = Box.parse_xyz_kwargs(x=x, y=y, z=z) ax = self.box.add_ax_lims(axis=axis, ax=ax) - ax = self._set_plot_bounds(bounds=self.bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + ax = self._set_plot_bounds(bounds=self.bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) #, transpose=transpose CONTINUEHERE # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + # CONTINUEHERE Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if NEEDED return ax @staticmethod @@ -1113,6 +1142,7 @@ def _pcolormesh_shape_custom_medium_structure_eps( ax: Ax, grid: Grid, eps_component: Optional[PermittivityComponent] = None, + # transpose: bool = False, CONTINUEHERE ): """ Plot shape made of custom medium with ``pcolormesh``. @@ -1248,6 +1278,7 @@ def _pcolormesh_shape_custom_medium_structure_eps( eps_shape = eps_min + eps_max - eps_shape # pcolormesh + # CONTINUEHERE: Do I need to swap xp<-->yp if transpose==True? plane_xp, plane_yp = np.meshgrid(plane_coord[0], plane_coord[1], indexing="ij") ax.pcolormesh( plane_xp, @@ -1339,6 +1370,7 @@ def plot_heat_charge_property( ax: Ax = None, hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of scebe's components on a plane defined by one nonzero x,y,z coordinate. The thermal conductivity is plotted in grayscale based on its value. @@ -1393,6 +1425,7 @@ def plot_structures_heat_conductivity( ax: Ax = None, hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of scene's structures on a plane defined by one nonzero x,y,z coordinate. The thermal conductivity is plotted in grayscale based on its value. @@ -1443,6 +1476,7 @@ def plot_structures_heat_conductivity( ax=ax, hlim=hlim, vlim=vlim, + # transpose=transpose, CONTINUEHERE ) @equal_aspect @@ -1459,6 +1493,7 @@ def plot_structures_heat_charge_property( ax: Ax = None, hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of scene's structures on a plane defined by one nonzero x,y,z coordinate. The thermal conductivity is plotted in grayscale based on its value. @@ -1524,6 +1559,7 @@ def plot_structures_heat_charge_property( shape=shape, ax=ax, property=property, + # transpose=transpose, CONTINUEHERE ) if cbar: @@ -1548,6 +1584,7 @@ def plot_structures_heat_charge_property( ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + # CONTINUEHERE: Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax def heat_charge_property_bounds(self, property) -> tuple[float, float]: diff --git a/tidy3d/components/simulation.py b/tidy3d/components/simulation.py index 3bf9f477c8..8ccd75d1f2 100644 --- a/tidy3d/components/simulation.py +++ b/tidy3d/components/simulation.py @@ -451,6 +451,7 @@ def plot( hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, fill_structures: bool = True, + transpose: bool = False, **patch_kwargs, ) -> Ax: """Plot each of simulation's components on a plane defined by one nonzero x,y,z coordinate. @@ -477,6 +478,8 @@ def plot( The x range if plotting on xy or xz planes, y range if plotting on yz plane. vlim : Tuple[float, float] = None The z range if plotting on xz or yz planes, y plane if plotting on xy plane. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. Returns ------- @@ -491,7 +494,7 @@ def plot( """ hlim, vlim = Scene._get_plot_lims( - bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose, ) ax = self.scene.plot( @@ -502,20 +505,21 @@ def plot( hlim=hlim, vlim=vlim, fill_structures=fill_structures, + transpose=transpose, ) - ax = self.plot_sources(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=source_alpha) - ax = self.plot_monitors(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=monitor_alpha) + ax = self.plot_sources(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=source_alpha, transpose=transpose) + ax = self.plot_monitors(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=monitor_alpha, transpose=transpose) ax = self.plot_lumped_elements( - ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=lumped_element_alpha + ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=lumped_element_alpha, transpose=transpose ) - ax = self.plot_symmetries(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) - ax = self.plot_pml(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + ax = self.plot_symmetries(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose) + ax = self.plot_pml(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose) ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) - ax = self.plot_boundaries(ax=ax, x=x, y=y, z=z) - + ax = self.plot_boundaries(ax=ax, x=x, y=y, z=z, transpose=transpose) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax @equal_aspect @@ -535,6 +539,7 @@ def plot_eps( ax: Ax = None, eps_component: Optional[PermittivityComponent] = None, eps_lim: tuple[Union[float, None], Union[float, None]] = (None, None), + # tuple: bool = False, CONTINUEHERE ) -> Ax: """Plot each of simulation's components on a plane defined by one nonzero x,y,z coordinate. The permittivity is plotted in grayscale based on its value at the specified frequency. @@ -596,7 +601,7 @@ def plot_eps( ) hlim, vlim = Scene._get_plot_lims( - bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) ax = self.plot_structures_eps( @@ -611,18 +616,19 @@ def plot_eps( vlim=vlim, eps_component=eps_component, eps_lim=eps_lim, + #, transpose=transpose CONTINUEHERE ) - ax = self.plot_sources(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=source_alpha) - ax = self.plot_monitors(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=monitor_alpha) + ax = self.plot_sources(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=source_alpha) #, transpose=transpose CONTINUEHERE + ax = self.plot_monitors(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=monitor_alpha) #, transpose=transpose CONTINUEHERE ax = self.plot_lumped_elements( - ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=lumped_element_alpha + ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, alpha=lumped_element_alpha #, transpose=transpose CONTINUEHERE ) - ax = self.plot_symmetries(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) - ax = self.plot_pml(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + ax = self.plot_symmetries(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) #, transpose=transpose CONTINUEHERE + ax = self.plot_pml(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) #, transpose=transpose CONTINUEHERE ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) - ax = self.plot_boundaries(ax=ax, x=x, y=y, z=z) + ax = self.plot_boundaries(ax=ax, x=x, y=y, z=z) #, transpose=transpose CONTINUEHERE return ax @equal_aspect @@ -641,6 +647,7 @@ def plot_structures_eps( vlim: Optional[tuple[float, float]] = None, eps_component: Optional[PermittivityComponent] = None, eps_lim: tuple[Union[float, None], Union[float, None]] = (None, None), + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of simulation's structures on a plane defined by one nonzero x,y,z coordinate. The permittivity is plotted in grayscale based on its value at the specified frequency. @@ -714,6 +721,7 @@ def plot_structures_eps( reverse=reverse, eps_component=eps_component, eps_lim=eps_lim, + # transpose=transpose, CONTINUEHERE ) @equal_aspect @@ -726,6 +734,7 @@ def plot_pml( hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, ax: Ax = None, + transpose: bool = False, ) -> Ax: """Plot each of simulation's absorbing boundaries on a plane defined by one nonzero x,y,z coordinate. @@ -744,6 +753,8 @@ def plot_pml( The z range if plotting on xz or yz planes, y plane if plotting on xy plane. ax : matplotlib.axes._subplots.Axes = None Matplotlib axes to plot on, if not specified, one is created. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. Returns ------- @@ -755,12 +766,13 @@ def plot_pml( for pml_box in pml_boxes: pml_box.plot(x=x, y=y, z=z, ax=ax, **plot_params_pml.to_kwargs()) ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) return ax # candidate for removal in 3.0 @@ -884,6 +896,7 @@ def plot_lumped_elements( vlim: Optional[tuple[float, float]] = None, alpha: Optional[float] = None, ax: Ax = None, + transpose: bool = False, ) -> Ax: """Plot each of simulation's lumped elements on a plane defined by one nonzero x,y,z coordinate. @@ -904,6 +917,8 @@ def plot_lumped_elements( Opacity of the lumped element, If ``None`` uses Tidy3d default. ax : matplotlib.axes._subplots.Axes = None Matplotlib axes to plot on, if not specified, one is created. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. Returns ------- @@ -913,10 +928,11 @@ def plot_lumped_elements( bounds = self.bounds for element in self.lumped_elements: kwargs = element.plot_params.include_kwargs(alpha=alpha).to_kwargs() - ax = element.to_geometry().plot(x=x, y=y, z=z, ax=ax, sim_bounds=bounds, **kwargs) + ax = element.to_geometry().plot(x=x, y=y, z=z, ax=ax, sim_bounds=bounds, transpose=transpose, **kwargs) ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) return ax @add_ax_if_none @@ -930,6 +946,7 @@ def plot_grid( vlim: Optional[tuple[float, float]] = None, override_structures_alpha: float = 1, snapping_points_alpha: float = 1, + transpose: bool = False, **kwargs, ) -> Ax: """Plot the cell boundaries as lines on a plane defined by one nonzero x,y,z coordinate. @@ -952,6 +969,8 @@ def plot_grid( Opacity of the snapping points. ax : matplotlib.axes._subplots.Axes = None Matplotlib axes to plot on, if not specified, one is created. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. **kwargs Optional keyword arguments passed to the matplotlib ``LineCollection``. For details on accepted values, refer to @@ -1010,6 +1029,8 @@ def plot_grid( xmin, xmax, ymin, ymax = ( self._evaluate_inf(v) for v in (xmin, xmax, ymin, ymax) ) + if transpose: + xmin, xmax, ymin, ymax = ymin, ymax, xmin, xmax rect = mpl.patches.Rectangle( xy=(xmin, ymin), width=(xmax - xmin), @@ -1030,6 +1051,8 @@ def plot_grid( ): for point in points: _, (x_point, y_point) = Geometry.pop_axis(point, axis=axis) + if transpose: + x_point, y_point = y_point, x_point # swap X and Y if x_point is None and y_point is None: continue if x_point is None: @@ -1058,12 +1081,13 @@ def plot_grid( ) ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim, transpose=transpose ) # Add the default axis labels, tick labels, and title ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax @equal_aspect @@ -1074,6 +1098,7 @@ def plot_boundaries( y: Optional[float] = None, z: Optional[float] = None, ax: Ax = None, + transpose: bool = False, **kwargs, ) -> Ax: """Plot the simulation boundary conditions as lines on a plane @@ -1089,6 +1114,8 @@ def plot_boundaries( position of plane in z direction, only one of x, y, z must be specified to define plane. ax : matplotlib.axes._subplots.Axes = None Matplotlib axes to plot on, if not specified, one is created. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. **kwargs Optional keyword arguments passed to the matplotlib ``LineCollection``. For details on accepted values, refer to @@ -1184,6 +1211,11 @@ def set_plot_params(boundary_edge, lim, side, thickness): ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) + if transpose: + import sys + sys.stderr.write( + "WARNING: Simulation.plot_boundaries() does not yet implement transpose=True!" + ) return ax # TODO: not yet supported diff --git a/tidy3d/components/source/base.py b/tidy3d/components/source/base.py index 388896fb5b..02fa986033 100644 --- a/tidy3d/components/source/base.py +++ b/tidy3d/components/source/base.py @@ -74,6 +74,7 @@ def plot( y: Optional[float] = None, z: Optional[float] = None, ax: Ax = None, + transpose: bool = None, **patch_kwargs, ) -> Ax: """Plot this source.""" @@ -81,7 +82,7 @@ def plot( kwargs_arrow_base = patch_kwargs.pop("arrow_base", None) # call the `Source.plot()` function first. - ax = Box.plot(self, x=x, y=y, z=z, ax=ax, **patch_kwargs) + ax = Box.plot(self, x=x, y=y, z=z, ax=ax, transpose=transpose, **patch_kwargs) kwargs_alpha = patch_kwargs.get("alpha") arrow_alpha = ARROW_ALPHA if kwargs_alpha is None else kwargs_alpha @@ -112,6 +113,7 @@ def plot( alpha=arrow_alpha, both_dirs=False, arrow_base=kwargs_arrow_base, + transpose=transpose, ) if self._pol_vector is not None: @@ -125,6 +127,7 @@ def plot( alpha=arrow_alpha, both_dirs=False, arrow_base=kwargs_arrow_base, + transpose=transpose, ) return ax diff --git a/tidy3d/components/structure.py b/tidy3d/components/structure.py index 17f175a8bb..9ef068d2e5 100644 --- a/tidy3d/components/structure.py +++ b/tidy3d/components/structure.py @@ -149,6 +149,7 @@ def plot( y: Optional[float] = None, z: Optional[float] = None, ax: Ax = None, + transpose: bool = False, **patch_kwargs, ) -> Ax: """Plot structure's geometric cross section at single (x,y,z) coordinate. @@ -163,6 +164,8 @@ def plot( Position of plane in z direction, only one of x,y,z can be specified to define plane. ax : matplotlib.axes._subplots.Axes = None Matplotlib axes to plot on, if not specified, one is created. + transpose: bool = False + Optional: Swap the horizontal and vertical axes. **patch_kwargs Optional keyword arguments passed to the matplotlib patch plotting of structure. For details on accepted values, refer to @@ -173,7 +176,7 @@ def plot( matplotlib.axes._subplots.Axes The supplied or created matplotlib axes. """ - return self.geometry.plot(x=x, y=y, z=z, ax=ax, viz_spec=self.viz_spec, **patch_kwargs) + return self.geometry.plot(x=x, y=y, z=z, ax=ax, viz_spec=self.viz_spec, transpose=transpose, **patch_kwargs) class Structure(AbstractStructure): diff --git a/tidy3d/components/tcad/simulation/heat_charge.py b/tidy3d/components/tcad/simulation/heat_charge.py index 3dd1d34f49..4ddd4d1686 100644 --- a/tidy3d/components/tcad/simulation/heat_charge.py +++ b/tidy3d/components/tcad/simulation/heat_charge.py @@ -916,6 +916,7 @@ def plot_property( property: str = "heat_conductivity", hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + # transpose: bool = False, CONTINUEHERE ) -> Ax: """Plot each of simulation's components on a plane defined by one nonzero x,y,z coordinate. @@ -951,7 +952,7 @@ def plot_property( """ hlim, vlim = Scene._get_plot_lims( - bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) cbar_cond = True @@ -986,16 +987,17 @@ def plot_property( hlim=hlim, vlim=vlim, property=property, + # transpose=transpose CONTINUEHERE ) ax = self.plot_sources( - ax=ax, x=x, y=y, z=z, property=property, alpha=source_alpha, hlim=hlim, vlim=vlim + ax=ax, x=x, y=y, z=z, property=property, alpha=source_alpha, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) - ax = self.plot_monitors(ax=ax, x=x, y=y, z=z, alpha=monitor_alpha, hlim=hlim, vlim=vlim) - ax = self.plot_boundaries(ax=ax, x=x, y=y, z=z, property=property) + ax = self.plot_monitors(ax=ax, x=x, y=y, z=z, alpha=monitor_alpha, hlim=hlim, vlim=vlim) #, transpose=transpose CONTINUEHERE + ax = self.plot_boundaries(ax=ax, x=x, y=y, z=z, property=property) #, transpose=transpose CONTINUEHERE ax = Scene._set_plot_bounds( - bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim + bounds=self.simulation_bounds, ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim #, transpose=transpose CONTINUEHERE ) - ax = self.plot_symmetries(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) + ax = self.plot_symmetries(ax=ax, x=x, y=y, z=z, hlim=hlim, vlim=vlim) #, transpose=transpose CONTINUEHERE if property == "source": self._add_source_cbar(ax=ax, property=property) @@ -1015,6 +1017,7 @@ def plot_heat_conductivity( colorbar: str = "conductivity", hlim: Optional[tuple[float, float]] = None, vlim: Optional[tuple[float, float]] = None, + # transpose: bool = False, CONTINUEHERE **kwargs, ) -> Ax: """ @@ -1074,6 +1077,7 @@ def plot_heat_conductivity( property=plot_type, hlim=hlim, vlim=vlim, + #, transpose=transpose CONTINUEHERE ) @equal_aspect @@ -1144,7 +1148,7 @@ def plot_boundaries( ax = Box.add_ax_labels_and_title( ax=ax, x=x, y=y, z=z, plot_length_units=self.plot_length_units ) - + # CONTINUEHERE: Geometry.transpose_axis_info(ax, swap_axis_labels=transpose) # Swap axis labels if needed return ax def _get_bc_plot_params(self, boundary_spec: HeatChargeBoundarySpec) -> PlotParams: