magnelio.plots#

Plotting components — the free functions behind the .plot() methods.

The primary plotting path is the methods on the objects themselves (model.plot(), model.plot_cross_section(), report.plot(), monitor.plot(), result.plot_s()); this module is their public home for direct use on objects you assembled yourself.

magnelio.plots.plot_cross_section(geometry, normal, position, *, mesh=None, scale_mm=True, flip=False, ax=None, title=None, deflection=0.0001, outline_transparent=True, show_wires=True, show_ports=True, slab=0.0, fill=True)#

Plot a 2D cross-section of 3D geometry at an axis-aligned plane.

Intersects every shape in geometry with the specified plane and renders the resulting polygons as matplotlib patches, coloured by material. Shapes with a fully transparent material (air/vacuum) are drawn as a dashed outline instead of being skipped — for a cavity carved into a conducting background, that outline is the wall.

Features that carry no volume are drawn too, since a picture of a wire antenna showing only its air box is not a picture of the model: thin wires from their curve, discrete ports and lumped elements from their two endpoints, and face ports along the domain edge they occupy. Each appears as a line where the cut runs along it and as a ring where the cut passes through it.

Parameters:
  • geometry (GeometryModel) – Geometry model containing the shapes to slice.

  • normal (str) – Normal axis of the cutting plane: 'x', 'y', or 'z'.

  • position (float) – Position along the normal axis in metres.

  • mesh (Mesh or None, optional) – If given, overlay the mesh grid lines for the cutting plane.

  • scale_mm (bool, optional) – If True (default), display axes in millimetres.

  • flip (bool, optional) – If True, swap the horizontal and vertical axes. Useful for structures that are tall and narrow in the default (u, v) layout (e.g. a long transmission line sliced at x = const).

  • ax (matplotlib.axes.Axes or None, optional) – Existing axes to draw into. A new figure is created when None.

  • title (str or None, optional) – Plot title. Defaults to "Cross-section at <axis> = <pos> <unit>".

  • deflection (float, optional) – Chordal deflection for curve tessellation [m]. Passed through to cross_section_polygons().

  • outline_transparent (bool, optional) – Draw transparent-material shapes as dashed outlines (default True). Set False to skip them entirely (pre-existing behaviour). Shapes whose material has visible=False are always skipped.

  • show_wires (bool, optional) – Draw ThinWire conductors (default True). A wire is a sub-cell model, so it is drawn at a fixed line width rather than to its radius — which would be invisible. The cut counts as passing through a wire when it comes within one radius of it.

  • show_ports (bool, optional) – Draw the model’s declared ports and lumped elements (default True), labelled. A port declared on a bbox face parallel to the cut is not drawn: it would cover the entire section.

  • slab (float, optional) – Half-thickness of the layer the picture stands for [m], zero by default (a mathematical plane). Volume-free features — thin wires, discrete ports, lumped elements — are drawn when they fall within this distance of the plane. Field plots pass the half-height of the cell layer they display, so a wire on a grid node still appears in a picture whose field samples sit half a cell off it.

  • fill (bool, optional) – Fill the sections of opaque materials (default True). False draws only their outline in the material colour — the overlay plot_mesh_section() uses on top of the cell fill.

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (matplotlib.axes.Axes)

Return type:

tuple[‘matplotlib.figure.Figure’, ‘matplotlib.axes.Axes’]

magnelio.plots.plot_field_scalar(xc, yc, values, *, xlabel='u', ylabel='v', title='', clabel='', ax=None, scale_mm=True, cmap='viridis', vmin=None, vmax=None, symmetric=False, plot_type='color', contour_levels=16, flip=False, geometry=None, colorbar=True)#

Scalar 2D field plot (pcolormesh or contourf).

