
Aggregate-then-shade dense lines and segments (datashader-style)
Source:R/datashade.R
datashade_lines.RdThe line/segment analogue of datashade(). Past a few hundred thousand line
vertices — a dense stack of timeseries, or the edges of a large graph — drawing
each line as a vector primitive overplots into a solid mass and balloons the
output. datashade_lines() and datashade_segments() instead rasterise the
lines into a canvas-sized grid in one pass: each cell accumulates the
(anti-aliased) coverage of the lines crossing it, so overlapping lines add and
the grid records true line density. The grid is shaded exactly like
datashade() (colors/how/span/clip) and returned as a single
raster_grob().
Usage
datashade_lines(
x,
y,
group = NULL,
weight = NULL,
width = 600L,
height = 400L,
xlim = NULL,
ylim = NULL,
colors = c("#deebf7", "#08306b"),
how = c("eq_hist", "log", "cbrt", "linear"),
span = NULL,
clip = NULL,
spread = NULL,
interpolate = FALSE,
name = NULL,
vp = NULL,
id = NULL,
role = NULL
)
datashade_segments(
x0,
y0,
x1,
y1,
weight = NULL,
width = 600L,
height = 400L,
xlim = NULL,
ylim = NULL,
colors = c("#deebf7", "#08306b"),
how = c("eq_hist", "log", "cbrt", "linear"),
span = NULL,
clip = NULL,
spread = NULL,
interpolate = FALSE,
name = NULL,
vp = NULL,
id = NULL,
role = NULL
)Arguments
- x, y
For
datashade_lines(), the polyline vertices (data space); a segment joins each consecutive pair.- group
For
datashade_lines(), an optional per-vertex series id (factor or vector) the same length asx. The line breaks between vertices whose group differs, so multiple series pack into one call.NULLtreats all vertices as one series (still broken byNAcoordinates).- weight
Optional per-line weight (per start-vertex for
datashade_lines(), per segment fordatashade_segments()): cells accumulate summed weight instead of plain coverage.NULLweighs each line 1; a scalar is recycled; otherwise it must match the line/segment count.- width, height
Aggregation grid size in cells (= output raster pixels).
- xlim, ylim
Data range to bin over; default the finite range of
x/y.- colors
For density shading, two or more colours forming the low-to-high ramp. For categorical shading (
categoryset), a per-category hue vector — named by category level, or one colour per level in level order.- how
Density-to-colour mapping:
"eq_hist"(histogram equalisation — datashader's default, reveals structure across orders of magnitude),"log","cbrt"(cube root), or"linear". Also drives the per-cell opacity under categorical shading.- span
Optional
c(lo, hi)density values mapped to the ends of the colour ramp / opacity range; densities outside are clamped.NULL(default) uses the full observed range.- clip
Optional percentile pair in
[0, 1](e.g.c(0.01, 0.99)) derivingspanfrom the quantiles of the non-empty cell densities — a robust way to keep a few extreme cells from flattening the rest. Overridesspan.- spread
Optional post-aggregation spreading, applied to the shaded raster to keep sparse output visible (see
spread()/dynspread()):NULL(default) none; a positive integer appliesspread()with that pixel radius;"auto"appliesdynspread()(radius chosen from the image density).- interpolate
Passed to
raster_grob();FALSEkeeps hard bin edges.- name, vp, id, role
Passed to
raster_grob()(see grob).- x0, y0, x1, y1
For
datashade_segments(), the segment endpoints (data space), one per segment; all four the same length.
Details
datashade_lines()takes a connected polyline: a segment is drawn between each consecutive(x, y). Passgroupto pack several series into one call — the line breaks wherever the group changes; anNAinx/yalso breaks it. This is the dense-timeseries path.datashade_segments()takes independent segments(x0, y0) -> (x1, y1), one per element. This is the network-edge /mark_segmentpath.
Line coverage is anti-aliased (a Wu accumulator) and summed, so a line deposits
roughly weight per cell it spans and dense bundles brighten honestly rather
than saturating. As with datashade(), align the raster to data axes by drawing
it in a vl_viewport() whose xscale/yscale match xlim/ylim.
See also
datashade() for points; dynspread()/spread() for keeping thin
lines visible.
Examples
set.seed(1)
# Dense timeseries: 400 random walks of 500 steps, packed into one raster.
k <- 400; m <- 500
walks <- apply(matrix(rnorm(k * m), m, k), 2, cumsum)
t <- rep(seq_len(m), k)
g <- datashade_lines(t, as.vector(walks), group = rep(seq_len(k), each = m),
width = 400, height = 300)
# Network edges: random segments shaded by edge density.
n <- 5000
e <- datashade_segments(rnorm(n), rnorm(n), rnorm(n), rnorm(n))