Skip to content

Releases

ggrust 0.9.0

Choose a tag to compare

@Zaf4 Zaf4 released this 15 Nov 14:14

Added

  • geom_band, as lets-plot: a band across the whole panel between xmin and xmax (vertical) or ymin and ymax (horizontal), mapped or constant (geom_band(xmin=1, xmax=2)), with edge lines and alpha on the fill only.
  • geom_bracket_dodge, as lets-plot: brackets between the dodged groups istart and iend of category x (ngroup, dodge_width), same bars, tips and labels as geom_bracket.
  • residual_plot (bistro), as lets_plot: from ggrust.bistro import residual_plot plots the residuals of a polynomial (method="lm", deg=) or local ("loess", needs statsmodels and scipy) fit of y on x, with a dashed line at zero and marginal densities; as_dict() matches lets_plot's.
  • image_matrix (bistro), as lets_plot: a grid of geom_imshow images from a 2D object array (cmap, norm, vmin, vmax, scale, spacer); the cells are inset_element figures, so it returns a PlotSpec. Empty (None) cells stay blank.
  • nudge_unit="size"/"px" on geom_text, geom_label, geom_text_repel, geom_label_repel and geom_bracket: the nudge is added in point diameters (2.2 px) or pixels after the coord, as lets-plot. alpha_stroke=True on geom_label and geom_label_repel fades the text and border by alpha too.
  • scale_identity(aesthetic, ...), the generic identity scale of lets-plot: a name or a list (scale_identity(['color', 'fill'])). The module of the per-aesthetic identity scales is now ggrust.plot.scale_identity_ (lets-plot's name), so ggrust.plot.scale_identity is the function.
  • joint_plot and qq_plot (bistro), as lets_plot: from ggrust.bistro.joint import joint_plot draws points, 2D bins or a 2D density with a dashed regression line and marginal histograms, densities or boxplots; from ggrust.bistro.qq import qq_plot draws a sample against a theoretical distribution (or two samples against each other) with the fitted line and marginal densities of the quantiles. joint_plot's as_dict() matches lets_plot's.
  • Animation, after gganimate: p + transition_manual("year", cumulative=False) draws one frame per value; animate(plot, nframes=, fps=, duration=, detail=, start_pause=, end_pause=, rewind=, width=, height=, dpi=) plans the frames as gganimate and returns an Animation (.frame(i), .save(), .to_gif(), .to_apng(), .to_html()). {current_frame}, {frame}, {nframes} and {progress} in the title, subtitle and caption are filled per frame. Notebooks show an HTML player (play, pause, slider); anim_save("x.gif") and ggsave(plot, "x.gif" | "x.png" | "x.html") write a GIF, animated PNG or player page. Scales are trained once, so axes stay fixed; stats and positions run per frame.
  • Animation states, after gganimate: p + transition_states("year", transition_length=1, state_length=1, wrap=True) holds each state and moves the marks smoothly into the next (rows matched by group; numbers and sizes eased, colours through CIE Lab, categories switch halfway), and ease_aes("cubic-in-out", y="bounce-out") picks tweenr's easing per aesthetic. Labels gain {closest_state}, {previous_state}, {next_state} and {transitioning}.
  • Animation over time, after gganimate: p + transition_time("year", range=None) spaces the frames evenly in time and moves the marks between the observed times (dates and date-times too), and p + transition_reveal("date", range=None, keep_last=True) grows lines, areas and polygons along a column with an interpolated end point while points travel along their group. Labels gain {frame_time} and {frame_along}.
  • Animation enter/exit effects and shadows, after gganimate: enter_fade(alpha=0), exit_fade(alpha=0), enter_grow(size=0) and exit_shrink(size=0) let marks without a partner in the next state fade, grow or shrink in and out over the transition (bars from the axis, lines and polygons from their centre; effects added with + apply in order); shadow_wake(wake_length, size=True, alpha=True, colour=None, fill=None, falloff="cubic-in", wrap=True, exclude_layer=None, exclude_phase=("enter", "exit")) trails moving marks with their last frames, and shadow_mark(past=True, future=False, exclude_layer=None, **styles) keeps earlier (or later) states in the background. Work with transition_states and transition_time.

Fixed

  • Animated GIFs are 2.5x to 22x smaller and about 3x faster to write: frames that come out pixel-identical are merged into one longer frame, and each later frame holds only the rectangle that changed, with unchanged pixels transparent (as gifski does). Frames of at most 255 colours keep their exact colours.
  • Animated lines and polygons whose point count changes between states now morph smoothly: points are inserted along the shape as gganimate (transformr) does, every shape gets at least 50 points, polygons are drawn clockwise and rotated for the least travel. The warning about points matched in order is gone.
  • Animation labels pad years to 4 digits (0001-01-01, as R), and a date-time column uses one label format for the whole animation: the time shows in every frame when any value has one, so midnight no longer prints the date alone next to frames with times (gganimate formats each frame alone; decided by the user).
  • Animations of a date or date-time column label states as dates ({current_frame}, {closest_state}, ...), not epoch numbers, and transition_time/transition_reveal reject a range of the wrong kind for the column (numbers for a date column, dates for a numeric one) with a SpecError.
  • ggsave(anim.frame(i), "x.png") writes that one frame as a still PNG (it wrote the whole animation as APNG); SVG, PDF and the notebook display of a frame are still too, and .gif of a frame is an ExportError.
  • A continuous legend over a single value shows one key at that value, as ggplot2, not about five near-identical ones (lets-plot #1267).
  • Legend keys with the same label but different values no longer merge (lets-plot #1129): scale_color_manual(labels=['A', 'A', 'C']) shows three keys, as ggplot2.

ggrust 0.8.0

Choose a tag to compare

@Zaf4 Zaf4 released this 08 Nov 09:45

Added

  • geom_streamline() / stat_streamline(), as R metR: ggplot(data) + geom_streamline(aes(x=, y=, u=, v=)) draws streamlines with one arrowhead half way along each line, per group and facet panel. Rows that form a complete regular grid are used as the field; scattered rows are first averaged onto a grid with velocity_grid() (gridded= forces either). Lines are integrated with streamplot() (density, minlength, maxlength, integration_direction, broken_streamlines). New stat-only aesthetics u and v. Not in lets-plot (see deviations.md).
  • velocity_grid(points, vectors, ...): average vectors at scattered points onto a regular grid (Gaussian-weighted nearest neighbours), as scVelo's compute_velocity_on_grid, without scVelo. Returns a VelocityGrid(x, y, u, v) that feeds streamplot() directly. Same values as scVelo 0.3.4 on the reference cases; about 7x faster.
  • density_outline(points, level=...): outline a 2D point cloud where its Gaussian kernel density falls to level times its peak, as scipy's gaussian_kde plus scikit-image's find_contours, without either. Returns an (x, y, path) frame for geom_path(). Same contours as scipy 1.17 / scikit-image 0.26 on the reference cases; about 10x faster.
  • kernel_density(values, at, bandwidth=...): the Gaussian kernel density of a 1D sample at given points, as scipy's 1D gaussian_kde (Scott, Silverman or a factor), returned as an (x, density) frame. Within 1e-13 of scipy's values on the reference cases.

ggrust 0.7.1

Choose a tag to compare

@Zaf4 Zaf4 released this 08 Nov 05:36

Added

  • streamplot(x, y, u, v, density=...): matplotlib's streamlines computed in Rust, no matplotlib needed. Returns a StreamplotSet with lines (x, y, group) and arrows (x, y, xend, yend, group) polars frames, ready for geom_path() + geom_segment(arrow=). Lines and arrows match matplotlib 3.10 exactly on the reference cases. Masked arrays and NaN/inf are treated as missing; a density that would need more than 1e8 mask cells raises an error instead of aborting.

ggrust 0.7.0

Choose a tag to compare

@Zaf4 Zaf4 released this 07 Nov 20:04

Changed

  • HTML output draws point layers with more than 5,000 markers on a canvas (was 50,000), so mid-sized scatters make much smaller pages. SVG and PNG output are unchanged.
  • Smaller interactive HTML: the interactive legend indexes keys per marker instead of wrapping runs of points, and point tooltips on canvas layers reuse the canvas coordinates. Rendering is unchanged.
  • PlotSpec, FeatureSpec and SupPlotsSpec + returns NotImplemented for operands it does not handle, so another object's __radd__(plot) runs: a plain class can extend + without subclassing PlotSpec. Unhandled operands still raise TypeError (Python's standard message). lets_plot raises in __add__ itself.

Added

  • grid[i] = figure on gggrid results replaces a cell in place (int or (row, column), negative from the end, None empties it), so grid[i] += layer adds a layer to one plot of a grid, nested grids included.
  • scale_x_dendro(leaf_levels=) / scale_y_dendro(leaf_levels=): dendrogram leaves that span a run of axis levels, {leaf: [levels]} (for example a tree over clusters beside a heatmap of their cells). The runs are placed end to end in the tree's order, each in its given order, and each leaf is drawn at the centre of its run, on either side, reversed, under coord_flip() and in gggrid(align=True). Every leaf needs a run, and a level belongs to one run; mistakes raise SpecError naming the leaf.
  • gggrid(axes=, axis_titles=), as patchwork's plot_layout(axes=, axis_titles=): "collect" (or "collect_x" / "collect_y") draws an axis that repeats in neighbouring plots once, on the outer plot of the run, and frees the room of the others; repeated axis titles become one, centred on the run's panels. Axes count as equal when their scales and axis theme match (use sharex / sharey) and, for x, they span the same columns (y: rows). Empty cells, nested grids and faceted plots break runs. A collecting grid keeps its panels equal (relative to widths / heights), as patchwork: the dropped room is shared by all panels. Default "keep".
  • guide_axis_nested() and key_range_manual(), as R legendry: brackets (or boxes) naming groups of an axis's breaks, past the axis labels or across the panel (side="opposite"). Groups as a mapping {group: [levels]} or key_range_manual(start, end, name); bracket="line" | "square" | "chevron", type="box", pad_discrete, angle; multi-line names with \n. Theme elements legendry_bracket, legendry_bracket_size, legendry_box, legendry_guide_spacing. Works on every side, coord_flip(), facets, gggrid(align=True), side band axes and the HTML zoom.
  • Side band panel theme elements, as R ggside's ggside.panel.*: theme(ggside_panel_border=, ggside_panel_background=) and their ggside_xside_panel_* / ggside_yside_panel_* forms, falling back to the main panel_border / panel_background. ggside_panel_border=element_blank() drops the side bands' frames and keeps the main panel's.

ggrust 0.6.2

Choose a tag to compare

@Zaf4 Zaf4 released this 06 Nov 08:06

Fixed

  • Interactive legend: clicking a key on a dense (canvas) point layer no longer blocks the page. The key dims at once and the canvas is redrawn once on the next frame; a double-click redraws one to two times instead of three.

ggrust 0.6.1

Choose a tag to compare

@Zaf4 Zaf4 released this 06 Nov 03:42

Added

  • Side band axis theme elements, as R ggside's ggside.axis.*: theme(ggside_axis_text, ggside_axis_ticks, ggside_axis_ticks_length, ggside_axis_minor_ticks, ggside_axis_minor_ticks_length, ggside_axis_line), each with _x, _x_top, _x_bottom, _y, _y_left, _y_right variants. Anything unset falls back to the main axis_* theme.
  • guide_axis_mark(): label a subset of an axis's breaks with leader lines (ComplexHeatmap's anno_mark as an axis guide). spread="nearest" or "even", link_width, padding. Works on discrete and continuous axes, every side, side bands, facets and gggrid(align=True).
  • Several side bands per axis: side_pos= on a ggside layer overrides ggside() for that layer, side_band= names a band (bands on one side stack outward in plot order), and side_size= sets a band's share of the panel. scale_xsidey_* / scale_ysidex_* take side_pos= and side_band= to set one band's axis.
  • Docs: the ggrust logo, and a showcase of plots on the README and docs home page.

Fixed

  • A y side band's own x axis now reserves room for its ticks and labels (it could overflow the canvas).
  • Blank side band axis labels no longer take up room.

ggrust 0.6.0

Choose a tag to compare

@Zaf4 Zaf4 released this 05 Nov 21:53

Highlights

  • Side panels and marginal plots: ggside-style side layers and lets-plot's ggmarginal().
  • Plot files: ggsave(plot, "x.ggrs") writes a self-contained plot file, ggload("x.ggrs") opens it.
  • Notebook output mode is now chosen with ggrust.display(mode).

Added

  • Side panels (ggside): geom_xside* / geom_yside* layers for tile, bar, col, histogram, density, point, boxplot, violin, line and text; scale_xsidey_* / scale_ysidex_*; ggside(x_pos=, y_pos=); theme(ggside_panel_scale*, ggside_panel_spacing*). Bands follow coord_flip, axis position= and HTML zoom.
  • ggmarginal(sides, size, layer), with the same spec as lets_plot.
  • .ggrs plot files: ggsave(plot, "x.ggrs") stores the spec, data (Arrow IPC) and registered fonts in one zip; ggload("x.ggrs") restores it (polars, pandas, pyarrow or dict data). Loading runs no code and verifies sizes and hashes.
  • ggrust.display("html" | "svg" | "png") picks what notebooks show: interactive HTML (default), static SVG without JavaScript, or PNG.
  • Boxplot tooltips show each statistic as a lets-plot style side tooltip.
  • Docs: a guide page and gallery section for the built-in ggplot2 extensions, with credits to the R packages.

Changed

  • ggtb() shows the layers menu by default; pass layers=False to remove it.

Breaking

  • The LetsPlot shim is removed. Delete LetsPlot.setup_html() calls; use ggrust.display(mode) to switch output. display is not in __all__, so from ggrust import * does not shadow IPython's display().

Fixed

  • Side band axes: discrete labels are no longer blanked and get room to fit; thin continuous bands keep at least one label.

ggrust 0.5.0

Choose a tag to compare

@Zaf4 Zaf4 released this 05 Nov 21:53

Highlights

  • Built-in ggplot2 extensions: ggsci palettes, ggbeeswarm, ggnewscale, ggpointdensity, ggrastr, gghalves/ggdist, ggpubr/ggpmisc statistics, ggforce marks, dendrograms, gghighlight and patchwork extras.
  • Secondary axes, axes on top/right, custom fonts, and an interactive legend in HTML output.
  • Read-only spec accessors: layer_data(), build() and plot properties.

Added

  • ggsci journal palettes: scale_color_* / scale_fill_* for npg, aaas, nejm, lancet, jama, jco, d3 and igv.
  • ggbeeswarm: geom_beeswarm, geom_quasirandom.
  • ggnewscale: new_scale_color(), new_scale_fill(), new_scale().
  • ggpointdensity: geom_pointdensity, stat_pointdensity.
  • ggrastr: rasterize(layer, dpi=300) draws a layer as an image in SVG and PDF.
  • gghalves and ggdist: half geoms, slabs and intervals for raincloud plots.
  • ggpubr / ggpmisc: stat_compare_means, stat_cor, stat_poly_eq.
  • ggforce: geom_mark_hull, geom_mark_ellipse, geom_mark_rect.
  • Dendrograms: hierarchical clustering, geom_dendrogram, scale_*_dendro and guide_axis_dendro (follow HTML zoom and pan).
  • gghighlight: grey out non-matching rows, with direct repel labels.
  • patchwork extras: tags, design layouts, insets and nested alignment.
  • geom_col, geom_rug and stat_ellipse (ggplot2 semantics).
  • Secondary axes: sec_axis, dup_axis, derive.
  • position= on x and y scales draws the axis on the top/right side, or both.
  • Custom fonts: register_font, register_font_dir, registered_fonts.
  • Spec accessors: PlotSpec.data, .mapping, .layers, .scales, .theme and more; with_data(); layer_data(i) and build() return the engine's computed data as polars frames. SupPlotsSpec gets figures, grid[i], with_figure(), with_layout() and more. New PlotIndexError.
  • Theme geom colors as lets-plot: defaults follow the theme flavor, the color names "pen", "brush", "paper" work everywhere, and theme(geom=element_geom(...)) is drawn.
  • Manual legends: manual_key= on every geom and layer_key(...).
  • gggrid captions via labs(caption=).
  • geom_boxplot(outlier_jitter=, outlier_seed=).
  • A style scale with an explicit na_value gets an "NA" legend key or colorbar swatch.
  • Interactive legend in HTML output: click legend keys to hide and show groups.

Fixed

  • Notebook HTML works in Google Colab (tooltips, toolbar and canvas layers were static there).
  • ipykernel is no longer a runtime dependency.

ggrust 0.4.0

Choose a tag to compare

@Zaf4 Zaf4 released this 05 Nov 21:53

Highlights

  • Arrow axis lines, oob= on color scales, and colorbar end labels.
  • HTML plots shrink to fit their container.

Added

  • element_line(arrow=, extent=) on axis lines: arrow heads and partial axis lines (for UMAP-style corner axes).
  • oob="censor" | "squish" on continuous color and fill scales.
  • guide_colorbar(label_position="ends"): min and max labels beside the ends of the bar.
  • lineheight on geom_text and geom_label.

Changed

  • A later style scale that sets a mapper (scale_color_manual after a default brewer scale, for example) now replaces the earlier one, as in ggplot2. Names, breaks, labels, limits, guide and trans still merge.
  • HTML plots wider than their notebook cell or docs column shrink to fit, keeping their aspect ratio. Tooltips and zoom keep working.

Fixed

  • gggrid(guides="collect"): each collected legend keeps its own figure's theme.
  • Horizontal colorbars reserve room for end labels so they no longer run into the title.

ggrust 0.3.0

Choose a tag to compare

@Zaf4 Zaf4 released this 05 Nov 21:53

Highlights

  • facet_grid, vector PDF output, and geom_curve.
  • corr_plot with a Rust correlation matrix.

Added

  • facet_grid: panels by columns and rows, row strips, free scales per grid column or row.
  • Facet label options: x_order/y_order, x_format/y_format, x_labwidth/y_labwidth on facet_grid, labwidth on facet_wrap, multi-line strips.
  • geom_curve (curvature, angle, ncp, spacer, arrow).
  • Vector PDF output from ggsave: paths, embedded subset fonts and images.
  • corr_plot (bistro).
  • Minor ticks and exponent_format.
  • halo_width / halo_color on geom_text and geom_text_repel.
  • Mapped hjust / vjust on geom_text and geom_label.

Changed

  • Faster zoom in ggtb plots: points are drawn on a canvas from 2,000 points, using a sprite atlas.

Fixed

  • Box zoom keeps the aspect ratio of coord_fixed panels.
  • exponent_format applies to HTML zoom labels.