Parameters:
  • xc (np.ndarray) – Cell-centre coordinates of the two in-plane axes.

  • yc (np.ndarray) – Cell-centre coordinates of the two in-plane axes.

  • values (np.ndarray) – Real-valued 2D array, shape (len(xc), len(yc)).

  • xlabel (str) – Axis labels (without unit suffix).

  • ylabel (str) – Axis labels (without unit suffix).

  • title (str) – Axes title.

  • clabel (str) – Colour-bar label.

  • scale_mm (bool) – If True, multiply coordinates by 1e3 and label in mm.

  • cmap (str) – Matplotlib colourmap.

  • vmin (float or None) – Explicit colour limits.

  • vmax (float or None) – Explicit colour limits.

  • symmetric (bool) – If True and vmin/vmax not set, use symmetric limits [-M, M].

  • plot_type (str) – "color" (pcolormesh) or "contour" (filled contours).

  • contour_levels (int) – Number of contour levels (contour mode only).

  • flip (bool) – Swap horizontal and vertical axes.

  • geometry (GeometryOverlay) – Optional geometry overlay.

  • ax (matplotlib.axes.Axes | None)

  • colorbar (bool)

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (matplotlib.axes.Axes)

Return type:

tuple[‘matplotlib.figure.Figure’, ‘matplotlib.axes.Axes’]

magnelio.plots.plot_field_vector(xc, yc, u, v, *, w=None, valid=None, xlabel='u', ylabel='v', wlabel='n', title='', clabel=None, ax=None, scale_mm=True, cmap='viridis', density=20, normalize_arrows=False, vmax=None, threshold=0.0, auto_scale=True, quiver_scale=None, flip=False, geometry=None, colorbar=True)#

Quiver plot for a 2D slice of a vector field.

The data is interpolated onto an isotropic arrow raster spanning the slice (see density): arrow positions are a property of the picture, not of the computational grid, so a locally refined mesh no longer shows up as clustered arrows.

Arrows show the in-plane vector components. When the out-of-plane component w is given, arrow colour encodes the full 3D magnitude, and grid points whose vector tilts out of the plane by more than ~72° (|w| >= 3x the in-plane part, at significant magnitude) are drawn as circle markers instead of unreadable foreshortened arrows: a filled circle with a centre dot (⊙) where the field points along the positive normal axis, with a cross (⊗) along the negative one. Without w the plot shows the in-plane projection only and the colour bar is labelled accordingly.

Parameters:
  • xc (np.ndarray) – Cell-centre coordinates of the two in-plane axes.

  • yc (np.ndarray) – Cell-centre coordinates of the two in-plane axes.

  • u (np.ndarray) – In-plane vector components, shape (len(xc), len(yc)).

  • v (np.ndarray) – In-plane vector components, shape (len(xc), len(yc)).

  • w (np.ndarray or None) – Out-of-plane (normal) component on the same grid. Enables the full-magnitude colouring and the ⊙/⊗ markers.

  • valid (np.ndarray or None) – Boolean mask of cells carrying field data, same shape as u. False marks a cell the field does not live in (buried in a conductor); it is excluded from the interpolation stencil rather than read as zero, and raster points dominated by such cells stay blank. None treats every cell as valid.

  • xlabel (str) – In-plane axis labels (without unit suffix).

  • ylabel (str) – In-plane axis labels (without unit suffix).

  • wlabel (str) – Name of the normal axis (e.g. "y"), used in the ⊙/⊗ marker legend.

  • clabel (str or None) – Colour-bar label. Default: "Field magnitude" when w is given, "In-plane field magnitude" otherwise.

  • density (int) – Number of arrows along the longer in-plane axis. The field is interpolated onto an isotropic raster of that spacing, so the arrow pattern shows the field rather than the local refinement of the computational grid.

  • normalize_arrows (bool) – If True, arrows have unit length and colour encodes magnitude (port-mode style). If False, arrow length is proportional to field strength (monitor style).

  • vmax (float or None) – Clip arrow length and colour at this magnitude.

  • threshold (float) – Suppress arrows below this fraction of peak magnitude. With w, max(threshold, 0.02) of the peak is also the significance floor below which no ⊙/⊗ marker is drawn.

  • auto_scale (bool) – Compute the quiver scale so the peak magnitude (full 3D with w, in-plane without) maps to ~ one cell spacing; arrow length over colour then reads as the out-of-plane tilt.

  • quiver_scale (float or None) – Explicit quiver scale override (e.g. for interact() fixed-scale animations). Overrides auto_scale.

  • flip (bool) – Swap horizontal and vertical axes.

  • geometry (GeometryOverlay) – Optional geometry overlay.

  • title (str)

  • ax (matplotlib.axes.Axes | None)

  • scale_mm (bool)

  • cmap (str)

  • colorbar (bool)

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (matplotlib.axes.Axes)

