spacr.figures.scene

Translate completed matplotlib figures into pyqtgraph scenes.

This module preserves the geometry and statistics already computed by a matplotlib panel while changing the renderer used for the saved file. Artist types listed in CARRIED are translated; an unsupported artist marks the translation incomplete and causes the caller to retain the original matplotlib output.

Scene exports support headless rendering when Qt is available and otherwise fall back to matplotlib. Output names follow spacr.plot.figure_path(), saved files are announced through spacr.figure_sink.publish_file(), and print colours are resolved by spacr.figure_style.export_colour() from each artist’s role.

Classes

SceneReport

What the translation could and could not carry.

Functions

build_scene(figure, *[, mode, dpi])

Translate a matplotlib Figure into a pyqtgraph scene.

export_scene(→ Optional[str])

Write a built scene to path. PDF, SVG and PNG, by the name.

pyqtgraph_ready(→ Tuple[bool, str])

(ok, reason): can a scene be built and exported here and now?

render_figure(figure, path, *[, fmt, mode, dpi, ...])

Write figure as a pyqtgraph render. None when it could not be.

requested_renderer(→ str)

The renderer SPACR_FIGURE_RENDERER asks for, or 'auto'.

scene_renderer(→ Tuple[str, str])

(renderer, reason) for a generated figure with NO interactive twin.

write_figure(figure, path, *[, fmt, dpi, renderer, ...])

Write a generated figure with the screen's renderer where that is possible.

Module Contents

class spacr.figures.scene.SceneReport[source]

What the translation could and could not carry.

complete is the only decision a caller has to read, and it is the whole contract: a scene operation that cannot produce a faithful file is not a picture of the panel, so the caller writes the matplotlib page instead. The rest is for the message, because “it fell back” without naming the cause is a report nobody can act on.

Parameters:
  • axes – number of matplotlib axes traversed and represented, including colour-bar axes.

  • items – number of data, annotation, legend, and colour-bar items successfully added to the scene.

  • missing – blocking capability or failure labels, including unsupported artists, renderer unavailability, and runtime or exporter failures; any entry makes complete false.

  • data_colours – deduplicated normalized data-mark colours retained for the post-export contrast check; chrome, separators, and colour-map ramps are excluded.

  • notes – human-readable diagnostic details accompanying failures or fallback decisions; notes do not independently determine complete.

reason() → str[source]

Return one sentence naming what stopped scene output.

property complete: bool[source]

Return whether no blocking translation or export failure was recorded.

spacr.figures.scene.build_scene(figure, *, mode=None, dpi=None)[source]

Translate a matplotlib Figure into a pyqtgraph scene.

Parameters:
  • figure – a drawn matplotlib Figure. It is NOT modified: everything here is a read.

  • mode – a spacr.figure_style.SAVE_MODES value, or None to ask the preference.

  • dpi – output resolution used to size the scene. By default, use the figure’s current resolution.

Returns:

(widget, report). The widget is a pyqtgraph.GraphicsLayoutWidget holding one plot per axes; the SceneReport says whether the translation was COMPLETE, and a caller must not write an incomplete one.

spacr.figures.scene.export_scene(widget, path) → str | None[source]

Write a built scene to path. PDF, SVG and PNG, by the name.

THE EXPORTER IS THE ONE THE TABS USE. FastPlot._export_pdf and _export_svg are classmethods over a plot item, and both go through _paint_scene, which turns pyqtgraph’s export mode on for every mark before painting – without it a ScatterPlotItem copies its cached marker PIXMAPS into the vector file, and a PDF full of little bitmaps of a dot is a PDF that claims to be vector and is not. Writing a second exporter here would recreate the same exporter duplication one level down.

Parameters:
  • widget – built pyqtgraph scene widget to export.

  • path – destination path; its suffix selects PDF, SVG, or raster export.

spacr.figures.scene.pyqtgraph_ready() → Tuple[bool, str][source]

(ok, reason): can a scene be built and exported here and now?

