Type: | Package |
Title: | Vector Field Visualizations with 'ggplot2' |
Version: | 1.0.0 |
Maintainer: | Dusty Turner <dusty.s.turner@gmail.com> |
Description: | A 'ggplot2' extension for visualizing vector fields in two-dimensional space. Provides flexible tools for creating vector and stream field layers, visualizing gradients and potential fields, and smoothing vector and scalar data to estimate underlying patterns. |
License: | MIT + file LICENSE |
Encoding: | UTF-8 |
RoxygenNote: | 7.3.2 |
Depends: | R (≥ 4.1.0), ggplot2 (≥ 3.3.0) |
Imports: | farver, tibble, numDeriv, deSolve, grid, utils, scales, cli |
URL: | https://github.com/dusty-turner/ggvfields |
BugReports: | https://github.com/dusty-turner/ggvfields/issues |
Suggests: | ggdensity, knitr, rmarkdown, testthat (≥ 3.0.0) |
Date: | 2025-03-08 |
Config/testthat/edition: | 3 |
BuildVignettes: | true |
NeedsCompilation: | no |
Packaged: | 2025-03-13 15:33:55 UTC; Dusty_Turner1 |
Author: | Dusty Turner [aut, cre], David Kahle [aut], Rodney X. Sturdivant [aut] |
Repository: | CRAN |
Date/Publication: | 2025-03-15 17:10:05 UTC |
ggvfields: Vector Field Visualizations with ggplot2
Description
A ggplot2 extension for visualizing vector fields in a two-dimensional space. Provides functions to create vector field layers using user-defined vector field functions.
See Also
Useful links:
Electric field
Description
The vector field generated by collection of fixed electrical charges, as dictated by Coulomb's law. This function is mainly used to provide examples for visualizing vector fields with ggvfields.
Usage
efield(u, charge_positions, charges, k = 1, q_test = +1)
efield_maker(
charge_positions = rbind(c(-1, -1), c(1, 1)),
charges = c(-1, +1),
k = 1,
q_test = +1
)
Arguments
u |
The position of the test charge. |
charge_positions |
The positions of the fixed charges generating the
electric field. Defaulted in |
charges |
The charges of the points placed at the positions of
charge_positions. Defaulted in |
k |
The constant of proportionality, defaulted to 1. See examples for a more rigorous use of physical constants. |
q_test |
The test charge, defaulted to +1. |
Value
A vector containing the force felt by the test charge on account of the electric field.
See Also
https://en.wikipedia.org/wiki/Coulomb%27s_law
Examples
# set a - charge at (-1,-1) and a + charge at (1,1)
charge_positions <- rbind(c(-1,-1), c(1,1))
charges <- c(-1, +1)
# calculate force on test charge (+1) at c(0,1), ignoring physical constants
efield(c(0,1), charge_positions, charges)
# efield_maker() simply wraps this function, defaulting to those charges
f <- efield_maker()
f(c(0,1))
ggplot() +
geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2)) +
scale_color_viridis_c(trans = "log10")
# electric constant from https://en.wikipedia.org/wiki/Vacuum_permittivity
ep0 <- 8.854187818814e-12
k <- (4*pi*ep0)^-1
efield(c(0,1), charge_positions, charges, k)
Create a Gradient Field Layer in ggplot2
Description
These functions provide convenient ggplot2 layers for drawing gradient fields
by computing the gradient of a scalar field. A user-defined function (fun
)
specifies the behavior of the scalar field by taking a numeric vector of
length 2 (representing (x, y)
) and returning a single numeric value.
The underlying StatStreamField computes the gradient via numerical
differentiation (using numDeriv::grad()
) and GeomStream renders the
resulting vectors.
Usage
geom_gradient_field(
mapping = NULL,
data = NULL,
stat = StatStreamField,
position = "identity",
...,
na.rm = FALSE,
show.legend = TRUE,
inherit.aes = TRUE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
max_it = 1000,
T = NULL,
L = NULL,
center = TRUE,
type = "vector",
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 30, length = grid::unit(0.02, "npc"), type = "closed")
)
stat_gradient_field(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = TRUE,
inherit.aes = TRUE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
max_it = 1000,
T = NULL,
L = NULL,
center = TRUE,
type = "vector",
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 30, length = grid::unit(0.02, "npc"), type = "closed")
)
geom_gradient_field2(
mapping = NULL,
data = NULL,
stat = StatStreamField,
position = "identity",
...,
na.rm = FALSE,
show.legend = TRUE,
inherit.aes = TRUE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
max_it = 1000,
T = NULL,
L = NULL,
center = FALSE,
type = "stream",
normalize = TRUE,
tail_point = TRUE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = NULL
)
stat_gradient_field2(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = TRUE,
inherit.aes = TRUE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
max_it = 1000,
T = NULL,
L = NULL,
center = FALSE,
type = "stream",
normalize = TRUE,
tail_point = TRUE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = NULL
)
Arguments
mapping |
A set of aesthetic mappings created by |
data |
A data frame containing the input data. |
stat |
The statistical transformation to use on the data for this layer. Defaults to StatStreamField. |
position |
Position adjustment, either as a string or the result of a position adjustment function. |
... |
Other arguments passed on to |
na.rm |
Logical. If |
show.legend |
Logical. Should this layer be included in the legends? |
inherit.aes |
Logical. If |
fun |
A function that defines the scalar field. It should take a numeric
vector of length 2 (representing |
xlim |
Numeric vector of length two. Specifies the limits of the x-axis
domain. Defaults to |
ylim |
Numeric vector of length two. Specifies the limits of the y-axis
domain. Defaults to |
n |
Integer. Grid resolution specifying the number of seed points along
each axis. Higher values produce a denser gradient field. Defaults to |
max_it |
Integer. Maximum number of integration steps allowed when
computing the gradient stream. Defaults to |
T |
Numeric. Time increment used for numerical integration when
|
L |
Numeric. Target length for the gradient vectors or streamlines. When
|
center |
Logical. If |
type |
Character. Specifies the type of field to compute: use |
normalize |
Logical. If |
tail_point |
Logical. If |
eval_point |
Logical. If |
grid |
A data frame containing precomputed grid points for seed
placement. If |
lineend |
Line end style (round, butt, square). |
linejoin |
Line join style (round, mitre, bevel). |
linemitre |
Line mitre limit (number greater than 1). |
arrow |
A |
geom |
The geometric object used to render the streamline (only used in
|
Details
Two variants are provided:
-
geom_gradient_field() uses a default mapping that sets
color = after_stat(norm)
. -
geom_gradient_field2() uses a default mapping that sets
length = after_stat(norm)
(withcolor
unmapped by default).
Value
A ggplot2 layer that computes and plots a gradient field by numerically differentiating a scalar field.
Aesthetics
geom_gradient_field()
and geom_gradient_field2()
understand the following aesthetics (required aesthetics are in bold):
-
x
: The x-coordinate of the seed point. -
y
: The y-coordinate of the seed point. -
color
: In geom_gradient_field, the color of the gradient vector. In geom_gradient_field2, color is not mapped by default. -
length
: In geom_gradient_field2, the computed vector norm. -
size
,linetype
,alpha
: Additional aesthetics to control appearance.
Computed Variables
The following variables are computed internally by StatStreamField when generating the gradient field from a scalar function:
- norm
The Euclidean norm of the gradient vector, calculated as
\sqrt{fx^2 + fy^2}
. This value is used, by default, for mapping color or scaling arrow lengths in the visualization.- avg_spd
This variable may represent an average speed computed from the gradient magnitude. In the default mapping for geom_gradient_field, the color aesthetic is mapped to
after_stat(avg_spd)
.
Examples
Si <- matrix(c(1, 0.75, 0.75, 1), nrow = 2)
f <- function(u) exp(-as.numeric(u %*% solve(Si) %*% u) / 2) / (2 * pi * det(Si))
ggplot() +
geom_gradient_field(fun = f, xlim = c(-3, 3), ylim = c(-3, 3))
df <- expand.grid(x = seq(-3, 3, 0.1), y = seq(-3, 3, 0.1)) |>
transform(fxy = apply(cbind(x, y), 1, f))
ggplot() +
geom_raster(aes(x, y, fill = fxy), data = df) +
geom_gradient_field(fun = f, xlim = c(-3, 3), ylim = c(-3, 3)) +
coord_equal()
fxy <- function(x, y) apply(cbind(x,y), 1, f)
ggplot() +
ggdensity::geom_hdr_fun(fun = fxy, xlim = c(-3,3), ylim = c(-3,3)) +
geom_gradient_field(fun = f, xlim = c(-3,3), ylim = c(-3,3)) +
coord_equal()
library("ggdensity")
fxy <- function(x, y) apply(cbind(x, y), 1, f)
fxy(1, 2)
f(1:2)
ggplot() +
geom_hdr_fun(fun = fxy, xlim = c(-3, 3), ylim = c(-3, 3)) +
geom_gradient_field(fun = f, xlim = c(-3, 3), ylim = c(-3, 3)) +
coord_equal()
Create a Gradient Smoothed Field Layer
Description
geom_gradient_smooth()
creates a ggplot2 layer that visualizes the gradient
of a scalar field computed from raw data. A linear model is fitted using the
supplied formula
(default: z ~ x + y + I(x^2) + I(y^2)
) on the raw data,
and the numerical gradient is computed using numDeriv::grad(). The computed
gradient field is then visualized using GeomStream()
.
Usage
geom_gradient_smooth(
mapping = NULL,
data = NULL,
stat = StatStreamField,
position = "identity",
...,
na.rm = FALSE,
show.legend = TRUE,
inherit.aes = TRUE,
formula = z ~ x + y + I(x^2) + I(y^2),
xlim = NULL,
ylim = NULL,
n = 11,
max_it = 1000,
T = NULL,
L = NULL,
center = TRUE,
type = "vector",
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 30, length = grid::unit(0.02, "npc"), type = "closed")
)
stat_gradient_smooth(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = TRUE,
inherit.aes = TRUE,
formula = z ~ x + y + I(x^2) + I(y^2),
xlim = NULL,
ylim = NULL,
n = 11,
max_it = 1000,
T = NULL,
L = NULL,
center = TRUE,
type = "vector",
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 30, length = grid::unit(0.02, "npc"), type = "closed")
)
Arguments
mapping |
A set of aesthetic mappings created by |
data |
A data frame containing the raw vector data. |
stat |
The statistical transformation to use on the data. Defaults to
|
position |
Position adjustment, either as a string or the result of a position adjustment function. |
... |
Additional arguments passed to the layer. |
na.rm |
Logical. If |
show.legend |
Logical. Should this layer be included in the legends? |
inherit.aes |
Logical. If |
formula |
A formula specifying the linear model for the scalar field.
Defaults to |
xlim |
Numeric vector of length 2 specifying the domain limits in the
|
ylim |
Numeric vector of length 2 specifying the domain limits in the
|
n |
An integer vector specifying the grid resolution for smoothing. |
max_it |
Maximum number of iterations for field integration (when used in streamlines). |
T |
If |
L |
If |
center |
Logical. If |
type |
Character. Either |
normalize |
Logical. If |
tail_point |
Logical. If |
eval_point |
Logical. If |
grid |
A user-supplied data frame or pattern (e.g., "hex") for specifying custom evaluation points. |
lineend |
Line end style (round, butt, square). |
linejoin |
Line join style (round, mitre, bevel). |
linemitre |
Line mitre limit (number greater than 1). |
arrow |
An optional |
geom |
The geometric object used to render the streamline (only used in
|
Value
A ggplot2 layer that can be added to a ggplot object.
Aesthetics
geom_gradient_smooth()
supports the following aesthetics (required aesthetics are in bold):
-
x
: The x-coordinate of the data point. -
y
: The y-coordinate of the data point. -
z
: The scalar value used for computing the gradient. -
color
: The color used for the gradient vectors. Defaults depend on the selectedtype
.
Details
Gradient Calculation:
A linear model is fitted using the provided formula
and the raw data. The scalar
field defined by the model is then differentiated numerically with
numDeriv::grad()
to yield gradient vectors.
Visualization:
The resulting gradient field is visualized using GeomStream()
. Since z
is only
used internally, it is dropped from the final visual output.
Examples
# Define several scalar field functions:
# Example 1: f(x, y) = x^2 - y^2
f <- function(u) {
x <- u[1]
y <- u[2]
x^2 - y^2
}
# Example 2: g(x, y) = sin(x) * cos(y)
g <- function(u) {
x <- u[1]
y <- u[2]
sin(x) * cos(y)
}
# Example 3: h(x, y) = log(|x| + 1) + sqrt(|y|)
h <- function(u) {
x <- u[1]
y <- u[2]
log(abs(x) + 1) + sqrt(abs(y))
}
# Create a grid of evaluation points
grid_data <- expand.grid(
x = seq(-5, 5, length.out = 30),
y = seq(-5, 5, length.out = 30)
)
# Compute the scalar field for f and plot its gradient
grid_data$z <- apply(grid_data, 1, f)
ggplot(grid_data, aes(x = x, y = y, z = z)) +
geom_gradient_smooth()
# Compute and plot for g:
grid_data$z <- apply(grid_data, 1, g)
ggplot(grid_data, aes(x = x, y = y, z = z)) +
geom_gradient_smooth()
# Compute and plot for h:
grid_data$z <- apply(grid_data, 1, h)
ggplot(grid_data, aes(x = x, y = y, z = z)) +
geom_gradient_smooth()
Compute and Plot Potential Function from a Conservative Vector Field
Description
geom_potential()
adds a raster layer to a ggplot object, visualizing the
potential function derived from a conservative vector field. It computes the
potential numerically over a specified grid and displays it as a heatmap.
Usage
geom_potential(
mapping = NULL,
data = NULL,
stat = StatPotential,
position = "identity",
...,
na.rm = FALSE,
inherit.aes = TRUE,
show.legend = NA,
fun,
xlim = NULL,
ylim = NULL,
n = 51,
tol = 1e-06,
verify_conservative = FALSE
)
stat_potential(
mapping = NULL,
data = NULL,
geom = GeomPotential,
position = "identity",
...,
na.rm = FALSE,
inherit.aes = TRUE,
show.legend = NA,
fun,
xlim = NULL,
ylim = NULL,
n = 51,
tol = 1e-06,
verify_conservative = FALSE
)
Arguments
mapping |
A set of aesthetic mappings created by |
data |
The data to be displayed in this layer. If |
stat |
The statistical transformation to use on the data (default: StatPotential). |
position |
Position adjustment, either as a string or the result of a position adjustment function. |
... |
Other arguments passed to |
na.rm |
Logical. If |
inherit.aes |
Logical. If |
show.legend |
Logical. Should this layer be included in the legends? |
fun |
A function that takes a numeric vector of length 2 ( |
xlim |
Numeric vector of length 2 defining the domain limits on the
x-axis. Defaults to |
ylim |
Numeric vector of length 2 defining the domain limits on the
y-axis. Defaults to |
n |
Integer. Number of grid points along each axis for computing the
potential. Defaults to |
tol |
Numeric. Tolerance for verifying if the vector field is
conservative. Defaults to |
verify_conservative |
Logical. If |
geom |
The geometric object used to render the potential function. Defaults to GeomPotential. |
Details
Note: the potential is only known up to a constant. The point of reference
used is the lower left corner c(xlim[1], ylim[1])
, where the potential is
assumed to be 0.
Value
A ggplot2 layer that produces a potential function heatmap.
Aesthetics
geom_potential()
accepts all aesthetics supported by
GeomRaster
. In particular, the key aesthetics include:
-
fill: The computed potential value at each grid cell, which is mapped to a color scale.
-
x
andy
: The coordinates of the grid cell centers. (calculated) -
alpha
: Controls the transparency of the raster fill.
Additional raster-specific aesthetics (e.g. those controlled by
scale_fill_gradient()
, scale_fill_viridis_c()
, etc.) can be applied to
modify the appearance of the potential heatmap.
Computed Variables
The following variable is computed internally by StatPotential during the potential function calculation:
- Potential
The scalar potential value computed numerically at each grid point. It represents the accumulated potential from a reference point (typically the lower bounds of
xlim
andylim
) to the given point. This value is mapped to thefill
aesthetic in the raster layer.
Examples
scalar_field <- function(u){
x <- u[1]; y <- u[2]
(x + y)^2 + 4*(x - y)^2 - 8*(.5)^2
}
gradient_field <- function(u) numDeriv::grad(scalar_field, u)
s <- seq(-1, 1, length.out = 51)
expand.grid("x" = s, "y" = s) |>
transform(phi = apply(cbind(x, y), 1, scalar_field)) |>
ggplot(aes(x, y)) + geom_raster(aes(fill = phi))
ggplot() + geom_potential(fun = gradient_field)
ggplot() + geom_potential(fun = gradient_field, verify_conservative = TRUE)
Create a Streamline Plot Layer in ggplot2
Description
geom_stream()
generates a ggplot2 layer that visualizes data as continuous
streams over a temporal variable t
. Each stream is defined by the
required aesthetics x
, y
, and t
, and optionally grouped by
group
(or mapped from id
). Within each group, data points are
automatically ordered by t
to form a continuous path.
Usage
geom_stream(
mapping = NULL,
data = NULL,
stat = StatStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
arrow.fill = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 25, length = unit(0.025, "npc"), type = "closed")
)
stat_stream(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
arrow.fill = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 25, length = unit(0.025, "npc"), type = "closed")
)
Arguments
mapping |
A set of aesthetic mappings created by |
data |
A data frame or other object, as in |
stat |
The statistical transformation to use on the data for this layer; defaults to StatStream. |
position |
Position adjustment, either as a string or the result of a position adjustment function. |
... |
Other arguments passed to the underlying layers for further customization. |
na.rm |
Logical. If |
show.legend |
Logical. Should this layer be included in the legends? |
inherit.aes |
Logical. If |
arrow.fill |
An optional parameter specifying the color of the arrow
head. Defaults to |
lineend |
Line end style (round, butt, square). |
linejoin |
Line join style (round, mitre, bevel). |
linemitre |
Line mitre limit (number greater than 1). |
arrow |
An optional |
geom |
The geometric object used to render the streamline (only used in
|
Details
There are two variants:
-
geom_stream()
: A convenient wrapper that setsstat = StatStream
and uses ggplot2::GeomPath by default. -
stat_stream()
: Provides direct access to the reordering stat (i.e.StatStream
) for advanced customization, using GeomStream for drawing.
Value
A ggplot2 layer that can be added to a plot to produce a streamline visualization.
Aesthetics
geom_stream()
and stat_stream()
understand the
following aesthetics (required aesthetics are in bold):
-
x
: Horizontal position. -
y
: Vertical position. -
t
: Temporal or ordered variable used to sequence data points. -
group
: Grouping variable for multiple streams (automatically mapped fromid
if absent). -
color
: Color of the stream. -
linetype
: Type of line used to draw the stream. -
linewidth
: Thickness of the stream line. -
alpha
: Transparency of the stream.
Details
-
Data Ordering: If
t
is not provided, an error is thrown. When present, points within each group are sorted byt
prior to drawing the stream. -
Arrows: The
arrow
parameter can be used to indicate direction along each stream.
Computed Variables
These are calculated by the 'stat' part of layers and can be accessed with delayed evaluation.
- norm
This variable is calculated as the Euclidean distance derived from the ranges of the
x
andy
values. It serves as a normalization factor for vector lengths when thenormalize
parameter is active.- avg_spd
Represents the average speed, which is defined as the length of the stream divided by the time it took to traverse that distance.
Examples
n <- 25
s <- seq(0, 1, length.out = n+1)[-(n+1)]
df <- data.frame( "t" = s, "x" = cos(2*pi*s), "y" = sin(2*pi*s) )
ggplot(df) +
geom_stream(aes(x, y, t = t)) +
coord_equal()
ggplot(df) +
geom_stream(aes(x, y, t = t, alpha = t), size = 5) +
coord_equal()
ggplot(df) +
geom_path(aes(x, y, alpha = t), size = 5) +
coord_equal()
stream_1 <- data.frame(
x = c(0, 3),
y = c(0, 0),
t = 0:1
)
stream_2 <- data.frame(
x = c(1, 1),
y = c(1, 5),
t = 0:1
)
stream_3 <- data.frame(
x = c(2, 5),
y = c(2, 6),
t = 0:1
)
streams <- rbind(
cbind(stream_1, id = 1),
cbind(stream_2, id = 2),
cbind(stream_3, id = 3)
)
ggplot(stream_1) +
geom_stream(aes(x = x, y = y, t = t))
# set group aes if multiple vectors
ggplot(streams) +
geom_stream(aes(x = x, y = y, t = t, group = id))
Create a Stream Field Layer in ggplot2
Description
geom_stream_field()
creates a ggplot2 layer that integrates a user-defined
vector field function f(x, y) \to (dx, dy)
over a grid of seed points
within a specified domain. The function numerically integrates the field
starting from these seeds, producing streamlines that visualize the flow.
This is useful for visualizing vector fields, flow patterns, or trajectories,
such as in fluid dynamics or gradient fields.
Usage
geom_stream_field(
mapping = NULL,
data = NULL,
stat = StatStreamField,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = FALSE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
args = list(),
max_it = 1000L,
tol = sqrt(.Machine$double.eps),
T = NULL,
L = NULL,
center = TRUE,
type = "stream",
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
grid = NULL,
method = "rk4",
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 30, length = unit(0.02, "npc"), type = "closed")
)
stat_stream_field(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
args = list(),
max_it = 1000,
tol = sqrt(.Machine$double.eps),
T = NULL,
L = NULL,
center = TRUE,
type = "stream",
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
grid = NULL,
method = "rk4",
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 30, length = unit(0.02, "npc"), type = "closed")
)
geom_stream_field2(
mapping = NULL,
data = NULL,
stat = StatStreamField,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = FALSE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
args = list(),
max_it = 1000,
tol = sqrt(.Machine$double.eps),
L = NULL,
center = FALSE,
type = "stream",
tail_point = TRUE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
method = "rk4"
)
stat_stream_field2(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = FALSE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
args = list(),
max_it = 1000,
tol = sqrt(.Machine$double.eps),
L = NULL,
center = FALSE,
type = "stream",
tail_point = TRUE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
method = "rk4"
)
Arguments
mapping |
A set of aesthetic mappings created by |
data |
A data frame or other object, as in |
stat |
The statistical transformation to use on the data (default: StatStreamField). |
position |
Position adjustment, either as a string or the result of a position adjustment function. |
... |
Other arguments passed to |
na.rm |
Logical. If |
show.legend |
Logical. Should this layer be included in the legends? |
inherit.aes |
Logical. If |
fun |
A function of two variables, |
xlim |
Numeric vector of length 2 specifying the domain limits in the
|
ylim |
Numeric vector of length 2 specifying the domain limits in the
|
n |
Integer or two-element numeric vector specifying the grid resolution
(number of seed points) along each axis. Defaults to |
args |
A list of additional arguments passed to |
max_it |
|
tol |
|
T |
Numeric. When |
L |
Numeric. Maximum arc length for each streamline. When |
center |
Logical. If |
type |
Character. Either |
normalize |
Logical.
When |
tail_point |
Logical. If |
eval_point |
Logical. If |
grid |
A data frame containing precomputed grid points for seed
placement. If |
method |
Character. Integration method (e.g. |
lineend |
Line end style (round, butt, square). |
linejoin |
Line join style (round, mitre, bevel). |
linemitre |
Line mitre limit (number greater than 1). |
arrow |
A |
geom |
The geometric object used to render the streamlines (defaults to GeomStream). |
Value
A ggplot2 layer that computes and renders streamlines over the specified domain.
Aesthetics
geom_stream_field()
(and its stat variant) inherit
aesthetics from GeomStream and understand the following:
-
x
: x-coordinate of the seed point. -
y
: y-coordinate of the seed point. -
color
: Color, typically used to represent computed statistics (e.g. average speed). -
linetype
: Type of line used to draw the streamlines. -
linewidth
: Thickness of the streamlines. -
alpha
: Transparency of the streamlines.
Details
The streamlines are generated by numerically integrating
the vector field defined by fun(x, y)
. When normalize = TRUE
,
integration stops once the cumulative arc length reaches L
; otherwise,
integration runs until time T
is reached. If both T
and L
are
provided in incompatible combinations, one parameter is ignored. The
computed paths are rendered by GeomStream.
Computed Variables
The following variables are computed internally by StatStreamField during the integration of the vector field:
- avg_spd
For vector fields, this is computed as the total arc length divided by the integration time, providing an estimate of the average speed. It is used to scale the vector lengths when mapping
length = after_stat(norm)
.- t
The integration time at each computed point along a streamline.
- d
The distance between consecutive points along the computed path.
- l
The cumulative arc length along the streamline, calculated as the cumulative sum of
d
.
Examples
f <- function(u) c(-u[2], u[1])
# the basic usage involves providing a fun, xlim, and ylim
ggplot() + geom_stream_field(fun = f, xlim = c(-1,1), ylim = c(-1,1))
# if unspecified, xlim and ylim default to c(-1,1). we use this in what
# follows to focus on other parts of the code
ggplot() + geom_stream_field(fun = f)
ggplot() + geom_stream_field(fun = f, center = FALSE)
ggplot() + geom_stream_field(fun = f, normalize = FALSE)
ggplot() + geom_stream_field(fun = f, normalize = FALSE, center = FALSE)
# run systems until specified lengths
ggplot() + geom_stream_field(fun = f, normalize = TRUE, L = .8)
ggplot() + geom_vector_field(fun = f, normalize = TRUE, L = .3)
ggplot() + geom_vector_field(fun = f, normalize = FALSE, L = 2)
# run systems for specified times
ggplot() + geom_stream_field(fun = f, normalize = FALSE, T = .1)
# tail and eval points
ggplot() + geom_stream_field(fun = f, tail_point = TRUE)
ggplot() + geom_stream_field(fun = f, eval_point = TRUE)
# changing the grid of evaluation
ggplot() + geom_stream_field(fun = f)
ggplot() + geom_stream_field(fun = f, grid = "hex")
ggplot() + geom_stream_field(fun = f, grid = "hex", n = 5)
ggplot() + geom_stream_field(fun = f, n = 5)
ggplot() + geom_stream_field(fun = f, xlim = c(-5, 5)) + coord_equal()
ggplot() + geom_stream_field(fun = f, xlim = c(-5, 5), n = c(21, 11)) + coord_equal()
ggplot() + geom_stream_field(fun = f)
ggplot() + geom_stream_field(fun = f, grid = grid_hex(c(-1,1), c(-1,1), .2))
# using other ggplot2 tools
f <- efield_maker()
ggplot() + geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2))
ggplot() +
geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2)) +
scale_color_viridis_c(trans = "log10")
ggplot() +
geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2)) +
scale_color_viridis_c(trans = "log10") +
coord_equal()
# other vector fields
f <- function(u) u
ggplot() + geom_stream_field(fun = f, xlim = c(-1,1), ylim = c(-1,1))
f <- function(u) c(2,1)
ggplot() + geom_stream_field(fun = f, xlim = c(-1,1), ylim = c(-1,1))
# neat examples
f <- function(u) {
x <- u[1]; y <- u[2]
c(y, y*(-x^2 - 2*y^2 + 1) - x)
}
ggplot() + geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2))
ggplot() + geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2), type = "vector")
f <- function(u) {
x <- u[1]; y <- u[2]
c(y, x - x^3)
}
ggplot() + geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2))
ggplot() + geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2),
grid = grid_hex(c(-2,2), c(-2,2), .35))
f <- function(u) {
x <- u[1]; y <- u[2]
c(x^2 - y^2, x^2 + y^2 - 2)
}
ggplot() + geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2))
ggplot() + geom_stream_field(fun = f, xlim = c(-2,2), ylim = c(-2,2),
grid = grid_hex(c(-2,2), c(-2,2), .35))
ggplot() +
geom_stream_field(fun = f, aes(alpha = after_stat(t)), xlim = c(-2,2), ylim = c(-2,2)) +
scale_alpha(range = c(0,1))
ggplot() +
geom_stream_field(
fun = f, xlim = c(-1,1), ylim = c(-1,1),
linewidth = .75, arrow = arrow(length = unit(0.015, "npc"))
)
Create a Smoothed Vector Field Layer
Description
geom_stream_smooth()
creates a ggplot2 layer that visualizes a smooth
vector field based on raw vector data. The function fits a multivariate
linear model (by default, using the formula cbind(fx, fy) ~ x * y
) to
predict the vector displacements at any given location. It also handles
different input formats by converting polar coordinates or endpoint data to
vector displacements.
Usage
geom_stream_smooth(
mapping = NULL,
data = NULL,
stat = StatStreamField,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
n = 11,
xlim = NULL,
ylim = NULL,
normalize = TRUE,
center = FALSE,
type = "vector",
formula = cbind(fx, fy) ~ x * y,
eval_points = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 20, length = unit(0.015, "npc"), type = "closed")
)
stat_stream_smooth(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
n = 11,
xlim = NULL,
ylim = NULL,
normalize = TRUE,
center = FALSE,
type = "vector",
formula = cbind(fx, fy) ~ x * y,
eval_points = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 20, length = unit(0.015, "npc"), type = "closed")
)
Arguments
mapping |
A set of aesthetic mappings created by |
data |
A data frame containing the raw vector data. |
stat |
The statistical transformation to use on the data. Defaults to
|
position |
Position adjustment, either as a string or the result of a position adjustment function. |
... |
Additional arguments passed to the layer. If a fixed parameter
|
na.rm |
Logical. If |
show.legend |
Logical. Should this layer be included in the legends? |
inherit.aes |
Logical. If |
n |
An integer vector specifying the grid resolution for smoothing. |
xlim |
Numeric vector of length 2 specifying the domain limits in the
|
ylim |
Numeric vector of length 2 specifying the domain limits in the
|
normalize |
Logical. If |
center |
Logical. If |
type |
Character. Either |
formula |
A formula specifying the multivariate linear model used for
smoothing. Defaults to |
eval_points |
A data frame of evaluation points, or |
lineend |
Line end style (round, butt, square). |
linejoin |
Line join style (round, mitre, bevel). |
linemitre |
Line mitre limit (number greater than 1). |
arrow |
An optional |
geom |
The geometric object used to render the streamline (only used in
|
Value
A ggplot2 layer that can be added to a ggplot object to display a smoothed vector field.
- norm
Computed as the Euclidean norm of the displacement,
\sqrt{fx^2 + fy^2}
, this variable is used to normalize and scale the vector lengths.- t
The integration time or evaluation time at each computed point along the smoothed field (when applicable).
- d
The incremental distance between consecutive computed points.
- l
The cumulative arc length along the smoothed vector field, calculated as the cumulative sum of
d
.
Aesthetics
geom_stream_smooth()
supports the following aesthetics
(required aesthetics are in bold):
-
x
: The x-coordinate of the vector's starting point. -
y
: The y-coordinate of the vector's starting point. -
fx
: The displacement along the x-axis. -
fy
: The displacement along the y-axis. -
color
: The fixed color for the vector. Defaults to"blue"
. -
linewidth
: The thickness of the vector line. -
linetype
: The type of the vector line (e.g., solid or dashed). -
alpha
: The transparency level of the vector. -
arrow
: Specifies arrowheads for the vectors.
Details
Data Conversion:
If xend
/yend
are missing or all NA
, the function computes them. It
first checks for vector displacements (fx
and fy
); if present, it
computes xend = x + fx,\quad yend = y + fy.
Otherwise, it checks for
polar coordinates (angle
and distance
) and computes xend = x +
distance \times \cos(angle \times 180/\pi),\quad yend = y + distance \times
\sin(angle \times 180/\pi).
An error is thrown if neither set is
available.
Smoothing:
The multivariate linear model is fitted using the provided formula
and
data
. This model is then used to predict vector displacements at any
specified grid point, generating a smooth approximation of the vector
field.
Prediction Intervals: Two types of prediction intervals can be displayed:
-
Ellipse: Depicts the joint uncertainty (covariance) in the predicted
fx
andfy
. -
Wedge: Indicates the range of possible vector directions and magnitudes.
Examples
# Define a true vector field function
f <- function(u) {
x <- u[1]; y <- u[2]
c(x^2 - y^2, x^2 + y^2 - 2)
}
# Alternative example function
f <- function(u) c(-u[2], u[1])
# Visualize the vector field
ggplot() + geom_stream_field(fun = f, xlim = c(-2, 2), ylim = c(-2, 2))
# Generate design points
n <- 20
df <- data.frame(x = runif(n, -2, 2), y = runif(n, -2, 2))
# Sample function values at design points
fdf <- as.data.frame(t(apply(df, 1, f)))
colnames(fdf) <- c("fx", "fy")
df <- cbind(df, fdf)
# Visualize raw vector field data
ggplot(df) + geom_vector(aes(x, y, fx = fx, fy = fy))
# Add smoothed layer using default model
ggplot(df) +
geom_vector(aes(x, y, fx = fx, fy = fy)) +
geom_stream_smooth(formula = cbind(fx, fy) ~ x * y)
# Use a more complex polynomial model
ggplot(df) +
geom_vector(aes(x, y, fx = fx, fy = fy)) +
geom_stream_smooth(formula = cbind(fx, fy) ~ poly(x, 2) * poly(y, 2), data = df)
# Fit a linear model and use it for prediction
fhat <- function(u) {
model <- lm(cbind(fx, fy) ~ x * y, data = df)
predict(model, newdata = data.frame(x = u[1], y = u[2])) |> as.numeric()
}
# Visualize estimated field with the raw vector field
ggplot(df) +
geom_stream_field(fun = fhat, normalize = FALSE, color = "#3366FF") +
geom_vector(aes(x, y, fx = fx, fy = fy))
# Generate a hexagonal grid
hex_lattice <- grid_hex(xlim = c(-5, 5), ylim = c(-5, 5), d = 1)
# Use the hexagonal grid in geom_stream_field
ggplot(data = df) +
geom_vector(aes(x, y, fx = fx, fy = fy), color = "black", normalize = FALSE) +
geom_stream_smooth(eval_points = hex_lattice)
# user specified point
eval_pts <- data.frame(x = c(0, 1), y = c(2, -1))
ggplot(data = df) +
geom_vector(aes(x, y, fx = fx, fy = fy), color = "black", normalize = FALSE) +
geom_stream_smooth(eval_points = eval_pts)
Vector Layers for ggplot2
Description
Create layers for drawing vectors on ggplot2 plots. These functions accept
wide-format data with the required aesthetics x
and y
plus either
xend
and yend
or one of the alternative specifications: fx
and fy
, or angle
/ angle_deg
and distance
.
Usage
geom_vector(
mapping = NULL,
data = NULL,
stat = StatVector,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
center = TRUE,
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
L = NULL,
arrow = grid::arrow(angle = 25, length = unit(0.025, "npc"), type = "closed")
)
stat_vector(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
center = TRUE,
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
L = NULL,
arrow = grid::arrow(angle = 25, length = unit(0.025, "npc"), type = "closed")
)
geom_vector2(
mapping = NULL,
data = NULL,
stat = StatVector,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
center = FALSE,
tail_point = TRUE,
eval_point = FALSE,
L = NULL,
arrow = NULL
)
stat_vector2(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
center = FALSE,
tail_point = TRUE,
eval_point = FALSE,
L = NULL,
arrow = NULL
)
Arguments
mapping |
A set of aesthetic mappings created by |
data |
A data frame containing the vector data in wide format. |
stat |
The statistical transformation to use on the data (default: StatVector). |
position |
Position adjustment, either as a string or the result of a position adjustment function. |
... |
Other arguments passed on to |
na.rm |
Logical. If |
show.legend |
Logical. Should this layer be included in the legends? |
inherit.aes |
Logical. If |
center |
Logical. If |
normalize |
Logical. If |
tail_point |
Logical. If |
eval_point |
Logical. If |
L |
Numeric scalar. The desired length for the vectors in data units. If
|
arrow |
An optional |
geom |
The geometric object used to render the streamline (only used in
|
Details
When specifying the vector direction using polar coordinates, you can provide either:
-
angle
: the vector direction in radians. -
angle_deg
: the vector direction in degrees (which is automatically converted to radians).
The endpoints are computed by translating the starting point using these
polar coordinates along with the supplied distance
.
The data is converted to long format (two rows per vector) via StatVector and rendered with GeomStream. Optionally, arrowheads can be added to indicate direction.
There are two variants:
-
geom_vector()
: Uses the user-supplied aesthetic mapping. -
geom_vector2()
: Uses the same underlying stat (StatVector) but adds a default mapping forlength = after_stat(norm)
, making the computed vector norm available as an aesthetic.
Value
A ggplot2 layer that can be added to a plot.
Aesthetics
geom_vector()
and geom_vector2()
understand the following aesthetics
(required aesthetics are in bold):
-
x
-
y
xend
yend
fx (alternative specification)
fy (alternative specification)
angle (vector direction in radians; alternative specification)
angle_deg (vector direction in degrees; alternative specification, converted to radians)
distance (with angle/angle_deg, used to compute endpoints)
alpha
color
fill
group
linetype
size
Computed Variables
These are calculated by the 'stat' part of layers and can be accessed with delayed evaluation.
- norm
Calculated as the Euclidean distance between the starting point (
x
,y
) and the computed endpoint (xend
,yend
). This value is used to normalize the vector length when thenormalize
parameter is set toTRUE
.
Examples
set.seed(1234)
n <- 10
# Generate wind data in polar coordinates
data <- data.frame(
x = rnorm(n),
y = rnorm(n),
dir = runif(n, -pi, pi), # angle in radians
spd = rchisq(n, df = 2) # speed
) |>
transform(fx = spd * cos(dir), fy = spd * sin(dir))
# Using fx/fy to compute endpoints
ggplot(data, aes(x, y)) +
geom_vector(aes(fx = fx, fy = fy))
# Using angle (in radians) and distance to compute endpoints
ggplot(data, aes(x, y)) +
geom_vector(aes(angle = dir, distance = spd))
# Using angle_deg (in degrees) and distance to compute endpoints
vectors3 <- data.frame(
x = c(0, 1, 2),
y = c(0, 1, 2),
angle_deg = c(0, 90, 45),
angle = c(0, pi/2, pi/4),
distance = c(3, 4, 5)
)
ggplot(vectors3, aes(x, y)) +
geom_vector(aes(angle_deg = angle_deg, distance = distance))
# Basic usage with explicit start and end points:
vectors1 <- data.frame(
x = c(0, 1, 2),
y = c(0, 1, 2),
xend = c(3, 1, 5),
yend = c(0, 5, 6)
)
ggplot(vectors1, aes(x = x, y = y, xend = xend, yend = yend)) +
geom_vector()
# Using center = TRUE to recenter vectors:
ggplot(vectors1, aes(x = x, y = y, xend = xend, yend = yend)) +
geom_vector(center = TRUE)
# Using normalize = TRUE to adjust vectors to unit length:
ggplot(vectors3, aes(x = x, y = y, angle = angle, distance = distance)) +
geom_vector(normalize = TRUE)
# Using geom_vector2, which adds a default mapping for `length`
ggplot(vectors1, aes(x = x, y = y, xend = xend, yend = yend)) +
geom_vector2()
Vector Field Layers for ggplot2
Description
These functions provide convenient ggplot2 layers for drawing vector fields using streamlines.
Usage
geom_vector_field(
mapping = NULL,
data = NULL,
stat = StatStreamField,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = FALSE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
args = list(),
center = TRUE,
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 30, length = unit(0.02, "npc"), type = "closed")
)
stat_vector_field(
mapping = NULL,
data = NULL,
stat = StatStreamField,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = FALSE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
args = list(),
center = TRUE,
normalize = TRUE,
tail_point = FALSE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = grid::arrow(angle = 30, length = unit(0.02, "npc"), type = "closed")
)
geom_vector_field2(
mapping = NULL,
data = NULL,
stat = StatStreamField,
position = "identity",
...,
na.rm = FALSE,
show.legend = TRUE,
inherit.aes = FALSE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
args = list(),
center = FALSE,
tail_point = TRUE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = NULL
)
stat_vector_field2(
mapping = NULL,
data = NULL,
geom = GeomStream,
position = "identity",
...,
na.rm = FALSE,
show.legend = TRUE,
inherit.aes = FALSE,
fun,
xlim = NULL,
ylim = NULL,
n = 11,
args = list(),
center = FALSE,
tail_point = TRUE,
eval_point = FALSE,
grid = NULL,
lineend = "butt",
linejoin = "round",
linemitre = 10,
arrow = NULL
)
Arguments
mapping |
A set of aesthetic mappings created by |
data |
A data frame containing the input data. |
stat |
The statistical transformation to use on the data for this layer. Defaults to StatStreamField. |
position |
Position adjustment, either as a string or the result of a call to a position adjustment function. |
... |
Other arguments passed on to |
na.rm |
Logical. If |
show.legend |
Logical. Should this layer be included in the legends? |
inherit.aes |
Logical. If |
fun |
A function that defines the vector field. It should take a numeric
vector of length 2 (representing |
xlim |
Numeric vector of length two. Specifies the limits of the x-axis
domain. Defaults to |
ylim |
Numeric vector of length two. Specifies the limits of the y-axis
domain. Defaults to |
n |
Integer. Grid resolution specifying the number of seed points along
each axis. Higher values produce a denser vector field. Defaults to |
args |
List of additional arguments passed on to the function defined by
|
center |
Logical. If |
normalize |
Logical. If |
tail_point |
Logical. If |
eval_point |
Logical. If |
grid |
A data frame containing precomputed grid points for seed
placement. If |
lineend |
Line end style (round, butt, square). |
linejoin |
Line join style (round, mitre, bevel). |
linemitre |
Line mitre limit (number greater than 1). |
arrow |
A |
geom |
The geometric object used to render the streamline (only used in
|
Details
A user-defined function (fun
) specifies the behavior of the vector field by
taking a numeric vector of length 2 (representing (x, y)
) and returning
a numeric vector of length 2 (representing (dx, dy)
). The underlying
StatStreamField computes the streamlines based on the vector field
function, and GeomStream renders them.
Two variants are provided:
-
geom_vector_field() uses a default mapping that sets
color = after_stat(norm)
. -
geom_vector_field2() uses a default mapping that sets
length = after_stat(norm)
(withcolor
unmapped by default).
Value
A ggplot2 layer that computes and plots a vector field using streamlines.
- norm
Calculated as the Euclidean distance between the starting point (
x
,y
) and the computed endpoint. Used to normalize the vector.
Aesthetics
geom_vector_field()
and geom_vector_field2()
understand the following aesthetics (required aesthetics are in bold):
-
x
: The x-coordinate of the vector's starting point. -
y
: The y-coordinate of the vector's starting point. -
fx
: The horizontal component of the vector displacement. -
fy
: The vertical component of the vector displacement. -
color
: The color of the vector lines (default mapping in geom_vector_field). -
length
: The computed vector norm (default mapping in geom_vector_field2). -
linetype
: The type of the vector line (e.g., solid, dashed). -
linewidth
: The thickness of the vector line. -
alpha
: The transparency of the vector.
See Also
Examples
f <- function(u) c(-u[2], u[1])
ggplot() + geom_vector_field(fun = f, xlim = c(-1,1), ylim = c(-1,1))
# xlim and ylim default to (-1,1), so for ease of illustration we remove them
ggplot() + geom_vector_field(fun = f)
ggplot() + geom_vector_field(fun = f, grid = "hex")
ggplot() + geom_vector_field2(fun = f)
ggplot() + geom_vector_field2(fun = f, grid = "hex")
f <- efield_maker()
ggplot() + geom_vector_field(fun = f, xlim = c(-2,2), ylim = c(-2,2))
ggplot() + geom_vector_field2(fun = f, xlim = c(-2,2), ylim = c(-2,2))
Create a Smooth Vector Plot Layer
Description
geom_vector_smooth()
creates a ggplot2 layer that visualizes a smooth
vector field. It takes raw vector data and applies smoothing (via a
multivariate linear model) to estimate the underlying vector field. This
functionality is analogous to geom_smooth()
in ggplot2 but is tailored for
vector data rather than scalar responses.
Usage
geom_vector_smooth(
mapping = NULL,
data = NULL,
stat = "vector_smooth",
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
n = c(11, 11),
method = "lm",
se = TRUE,
se.circle = TRUE,
pi_type = "ellipse",
conf_level = c(0.95, NA),
formula = cbind(fx, fy) ~ x * y,
eval_points = NULL,
arrow = grid::arrow(angle = 20, length = unit(0.015, "npc"), type = "closed")
)
GeomVectorSmooth
Arguments
mapping |
A set of aesthetic mappings created by |
data |
A data frame containing the raw vector data. |
stat |
The statistical transformation to use on the data (default:
|
position |
Position adjustment, either as a string or the result of a position adjustment function. |
... |
Other arguments passed to |
n |
An integer vector specifying the number of grid points along each axis for smoothing. |
method |
Character. Specifies the smoothing method. Currently, the only
supported method is |
se |
Logical. If |
se.circle |
Logical. If |
pi_type |
Character. Determines the display style for prediction intervals:
|
conf_level |
Numeric. Specifies the confidence level for the prediction
intervals. Default is |
formula |
A formula specifying the multivariate linear model used for
smoothing. The default is |
eval_points |
A data frame of evaluation points. If provided, these
specify the grid where the smoothing model is evaluated. If |
arrow |
A |
Format
An object of class GeomVectorSmooth
(inherits from GeomSegment
, Geom
, ggproto
, gg
) of length 6.
Value
A ggplot2 layer that can be added to a plot to create a smooth vector field visualization.
Aesthetics
geom_vector_smooth()
supports the following aesthetics
(required aesthetics are in bold):
-
x
: The x-coordinate of the vector's starting point. -
y
: The y-coordinate of the vector's starting point. -
fx
: The horizontal component of the vector displacement. -
fy
: The vertical component of the vector displacement. -
color
: The color of the vector lines. -
linewidth
: The thickness of the vector lines. -
linetype
: The type of the vector lines (e.g., solid, dashed). -
alpha
: The transparency level of the vectors. -
arrow
: An aesthetic that can be used to modify arrowhead properties.
Details
Multivariate Linear Model:
The "lm"
method fits a multivariate linear model to predict vector
displacements (fx
and fy
) based on the coordinates x
and y
, including
interaction terms (x * y
). This model smooths the raw vector data to
provide an estimate of the underlying vector field.
Prediction Intervals:
When se = TRUE
, prediction intervals are computed for the smoothed vectors.
Two types of intervals are supported:
-
Ellipse: Ellipses represent the joint uncertainty (covariance) in the predicted
fx
andfy
. -
Wedge: Wedges (angular sectors) indicate the range of possible vector directions and magnitudes. The type of interval displayed is controlled by
pi_type
, and the confidence level is set viaconf_level
.
Examples
# Function to generate vectors
generate_vectors <- function(v) {
x <- v[1]
y <- v[2]
c(
sin(x) + sin(y) + rnorm(1, 5, 1),
sin(x) - sin(y) - rnorm(1, 5, 1)
)
}
# Set seed for reproducibility
set.seed(123)
# Create sample points and compute vectors
sample_points <- data.frame(
x = runif(30, 0, 10),
y = runif(30, 0, 10)
)
result <- t(apply(sample_points, 1, generate_vectors))
sample_points$xend <- result[, 1]
sample_points$yend <- result[, 2]
sample_points$fx <- sample_points$xend - sample_points$x
sample_points$fy <- sample_points$yend - sample_points$y
sample_points$distance <- sqrt(sample_points$fx^2 + sample_points$fy^2)
sample_points$angle <- atan2(sample_points$fy, sample_points$fx)
# Define evaluation points
eval_points <- data.frame(
x = c(0, 7.5),
y = c(10, 5)
)
# Example 1:
ggplot(sample_points, aes(x = x, y = y)) +
geom_vector(aes(fx = fx, fy = fy, color = NULL), center = FALSE, alpha = 0.2) +
geom_vector_smooth(aes(fx = fx, fy = fy), n = 5) +
ggtitle("Smoothed Vector Field")
# Example 2: Ellipse with eval_points
ggplot(sample_points, aes(x = x, y = y)) +
geom_vector(aes(fx = fx, fy = fy, color = NULL), center = FALSE, alpha = 0.2) +
geom_vector_smooth(aes(fx = fx, fy = fy), eval_points = eval_points, conf_level = c(0.9)) +
ggtitle("Smoothed Vector Field with Ellipse Intervals")
# Example 3: Wedge with eval_points
ggplot(sample_points, aes(x = x, y = y)) +
geom_vector(aes(fx = fx, fy = fy, color = NULL), center = FALSE, alpha = 0.2) +
geom_vector_smooth(aes(fx = fx, fy = fy), eval_points = eval_points, pi_type = "ellipse") +
ggtitle("Smoothed Vector Field with Wedge Intervals")
Generate a Hexagonal Lattice
Description
This function generates a hexagonal lattice of points within the given x and y limits, using a specified hexagon diameter. The diameter is 2 times the distance between adjacent x (and y) values, see examples.
Usage
grid_hex(xlim, ylim, d)
Arguments
xlim |
A numeric vector of length 2 specifying the x-axis limits. |
ylim |
A numeric vector of length 2 specifying the y-axis limits. |
d |
A numeric value specifying the hexagon diameter. |
Value
A data frame with two columns, x
and y
, containing the
coordinates of the hexagonal grid points.
Examples
xlim <- c(-1, 1)
ylim <- c(-1, 0)
grid <- grid_hex(xlim, ylim, .25)
head( grid )
str( grid )
plot( grid, asp = 1 )
diff(sort(unique(grid$x)))
Create a Continuous Scale for Vector Length
Description
scale_length_continuous()
provides a continuous scale for controlling the
length aesthetic in a ggplot. This is particularly useful when working with
vector plots where vector lengths are mapped to a continuous scale.
Usage
scale_length_continuous(max_range = 0.5, ...)
Arguments
max_range |
The maximum value to which the input is rescaled. Numeric scalar specifying the upper bound of the output range. Should be between 0 and 1. |
... |
Other arguments passed to |
Value
If max_range
is less than or equal to 0.5 (the default), a
continuous scale object (typically of class "ScaleContinuous"
)
mapping the length
aesthetic is returned. If max_range
is
greater than 0.5, a list is returned with two components:
the continuous scale object, and
a theme modification (a
theme
object) that adjusts the legend key width based on the value ofmax_range
.