NEWS
autograph 1.2.7
Package
- Added design principles to the README and the contributing guide
- Raised the 'manynet' floor to 2.4.0 for
manynet::is_spatial()
Graphing
- Added
plot.stocnet() so that plot() graphs a 'stocnet' as it does an 'mnet'
- Added
layout_spatial(), which places each node at its own position
- Used by default for a spatial network, and snapping/backbone are ignored
- Drawn on an equirectangular projection centred on the network's mean latitude
- Improved how
graphr() treats tie lengths
- In "stress" and "kk" layouts these are drawns as distances
- In backbone layouts they are used to filter the ties, but not to draw them
- Fixed the arcs of
graphr() to read reciprocated ties from a network of any class
Theming
- Improved "iheid" theme to prefer Montserrat over Helvetica
- Fixed "iast" theme looking for "Monserrat"
autograph 1.2.6 (2026-10-07)
Package
- Moved the slower
graphr() examples into \donttest{}, and they no longer call {netrics}
Graphing
- Fixed
graphr() holding labels too far from their nodes
- Node size was given to the repel algorithm in points rather than units
- Labels on a selection of the nodes now stay against the nodes they name
autograph 1.2.5
Package
- Fixed the slow r-forge link in documentation
Tutorials
- Trimmed the thumbnail path lengths to less than 100 bytes
autograph 1.2.4
Package
- Raised
{manynet} floor to 2.3.4 and {netrics} floor to 1.0.3
- Dropped shims for
manynet::delete_isolates(), manynet::is_multilevel(), manynet::tie_is_backbone(), and manynet::to_times()
- Dropped workarounds for
manynet::to_waves() failing on non-character changing attributes, "time" panels, and diffusions
- Tests now run serially on CRAN
Graphing
- Improved concept lattice drawing so that it is drawn as a Hasse diagram
- Arrowheads are left off only in the "layered" and "railway" layouts, where each tie points down the page
- Fixed
graphr() warning about ties that an automatically chosen backbone was drawn from
Aesthetics
- Added
edge_arrows= for tailoring the size of the arrowheads
NULL (default) leaves choice to the network, TRUE draws them, FALSE not
- A directed network will, by default, draw arrowheads following
edge_size
- An undirected network has no arrowheads and ignores the argument
- A number gives the length of the arrowheads in ggplot2 units
Layouts
- Fixed
layout_concentric() and plot.matrix() to square a two-mode network with manynet::to_onemode()
- Fixed
layout_layered(), layout_lineage(), layout_railway(), layout_ladder(), and layout_matching() erroring on a two-mode 'stocnet'
- The node names are now read with
manynet::node_names(), since igraph reads only an igraph
Tutorials
- Restructured the "Visualisation" tutorial so that each topic holds one idea
- Moved "Labels and titles" to directly after "Getting started", and added a free play exercise to "Getting started"
- Renamed "Illustrating graphs" to "Aesthetics", which now closes with "Legends"
- Added
edge_arrows to the aesthetics table and the "Pointing arrows" section of the "Visualisation" tutorial
- Added an example of
node_colour on a continuous attribute, which is drawn as a gradient
- Reordered "Layouts" by how much of a node's position is data: spectral, layered, circular, grid, force-directed, then manual
- Added a "Checking layouts" topic for the
check_*() functions, stress, inertia, and cos2
- Moved isolates, bundling, and backbones to an "Ew, hairballs" topic after the layouts
- Added explanatory figures to the "Visualisation" tutorial
- A gallery of small graphs shows what each aesthetic argument changes
- A gallery shows one network under one layout from each family
- Pairs of drawings of one small network show what each layout check scores
- Improved the introduction of the
"eigen" layout, which now says what its axes are and how to read them
- Examples now use only degree and attributes that come with the data, in place of measures that the
{netrics} tutorials introduce
- Fixed the "Legends" example retitling a legend that
labs(colour = ) does not reach
- Chunks labelled
explain-* are now drawn in the static article
autograph 1.2.3 (2026-09-09)
Package
- Added
{messydates} to Suggests
- Raised
{manynet} floor to 2.3.1
Theming
- Added
scale_x_mdate() and scale_y_mdate() (closes globalgov/messydates#104)
FUN resolves each messy date to one date; messydates::vmin by default
- Moved the colour checks into
R/theme_aesthetics.R
Layouts
- Added
check_crossings() for how many other ties each tie crosses
- Added
check_slopes() for the slope each tie is drawn at
- Added
check_lengths() for the total, max, and variance of tie lengths
- Added
check_angles() for the angular resolution at each node
- Added
check_drawing(), which reports those checks plus check_stress()
Tutorials
- Improved the isolate/bundling/backbone section ordering
- Each layout quality measure now names the function that measures it
autograph 1.2.2 (2026-08-29)
Package
- Shortened the startup message of
.onAttach()
Graphing
- Improved how
node_color= colours numeric node variables
Tests
- Fixed the arc strength test depending on the BLAS
autograph 1.2.1 (2026-08-26)
Layouts
- Fixed "valence" layout returning a poor layout for some random starts
- The nodes now start on a circle, so one run resembles the next
- The repulsion force between two close nodes is now bounded
- Each step is now capped and cools over the iterations
Tests
- Fixed the tutorial test failing on a deprecation warning that the tutorial code does not raise itself
- Fixed the "valence" layout test depending on the random seed
autograph 1.2.0
Package
- Removed the CRAN version check from
.onAttach(), making library(autograph) faster to attach
- Fixed
.onAttach() not applying the ink of a persisted theme
- Added
{goldfish} to Enhances
- Added
{systemfonts} to Suggests
- Added a
website-builds job to prchecks.yml, reporting whether the site builds
count_pages() was missing from the reference index, which stopped it
- Updated CONTRIBUTING with conventions for function names,
NEWS.md bullets,
the website reference index, and keeping tutorials and articles in step
- Added
stocnet_completion() to offer values an argument accepts as RStudio completions
graphr(fict_lotr, node_color = Tab lists the node variables fict_lotr holds
- Covers node and tie variables, layouts, label criteria, themes, and defaults such as
isolates
- Off unless asked for, since it replaces/encapsulates one of RStudio's internal functions;
stocnet_completion(FALSE) restores it
- A
persist argument remembers the choice, as stocnet_theme() does
- Values labelled with its class and its categories or range; a layout with the package that draws it
Layouts
- Improved layered layouts
- Consolidated layered layouts onto one engine
- "layered" is now default layout for directed acyclic networks
- Deprecating "hierarchy" as "layered" is more consistent for two-mode networks
- "lineage" is now exactly "layered" with the axes exchanged
- Deprecating "alluvial" to free name for plot of changing membership composition
- "railway" and "ladder" unchanged, but are
alignment = "rungs"
- Checks whether layout is appropriate for the network, and reverts to default if not
- Minimises two costs: tie length (
check_span()) and nodal offset (check_offset())
- Added
ranks= to choose the layers:
- "compact" asks
igraph::layout_with_sugiyama()
- "generation" ranks each node by its distance from a root
- "tight" (default) minimises total tie length while every tie points down at least one layer
- a numeric node attribute lays the layers out by its values, spaced in proportion to them, which is what "lineage" used to take a
rank for
- Added
alignment= to choose how a layer is spread out:
- "straight" (default) draws ties as close to straight as ordering allows
- "rungs" gives every layer same integer spacing
- Each weakly connected component now laid out on its own and packed beside others
- Fixed
layout_layered() centring on a second mode node yet reading first mode labels
- Fixed the direction of layers given as values to
ranks=
- Fixed layered layout labels to ignore
label_repel
- Improved multilevel layout
- Renamed "multilevel" layout to "levels" to avoid potential future collisions
- Fixed
layout_levels() to identify modes without having to name a level
- Exposed
method, alpha, beta, FUN1 and FUN2 arguments
- Deprecated "dyad", "triad", "tetrad", "pentad" and "hexad" layout names
- "configuration" already picks the one matching the number of nodes
- The
layout_dyad() to layout_hexad() functions themselves are unchanged
- Fixed three broken paths in
layout_concentric()
- Fixed drawing each node of an unlabelled network on a circle of its own
- Fixed erroring where a membership holds
NA, now gathers NA nodes onto own circle
- Fixed
order.by=, which errored on every network; now orders nodes around each circle by that attribute, decreasing
- Fixed
graphr(snap = TRUE) to use rotation and other improvements
- Added a "scaling" layout for multidimensional scaling
- Scales classically up to a hundred nodes, and by pivots above that
- Scales unweighted path distances, so it can handle signed/weighted networks
- Lays each component out separately, where "pmds" refuses disconnected networks outright
- Drawn with labelled axes at a fixed ratio, since these coordinates can be read
- Captioned with
check_stress() for Kruskal's stress-1, and console-reported where poor,
as well as the share of distance variance two dimensions hold
- Added a "correspondence" layout for correspondence analysis
- Places nodes by the similarity of their tie profiles
- Reads directed networks symmetrically by default, but "out" or "in" possible
- Refuses signed network, but
double=TRUE an option
- Console-reports low broomstick ratio dimensions and low cos2 nodes
- Added a
layout_matching() alias so every layout has a short name
- Removed unreachable
getNNvec()
Graphing
- Fixed
graphr() clipping nodes at panel edges
- Nodes were drawn at absolute sizes, but scales are expanded by a share of data range,
so
ggplot2's 5% left less room than the radius of a node in a small network
- Room is now taken from node size, so small networks are given more space
- Added
backbone= to graphr() for drawing dense, hairball "stress", "fr", "drl", "kk" networks
- By default, networks with 50+ nodes and a mean degree ≥8 use backbones
TRUE/FALSE force, or specify filter/threshold (see manynet::tie_is_backbone())
- Improved
graphr() to draw multilevel networks of interlocking one-mode and two-mode layers by default
- Fixed tie opacity so that those between levels fade behind those within them
- Fixed default node size in multilevel layout, which is now taken from how many nodes there are at each level rather than in the whole network
- Fixed labelling to be plain text nudged away instead of white-boxed labels
- Fixed arcs drawn on layout that places two nodes at one point,
e.g.
graphr(ison_networkers, layout = "scaling")
- Fixed
graphr() to draw parallel ties as a fan instead of one on top of another
- Fixed tie colouring in multiplex networks to color layers not signs by default
- Signs are still drawn as linetypes
- Added a legend for the tie linetype wherever it is the only thing showing the signs, and is titled by whatever color is showing
- Improved node shape legend to name modes where two-mode network records them instead of default "One" and "Two"
- Fixed size of self-loops to draw as a fraction of how far the layout spreads rather than at a fixed diameter of one coordinate unit
- Improved
node_group to draw overlapping hulls (closes #51)
- e.g.
graphr(ison_adolescents, node_group = netrics::node_x_clique())
- Improved
graphr() to note when a colour/shape legend grows past about 7 keys
- Fixed
graphs() to collect guides even where panels held different ranges or categories (closes #15)
Theming
- Added
persist= to stocnet_theme()
persist = TRUE writes it to tools::R_user_dir("autograph", "config")
- Nothing written to disk unless passed explicitly
- Setting a theme without it clears any choice persisted earlier
- Improved font detection in
stocnet_theme() via {systemfonts}
- Added
list_fonts() for listing the font families R can see
- Added
stocnet_medium() for standardising output to the expected medium:
- "screen" (default), "presentation", "mobile", and "print"
ag_size() scales text, not node size or anything else
- "print" draws on white irrespective of theme grounding
- Improved theme backgrounds to reach every plot, not only the graphs
- Plot themes are now built with the
ag_theme_*() wrappers
- Blanked elements stay blank, so a graph keeps no axis text or coordinates
- Ties, nodes, and labels with no colour take
ag_ink() and the ground
- Added
simulate_colorblind(), check_separation() and check_contrast() for checking palettes
- Simulates deuteranopia, protanopia, and tritanopia (Machado et al. 2009)
- Scores a pair by its worst case across those and normal vision
- Added
severity= to view anomalous trichromacy (deuteranomaly, protanomaly)
- Added "grey" type to show a palette as print and photocopy may render it
- Added
check_span() for scoring how far each tie travels down the page
- Added
check_offset() for scoring how far each tie is from its ideal straight line
- Added
ag_ink() for the colour a theme writes with
- Used by axis text and reference lines, clearing 4.5:1 from the ground
- Frees
ag_base() to be light where that sets it off from the highlight
- Added
ag_missing() for the neutral that data recedes into:
- missing values, isolates, and any "other" remainder
- Improved
ag_qualitative() to note when a palette is asked for more colours than it holds
- Improved every theme's categorical palette for colour-blind viewers
ag_qualitative() uses most distinct, own colors first not mixtures
- Samples across the palette only where it holds too few colours
- Kept "rainbow" in its own order, since fidelity to a spectrum is its point
- Improved some highlight pairs
- Fixed "neon" highlight pair, a cyan and a green 12.7 apart
- Fixed "ethz" and "cmu" highlight pairs by lightening their greys
- Fixed divergent palettes pairing a red pole with a green or teal one, such as in "ethz"
- Added a "clay" theme inspired by palette and fonts of Anthropic's Claude
Plotting
- Added
plot.goldfishFit() for the four diagnostic panels a fit can supply
- Deviance trace, Schoenfeld smooths, score processes, and waiting times
- Draws only from what the fit stores, leaving a missing panel out
- Draws the waiting-time panel for exact-time models only
- Draws the compact term strings the test itself carries, which do not
repeat where an effect appears over two networks
- Reports how many terms the Schoenfeld panel dropped
- Fixed the Schoenfeld panel to select terms by column position
- The labels it matched on intersect the effect names on the intercept
alone, so it drew one term where four were asked for
- Added
plot.goldfishGOF() for each effect's cumulative score process
- Draws the Brownian-bridge bands the effect's p-value was read from
- Draws x on the object's own process time, named for the clock it records
- Inverts the distribution the event-clock p-value comes from
- Added
plot.goldfishTimeTest() for the scaled Schoenfeld residuals
- Draws a smooth per effect, with the fitted estimate as the reference
- Colours the scatter by period under
method = "periods"
- Added
plot.goldfishOnset() for the parameter path and information accrual
- Windows both panels on the excursion, so each coefficient gets its scales
- Draws the proportional diagonal, the departure from which is the finding
- Added
view = c("both", "path", "accrual") to select a single panel
- Added
plot.goldfishMargins() for observed against expected activity
- Draws martingale residuals where the model class defines a compensator
- Draws the calibration ratio where it does not, from the recorded scales
- Draws the
top actors furthest from the reference, and counts the rest
- Draws level against shape where goldfish supplies
dispersion
- Names both omissions: under two completed spans, and beyond
top
- Added a
page argument to plot() on the per-term diagnostics
- Applies to
goldfishGOF, goldfishTimeTest, and goldfishOnset
- Added
count_pages(), reporting the count without rendering
- Renamed from
ag_pages(), since ag_ is for the theme accessors
- Errors with the page count where
page is past the last
- Leaves each figure as it was where
page is omitted
- Renamed the goldfish classes to a package prefix and a camelCase noun
goldfishOutliers, goldfishChangepoints, goldfishOnset,
goldfishMargins, goldfishGOF, goldfishTimeTest, goldfishScoreTest,
and goldfishFit
- A name such as
test_gof is what a sibling package would pick too, and
two packages emitting one class string cannot be told apart by dispatch
- Renamed the dispatch methods and the precooked fixtures to match
- Kept the older class names as aliases, so such objects plot as before
- Documented the convention in CONTRIBUTING, for the whole ecosystem
- Improved
plot.goldfishOutliers() and plot.goldfishChangepoints()
- Renamed from
plot.outliers.goldfish() and plot.changepoints.goldfish()
- Read the metadata each object carries rather than inferring it
- Plot the
.series column, so a diagnostic called with effect = is
drawn as that term's series rather than as a log-likelihood trace
- Fixed both to facet on process, so no line crosses a process boundary
- Fixed
plot.goldfishChangepoints() to draw each process's own breaks
- Fixed
plot.goldfishOutliers() to read the now-logical outlier column
- Rewrote
plot.goldfishChangepoints() for the tibble with a cpt column
- Labels the axis with break times only where they are numbers,
so a dated event stream keeps its date scale
- Added precooked
goldfish_margins, goldfish_gof, goldfish_time,
and goldfish_onset, and refreshed the two older fixtures
- Each is stamped with the goldfish version that produced it, 1.9.21
goldfish_outliers comes from a receiver-choice model of the calls
- The others come from event models of the
fisheries_treaties layer
- Replaced
cli::cli_abort() in gf_facet_paged() with snet_abort()
- Replaced em dashes in
R/plot_diagnostics.R since only ASCII is portable
- Fixed signed branch of
plot.matrix() hard-coding its poles
Tutorials
- Moved the decorative gifs in the visualisation tutorial into quiz answer feedback
autograph 1.1.2 (2026-07-31)
Package
- Improved the declared dependencies
- Removed
{knitr} from Suggests: it was used solely by the tutorial tests, which now extract the tutorials' {r} chunks with the same small scanner used in {manynet} and {netrics} (verified to yield an identical expression set to knitr::purl() on the autograph tutorial)
- Removed
{tidygraph} from Imports: its only functional use was reading the edgelist's target column in .infer_end_cap(), which now uses igraph::as_edgelist() (verified to give identical end caps)
- Promoted
{graphlayouts} from Suggests to Imports, since it is required for grapht()'s default "stress" layout (without it, wave-to-wave node transitions silently degraded to a static aggregate layout) and is installed regardless as {ggraph} imports it; its requireNamespace()/thisRequires() guards have been removed
- Declared a minimum
{manynet} version (>= 2.2.1)
- Updated the GitHub Actions workflows
- Updated the actions to their latest major versions (
actions/checkout@v7, actions/upload-artifact@v7, actions/download-artifact@v8), replacing some long-outdated @v2 pins
- Updated the website deploy job's
r-lib/actions/setup-pandoc from @v1 to @v2, matching every other r-lib/actions step
- Added checks that metadata and tutorial vignettes correspond
- Improved the test suite while reducing what CRAN has to run
- The functional audits now fail rather than skip when
AUTOGRAPH_STRICT_AUDIT=true, which the CI check step now sets, so a broken layout or plot method can no longer pass CI green
- Fixed the layout audit's fixture and argument maps, which paired several layouts with networks they cannot lay out; because
skip() aborts the enclosing test_that(), the first such mismatch had been silently preventing every later layout from being audited at all (the layout audit goes from 21 to 108 assertions)
- Coverage is now measured with
NOT_CRAN=true, without which every skip_on_cran() test — most of the suite — was skipped while covr ran, badly under-reporting coverage
release and pkgdown no longer run under if: always(), so a failing R CMD check can no longer tag a release or deploy the website
- Replaced
graphr()'s sweep over every bundled {manynet} dataset with a representative sample, and dropped the plot.* smoke tests now subsumed by the plot-method audit; CRAN-visible test time falls while CRAN-visible assertions rise
- Added an edge-case audit (
test-functional_errors.R), an audit of the user-facing layout_* aliases, and examples for the ag_* palette accessors and configurational layouts, none of which were previously covered
- Theme-mutating tests now restore the previous theme with
on.exit(), so global theme state cannot leak between parallel test workers
- Updated the website and README
- Updated favicons
- Split Graphing from Plotting functions
- Updated README to send visualisation examples to the website
- Fixed README double logoing on pkgdown build, and added alttext
- Updated CONTRIBUTING with the package architecture, conventions, and dev commands
- Updated remaining base R
stop(), warning() and stopifnot() calls to the {manynet} cli interface
Graphing
- Improved
graphr()'s labels argument to label a selection of the nodes, where previously the only alternative to labelling every node was labelling none
labels now also accepts a depth of ranks (labels = 5), a measure to rank by (labels = "betweenness", or labels = c(betweenness = 5) for both), the name of a logical node attribute, or a logical/name/position vector of the nodes to label
- Selection is by rank rather than by headcount, so nodes tied at the cut are labelled together, using
netrics::node_is_max(); a two-mode or multilevel network is ranked within each mode or level, so a dense level cannot crowd the others out of the labelling
- Networks of more than 30 nodes now label only their most central nodes by default, reporting how many;
labels = TRUE still labels every node. manynet::fict_marvel went from 194 overlapping labels to 10
- Labels are drawn from the selected rows rather than by blanking the rest, so no space is reserved (and nothing is repelled away from) labels that are not drawn
grapht() resolves the selection once across all waves, so the same nodes stay labelled from frame to frame, and graphs() resolves it once for all its panels; grapht()'s own default above 30 nodes remains no labels at all
{netrics} is only suggested, so an automatic selection falls back to a random sample when it is not installed, and a measure asked for by name says what to install
- Fixed
graphs()/grapht() erroring ("Can't combine ..1 and ..2 ") on a longitudinal network whose changing node attributes are stored as non-character vectors (e.g. the logical active flag and numeric height/mass in fict_starwars)
- Such networks now split into waves via a guarded
to_waves() that coerces the offending attributes when {manynet}'s splitter cannot combine them
- Fixed
graphr(..., snap = TRUE) erroring ("'-' only defined for equally-sized data frames") whenever a node sat exactly on a grid point
depth_first_recursive_search() compared each node against a distance vector that still included its own zero self-distance, so an exact hit selected that entry and yielded an empty grid point; the self-distance is now dropped before the nearest vacant point is chosen
- two-mode networks hit this on their very first node, since their coordinates are exactly 0 or 1
- Improved
graphr() to ignore snap = TRUE for layered layouts ("hierarchy", "railway", "ladder", "alluvial", "multilevel", "lineage", "layered")
- These layouts encode rank, mode, or generation along an axis, which square-grid snapping would collapse
- Fixed
graphr() erroring with "argument "node_color" is missing, with no default" when passed a list of networks; the call is now forwarded to graphs() as written, rather than argument by argument
- Improved how
graphr() checks the attribute names given to its aesthetic arguments
- A mistyped node or tie attribute name now errors immediately, naming the argument and offering the closest match:
graphr(net, node_color = "welth") reported "Unknown colour name: welth" at draw time, and now reports that "welth" was not found among the node attributes and asks whether "wealth" was meant
- The same applies to
node_shape (previously "Shape aesthetic contains invalid value"), node_size and edge_size (previously "Aesthetics must be either length 1 or the same as the data (8)"), node_group, and edge_color
- Improved the error when the input is not a network, which now names the argument and the class given, rather than reporting a missing method for
as_tidygraph()
- Fixed
isolates being validated only when the network happened to contain isolates, so the same typo errored on one network and was ignored on another
- Fixed
node_size values between 0 and 1 being silently multiplied by ten; node_size = 0.5 now means 0.5, while a vector of proportions is still rescaled to stay visible
- Fixed
graphs() producing empty panels by checking waves against the number of networks available
- Added a set of internal argument checks (
R/graph_checks.R) shared by graphr(), graphs(), grapht(), the layout_*() functions, and stocnet_theme()
- An unrecognised value now errors immediately, naming the argument and offering the closest match, rather than falling through to
{ggplot2}, {grid}, or match.arg() (so isolates = "drop" reports isolates, rather than "'arg' should be one of ...")
- A value that differs only in capitalisation is now used as intended, with a note, instead of being rejected:
node_color = "Wealth" finds the wealth attribute
- Note that these checks are stricter than before: a mistyped attribute name used to be ignored silently or to fail later, and now stops the call
- Updated group-reduction note in
graphr() and constant-colour note shared by graphr() and grapht() so that their wording cannot drift
Plotting
- Improved
plot.node_member() to draw its dendrogram with {ggraph}
- Passes
hclust object's own merge heights to the dendrogram layout to reproduce the previous plot's leaf order, merge heights, cluster label colours, and cutpoint line
- Branches now drawn in
ag_base() rather than black, matching the height axis and so respecting the active stocnet_theme()
- Removed
{ggdendro} from Imports
- Updated a stale doc cross-reference in
plot.node_member(), which pointed at manynet::node_in_community(); that function moved to {netrics} in manynet 2.0.0
- Updated terse or dead-end messages to say what to do next, including
plot.node_motif()/plot.network_motif() ("Cannot plot these motifs yet, sorry."), match_color(), plot.diff_model(), and the concentric and hierarchy layouts ("Duplicated nodes in layers!")
- Updated zero-variance note shared by three GOF plot methods so that their wording cannot drift
Layouts
- Improved the error on an unrecognised
layout, which now names the argument, suggests the nearest layout, and lists autograph's own layouts, rather than reporting "object 'layout_tbl_graph_stresss' not found"
- Passing a layout function (e.g.
layout = igraph::layout_with_fr), rather than its name, now says so instead of erroring with "invalid indexing"
- Added checks of the
membership/level/rank arguments that the partition layouts require, which name the argument and offer the closest match
Theming
- Improved
stocnet_theme() to error with the nearest match on an unrecognised theme name, instead of warning and silently leaving the previous theme in place; giving more than one theme name is also caught
Tutorials
- Added a colour blindness section to the visualisation tutorial
- Covers
simulate_colorblind(), check_separation(), and how palettes are ordered
- Notes that the "rainbow" theme is not a colour-blind safe scheme
- Added a note on installing a theme's fonts to the visualisation tutorial
- Updated the README with the case for colour-blind readable palettes
- Updated visualization tutorial to use colour/color consistently
- Updated the Labels section of the visualisation tutorial to cover selecting which nodes to label, replacing the
mutate(name = ifelse(...)) workaround it used to recommend
fict_lotr, the tutorial's running example, has 36 nodes, so its graphs now name only its most central characters; the surrounding prose says so and shows how to choose otherwise
- Regenerated
vignettes/articles/visualising-networks.Rmd and the pre-rendered tutorial HTML to match
autograph 1.1.1 (2026-07-21)
Graphing
- Fixed
grapht() example, which took too long to run, by couching it in \donttest{}
- Improved
graphs() to accept bare longitudinal or dynamic networks
- Splits it into waves or time slices automatically (consistent with
grapht()),
instead of erroring with "invalid to use names()<- on an S4 object of class 'dgCMatrix'"
- Fixed various errors and warnings in
graphr()/graphs() on signed, directed, or changing networks:
- Fixed recycling warnings ("longer object length is not a multiple of shorter object length") in
graphr() on a complex network
- arc geom's
strength parameter now excludes loop edges, which are drawn separately by geom_edge_loop0()
- Fixed spurious warning ("no non-missing arguments to max; returning -Inf") in
graphr() on a changing network without any adoption events (e.g. fict_potter)
- such networks now rendered as standard changing networks rather than routed through the diffusion node-colour mapping
- Fixed fails at draw time with "invalid hex digit in 'color' or 'lty'" in
graphr() on a signed multiplex network (e.g. fict_marvel)
- ties on non-signed layers (which have a missing sign) are now drawn solid/positive rather than passing
NA to grid
- Fixed error with "Aesthetics must be either length 1 or the same as the data" in
graphr()/graphs() on signed longitudinal or directed networks (e.g. to_waves(ison_monks))
- per-tie sign linetypes are now mapped through
aes() (with an identity scale) so ggraph's edge geoms expand and subset them consistently with edge colour and width
- Fixed
graphr(..., snap = TRUE) erroring on two-mode networks: their default "hierarchy" layout is now left un-snapped (with an informative message) since collapsing its layered coordinates onto a square grid is not meaningful, while snapping a two-mode network under a force-directed layout continues to work; also hardened the grid-snapping search so a coordinate landing exactly on a grid point is no longer mistaken for a node's zero self-distance
Tutorials
- Updated visualisation tutorial with a bit more structuring of further options
autograph 1.1.0
Package
- Test coverage raised by introducing functional testing infrastructure (
tests/testthat/helper-functional.R and test-functional_*.R) for:
- the layout family
- the
plot.* S3 method family
- the
ag_* palette accessors across all themes
graphr()'s aesthetic arguments each enumerated automatically and audited against fixture grids
- Removed the unused internal helper
seq_nodes()
- Excluded the interactive-only palette helper
ggpizza() from coverage
- Added
{migraph} to Suggests (used in tests only)
Graphing
- Improved how
graphr() treats labels
- Fixed labels overlapping nodes (closes #13): labels now keep clear of node borders automatically by giving ggrepel each node's true rendered size, with
label_dist adding a further points-based gap (mirroring igraph's vertex.label.dist) and label_repel = FALSE selecting a fixed offset instead of repulsion.
- This also fixed a pre-existing bug where non-repelled labels rendered with a fully transparent fill under this package's theme, making them invisible over nodes.
- Improved
grapht() has been rewritten for smoother, more consistent animations of dynamic networks
- Node positions now transition seamlessly between waves using the dynamic stress layout
from
{graphlayouts} (layout_as_dynamic()), with a new alpha argument controlling
layout stability; other layouts are computed once on the aggregate network and held fixed
- Changing node composition is now handled properly: every node that ever appears gets a
stable position and fades in and out in place as it enters and exits the network
- New
isolates argument ("keep" or "fade") controls whether temporarily isolated nodes
stay visible or fade out; keep_isolates is deprecated
- Dynamic (time-stamped, event-based) networks such as
irps_nuclear are now split
automatically into cumulative time slices via manynet::to_slices(), so a single
dynamic network object passed to grapht() works without manual conversion
- Interval (spell) networks that record tie
begin/end lifespans, such as irps_wwi,
are now split automatically into one snapshot per change point showing the ties active
in that spell, so grapht(irps_wwi) works directly (previously it errored because such
networks are dynamic but carry no time attribute for to_slices()); irps_wwi is now
a runnable example in the documentation
grapht() now uses the dynamic stress layout by default even for two-mode networks
(rather than a hierarchy layout, which collapsed many nodes onto a line), suppresses
node labels by default for networks with more than 30 nodes to keep frames legible,
and fades densely overlapping ties so they read as a density gradient rather than a
solid mass
- Fixed an error when animating networks whose node names contain non-ASCII characters
- Waves without any ties are no longer silently dropped
- Closer visual parity with
graphr(): directed networks get arrowheads on segments trimmed
at the target node, signed networks distinguish positive/negative ties by linetype and
colour, mapped aesthetics use the same palettes with factor levels consistent across
frames, and legends transition along with the animation
- Aesthetic-resolution helpers are now shared between
graphr() and grapht()
(new R/graph_aes.R), so styling cannot drift between static and animated plots
- Added a test suite for
grapht() (no gif rendering required)
- Now aborts with a clear message when its input cannot be split into waves or slices, instead of failing much later with a cryptic igraph error (closes #40); the underlying cause —
to_waves() silently ignoring a time attribute not named "wave" — will be fixed in {manynet} 2.2.2, and the tutorial example now uses a wave attribute, which splits correctly with {manynet} 2.2.1
- Added an
edge_bundle argument to graphr() for bundling edges in dense networks (closes #19):
TRUE/"force" uses force-directed bundling, with "path" and "minimal" selecting the other non-hierarchical algorithms
- colour/width/linetype mappings are preserved and directed networks keep their arrowheads.
- This wires up ggraph's non-hierarchical bundling geoms (added in ggraph 2.2.0), which were previously imported but never called, so the ggraph dependency is now
(>= 2.2.0)
- Fixed
edge_size = 0 not fully suppressing edges on directed networks (closes #50): arrowhead length was hard-coded regardless of edge_size, leaving a visible arrowhead when the line was hidden. Arrow length now scales with the resolved edge width (capped so heavily-weighted edges don't get oversized heads) and is omitted entirely when the width is 0
- Fixed two-mode auto-shapes assigning circles to the second mode: the first mode now takes circles and the second squares, as intended
- Fixed
graphr() returning an empty plot for networks consisting only of isolates (e.g. the empty dyad/triad motifs): isolates are now kept whenever removing them would empty the graph
- Fixed
graphs() erroring on lists containing tie-less networks (e.g. plot() on motif censuses): panels sharing a layout now keep isolates so every node has a coordinate in every wave
- Fixed
graphr() erroring on weight or size attributes carrying measure classes (e.g. tie_measure results from {netrics} stored as attributes)
- Fixed a vector-recycling warning in
graphs()' ego-network detection
Tutorials
- Fixed the "Tying up loose ends" exercise in the visualisation tutorial erroring on
tie_closeness() (closes #39): the tutorial now loads {netrics} and uses its measure functions (tie_by_closeness(), tie_is_triangular()), and every tutorial code chunk is now exercised by the functional tests below
- Reworked the "Visualising Networks" tutorial to match the structure and features of the
{manynet} v2.2 tutorials
- Rebranded the tutorial in autograph red, with larger, more readable text and matching 'Run code' buttons
- Added a checkbox Aims section, "Catching up", "Going further", "Beginner note", and "In brief" callout boxes, per-page mini-tables of contents, and free play sections with a choose-your-own-data difficulty ladder
- Added hover-over glossary terms throughout and a closing Summary section with a function overview table and glossary
- Added quiz questions with feedback, and hints for the coding exercises
- New coverage of
edge_bundle, label_repel/label_dist, the isolates argument, snap grid-snapping, autograph's own special-purpose layouts, and programmatic export with ggsave()
- New sections on directed networks (automatic, width-scaled arrowheads and manual control via
edge_size), automatic mode shapes in two-mode networks, and manually adjusting a layout's coordinate table before passing it back via x/y
- Added artist-themed gifs throughout, including as quiz-answer feedback
- Added a static, read-only version of the tutorial as a pkgdown article ("Tutorials" menu on the website), as in
{manynet}
- Added functional testing of all tutorial code chunks (
tests/testthat/test-tutorials_autograph.R), mirroring {manynet}'s tutorial testing infrastructure
Layouts
- Fixed
layout_tbl_graph_layered() ordering nodes by the names rather than the positions of their neighbours in adjacent layers, which degraded every barycenter sweep to NA and raised warnings
- Replaced deprecated
dplyr::case_match() with dplyr::recode_values()
Plotting
- Fixed
plot.matrix() erroring when no membership argument was supplied, for both one-mode and two-mode matrices
autograph 1.0.3 (2026-05-01)
Plotting
- Fixed the error produced by a namespace reference in a call in
ergm_res by serializing it, moving to extdata, and loading it via load_ergm_res()
autograph 1.0.2
Plotting
- Fixed the error produced by a namespace reference in a call in
ergm_res
autograph 1.0.1
Package
Plotting
- Fixed the error in some flavours by removing environment references in included objects
- Closed #44 by adding example that uses
ggplot2::scale_colour_discrete() to tweak colour output
Tutorials
- Fixed the tutorial to use netrics functions
autograph 1.0.0 (2026-04-04)
Package
- Updated startup message to declare the set theme
Graphing
- Improved
node_shape to accept more categories
- Moved
node_is_isolate and node_adoption_time to internal helpers to reduce dependencies
- Fixed #47 by overriding shape to fillable (21)
- Fixed #10 and #52 by adding label distance parameter
- Fixed #17 and #40 by improving
grapht()
Plotting
- Closed #37 by adding EgoAlter sienaGOF plot
- Fixed #36 by using
.to_factor() in plot.ag_gof() to correct numeric ordering of statistics, and dropped cumulative correction in plot.sienaGOF()
- Fixed #38 by dropping linetype in favour of colours even for bw theme in
plot.influenceTable()
- Fixed option reference from
snet_theme to stocnet_theme in plot.selectionTable() and plot.influenceTable()
- Applied
ag_font() to migraph model plots for consistent typography
- Reorganised plot scripts by purpose: summaries, tests, and analysis
- Fixed #46 by not appending "X" to the names when creating the data frame and moving factor coercion later in the process
Tutorial
- Fixed #41 by updating tutorials to use fill aesthetics (
scale_fill_*()) instead of colour aesthetics (scale_colour_*())
autograph 0.6.0 (2026-03-01)
Package
Graphing
graphr() now auto-dispatches to graphs() when passed a list of graphs
graphs() no longer requires {patchwork} to be loaded separately
- Closed #12 by changing node aesthetics from
color to fill using fillable shape codes (21–25) for nodes to support fill-based colour scales
- Consolidated legend modifications into internal
graph_legends() helper
- Improved legend labelling:
- edge sign legend now labelled "Sign"
- edge weight/width now labelled "Weight"/"Width"
- node mode/shape legend now labelled "Mode"/"Shape"
- Closed #8 by adding "isolates" argument to
graphr():
"legend" (default) removes isolates from the graph but notes them in the legend
"caption" removes isolates from the graph but notes them in the caption
"keep" retains isolates in the graph as-is (closes #12)
Theming
- Removed
scale_*() functions as redundant with better theme support and match_color()
Layouts
- Replaced
{Rgraphviz} (Bioconductor) with igraph::layout_with_sugiyama for Sugiyama/hierarchy layouts, removing the Bioconductor dependency
- Improved Sugiyama layout with dummy node insertion and barycenter crossing minimisation for better edge routing
- Fixed #18 for lattice layout snapping by rotating the layout to optimise edge verticality and horizontality
autograph 0.5.1
Plotting
- Improved
plot.gof.ergm() (closes #31)
- Now works on directed and two-mode networks and dyadwise shared partners
- Now has more informative error message if statistic not available
- Now accepts more descriptive and gof-formula consistent statistic names
autograph 0.5.0 (2025-11-19)
Package
- Shortened startup messages
Plotting
- Added
plot.goldfish.changepoints()
- Added
plot.goldfish.outliers()
- Added
plot.mnet() to avoid igraph::plot.igraph() dispatching
Graphing
- Restructured scripts for improved maintenance and development in the future
- Fixed
ggplot2::geom_violin() call in graphr() to avoid warnings with ggplot2 v4.0.0
- Improved
graphr() internals to rely on a NULL "layout" parameter and .infer_layout()
- Improved
graphr() to use match_color() for diffusion palettes
- Fixed
graphs() handling of changing networks
autograph 0.4.2
Package
Plotting
- Fixed node overflow issue and restored marginal density plot in
plot.ag_conv() by dropping +.ggplot()
- Added automatic legend labelling where node_size or node_color or edge_color is given
Theming
- Added "hwu" theme for Heriot-Watt University
- Improved highlight and divergent theme setting to use switch
- Added some discussion about colour-blindedness to palettes documentation and viz tute
- Added some instruction on how to customise themes more specifically
autograph 0.4.1 (2025-09-11)
Package
- Improved startup message to ignore class
Theming
- Added "iast" theme for the Institute of Advanced Studies, Toulouse
Plotting
- Improved ergm convergence diagnostic plotting by working on the results object,
mostly avoiding startup conflict warning
- Dropped marginal density plot in
plot.ag_conv() to fix {ggplot2} v4.0.0-related node overflow issue
autograph 0.4.0 (2025-09-10)
Package
- Fixed DOI in CITATION
- Improved README introduction
- Improved README graphing illustration, including igraph comparison figure
- Improved README plotting illustration, added SAOM/ERGM GOF comparison figure
Theming
- Improved
stocnet_theme() documentation
- Improved
stocnet_theme() to register a font family for plots
- A vector of potential fonts is included for some themes
- The first font found on the system will be used, and user notified
- If no fonts are found, the default R font ("sans") will be used
- A message is printed to inform the user if the default is used,
and how to install missing fonts via
{extrafont}
- Added font options for "iheid", "oxf", "ethz", "uzh", and "rug" themes
- Added
ag_font() for retrieving the registered font family
- Improved
match_colors() documentation
- Exported
is_dark() and made it vectorised
- Added
match_colors() and is_dark() tests
- Dropped
theme_*() functions in favour of stocnet_theme()
- Dropped
theme_*() tests
- Added
stocnet_theme() tests
- Added "cmu" theme for Carnegie Mellon University
Graphing
- Improved
graphr() by using registered fonts where available
- Improved
graphr() by using ag_qualitative() for discrete colour scales
Plotting
- Improved
plot.selectionTable() and plot.influenceTable() documentation
by consolidating them together into one help file
- Improved
plot.ag_conv(), plot.ag_gof(), and plot_interp by using
registered fonts where available
- Improved
plot.sienaGOF() to use lower case auxiliary statistic description
Data
- Renamed
res_monan_traces to monan_conv
- Renamed
res_monan_gof to monan_gof
- Renamed
res_ergm_gof to ergm_gof
- Renamed
res_siena_gof to siena_gof
- Renamed
res_siena_influence to siena_influence
- Renamed
res_siena_selection to siena_selection
autograph 0.3.1
Package
- Fixed old citation style issue for CRAN
Plotting
- Added
plot.ag_conv() as a new plotting method for convergence diagnostics
- Plots MCMC traces as a line plot with loess smoothing highlighting the trend
- Plots overall density plot of the samples on the right margin
- Improved plotting of
{MoNAn} trace objects by using plot.ag_conv()
- Added
plot.mcmc.list() for plotting MCMC samples from ergm::ergm results objects,
using plot.ag_conv()
Data
- Added
ergm_res for testing and illustration of plot.mcmc.list(),
use ergm_res$sample to access the MCMC sample
autograph 0.3.0
Package
- Added package documentation
- Added citation
- Dropped dependencies
{tidyr}, {cli}, and {concaveman}
- Added more description to the function overview sections on the website
- Added CODECOV_TOKEN to Github secrets for test coverage reporting
Graphing
- Fixed
graphr() not using theme colours for node and edge aesthetics
Plotting
- Added new plot class and method for centralising GOF plotting
- Improved
plot.sienaGOF() and plot.gof.stats.monan() to use new plotting method
- Added
plot.gof.ergm() for plotting ERGM GOF objects
- Improved GOF plotting by adding boxplot within the violins
- Improved GOF plotting by adding crosses for outliers
- Improved GOF plotting by adding dashed line for 0.05 and 0.95 quantile bounds
- Improved GOF plotting by dropping statistics without variance
- Improved GOF plotting by using
cumulative = FALSE by default
- Fixed issue with pre-v1.3.20 RSiena::gof() objects, thanks @TomSnijders
- Added testing of GOF plotting
- Added testing of measures plotting
Theming
- Added
set_stocnet_theme() alias for stocnet_theme()
- Fixed issue with 'oxf' and 'unige' themes not being recognised
Data
- Added
res_ergm_gof for testing and illustration of plot.gof.ergm()
Tutorial
- Added visualisation tutorial from manynet
- Improved introduction
- Improved section on titles, labels, and legends
- Improved section explaining base and grid graphics
- Added section demonstrating difference between
igraph::plot(), ggraph::ggraph(), and graphr()
- Added table describing the main arguments of
graphr() and the visualisation dimensions to which they relate
- Added section showing how to use "node_shape" (poorly)
- Improved section showing how to use "node_colour" and "node_group"
- Added section showing how to use "node_size"
- Added section showing how to set a theme
- Added section showing how to use "edge_colour" and "edge_size"
- Improved section introducing
{patchwork}, graphs(), and grapht()
- Added plotting section to viz tutorial
autograph 0.2.0 (2025-08-22)
Package
- Added (currently) necessary dependencies
- Removed unnecessary manynet dependencies
Plotting
- Added
graphr(), graphs(), and grapht() from manynet for quick plotting of one or more graphs
- Improved
+.ggplot() to check whether second object inherits ggplot class (thanks @teunbrand for fixing #110)
- Fixed issue with edge_linetype in signed, directed networks with weights (closed #14)
- Updated README with examples of
graphr() and others
Themes
- Added themes for Oxford and UNIGE (closed #1)
- Improved
stocnet_theme() to add option to "stocnet_theme" (previously "snet_theme")
- Added
is_dark() to check whether a theme is dark or light
- Added
match_color() to return closest matching colors from a palette
Layouts
- Added layout_valence() for signed graphs (closed #6)
- Added configurational layouts from manynet
- Added aliases for various layout_tbl_graph_*() functions
autograph 0.1.2 (2025-07-02)
Package
- Fixed line break issues in DESCRIPTION
Themes
- Fixed default for
ag_sequential()
Layouts
- Fixed "layout_layered" to accept typical ggraph parameters
manynet
- Added return value statements
migraph
- Added return value statements
RSiena
- Added return value statements
MoNAn
- Added
plot.traces.monan()
- Added
plot.gof.stats.monan()
autograph 0.1.1
Package
autograph 0.1.0
Package
- Initial setup, with all the goodies
Theming
- Added
stocnet_theme() for setting a theme that can then be reused across
successive plots (closes #3)
- For example,
stocnet_theme("iheid") for IHEID colour theme
- Added
ag_*() palettes, for example:
ag_highlight() to select the highlight colours of a particular palette
- Added
match_color() for matching one or more hexcodes to a palette's
offerings
Plotting
- Added manynet plot methods
- Added
plot.diff_model()
- Added
plot.matrix()
- Added
plot.learn_model()
- Added
plot.network_measures()
- Added
plot.network_motif()
- Added
plot.tie_measure()
- Added
plot.node_measure()
- Added
plot.node_member()
- Added
plot.node_members()
- Added
plot.node_motif()
- Added migraph plot methods
- Added
plot.netlm()
- Added
plot.netlogit()
- Added
plot.network_test()
- Added
plot.diffs_model()
- Added RSiena plot methods
- Added
plot.sienaGOF()
- Added
plot.influenceTable()
- Added
plot.selectionTable()
Layouts
- Added
layout_tbl_graph_matching() for positioning nodes according to their
manynet::to_matching() partners
- Added first version of
layout_tbl_graph_layered() for layering nodes
according to a Sugiyama-type layout
Data
- Added some precooked results for testing and illustration