Pitfalls#
This page collects limitations that can otherwise produce plausible but incorrect figures, following the prominent pitfalls guidance used by statsmodels.
Coordinate transforms on collapsed axes#
Collapsed mode is a registered matplotlib x-scale. Ordinary ax.transData artists and
public blended transforms with an x-data component, including
ax.axvline(timestamp), pass through that scale. Axes-, figure-, display-, and custom
transforms do not automatically become date-bearing; use native matplotlib semantics for
those coordinate systems.
Collection observation discovery#
Lines, scatter collections, and fill_between polygons retain matplotlib date
numbers and render correctly before or after collapse. All three contribute observations
automatically. Polygon discovery reads only the source-side vertices of each native
fill_between path. Closing vertices and boundaries generated by
interpolate=True never become observations; masks, NaNs, and where=False regions
do not contribute because Matplotlib omits them from the retained paths.
Matplotlib does not retain enough information to recover the original interior dates from
step="mid" polygons. Supply the complete source sequence explicitly for that form:
handle = gs.dates(ax, data=dates).collapse()
fill_betweenx remains unsupported on an x-date handle, and polygon transforms other
than ax.transData fail with ggstyle.DateDiscoveryError. These checks happen
before a registry revision is committed.
Dates between observations#
ggstyle.DateAxis.loc() interpolates a missing date between neighboring
observations. Use snap=True to select the nearest observation or strict=True to
reject dates that were not observed.
Timezone display#
Timezone-aware inputs are converted to naive UTC instants for positioning.
ggstyle.DateAxis.tz() changes labels only. For naive input, display-timezone
conversion assumes that the original values represent UTC.
Input interpretation#
Whole data frames, scalar dates, and string-typed pandas or polars columns are rejected. Select one column and convert it to a datetime dtype explicitly. This prevents accidental interpretation of identifiers or ambiguous date strings.
Missing explicit dates#
Explicit data containing missing dates raises by default. missing="drop" excludes
those values and records their count in ggstyle.DateAxis.summary(). Missing x-values
already present in a line are treated as intentional line breaks and are not counted.
Synchronized collapsed panels#
Calling ggstyle.DateAxis.collapse() independently on several panels can assign
different ordinal positions to the same date. Use ggstyle.sync_dates() when panels
are intended for comparison.
Synchronization uses one live, revisioned registry. After changing plotted artists, call
ggstyle.DateAxis.refresh() on any member. The refresh rescans every member and
updates their transforms in one transaction while preserving view limits.
Refresh boundaries#
Refresh discovers ordinary data-space lines and scatter offsets. A date-bearing line or
scatter collection using a custom x transform is rejected with
ggstyle.DateDiscoveryError; ggstyle does not guess whether arbitrary display or
axes coordinates are dates. Native axvline blended transforms and ggstyle-managed
annotations and grids are presentation elements and do not contribute observations.
Native fill_between polygons are also discovered when their vertices use
ax.transData. Arbitrary third-party collection subclasses are not accepted. Version
0.3 uses strict exceptions only and has no permissive warning mode.
Raw numeric coordinates on an axes whose date converter was installed by another artist
remain inherently ambiguous. Supply complete explicit data= whenever numeric values
are intended to represent date numbers.
Existing-axes themes#
An rcParams theme fully controls artists created inside its context. Applying a theme
later through ggstyle.finish() changes only properties that are safely retroactive.
It does not recolour data, replace the axes property cycle, resize the figure, or rewrite
line defaults. Inspect result.diagnostics or a dry-run plan for the preserved
creation-, data-, and output-time settings.
Direct-label eligibility#
Endpoint labels use public legend participation, so labels beginning with an underscore
are ignored. Every visible participant must be an ordinary data-transform Line2D on
a rectilinear axes. A mixed line/scatter plot does not receive a misleading partial set:
it falls back wholly to a legend by default or raises when fallback="raise".
Semantic-guide ownership#
ggstyle.guides() preserves caller-owned legends and colorbars and manages only the
objects returned in ggstyle.GuideResult. Consequently ax.get_legend() still
refers to the caller-owned axes legend; use result.legends for semantic legends.
Passing enabled=False removes managed semantic guides without touching native ones.
Automatic layout is capped at four distinct legends and four distinct colorbars on one
axes. Use facets or explicit Matplotlib guides beyond that boundary.
Semantic frame inputs#
Semantic helpers accept named one-dimensional columns from pandas, Polars, and ordinary
mapping-like frames without mutating the input. Materialize a Polars LazyFrame with
collect() first. Duplicate column names, unequal column lengths, and expression-like
arguments are rejected rather than guessed. Numeric color is continuous by default;
pass ggstyle.DiscreteScale when numeric codes represent categories. A continuous
color must be constant within each resolved line or ribbon because each native artist has
one color, while points may vary per observation.
Figure export#
ggstyle.save() refuses to overwrite by default and never creates parent
directories. Tight bounds crop the nominal canvas around decorated content; use
bbox="standard" when exact raster dimensions are the contract. Metadata support is
defined by the selected Matplotlib backend rather than normalized across formats.