Return type:

tuple[‘matplotlib.figure.Figure’, ‘matplotlib.axes.Axes’]

magnelio.plots.plot_mesh_section(mesh, normal, position, *, geometry=None, scale_mm=True, flip=False, ax=None, title=None, fill='coverage', edges=False, legend=True)#

Plot an axis-aligned section of the mesh: cells and grid lines by origin.

Every grid line of the two in-plane axes is drawn in the style of the rule that placed it (see the legend); lines that are graded fill between those planes are hairlines, absorber cells are hatched, and a plane holding a conductor edge with a field singularity carries red markers at its ends. Pass the model as geometry to overlay the exact section outline.

The fill answers one of three questions. "coverage" (default) shows how much of each cell is conductor: the exact PEC-covered area of the primal faces normal to the cut, in the node plane nearest to it, as measured by the sub-cell classifier — every cell in the colour of its classified material, blended towards PEC grey by that share. "material" shows the cell classification: the material containing each cell’s centre, on the real cell size. It is the staircase baseline the sub-cell values override on every cut cell, not the accuracy of the discretisation, and thin sheets do not appear in it. "conformal" shows the dual faces of the edges normal to the cut — one tile per node, bounded by the cell midpoints, so the tiles sit half a cell off the grid lines — each coloured by the area-weighted permittivity that enters the electric material matrix for that edge (0 = PEC), with a colour bar. Around a conductor the masked tiles reach one node beyond the contour: edges running along a conductor surface are held at its potential.

Parameters:
  • mesh (Mesh) – The mesh to draw. Its planes record supplies the line styles; a mesh without one (built from a grid) draws every line as graded fill. The "conformal" fill and the edge layer need the sub-cell data of a mesh built by Mesh.from_geometry.

  • normal (str) – Normal axis of the cutting plane: 'x', 'y', or 'z'.

  • position (float) – Position along the normal axis in metres. The cell layer containing it is shown; the edge layer takes the node plane nearest to it.

  • geometry (GeometryModel or None, optional) – Overlay the exact section outline of this model (via plot_cross_section() with fill=False).

  • scale_mm (bool, optional) – Display axes in millimetres (default) or metres.

  • flip (bool, optional) – Swap the horizontal and vertical axes.

  • ax (matplotlib.axes.Axes or None, optional) – Existing axes to draw into. A new figure is created when None.

  • title (str or None, optional) – Plot title. Defaults to "Mesh section at <axis> = <pos> <unit>".

  • fill ({"coverage", "material", "conformal", None}, optional) – "coverage" (default) shades every cell by its exact PEC-covered area; "material" colours every cell by its classified material; "conformal" colours the dual-face tiles of the normal edges by their area-weighted permittivity, with a colour bar; None draws the lines only.

  • edges (bool, optional) – Add the in-plane primal edges of the nearest node plane: PEC-masked edges dark, edges partly inside PEC orange (the more metal, the stronger), edges borrowed out by the enlarged-cell technique with a red cross. Free edges are not drawn. Default False.

  • legend (bool, optional) – Add a legend of the plane kinds and edge classes present (default True).

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (matplotlib.axes.Axes)

Raises:

ValueError – For an unknown normal or fill, or when fill="coverage", fill="conformal" or edges=True is asked of a mesh without sub-cell data.

Return type:

tuple[‘matplotlib.figure.Figure’, ‘matplotlib.axes.Axes’]

magnelio.plots.plot_pattern_3d(theta, phi, values, *, db=True, floor_db=-40.0, ax=None, cmap=None, title=None)#

3D radiation surface: radius proportional to the pattern.

In dB mode the radius is value_dB − floor_dB clipped at zero, so the floor collapses to the origin and nulls stay visible as indentations.

