geom_arrowbar
Başka bir geom gibi kullanabileceğimiz yeni bir geom oluşturabiliriz , bu durumda sizin durumunuzda istediğiniz grafiği aşağıdaki şekilde verir:
tibble(y = c(10, 20, 30), n = c(300, 100, 200), transparency = c(10, 2, 4)) %>%
ggplot() +
geom_arrowbar(aes(x = n, y = y, alpha = transparency), fill = "red") +
scale_y_continuous(limits = c(5, 35)) +
scale_x_continuous(limits = c(0, 350))
Ve bu 3 parametre içerir column_width
, head_width
ve head_length
bu ayarları varsayılan sevmiyorum eğer ok şeklini değiştirmek için izin verir. Ayrıca dolgu rengini ve diğer estetiği gerektiği gibi belirtebiliriz:
tibble(y = c(10, 20, 30), n = c(300, 100, 200), transparency = c(10, 2, 4)) %>%
ggplot() +
geom_arrowbar(aes(x = n, y = y, alpha = transparency, fill = as.factor(n)),
column_width = 1.8, head_width = 1.8, colour = "black") +
scale_y_continuous(limits = c(5, 35)) +
scale_x_continuous(limits = c(0, 350))
İlk olarak yazmak zorunda olduğumuz tek engel!
Aşağıdaki örneklerde uzanan ggplot2 vignette'in , bizim tanımlayabilir geom_arrowbar
biz ok şeklini kontrol eden 3 parametreleri geçebilecektir istiyorum hariç diğer geoms tanımlandığı aynı şekilde. Bunlar, oklar katmanımızı oluşturmak için kullanılacak params
sonuç layer
nesnesi listesine eklenir :
library(tidyverse)
geom_arrowbar <- function(mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, head_width = 1, column_width = 1,
head_length = 1, ...)
{
layer(geom = GeomArrowBar, mapping = mapping, data = data, stat = stat,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, head_width = head_width,
column_width = column_width, head_length = head_length, ...))
}
Şimdi geriye kalan "hepsi" ne bir GeomArrowBar
. Bu etkili bir şekilde ggproto
sınıf tanımlamasıdır. En önemli kısmı draw_panel
, veri çerçevemizin her satırını alan ve onu ok şekillerine dönüştüren üye işlevidir. Bazı temel matematikler x ve y koordinatlarından ve çeşitli şekil parametrelerimizden okun şeklinin ne olması gerektiğinden sonra, grid::polygonGrob
verilerimizin her satırı için bir tane üretir ve a gTree
. Bu, katmanın grafik bileşenini oluşturur.
GeomArrowBar <- ggproto("GeomArrowBar", Geom,
required_aes = c("x", "y"),
default_aes = aes(colour = NA, fill = "grey20", size = 0.5, linetype = 1, alpha = 1),
extra_params = c("na.rm", "head_width", "column_width", "head_length"),
draw_key = draw_key_polygon,
draw_panel = function(data, panel_params, coord, head_width = 1,
column_width = 1, head_length = 1) {
hwidth <- head_width / 5
wid <- column_width / 10
len <- head_length / 10
data2 <- data
data2$x[1] <- data2$y[1] <- 0
zero <- coord$transform(data2, panel_params)$x[1]
coords <- coord$transform(data, panel_params)
make_arrow_y <- function(y, wid, hwidth) {
c(y - wid/2, y - wid/2, y - hwidth/2, y, y + hwidth/2, y + wid/2, y + wid/2)
}
make_arrow_x <- function(x, len){
if(x < zero) len <- -len
return(c(zero, x - len, x - len , x, x - len, x - len, zero))
}
my_tree <- grid::gTree()
for(i in seq(nrow(coords))){
my_tree <- grid::addGrob(my_tree, grid::polygonGrob(
make_arrow_x(coords$x[i], len),
make_arrow_y(coords$y[i], wid, hwidth),
default.units = "native",
gp = grid::gpar(
col = coords$colour[i],
fill = scales::alpha(coords$fill[i], coords$alpha[i]),
lwd = coords$size[i] * .pt,
lty = coords$linetype[i]))) }
my_tree}
)
Bu uygulama mükemmel olmaktan uzak. Mantıklı varsayılan eksen sınırları ve yeteneği gibi bazı önemli işlevler eksiktir coord_flip
ve ok başları tüm sütundan daha uzunsa (yine de bu durumda böyle bir arsa kullanmak istemeyebilirsiniz), estetik sonuçlar üretecektir. . Bununla birlikte, negatif bir değeriniz varsa, oku belirgin bir şekilde sola bakacaktır. Daha iyi bir uygulama, boş ok başları için bir seçenek de ekleyebilir.
Kısacası, bu (ve diğer) böcekleri ütülemek ve üretime hazır hale getirmek için çok fazla ince ayar yapılması gerekir, ancak bu arada çok fazla çaba harcamadan bazı güzel grafikler üretmek için yeterince iyidir.
2020-03-08 tarihinde reprex paketi tarafından oluşturuldu (v0.3.0)
tibble(y = c(10, 20, 30), n = c(300, 100, 200), transparency = c(10, 2, 4)) %>% ggplot() + geom_segment(aes(x = 0, xend = n-10, y = y, yend = y, alpha = transparency), colour = 'red', size = 10) + geom_segment(aes(x = n-0.1, xend = n, y = y, yend = y, alpha = transparency), colour = 'red', size = 1, arrow = arrow(length = unit(1.5, 'cm'), type = 'closed')) + scale_y_continuous(limits = c(5, 35))