Skip to main content

scistackplot

Build the figure by looking at it, then keep it

scistackplot turns a long-format table into a figure from a small, serializable description — a PlotSpec. It works standalone on a CSV or a DataFrame with no database and no configuration, and the same PlotSpec is exactly what the body of a SciDB plot_ endpoint needs, so an interactive exploration can be frozen into a lineage-tracked pipeline step.

pip install scistackplot

The idea

A plotting GUI looks like it produces pictures. It doesn't — it produces a specification, and the picture is a view of it. That is what lets an inherently visual tool live inside a reproducible pipeline:

import pandas as pd
from scistackplot import DataFrameSource, PlotSpec, Role, PlotKind, render

source = DataFrameSource(pd.read_csv("gait.csv"))
spec = PlotSpec(
    measures=["StepLength"],
    roles={"session": Role.X, "limb": Role.COLOR, "subject": Role.FREE},
    kind=PlotKind.BOX,
)
figure = render(source, spec)

Every factor does exactly one thing

The whole control surface is one rule: each categorical column carries exactly one role.

Role Meaning
X x-axis position
COLOR one coloured series per level
FACET one subplot per level (arranged by FacetOptions)
ITERATE a separate figure per level
AGGREGATE collapse — average over this factor
FREE keep as replicate rows

Which plot kinds are available follows from that assignment plus the measure's shape, through one pure function:

from scistackplot import available_plots, default_plot, Shape

available_plots(Shape.SCALAR, {"session": Role.X})                    # scatter, strip
available_plots(Shape.SCALAR, {"session": Role.X, "trial": Role.FREE})  # + box, violin, bar

A distribution needs replicates, and replicates exist only when some factor is left FREE. That single rule produces both defaults and availability:

Measure shape no replicates with replicates
scalar scatter box / violin / bar + CI
1-D array one line per observation mean line + shaded error band
2-D heatmap mean heatmap

AGGREGATE deliberately does not count as replicates: it averages its factor away before anything is drawn. "Average over trials, then show the spread across subjects" is trial=AGGREGATE, subject=FREE.

Arranging the subplots

Faceted panels flow in order by default, wrapping at FacetOptions.wrap. When the arrangement matters, describe it with rules instead of positions:

from scistackplot import FacetOptions, MatchOp, Matcher, PlotSpec, Role

spec = PlotSpec(
    measures=["RawEMG"],
    roles={"ColName": Role.FACET, "subject": Role.COLOR},
    facet=FacetOptions(
        rows=[Matcher(op=MatchOp.STARTS_WITH, value="R"),
              Matcher(op=MatchOp.STARTS_WITH, value="L")],
        cols=[Matcher(op=MatchOp.ENDS_WITH, value="HAM"),
              Matcher(op=MatchOp.ENDS_WITH, value="TA")],
    ),
)

Rules describe a layout rather than a hand-arrangement, so the same FacetOptions applies to any variable whose panels are named the same way. Ops are starts_with, ends_with, contains, not_contains, equals and regex; a panel matching no rule lands in a trailing "other" row or column rather than vanishing.

Each panel is named on its y axis, not by a caption above it. A caption spends a strip of every row of the grid on text; the axis title is room the panel was already spending, so a 4x3 grid gets that height back for the data. The generated seaborn code says the same thing (g.set_titles("")), because the export must be the figure you previewed.

Ordering is not cosmetic

Zero-padded IDs ("01", "02", … "10") sort lexicographically into 1, 10, 2 under pandas' default — visibly wrong on an axis, and wrong in a way that looks like a data problem. LongTable carries each factor's real level order; sources that know better (SciDB knows its declared schema_key_types) supply it explicitly, and everything else falls back to a natural sort.

Rendering

Two backends translate the same reduced plot, so the interactive view and the exported figure cannot disagree:

from scistackplot import resolve, render_matplotlib, render_plotly

resolved = resolve(spec, table)          # all reduction happens here
figure  = render_matplotlib(resolved[0]) # export / pipeline — a Figure
payload = render_plotly(resolved[0])     # interactive — a plotly.js dict

render_plotly builds plain JSON and needs no plotly package.

Export: real code, not a call back into this library

from scistackplot import generate_plot_function

print(generate_plot_function(spec, table))
def plot_steplength(df, filename):
    import matplotlib.pyplot as plt
    import pandas as pd
    import seaborn as sns

    g = sns.catplot(
        data=df,
        x='session',
        y='StepLength',
        hue='limb',
        kind="box",
    )
    g.set_axis_labels('session', 'StepLength')
    return g.figure

Your pipeline gets ordinary seaborn code it can keep, edit, and read — no runtime dependency on this package. The spec is embedded in the docstring, so the GUI can reopen a figure you have since hand-edited.

Data sources

DataSource is a three-method protocol (describe, get_table, joinable_with). scistackplot ships CsvSource and DataFrameSource; scistackplotdb ships the SciDB one. Anything consuming the protocol — including the Plot Studio panel in the SciStack GUI — works identically against a lone CSV and a full project database.

Relationship to SciDB endpoints

Recording a figure is SciDB's job and is unchanged: name a function plot_, return a Figure, and finalized=True stores it as a queryable record with an embedded provenance stamp. scistackplot supplies the body of that function; scistackplotdb generates the for_each call around it.

See docs/claude/plotting-library-design.md.

Optional extras

pip install "scistackplot[mpl]"          # matplotlib + seaborn (export)
pip install "scistackplot[interactive]"  # plotly Figure objects

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scistackplot-0.1.26.tar.gz (104.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scistackplot-0.1.26-py3-none-any.whl (120.3 kB view details)

Uploaded Python 3

File details

Details for the file scistackplot-0.1.26.tar.gz.

File metadata

  • Download URL: scistackplot-0.1.26.tar.gz
  • Upload date:
  • Size: 104.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for scistackplot-0.1.26.tar.gz
Algorithm Hash digest
SHA256 4d3b93339d22d72bf6d0ef3d67576d778f98fd1339067b665afecd2832659fb2
MD5 4e044f6f67fe79f24cad00d4ebe2932a
BLAKE2b-256 4d32517c8d91618eb5dd314f4c242c1df3c20465a4c80c871b3df194ed9b6a19

See more details on using hashes here.

Provenance

The following attestation bundles were made for scistackplot-0.1.26.tar.gz:

Publisher: publish.yml on mtillman14/scistack

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scistackplot-0.1.26-py3-none-any.whl.

File metadata

  • Download URL: scistackplot-0.1.26-py3-none-any.whl
  • Upload date:
  • Size: 120.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for scistackplot-0.1.26-py3-none-any.whl
Algorithm Hash digest
SHA256 6158dec7614e3e6fb861d2cb2acd4f46cd8128bf63907e59ae938096550dc4a5
MD5 8d84d05ca2c6fb50bc642039f5ce7a31
BLAKE2b-256 46f821b66dcc2108f16da886fabdee31ca7c58cde7e2d5b3a13a91d2d40f8a09

See more details on using hashes here.

Provenance

The following attestation bundles were made for scistackplot-0.1.26-py3-none-any.whl:

Publisher: publish.yml on mtillman14/scistack

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.29

2 files

0.1.28

2 files

This release

0.1.26 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page