Skip to content

Add duration curve and histogram plot types (#99) - #6

Open
PabloBotin wants to merge 1 commit into
mainfrom
issue-99-plot-types
Open

PabloBotin wants to merge 1 commit into
mainfrom
issue-99-plot-types

Conversation

@PabloBotin

Copy link
Copy Markdown
Owner

Closes Sienna-Platform#99.

Adds the two plot types the issue asks for. Neither existed; duration curves in particular are a standard power-systems deliverable.

Approach

Both are data transforms, not new drawing primitives — a duration curve is each series sorted descending, a histogram is binned counts. So the transforms live in the backend-agnostic core and route through the existing _plot_dataframe! path.

That means no new functions in the extension contract and no duplicated drawing code, so the two backends stay consistent by construction rather than by discipline — this repo's standing drift hazard.

The cost is that the recipes had to accept a non-temporal x axis. Both now dispatch on _is_temporal(time_range):

temporal (existing) numeric (new)
x values datetime2unix.(…) float.(…)
x label IS.convert_compound_period string x_label kwarg
ticks two endpoint labels backend auto-ticks
bars integrate over time, one bar/series one bar per row

API

plot_duration_curve and plot_histogram, each with !, _plotly, and _plotly! variants — 8 new exports, following the house pattern exactly. DataFrame input only for this first cut.

  • plot_duration_curve(df) — each column sorted descending vs percent of time; x_axis = :hours for elapsed hours instead.
  • plot_histogram(df) — bin count from Sturges' rule, overridable with bins. All columns share one common edge range so overlaid series stay comparable, and the top bin is closed on the right so the maximum sample is never dropped.

Verification

Full suite 178/178, exit 0, zero Error log events. Formatter idempotent.

Because this touches code every existing plot flows through, regression came first. Exercised directly against the real API — 25/25:

Regression (7): plot_dataframe still 3 series with a time-interval x label, both backends; temporal bar=true still aggregates to 3 series, both backends; temporal stack=true unchanged.

Duration curve (9): 3 series both backends; every series monotonically non-increasing; values preserved (sorted permutation of the source column); percent x spans exactly 0–100; :hours spans 0–47 for 48 hourly samples; invalid x_axis raises ArgumentError.

Histogram (9): 3 series both backends; Sturges default = 7 bins for n=48; explicit bins=12 honored; every series' counts sum to 48 (nothing dropped at the edges); all series share identical bin centers.

The temporal no-op claims were checked by reduction, not just by test: showticklabels went from !bar to !(bar && temporal) and barmode gained an overlay branch — both reduce to their previous values whenever temporal is true, and no pre-existing caller can reach the new numeric branch, since a non-DateTime axis previously threw in datetime2unix.

Known limitations

  • x_label now overrides the time-interval label on temporal plots too, since _x_axis_label is something(x_label, interval_string). No existing caller passes x_label, so behavior is unchanged in practice, but it is technically a new capability on every plot function. It is documented only on the new functions — the shared docstrings were left alone to avoid colliding with the pending PA-migration PR.
  • plot_histogram's time_range argument is accepted and ignored; it exists only to mirror plot_dataframe's signatures.
  • The histogram's default x_label is the column name when there is exactly one column, else "Value".
  • DataFrame input only — PowerData/Results overloads were deliberately skipped because that code is being rewritten by the PA-migration PR.

Conflict surface

Deliberately avoids _plot_demand!, _plot_fuel!, _plot_powerdata! and _signed_stack_bounds, so it does not overlap the PowerAnalytics migration PR.

Neither of the plot types requested in Sienna-Platform#99 existed. Both are data transforms
rather than new drawing primitives, so they are computed in the
backend-agnostic core and routed through the existing `_plot_dataframe!`
path. No functions were added to the extension contract and no drawing code
is duplicated, which keeps the two backends consistent by construction.

`plot_duration_curve` sorts each column descending and plots it against
percent of time, or against elapsed hours with `x_axis = :hours`.
`plot_histogram` bins every column over one common edge range so overlaid
series stay comparable, defaulting the bin count to Sturges' rule and
accepting an explicit `bins`.

Supporting this required the recipes to accept a non-temporal x axis. Both
now dispatch on whether the axis is a `TimeType`: the temporal path is
unchanged, while a numeric axis uses its values directly, takes its label
from `x_label`, ticks automatically, and draws bars per row rather than
integrating over time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

new plot types

1 participant