Changelog
Source:NEWS.md
ggchord 0.10.0 (development version)
Fixed labels and publication defaults
geom_feature()now draws independent"arrow","block","chevron", and"lollipop"geometries along each sequence’s real local curve. Mapfeature_shapeand control category-to-geometry values with the newscale_feature_shape_manual(); fixedfeature_shapevalues remain available directly in the geom. Legend keys use the same silhouettes as the plot.Sequence grouping has been removed.
geom_seq_group_label(),scale_group_colour_manual()/scale_group_color_manual(), and allseq_group*arguments ingeom_seq()no longer form part of the package. Passing a removed grouping argument or aesthetic now produces a direct migration error instead of silently changing sequence spacing.geom_ribbon()now uses a darker neutral default outline (#59636D) so ribbon boundaries remain legible after transparency is applied. Explicit outline colours andribbon_colourscales still take precedence.geom_gene_label()is now the single fixed/manual label layer; no separategeom_gene_label_manual()is planned. It addsgene_label_orientation = "horizontal" | "radial" | "tangent",gene_label_side = "outside" | "auto" | "inside", andgene_label_overlap = "hide" | "nudge" | "allow". The new defaults keep fixed labels horizontal and outside the chord, and deterministically omit later colliding labels in input order. Existing per-sequence/per-strand rotation and offsets remain available for direct control; automatic leader-line placement remains the responsibility ofgeom_gene_label_repel().The Identity colourbar now has compact physical dimensions instead of filling the available device height. Its title is
Identity (%), its default breaks are less crowded, and vertical and horizontal guides remain stable when the export size changes. The initial compact bar was lengthened slightly after visual review.Automatic coordinate fitting now keeps independent tight x/y ranges instead of padding both dimensions to a square.
coord_fixed()still preserves the geometry’s physical aspect ratio, while the panel uses wide or tall devices more efficiently.coord_chord()now defaults toexpand = FALSEbecause automatic fitting already includes a small safety margin. The default plot also retainstheme_ggchord()’s small outer margin; the deprecatedpanel_marginargument only overrides it when explicitly supplied.The default theme now uses a white export-safe canvas, quieter axes, a smaller title and tighter legend spacing. Sequence strokes and arrowheads are lighter, ribbon opacity is slightly increased, and strand keys use slim arrows that point in opposite directions for
+and-. Colourbar titles now have a physical gap from the bar, and vertically stacked legend groups have slightly more separation. Package examples use a conventional 4:3 canvas; external RStudio/graphics-device dimensions remain under user control, as in ggplot2.The visual hierarchy is informed by Circos’ restrained circular information design, clinker’s publication-oriented gene arrows, DNA Features Viewer’s annotation collision handling, and the local annotation/crowding behaviour documented by SnapGene and Geneious. ggchord uses its own palettes, generic API names, geometry and key glyphs rather than copying third-party assets.
ggchord 0.9.0
Release audit
The v0.9.0 public API was audited across constructors, geoms, role-specific scales, themes, guides, coordinates, data utilities and import helpers. Layer-local data/mappings, same-type layer isolation, old/new scale conflicts and plot-owned layout retrieval were rechecked against the final v0.9.0 interface.
The obsolete, unused
ggchord_label_pad()internal helper and its generated help page were removed. Adaptive limits remain the single implementation used to fit rendered label boxes.ggchord()now reuses the structured validator for its always-on safety checks instead of maintaining a second validation rule set. Validation also stops advanced coordinate and duplicate calculations when malformed numeric columns make those calculations unsafe, returning a complete report rather than a secondary type error.
Static rendering focus
The experimental Plotly conversion method and dependency have been removed. v0.9.0 focuses on deterministic ggplot2 output; a future interactive design will be considered separately after the static API is stable.
Default discrete colours now use a colour-vision-friendly palette (with a qualitative HCL fallback for larger sets). Strand colours, sequence and gene outlines, ribbon separation, highlight colour and legend key glyphs were recalibrated for clearer screen, PDF and greyscale output. These defaults remain fully replaceable through the role-specific scales and geom styles.
Data correctness and import fixes
clean_ggchord_data(unknown_id = "keep")now retains unknown gene rows without attempting coordinate checks against a missing sequence length. Sorting reversed ribbon intervals records their original same/reverse direction so drawing does not silently change alignment orientation.Ribbon filtering reports every removal reason for a row;
deduplicate_ggchord_ribbons(keep = "first")now means the first input row; andmerge_ggchord_ribbons()no longer leaves stale values in disagreeing auxiliary columns. Useextra_columns = "first"to request the previous first-row behaviour explicitly.BLAST outfmt 7 imports now parse and validate
# Fields:instead of assuming a fixed 17-column layout. GFF3 parsing stops at##FASTA. All three import helpers can add.source_filewithsource_file = TRUE.Unknown ribbon and gene sequence IDs now have the same severe validation level. Skipped duplicate checks for exceptionally large pair groups are reported rather than omitted silently. Feature categories, region outlines, curved-region side selection and highlight argument validation were fixed.
Layer-specific data and geometry
Every ggchord layer now receives a stable
layer_idand its own geometry registry entry. Multiple gene, feature, region, ribbon, highlight, axis or label layers no longer reuse the last layer’s data and parameters.Layer
dataand role mappings such asaes(seq_id = chromosome, start = from)are evaluated against that layer’s input. Original columns are joined back to expanded geometry throughsource_row, so ordinary visual mappings remain available during the ggplot2 build.get_chord_layout(plot, build = TRUE)retrieves the layout owned by a specific plot. Callingget_chord_layout()without a plot still works for compatibility but is deprecated because “most recently built plot” is ambiguous when plots are built in an interleaved order.Sequence reference paths are cached within one build and reused by independent same-type layers. The cache is local to that build and cannot leak geometry between plots.
Role-specific scales
Sequence, group, ribbon, gene, feature and region layers now use independent role aesthetics:
seq_colour,group_colour,ribbon_fill,ribbon_alpha,ribbon_colour,ribbon_linetype,gene_fill,feature_fillandregion_fill. Their publicscale_*()constructors can coexist in one plot without replacing another layer’s fill or colour scale.scale_seq_position_continuous()controls genomic major/minor breaks and labels. It is trained independently against each sequence length.scale_group_color_manual()andscale_ribbon_color_manual()are available as American-English aliases of theircolourcounterparts, matching ggplot2’s spelling convention.Old scale-like geom arguments remain functional during v0.9.0 and emit one migration warning per session. Supplying both an old argument and the new role scale is an error rather than silently choosing one. Principal migrations are:
| Old geom argument | New interface |
|---|---|
seq_colors, seq_group_colors
|
scale_seq_colour_manual(), scale_group_colour_manual()
|
ribbon_colors, colour limits/breaks/name |
scale_ribbon_fill_*() |
ribbon_*_by |
the corresponding aes(ribbon_* = ...)
|
ribbon_alpha_range |
scale_ribbon_alpha_continuous(range = ...) |
| ribbon outline/linetype/direction visual values | ribbon colour/linetype/alpha scales |
gene_colors, gene_order
|
scale_gene_fill_manual() |
feature_colors, feature_order
|
scale_feature_fill_manual() |
| axis major/minor counts and labels | scale_seq_position_continuous() |
Coordinate, theme and guide helpers
coord_chord()now owns global rotation, aspect ratio, clipping and view fitting.fit = "labels"measures annotation boxes,fit = "geometry"fits only geometric marks, andfit = "manual"requires explicit limits. User-supplied limits take priority, and replacing it with another ggplot2 coordinate system is no longer silently undone during the build.theme_ggchord(),theme_ggchord_minimal(),theme_ggchord_dark()andtheme_ggchord_publication()provide a small set of composable themes. Dedicated theme elements are registered for axes, sequence/group labels, gene labels and leader segments; data-driven colours remain scales.guide_ggchord_legend()andguide_ggchord_colourbar()are thin wrappers around ggplot2 guides with compact chord-diagram defaults. Existingggchord()argumentstitle,rotation,panel_marginandshow_legendremain functional in v0.9.0 but point users tolabs(),coord_chord()andtheme()respectively.
Geom and annotation interfaces
Gene, sequence and axis text sizes are now fixed layer values rather than a shared
sizescale, so adding one label layer cannot rescale another. Registered axis, sequence-label, gene-label and leader-line theme elements are resolved before the standard ggplot2 build; an explicit geom style still takes priority.geom_axis()routes shared styles only to compatible child geoms and accepts separateline_params,tick_paramsandtext_params. Its formershow_legendargument is removed because axis annotations never participate in a legend.geom_seq_group_label()provides an independent group-label layer, while the labels created implicitly bygeom_seq()remain available for compatibility. Group values now trainscale_group_colour_manual()instead of treating already-resolved colour strings as categories.geom_seq_label(labels = ...)separates displayed sequence text from scale labels;seq_labelsremains a deprecated alias. Label arguments passed togeom_gene()now fail clearly instead of being warned about and then leaked intogeom_polygon(). Geom-level legend positions and colourbar dimensions remain functional during v0.9.0 but direct users toguides().
Deterministic gene-label layouts
geom_gene_label_repel()now uses the deterministicgene_label_layout = "aligned" | "radial" | "arc"interface."aligned"remains the default and arranges horizontal labels on orderly cardinal rails."radial"uses the nearest collision-free local offset track while keeping text horizontal."arc"rotates readable text along the sequence tangent and draws a short leader only when a label has moved away from its first track.All modes now use each sequence’s real curve and local normal, including custom
seq_radius,seq_curvature,seq_gap, mixedseq_orientation, rotation and sequence groups. They share fixed-obstacle avoidance, cross-sequence collision handling, order-preserving leader routing and device-aware clipping. Rotated labels use oriented-rectangle collision and clipping, preventing spurious whitespace and oversized breaks in leaders.The layout ideas are informed by orderly multi-sequence callout figures and by the external/inside feature-label approaches offered by SnapGene and Geneious. ggchord uses its own generic mode names and implementation; it does not copy third-party assets or visual designs. See the SnapGene feature-label documentation and Geneious label options.
Breaking API simplification
geom_gene_label_repel() now has the following focused interface:
geom_gene_label_repel(
mapping = NULL, data = NULL,
gene_label_layout = "aligned",
gene_label_size = NULL, gene_label_wrap = NULL,
gene_label_side = "outside", max_overlaps = Inf,
gene_label_segment_linetype = "auto",
show_legend = FALSE, ...
)Removed arguments fail immediately rather than being silently ignored:
| Removed argument(s) | Migration |
|---|---|
gene_label_rotation, gene_label_radial_offset, gene_label_circum_offset, gene_label_circum_limit
|
Use geom_gene_label() for manual rotation or offsets. |
box_padding, point_padding, min_segment_length, force, seed
|
Select an automatic gene_label_layout; collision and line settings are managed by the mode. |
gene_label_orientation, gene_label_segment
|
Use gene_label_layout = "aligned", "radial", or "arc". |
This was the v0.9.0 interface. v0.10.0 subsequently strengthens the existing fixed-position geom_gene_label() instead of introducing a separate manual geom; see the development section above.
ggchord 0.8.0
CRAN release: 2026-08-24
New features: improved label placement and de-overlap
geom_seq_label()now places sequence names on the arc by default (seq_label_radius = 1) and rotates them along the arc while keeping them readable;seq_label_orientation = "horizontal"draws every label horizontally, extending away from the chord centre.geom_gene_label()now sits right beside the gene arrows by default (gene_label_radial_offset = 0.04) and gainsgene_label_wrapfor wrapping long annotations into narrower, less overlapping labels.geom_gene_label_repel()now defaults togene_label_orientation = "horizontal",gene_label_segment = "elbow"(an L-shaped leader line that adapts to each label’s position and text width) andgene_label_side = "outside", so labels stay readable and out of the ribbon area. A deterministic final de-overlap pass measures the exact rendered text boxes and treats the sequence, group and axis labels as hard rectangular obstacles;max_overlapshides labels that still collide after repulsion (ggrepel-style decluttering).The label text-box projection is now shared by the repulsion solver, the obstacle boxes and the coordinate limits, so all three agree on where text will actually be drawn.
New features: adaptive plot limits
- Plot limits now fit the rendered text boxes instead of adding one global text-width pad on every side. The actual gene/sequence/group/axis label boxes are measured and only the sides that need it are expanded, reducing empty margins and using the panel area more efficiently.
New features: sequence grouping
geom_seq()gains sequence-grouping support viaseq_group,seq_group_gap,seq_group_labels,seq_group_label_radiusandseq_group_colors. Groups can come from aseq_groupcolumn inseq_dataor be supplied as a single value, a named/positional vector, or a list.An extra inter-group gap (
seq_group_gap) is inserted only at boundaries between different groups, and optional group labels are drawn at the angular midpoint of each group, at a customisable radius.Group labels are rendered horizontally and use their own internal
zcolouridentity scale, so they never interfere with the Seq ID colour legend.geom_seq()stays backward compatible and still returns a single layer; group labels are appended lazily at build time.
New features: ribbon visual mappings and direction
geom_ribbon()can now map any numeric column to a continuous fill viaribbon_color_by(for example"bitscore"instead ofpident), withribbon_color_limits,ribbon_color_breaksandribbon_color_nameto control the colourbar.ribbon_alpha_by/ribbon_alpha_rangescale ribbon transparency continuously from a numeric column.ribbon_outline_by/ribbon_outline_colorsandribbon_linetype_by/ribbon_linetypesmap discrete columns to outline colour and linetype using internal aesthetics, without disturbing the Seq ID or Identity(%) legends.ribbon_direction(one of"none","alpha","outline"or"linetype") visually distinguishes same- vs reverse-orientation alignments, withribbon_direction_colors,ribbon_direction_linetypesandribbon_direction_alphafor fine control.legend_key_width/legend_key_heightcontrol the size of the Identity(%) colourbar key.
New features: highlights and generic features
New
geom_seq_region()draws rectangular bands along sequence arcs to mark loci, repeats, CRISPR arrays or other user-defined intervals. It acceptsseq_id,startandend(plus optionallabel,categoryandcolor) and exposesregion_fill,region_color,region_alpha,region_width,region_offsetandregion_side.New
geom_ribbon_highlight()emphasizes selected ribbons without changing the underlying Identity(%) legend. Selection uses safe, explicit filters (ribbon_ids, query/subject IDs, pident/length ranges, or a predicate function) and reuses the computed ribbon geometry.New
geom_feature()is a thin, backwards-compatible convenience layer for CDS, tRNA, rRNA, repeat, CRISPR, promoter and custom feature tables; it prepares a gene-compatible table and reusesgeom_gene()’s geometry and scales, withfeature_colors,feature_width,feature_offsetandfeature_orderfor styling.
Documentation
- Added man pages and runnable examples for the new layers (
geom_seq_region(),geom_ribbon_highlight(),geom_feature()) and expanded the documentation for the updatedgeom_seq(),geom_ribbon(),geom_seq_label()andgeom_gene_label_repel()parameters.
ggchord 0.7.0
New features: structured data validation and cleaning
New exported function
validate_ggchord_data()returns a structuredggchord_validationobject: avalidflag,errors(severe problems),warnings(drawable but noteworthy issues), per-categorysummarycounts, adata_summary(sequences/ribbons/genes, unknown IDs, out-of-range rows, …), the original row numbers of every problem (invalid_rows) and the automatically fixable issues (cleanable).print()andsummary()methods are provided;strict = TRUEstops on severe problems.New exported function
clean_ggchord_data()applies explicit, conservative policies (unknown_id,out_of_range,reversed_interval,invalid_pident,empty_annotation) and returns the cleaned tables plus a full report of every change (original row number, reason, original/new values, action). The input objects are never modified and nothing is dropped silently.ggchord()gains avalidate = c("warn", "error", "none")argument. The default"warn"emits a single summary warning (never one warning per row) and caches the full report on the plot (p$ggchord$validation);"error"stops on severe problems;"none"keeps a fast path. Valid input renders exactly as before.
New features: data import and ribbon preparation
read_blast()parses BLAST-outfmt 6/7tabular output (12 or 17 columns, auto-detected) intoribbon_dataformat, preservingevalue,bitscore,qcovs,qlen,slen,sstrandandstitlewhen present.read_gff3()parses GFF3 files intogene_dataformat, selectingfeature_types(defaultCDS), extractingannofrom attribute keys (product,Name, …), decoding percent-encoding, and mapping unstranded features to+(or dropping them).read_fasta_lengths()reads FASTA headers and sequence lengths intoseq_dataformat, with optionalheader_delimsplitting.filter_ggchord_ribbons()filters ribbons by sequence IDs, pident, length, E-value, bitscore, query/subject coverage, undirected sequence pairs and self-links, with optional sorting; missing columns produce clear errors.deduplicate_ggchord_ribbons()removes exact, coordinate-near or highly overlapping duplicate blocks (by = "exact" | "coordinates" | "overlap") keeping the best pident, longest, or first representative.merge_ggchord_ribbons()merges adjacent/overlapping blocks of the same sequence pair with length-weighted pident. Merging is deliberately conservative: blocks with inconsistent spans, large pident differences or different orientations are left unmerged.All ribbon utilities keep extra columns and the original column order, attach the original row numbers as the
source_rowsattribute, and return a report of what was removed/merged and why.
ggchord 0.6.0
New features
Plot objects are now fully self-contained: data and parameters are stored on the plot itself instead of in a package-wide environment. Multiple plots can be created and built independently in the same session, and plots survive
saveRDS()/readRDS().The layout is now computed by
ggplot_build()rather than by a customprint()method. As a resultprint(),ggsave(),ggplot_build()and other standard ggplot2 workflows all work directly on ggchord plots, and rendering no longer modifies the user’s plot object.New layer
geom_seq_label(): places sequence labels at the midpoint of each sequence arc with control over radial offset (seq_label_radius), rotation (seq_label_rotation) and font size (seq_label_size).New ribbon color scheme
"subject": colors ribbons by the subject sequence (saccver), complementing the existing"query"scheme.The layout accessor
get_chord_layout()is now exported, making the computed geometry available for custom layers and annotations.Themes, scales and other ggplot2 objects can now be added with
+(e.g.p + theme(legend.position = "bottom")), and user-supplied colour/fill scales are respected instead of being overwritten.ggchord()now warns about suspicious input data: reversed or out-of-range alignment/gene coordinates,pidentoutside [0, 100], and sequence IDs that are not present inseq_data.geom_gene_label_repel()gainsgene_label_side = "auto" | "inside" | "outside". With"outside", labels that would sit inside the chord (where they can overlap the ribbons) are mirrored to the outside of their sequence arc, keeping the same radial distance from the arc.New
gene_label_segment_linetypeargument controls the leader-line linetype. The default"auto"draws solid lines, except for labels that were moved to the other side of their arc (gene_label_side), which are drawn dashed. Any other valid ggplot2 linetype (e.g."dotted"or a numeric dash pattern) is applied to all leader lines.Elbow leader lines no longer force fixed segment lengths: the stub scales with each label’s text width and the horizontal space available between the gene and the label, so labels can be placed more flexibly without degenerate (near-zero) stubs.
geom_seq_label()now documents and follows the intendedseq_label_radiussemantics:1sits on the arc,> 1places the label outside (away from the chord center) and< 1inside. Previously the multiplier was applied in the opposite direction (the default1.15put labels inside the chord).New
geom_seq_label()options:seq_label_orientation = "arc" | "horizontal"(horizontal labels extend away from the chord center),seq_label_hjust/seq_label_vjustfor per-sequence justification, andcheck_overlapto skip labels that would overlap.The default theme no longer draws grid lines (
panel.gridis blank) and legend keys are transparent (they blend into the plot background instead of a fixed white rectangle).
Performance
- Replaced the linear angle lookup in the layout mapping with a binary search (
findInterval), speeding up layout computation for large plots.
Dependency changes
- Declares
ggplot2 (>= 4.0.0)andR (>= 4.1.0)to match the implementation (the package relies on ggplot2 4.x internals).
Infrastructure
- Added a GitHub Actions
R CMD checkworkflow (macOS, Windows, Linux). - Removed the internal legacy
fill_ggnewscale_1aesthetic name in favour offill_ribbon.
Bug fixes
Tests no longer write to a hard-coded
/tmppath: they usetempfile(), so the test suite passes on Windows and leaves no stray files behind forR CMD check(fixes the CRAN incoming-check failure).The Identity(%) colourbar no longer collapses into a thin/invisible line when the legend is placed at the top/bottom or the legend box is horizontal (
legend.box = "horizontal"). It now follows the theme’s legend position: a vertical bar filling the available height at the left/right, and a fixed-size horizontal bar at the top/bottom.Legend keys are transparent and do not inherit
panel.background(ggplot2 4.x lets unset legend keys follow the panel background, so the key fill is set explicitly to stay transparent).Sequence (and gene) labels no longer end up upside down when a global
rotation >= 90is used: the readability flip is now re-applied after the layout rotation instead of only before it.The repulsion spring now pulls labels toward their own starting position rather than the leader-line anchor, which keeps labels moved with
gene_label_side = "outside"on the outside while their leader line still starts at the gene.With
gene_label_side, every label is kept on the requested side of its arc (previously only the labels moved by the side switch were re-checked, so a crowded repulsion layout could push other labels across the arc).The built-in
gene_data_exampleannotations no longer contain URL-encoded%2Cartifacts (e.g. “ribonucleotide reductase%2C large subunit” is now “ribonucleotide reductase large subunit”).
New features
Each legend can now be positioned independently via the
legend_positionargument ofgeom_seq(),geom_ribbon()andgeom_gene()(e.g.geom_ribbon(legend_position = "bottom")). Legends without an explicit position stay together attheme(legend.position = ...).Parameter specification is now more flexible and human-friendly. Sequence parameters accept a single value, vectors, vectors/lists named by sequence ID, lists named by sequence order (
"1","2", …) and unnamed lists; gene parameters additionally accept per-strand (+/-) specifications in any of those forms (e.g.gene_label_rotation = c("+" = -15, "-" = -45)orlist(c("+" = -15, "-" = -45), ...)), including length-one lists that recycle.
ggchord 0.5.0
New features
- Added ribbon outline customization to
geom_ribbon():ribbon_outline_color(default"black"),ribbon_outline_width(default0.05) andribbon_outline_linetype(default1, solid).
Dependency changes
- Removed the
ggnewscaledependency. The ribbon and gene fill scales are now kept independent via an internal renamed-fill aesthetic, so no external package is required for plots with both ribbon and gene layers. - Removed the
RColorBrewerdependency. The default Set1 categorical palette is now built into the package, so the rendered default colors are unchanged.
Bug fixes
- Fixed the ribbon fill scale being overwritten by the gene fill scale when both
geom_ribbon()andgeom_gene()were present (previously produced wrong ribbon colors and a “Scale for fill is already present” message). - Fixed
ribbon_alpharendering at the wrong opacity (e.g.0.35was drawn as ~0.55); the alpha value is now applied exactly as specified. - Fixed
geom_axis(show_axis = FALSE)failing with “object ‘label’ not found”. - Fixed
axis_label_orientationrejecting mixed vectors such asc("horizontal", 45, ...). - Fixed warnings from
brewer.pal()when fewer than 3 sequences or gene annotations are used (two-sequence plots now render cleanly). - Fixed an error when
geom_gene()was added beforegeom_ribbon()(“Continuous value supplied to a discrete scale”). - Fixed plots containing only
geom_axis()where the axis path was misclassified as a sequence arc. - Registered
+.ggchordandggplot_build.ggchord()as proper S3 methods and aligned theggplot_build.ggchord()signature with the generic.
Documentation
- Translated all code comments and user-facing messages to English.
- Added man pages for previously undocumented exported functions (
geom_seq(),geom_ribbon(),geom_gene(),geom_axis(),coord_chord(),+.ggchord()and others). - README: added per-column data preparation tables with example rows, rendered example plots under
examples/plots/, generalized the package description beyond BLAST, and documented the ribbon outline parameters. - Rewrote the package vignette for the layered
ggchord() + geom_*API.
ggchord 0.4.0
Changes
- Parameter redistribution: layout parameters moved from
ggchord()into the individualgeom_*layers;ggchord()now only validates data and sets global style (title,rotation,panel_margin,show_legend,debug). - Deferred computation: the coordinate layout is computed at
print()time, collecting parameters from all layers during rendering. - Custom
print.ggchord()method: merge parameters, compute the layout, inject data into layers, then render. - Added 15 unit tests.
ggchord 0.3.0
- Layered API refactoring: split the monolithic function into
ggchord() + geom_seq() + geom_ribbon() + geom_gene() + geom_axis(). - Custom
+.ggchordmethod that flattens layer lists automatically. - Lightweight
coord_chord()coordinate system.
ggchord 0.2.0
CRAN release: 2025-07-16
- Enhanced arc and line mode optimization.
- Precise curvature and gap control.
- Enhanced color customization.