User teunbrand has created a geom
size = 0
library(ggplot2)
library(grid) # You usually won't need this, but reprex requires it
## create geom as per below
df <- data.frame(x = rep(1:5, 9), y = c(0.02, 0.04, 0.07, 0.09, 0.11, 0.13, 0.16, 0.18, 0.2, 0.22, 0.24, 0.27, 0.29, 0.31, 0.33, 0.36, 0.38, 0.4, 0.42, 0.44, 0.47, 0.49, 0.51, 0.53, 0.56, 0.58, 0.6, 0.62, 0.64, 0.67, 0.69, 0.71, 0.73, 0.76, 0.78, 0.8, 0.82, 0.84, 0.87, 0.89, 0.91, 0.93, 0.96, 0.98, 1), cat = rep(paste("a", 1:9, sep = ""), each = 5))
ggplot(df, aes(x, y)) +
geom_text(aes(label = cat)) +
geom_trail(size = 0)
于2020-05-15由
reprex package
(第0.3.0版)
geomèu小径
GeomTrail <- ggplot2::ggproto(
"GeomTrail", ggplot2::GeomPoint,
draw_panel = function(data, panel_params, coord, na.rm = FALSE) {
# Default geom point behaviour
if (is.character(data$shape)) {
data$shape <- translate_shape_string(data$shape)
}
coords <- coord$transform(data, panel_params)
if (unique(coords$size == 0)) {
my_points <- NULL
} else {
my_points <- pointsGrob(
coords$x,
coords$y,
pch = coords$shape,
gp = gpar(
col = alpha(coords$colour, coords$alpha),
fill = alpha(coords$fill, coords$alpha),
fontsize = coords$size * .pt + coords$stroke * .stroke / 2,
lwd = coords$stroke * .stroke / 2
)
)
}
# New behaviour
## Convert x and y to units
x <- unit(coords$x, "npc")
y <- unit(coords$y, "npc")
## Make custom grob class
my_path <- grob(
x = x,
y = y,
mult = coords$gap * .pt,
name = "trail",
gp = grid::gpar(
col = alpha(coords$colour, coords$alpha),
fill = alpha(coords$colour, coords$alpha),
lwd = coords$linesize * .pt,
lty = coords$linetype,
lineend = "butt",
linejoin = "round", linemitre = 10
),
vp = NULL,
### Now this is the important bit:
cl = "trail"
)
## Combine grobs
ggplot2:::ggname(
"geom_trail",
grid::grobTree(my_path, my_points)
)
},
# Adding some defaults for lines and gap
default_aes = aes(
shape = 19, colour = "black", size = 1.5, fill = NA, alpha = NA, stroke = 0.5,
linesize = 0.5, linetype = 1, gap = .9,
)
)
makeContent.trail <- function(x) {
# Make hook for drawing
# Convert npcs to absolute units
x_new <- convertX(x$x, "mm", TRUE)
y_new <- convertY(x$y, "mm", TRUE)
# Do trigonometry stuff
hyp <- sqrt(diff(x_new)^2 + diff(y_new)^2)
sin_plot <- diff(y_new) / hyp
cos_plot <- diff(x_new) / hyp
diff_x0_seg <- head(x$mult, -1) * cos_plot
diff_x1_seg <- (hyp - head(x$mult, -1)) * cos_plot
diff_y0_seg <- head(x$mult, -1) * sin_plot
diff_y1_seg <- (hyp - head(x$mult, -1)) * sin_plot
x0 <- head(x_new, -1) + diff_x0_seg
x1 <- head(x_new, -1) + diff_x1_seg
y0 <- head(y_new, -1) + diff_y0_seg
y1 <- head(y_new, -1) + diff_y1_seg
keep <- unclass(x0) < unclass(x1)
# Remove old xy coordinates
x$x <- NULL
x$y <- NULL
# Supply new xy coordinates
x$x0 <- unit(x0, "mm")[keep]
x$x1 <- unit(x1, "mm")[keep]
x$y0 <- unit(y0, "mm")[keep]
x$y1 <- unit(y1, "mm")[keep]
# Set to segments class
class(x)[1] <- "segments"
x
}
geom_trail <-
function(mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE, ...) {
layer(
data = data, mapping = mapping, stat = stat,
geom = GeomTrail, position = position, show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}