Parameters:
  • theta (array_like) – Spherical angle grids [rad]; θ from +z, φ from +x.

  • phi (array_like) – Spherical angle grids [rad]; θ from +z, φ from +x.

  • values (array_like) – Pattern quantity on the (θ, φ) grid (linear), shape (len(theta), len(phi)).

  • db (bool, default True) – Radius from the dB value (with floor_db) instead of linear.

  • floor_db (float, default -40.0) – Radius origin for the dB display.

  • cmap (str, optional) – Colormap for the radius shading (default "viridis").

  • ax (mpl_toolkits.mplot3d.axes3d.Axes3D, optional) – 3D axes to draw into; a new figure is created otherwise.

  • title (str | None)

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (mpl_toolkits.mplot3d.axes3d.Axes3D)

magnelio.plots.plot_pattern_cut(angles, values, *, db=True, floor_db=-40.0, ax=None, label=None, title=None)#

Polar plot of one pattern cut.

Follows the antenna-plot convention: the zero angle points up and angles run clockwise, so a θ-cut shows the zenith at the top.

Parameters:
  • angles (array_like) – Cut angles [rad].

  • values (array_like) – Pattern quantity along the cut (linear, e.g. gain or directivity).

  • db (bool, default True) – Radial axis in dB (with floor_db) instead of linear.

  • floor_db (float, default -40.0) – Clip floor and radial-axis minimum for the dB display.

  • label (str, optional) – Legend label for this trace.

  • ax (matplotlib.projections.polar.PolarAxes, optional) – Polar axes to draw into; a new figure is created otherwise.

  • title (str | None)

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (matplotlib.projections.polar.PolarAxes)

magnelio.plots.show_field(source, component='E', *, normal=None, position=None, flip=False, plot_type='vector', frame=None, t=None, f=None, phase=0.0, vmax=None, cmap=None, density=20, threshold=0.02, opacity=1.0, arrow_color=None, fps=4.0, volume=None, levels=None, iso_level=0.5, glyph='arrow', glyph_width=1.0, mirror=True, geometry=None, mesh=None, show_ports=True, show_wires=True, show_grid=False, show_labels=True, mode=None, size=None, quality=1.0, scale_mm=True, camera='iso')#

Interactive 3D view of a field, or a field monitor, on a cutting plane.

The view is the geometry viewer’s (show_geometry()) with the field laid on the cutting plane: the cell layer the cut exposes as a coloured sheet — the magnitude of a field group, or one signed component — and, for a field group, arrows on an even lattice over that layer. The volume behind the cut can carry the field too (volume): arrows on a 3D lattice, coloured by magnitude, and isosurfaces of the magnitude (the ±level of a signed component), both clipped to the kept half like the solids; the Show menu turns either on and off. Moving the position slider walks the cut through the recorded volume; a time or frequency monitor adds a frame slider, an eigenmode result a mode slider, complex data a phase slider, a selector switches the field, and sliders set the isosurface level and the arrow density. The values are the cell-centred physical fields of the exposed layer, computed for that layer when the cut moves — and of the whole region when a volume representation is shown. With a mesh that declares symmetry planes the field is continued across them, so the picture is the whole model.

