Alfa estetiği düz şekil yerine okun iskeletini gösterir - nasıl önlenir?


11

Barların sonunda oklarla bir bar arsası oluşturmayı hedefliyorum. Ben tanımlanmış geom_segmentile gitti arrow. Bir sütunu saydamlığa eşlemek istiyorum, ancak alfa estetiği ok nesnesiyle iyi çalışmıyor gibi görünüyor. Kod pasajı şöyledir:

tibble(y = c(10, 20, 30), n = c(300, 100, 200), transparency = c(10, 2, 4)) %>% 
  ggplot() + geom_segment(aes(x = 0, xend = n, y = y, yend = y, alpha = transparency), 
                          colour = 'red', size = 10, arrow = arrow(length = unit(1.5, 'cm'), type = 'closed')) +
  scale_y_continuous(limits = c(5, 35))

resim açıklamasını buraya girin

arrowNesnenin alphadüz, şeffaf şekil yerine iskeletini gösteren daha düşük değerlerle iyi görünmediği kolayca görülebilir . Bunu önlemenin bir yolu var mı?


İlginç gözlem - Sadece daha küçük genişliğe sahip ayrı bir segment çizmek gibi bazı geçici çözümleri düşünebilirim, örneğin: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))
Wolfgang Arnold

bu gerçekten ilginç. Üst üste binen "iskeletler" için kesin alanı hesaplamaktan ve her alan için alfa programlı olarak ayarlamaktan kaçınmak mümkün değil (bu korkunç bir hack olacak). Gerçekten şeffaf oklar istiyorsanız, başka bir yaklaşım 1) segmenti ve 2) yanına üçgen çizmek olacaktır. (bu da benim için oldukça büyük bir saldırı gibi görünüyor).
Tjebo

2
Oklar için düz bir şeffaflığa sahip olmanın iyi olacağını kesinlikle haklı olacaksınız. Bunun ggplot'un sonundaki herhangi bir davranıştan kaynaklanmadığına inanıyorum, ancak 'grid' paketinin okları nasıl çizdiği ile ilgili gibi görünüyor (hangi ggplot2 bağlıdır).
teunbrand

Yanıtlar:


13

geom_arrowbarBaş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))

resim açıklamasını buraya girin

Ve bu 3 parametre içerir column_width, head_widthve head_lengthbu 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))

resim açıklamasını buraya girin

İlk olarak yazmak zorunda olduğumuz tek engel!

Aşağıdaki örneklerde uzanan ggplot2 vignette'in , bizim tanımlayabilir geom_arrowbarbiz 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 paramssonuç layernesnesi 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 ggprotosı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::polygonGrobverilerimizin 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_flipve 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)


4

Sen kullanabilirsiniz geom_gene_arrowdanlibrary(gggenes)

data.frame(y=c(10, 20, 30), n=c(300, 100, 200), transparency=c(10, 2, 4)) %>% 
  ggplot() + 
  geom_gene_arrow(aes(xmin = 0, xmax = n, y = y, alpha = transparency), 
                  arrowhead_height = unit(6, "mm"), fill='red') +
  scale_y_continuous(limits = c(5, 35))

resim açıklamasını buraya girin


2
Bu yeni keşfettiğim tekerlek olmalı! ;)
Allan Cameron
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.