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
gains gene_label_wrap for wrapping long annotations into
narrower, less overlapping labels.
geom_gene_label_repel() now defaults to
gene_label_orientation = "horizontal",
gene_label_segment = "elbow" (an L-shaped leader line that
adapts to each label’s position and text width) and
gene_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_overlaps hides
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.
geom_seq() gains sequence-grouping support via
seq_group, seq_group_gap,
seq_group_labels, seq_group_label_radius and
seq_group_colors. Groups can come from a
seq_group column in seq_data or 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
zcolour identity 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.
plotly::ggplotly() and the layout-data path now
include the group labels.
geom_ribbon() can now map any numeric column to a
continuous fill via ribbon_color_by (for example
"bitscore" instead of pident), with
ribbon_color_limits, ribbon_color_breaks and
ribbon_color_name to control the colourbar.
ribbon_alpha_by / ribbon_alpha_range
scale ribbon transparency continuously from a numeric column.
ribbon_outline_by /
ribbon_outline_colors and ribbon_linetype_by /
ribbon_linetypes map 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, with
ribbon_direction_colors,
ribbon_direction_linetypes and
ribbon_direction_alpha for fine control.
legend_key_width / legend_key_height
control the size of the Identity(%) colourbar key.
New geom_seq_region() draws rectangular bands along
sequence arcs to mark loci, repeats, CRISPR arrays or other user-defined
intervals. It accepts seq_id, start and
end (plus optional label,
category and color) and exposes
region_fill, region_color,
region_alpha, region_width,
region_offset and region_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 reuses
geom_gene()’s geometry and scales, with
feature_colors, feature_width,
feature_offset and feature_order for
styling.
geom_seq_region(), geom_ribbon_highlight(),
geom_feature()) and expanded the documentation for the
updated geom_seq(), geom_ribbon(),
geom_seq_label() and geom_gene_label_repel()
parameters.New exported function validate_ggchord_data()
returns a structured ggchord_validation object: a
valid flag, errors (severe problems),
warnings (drawable but noteworthy issues), per-category
summary counts, a data_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() and summary() methods are provided;
strict = TRUE stops 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 a
validate = 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.
read_blast() parses BLAST -outfmt 6/7
tabular output (12 or 17 columns, auto-detected) into
ribbon_data format, preserving evalue,
bitscore, qcovs, qlen,
slen, sstrand and stitle when
present.
read_gff3() parses GFF3 files into
gene_data format, selecting feature_types
(default CDS), extracting anno from attribute
keys (product, Name, …), decoding
percent-encoding, and mapping unstranded features to + (or
dropping them).
read_fasta_lengths() reads FASTA headers and
sequence lengths into seq_data format, with optional
header_delim splitting.
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_rows
attribute, and return a report of what was removed/merged and
why.
validate integration, data import, ribbon
filtering/deduplication/merging and a lightweight visual-regression
suite (deterministic layout fingerprints plus an opt-in PNG md5 baseline
behind GGCHORD_VISUAL_REGRESSION=1).(No user-facing changes; internal bug fixes.)
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 custom print() method. As a result
print(), ggsave(), ggplot_build()
and other standard ggplot2 workflows
(e.g. plotly::ggplotly()) 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.
plotly::ggplotly() now works on any ggchord plot,
including plots that combine the ribbon and gene layers (previously this
raised a scale error). A dedicated ggplotly.ggchord()
method converts the computed geometry to a plotly-friendly plot and
restores the Seq ID / Strand / Identity legends.
ggchord() now warns about suspicious input data:
reversed or out-of-range alignment/gene coordinates, pident
outside [0, 100], and sequence IDs that are not present in
seq_data.
geom_gene_label_repel() gains
gene_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_linetype argument 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
intended seq_label_radius semantics: 1 sits on
the arc, > 1 places the label outside (away from the
chord center) and < 1 inside. Previously the multiplier
was applied in the opposite direction (the default 1.15 put
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_vjust for per-sequence justification, and
check_overlap to skip labels that would overlap.
The default theme no longer draws grid lines
(panel.grid is blank) and legend keys are transparent (they
blend into the plot background instead of a fixed white
rectangle).
findInterval), speeding up layout computation for
large plots.ggplot2 (>= 4.0.0) and
R (>= 4.1.0) to match the implementation (the package
relies on ggplot2 4.x internals).R CMD check workflow (macOS,
Windows, Linux).fill_ggnewscale_1 aesthetic
name in favour of fill_ribbon.Tests no longer write to a hard-coded /tmp path:
they use tempfile(), so the test suite passes on Windows
and leaves no stray files behind for R 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).
plotly::ggplotly() output now shows the Seq ID /
Strand / Identity legends (the layout-level showlegend
switch is enabled) and reproduces the geom_seq()
directional arrowheads as plotly annotations.
Sequence (and gene) labels no longer end up upside down when a
global rotation >= 90 is 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_example annotations no longer
contain URL-encoded %2C artifacts (e.g. “ribonucleotide
reductase%2C large subunit” is now “ribonucleotide reductase large
subunit”).
Each legend can now be positioned independently via the
legend_position argument of geom_seq(),
geom_ribbon() and geom_gene() (e.g.
geom_ribbon(legend_position = "bottom")). Legends without
an explicit position stay together at
theme(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) or
list(c("+" = -15, "-" = -45), ...)), including length-one
lists that recycle.
geom_ribbon():
ribbon_outline_color (default "black"),
ribbon_outline_width (default 0.05) and
ribbon_outline_linetype (default 1,
solid).ggnewscale dependency. 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.RColorBrewer dependency. The default Set1
categorical palette is now built into the package, so the rendered
default colors are unchanged.geom_ribbon() and geom_gene() were
present (previously produced wrong ribbon colors and a “Scale for fill
is already present” message).ribbon_alpha rendering at the wrong opacity
(e.g. 0.35 was drawn as ~0.55); the alpha value is now
applied exactly as specified.geom_axis(show_axis = FALSE) failing with “object
‘label’ not found”.axis_label_orientation rejecting mixed vectors
such as c("horizontal", 45, ...).brewer.pal() when fewer than 3
sequences or gene annotations are used (two-sequence plots now render
cleanly).geom_gene() was added before
geom_ribbon() (“Continuous value supplied to a discrete
scale”).geom_axis() where the axis
path was misclassified as a sequence arc.+.ggchord and
ggplot_build.ggchord() as proper S3 methods and aligned the
ggplot_build.ggchord() signature with the generic.geom_seq(), geom_ribbon(),
geom_gene(), geom_axis(),
coord_chord(), +.ggchord() and others).examples/plots/, generalized
the package description beyond BLAST, and documented the ribbon outline
parameters.ggchord() + geom_* API.ggchord() into the individual geom_* layers;
ggchord() now only validates data and sets global style
(title, rotation, panel_margin,
show_legend, debug).print() time, collecting parameters from all layers during
rendering.print.ggchord() method: merge parameters,
compute the layout, inject data into layers, then render.ggchord() + geom_seq() + geom_ribbon() + geom_gene() + geom_axis().+.ggchord method that flattens layer lists
automatically.coord_chord() coordinate system.