Starting a QApplication is licensed by this being the renderer that was chosen, not by a guess about a GUI. The offscreen platform is set only when there is no display, and it is MEASURED to work: with it, ImageExporter writes a PNG and a QPdfWriter writes a real vector PDF on a machine with no display at all.

spacr.figures.scene.render_figure(figure, path, *, fmt=None, mode=None, dpi=None, announce=True, title=None)[source]

Write figure as a pyqtgraph render. None when it could not be.

Parameters:
  • figure – the drawn matplotlib figure, used as the GEOMETRY. It is not written and not modified.

  • path – destination; the extension is settled by spacr.plot.figure_path() BEFORE the exporter sees it, because pyqtgraph decides what it writes from the file name.

  • dpi – output resolution used to size the scene. By default, use the figure’s current resolution.

  • announce – put the file in the gallery as well as on disk.

Returns:

(written_path, report), or (None, report). A caller that gets None writes the matplotlib page and says why.

NOTHING HERE RAISES. A figure is the last thing a run produces and the least important thing it produces; losing an hour’s fit to a renderer is the worst trade in this module, which is the same rule spacr.figure_sink.publish() follows.

spacr.figures.scene.requested_renderer() → str[source]

The renderer SPACR_FIGURE_RENDERER asks for, or 'auto'.

An unrecognised value is 'auto' rather than an error, for the reason spacr.figure_style.figure_save_mode() gives: a run must not lose its figures over a misspelt environment variable.

spacr.figures.scene.scene_renderer(force: str | None = None) → Tuple[str, str][source]

(renderer, reason) for a generated figure with NO interactive twin.

THIS IS A DIFFERENT QUESTION FROM THE ONE spacr.figures.fast_render.renderer_for() ANSWERS, and the difference is why there are two functions rather than one with a flag. There, the question is “is there a live widget to render, so the file can BE the tab”, and the answer must never be guessed – two attempts to detect a live GUI were built and both were wrong (a QApplication exists because matplotlib’s QtAgg backend made one; a module is imported because a test imported it). Here there is no widget to find and nothing to disagree with: the only question is whether this machine can paint with pyqtgraph at all, and that is answerable by trying it.

So auto means “pyqtgraph if it is available here”. A machine without Qt writes the matplotlib page it always wrote, and says so.

Parameters:

force – one of RENDERERS, overruling the environment.

Returns:

('pyqtgraph', '') or ('matplotlib', why). The reason is never empty for matplotlib, because “why does this figure not look like the others” is the question a user asks of it.

spacr.figures.scene.write_figure(figure, path, *, fmt=None, dpi=None, renderer=None, announce=True, title=None, **savefig)[source]

Write a generated figure with the screen’s renderer where that is possible.

THE ONE CALL A GENERATED-FIGURE MODULE MAKES. It replaces a spacr.figure_sink.publish() and behaves exactly like one when pyqtgraph is not the renderer, so a module adopting it cannot lose the gallery tile, the format preference or the resolution preference on the way past.

Parameters:
  • figure – drawn matplotlib figure whose artists become the scene, or which is saved directly when scene translation is unavailable.

  • path – destination path or stem; the configured or explicit format settles its final extension before either exporter writes it.

  • renderer – force one of RENDERERS; None asks scene_renderer().

  • dpi – force an output resolution; otherwise use the configured figure preference.

  • savefig – forwarded to matplotlib on the fallback path (bbox_inches and friends). pyqtgraph has no use for them.

Returns:

(path, renderer, reason). reason is why it is not the screen’s renderer, and it is empty only when it is.

THE FALLBACK IS NOT A FAILURE. A panel whose translation is incomplete – an artist nobody has taught this module, a formula it will not guess at – is written by matplotlib exactly as it always was. The picture is never the thing that is lost.

Nested helpers

_plain_text._script(match, table)

Translate an entire captured regex script run or none of it.

Parameters:
  • match – regex match whose first group is a super/subscript run.

  • table – Unicode translation mapping for that script position.

Returns:

the fully translated run when every character is supported; otherwise the original matched source unchanged, allowing the caller’s leftover-marker check to reject unsupported mathtext.

spacr/figures/scene.py:754