Parameters:
  • source (FieldState, monitor, EigenmodeResult, or a project's monitor reader) – What to show. A monitor must have recorded (or be read from a project); a FieldState is one frame; an eigenmode result’s modes are its frames.

  • component (str) – "E" or "H" for the magnitude sheet (with arrows when plot_type is "vector"); "Ex", "Hy", … for one signed component on a diverging colour scale.

  • normal ({"x", "y", "z"}, optional) – Normal of the initial cutting plane. Default: the axis along which the region has the fewest cells — for a plane monitor, its own normal.

  • position (float, optional) – Initial plane position along normal [m]. Default: the middle of the recorded region.

  • flip (bool, default False) – Which half the cut removes (see the geometry viewer).

  • plot_type ({"vector", "color"}) – Arrows over the magnitude sheet, or the sheet alone. A single component is always drawn as a sheet.

  • frame (int, optional) – Initial frame (time or frequency index). Default 0.

  • t (float, optional) – Initial frame by time [s] (time monitors) or frequency [Hz] (frequency monitors); the nearest recorded one is used.

  • f (float, optional) – Initial frame by time [s] (time monitors) or frequency [Hz] (frequency monitors); the nearest recorded one is used.

  • phase (float, default 0.0) – Instant [degrees] at which a complex field is shown: Re(F · exp(+j·phase)), the pattern at w t = phase. The phase advances with time, so the play button walks a travelling wave the way it ran in the simulation — away from the port that launched it.

  • vmax (float, optional) – Ceiling of the colour scale and of the arrow length. Default: the peak over every frame and layer of the region, so that the colours stay comparable while sliding through time.

  • cmap (str, optional) – Colour map; default "viridis" for a magnitude, "RdBu_r" for a signed component.

  • density (int, default 20) – Arrows along the longer in-plane axis of the cut, and along the longest axis of the region in the volume; the other axes get the count that keeps the lattice even.

  • threshold (float, default 0.02) – Arrows below this fraction of vmax are not drawn.

  • opacity (float, default 1.0) – Opacity of the field sheet.

  • arrow_color (str, optional) – One colour for every arrow. Default: the arrows are coloured by their magnitude on the sheet’s colour scale. Either way an arrow’s length grows with its magnitude, from three tenths of the lattice spacing up to one spacing, so a decaying field keeps readable arrows.

  • fps (float, default 4.0) – Frames per second of the toolbar’s play button (notebook widget); the effective rate is bounded by how fast the browser receives a frame — a volume representation costs the whole region per frame.

  • volume ({"arrows", "isosurface", "both"}, optional) – What to draw in the volume behind the cut at first. "arrows" replaces the arrows on the cut by arrows on a 3D lattice over the kept half; "isosurface" adds translucent surfaces of the magnitude at iso_level (or at levels); "both" draws both. Default: nothing in the volume — the Show menu offers both representations whenever the source is a volume.

  • levels (sequence of float, optional) – Isosurface levels in field units (V/m or A/m). Default: one surface at iso_level of the colour ceiling, movable with the toolbar’s level slider; given levels are fixed. A signed component gets each level with both signs.

  • iso_level (float, default 0.5) – The isosurface level as a fraction of vmax when levels is not given.

  • glyph ({"arrow", "cone"}) – The shape of the field vectors, centred on their sample points.

  • glyph_width (float, default 1.0) – Thickness of the vectors relative to the default.

  • mirror (bool, default True) – Continue the field across the model’s symmetry planes, so the view shows the whole model (as every other field picture does). Needs mesh (an eigenmode result brings its own), whose boundary declaration names the planes; a region that stops short of a plane is not mirrored across it. False shows the modelled part only.

  • geometry (GeometryModel, optional) – Draw the model’s solids and features with the field.

  • mesh (Mesh, optional) – The mesh the field was computed on. Cells buried in a perfect conductor are cut out of the sheet, so the solids’ cut faces show through where the field is not defined; with show_grid the grid cells are drawn on the cut as well; and the symmetry planes are read from it (mirror).

  • show_ports (bool, default True) – As in the geometry viewer.

  • show_wires (bool, default True) – As in the geometry viewer.

  • show_labels (bool, default True) – As in the geometry viewer.

  • show_grid (bool, default False) – With mesh: draw the grid cells on the cut under the field.

  • mode (str | None) – As in show_geometry(); size sets the widget’s height in the notebook, the toolbar’s pop-out button opens the same view in a browser tab of its own.

  • size (tuple[int, int] | None) – As in show_geometry(); size sets the widget’s height in the notebook, the toolbar’s pop-out button opens the same view in a browser tab of its own.

  • quality (float) – As in show_geometry(); size sets the widget’s height in the notebook, the toolbar’s pop-out button opens the same view in a browser tab of its own.

  • scale_mm (bool) – As in show_geometry(); size sets the widget’s height in the notebook, the toolbar’s pop-out button opens the same view in a browser tab of its own.

  • camera (Any) – As in show_geometry(); size sets the widget’s height in the notebook, the toolbar’s pop-out button opens the same view in a browser tab of its own.

Returns:

The plotter when mode="none"; otherwise the view is displayed as a side effect.

Return type:

pyvista.Plotter or None

Notes

Controls (notebook widget). The first toolbar row is the geometry viewer’s — camera buttons (reset, isometric, along x/y/z, parallel or perspective projection, ruler, screenshot, HTML export, pop-out, help), Cut / position / Flip / undo / reset, and the Show menu with Field on cut, Vectors on cut, Field vectors (in the volume) and Isosurfaces beside the geometry’s groups. The second row holds the field: play and frame slider with the frame’s time, frequency or mode; play and phase slider for complex data; the Field selector; the isosurface level and the arrow density. The mouse in the browser: left drag orbits, middle drag (or shift + left) pans, right drag or the wheel zooms, ctrl + left rolls; the help button lists the same.

Every sample is a cell-centre average of the staggered components — the picture stands for a layer of cells, not for a plane — and the isosurfaces interpolate those cell values to the nodes before they are contoured.

magnelio.plots.show_geometry(geometry, *, mesh=None, cut=None, flip=False, show_ports=True, show_wires=True, show_grid=True, show_labels=True, mode=None, size=None, render_edges=False, edge_color='#202020', quality=1.0, scale_mm=True, camera='iso', surface_current=None, current_frame=0, current_density=1)#

Interactive 3D view of a GeometryModel.

Solids are coloured by material (air and vacuum bodies are drawn as faint translucent shells), thin wires, ports, lumped elements and symmetry planes are overlaid, and the domain box is outlined. With a mesh a cutting plane exposes the grid cells — each coloured by the material the mesher assigned — on the cut.

The cutting plane is axis-aligned. In the notebook widget it is driven from the toolbar (normal axis, position slider, flip side, undo, reset), which also hides or shows object groups; cut sets the plane’s initial state, and is the only way to place it for a screenshot. The cut applies to the features as well: a port or element in the removed half disappears with it.

Parameters:
  • geometry (GeometryModel or iterable of shapes) – The geometry to display. A GeometryModel contributes its ports, lumped elements and boundary declaration.

  • mesh (Mesh, optional) – Show this mesh’s grid with the geometry.

  • cut ((str, float), optional) – Initial cutting plane as (normal, position) with the normal 'x', 'y' or 'z' and the position in metres, e.g. ("y", 0.0). None (default) starts uncut.

  • flip (bool, default False) – Which half the cut removes: by default the side the normal points to; True removes the other side.

  • show_ports (bool, default True) – Draw ports and lumped elements, and thin wires.

  • show_wires (bool, default True) – Draw ports and lumped elements, and thin wires.

  • show_grid (bool, default True) – With mesh: draw the grid cells on the cutting plane.

  • show_labels (bool, default True) – Write the names of ports and lumped elements next to them.

  • mode (str, optional) – Where to render in a notebook: "client" (default) renders in the browser and needs no OpenGL in the kernel; "server" renders in the kernel and streams images; "trame" offers both with a toggle; "static" embeds a screenshot; "none" builds the scene without showing it and returns the plotter. Outside a notebook the value is ignored: a script opens an interactive window, a documentation build takes a screenshot.

  • size ((int, int), optional) – Widget or window size in pixels. Default: full cell width.

  • render_edges (bool, default False) – Draw the tessellation edges on every solid.

  • edge_color (str, default "#202020") – Colour of those edges.

  • quality (float, default 1.0) – Tessellation fineness; values above 1 give finer triangles.

  • scale_mm (bool, default True) – Display in millimetres (False: metres).

  • camera (str or sequence, default "iso") – Initial camera: a PyVista preset ("iso", "xy", "xz", "yz") or an explicit [position, focal_point, view_up].

  • current_frame (int)

  • current_density (int)

Returns:

The plotter when mode="none"; otherwise the view is displayed as a side effect and None is returned.

Return type:

pyvista.Plotter or None

Notes

Controls (notebook widget). The toolbar: camera buttons (reset, isometric, along x/y/z, parallel or perspective projection), a ruler, a screenshot, an HTML export, a pop-out into a browser tab of its own and help, then Cut / position / Flip / undo / reset and the Show menu of the object groups. The mouse: left drag orbits, middle drag (or alt + left) pans, right drag or the wheel zooms, alt + shift + left rolls. The help button lists the same.

The widget needs the trame stack (pip install magnelio[jupyter] or the conda-forge packages trame, trame-vtk, trame-vuetify). Without it the view falls back to a static image with a warning.