Incapaz de replicar este gráfico ggplot2
Não consigo reproduzir um exemplo da ggroughbiblioteca (https://xvrdm.github.io/ggrough/articles/Customize%20chart.html) Em particular, estou tentando replicar o seguinte gráfico (sem os aspectos da fonte):
O código vem do mesmo link acima sob o cabeçalho "Jardim de infância".
Estou usando o seguinte código:
library(hrbrthemes)
library(tidyverse)
library(gcookbook)
library(ggplot2)
library(ggrough)
ggplot(uspopage, aes(x=Year, y=Thousands, fill=AgeGroup)) +
geom_area(alpha=0.8) +
scale_fill_ipsum() +
scale_x_continuous(expand=c(0,0)) +
scale_y_comma() -> p
options <- list(GeomArea=list(fill_style="hachure",
angle_noise=0.5,
gap_noise=0.2,
gap=1.5,
fill_weight=1))
get_rough_chart(p, options)
No entanto, não sou capaz de replicar o acima. Aqui está o que eu recebo:
Novamente, não estou preocupado com as fontes, mas quero que a geom_area sombreada funcione. Atualmente não é renderizado. Para referência, aqui está o que o pobjeto produz (ou seja, o gráfico antes de passar pelo ggroughprocessamento):
Observe também que sou capaz de replicar o exemplo "Blueprint", que usa geom_col. Parece que algo está errado com o ggroughprocessamento de geom_area, mas não tenho certeza.
Respostas
O pacote ggrough não funciona bem com a versão atual do ggplot2 para geom_area, porque procura a área de destino em nós xml com o nome "polilinha". Em versões anteriores do ggplot2, isso provavelmente funcionava bem, porque cada área era delimitada por uma polilinha. Em versões mais recentes, no entanto, esse não é mais o caso (consulte as alterações mais recentes em 3.3.0 ).
Veja se o seguinte funciona para você:
- Defina uma versão da
parse_*função que procure "polígono", em vez de "polilinha".
parse_polygons <- function (svg) {
shape <- "polygon" # was "polyline" in ggrough:::parse_areas
keys <- NULL
ggrough:::parse_shape(svg, shape, keys) %>% {
purrr::map(.,
~purrr::list_modify(.x,
points = stringr::str_squish(.x$points) %>%
{stringr::str_glue("M{.}Z")},
shape = "path"))
}
}
- Altere a função não exportada correspondente em ggrough para usar a recém-definida
parse_polygonspara as camadas GeomArea.
Além disso, adicionei GeomRibbon (que parecia estar faltando no original, mas é na verdade um caso mais geral de GeomArea) e movi GeomViolin de parse_areaspara parse_polygons, porque enfrenta o mesmo problema.
(Observação: GeomSmooth provavelmente também quebrará, mas acho que sua função de análise exigirá um pouco mais de ajustes, em comparação com GeomRibbon / GeomViolin, e não estou vendo um caso de uso para ele ...)
trace(ggrough:::parse_rough, edit = TRUE)
# paste the following function into the pop-up window
function (svg, geom) {
rough_els <- list()
if (geom %in% c("GeomCol", "GeomBar", "GeomTile", "Background")) {
rough_els <- append(rough_els, parse_rects(svg))
}
if (geom %in% c("GeomSmooth", "Background")) { # removed GeomArea / GeomViolin from here
rough_els <- append(rough_els, parse_areas(svg))
}
if (geom %in% c("GeomArea", "GeomRibbon", "GeomViolin")) { # new condition here
rough_els <- append(rough_els, parse_polygons(svg))
}
if (geom %in% c("GeomPoint", "GeomJitter", "GeomDotPlot", "Background")) {
rough_els <- append(rough_els, parse_circles(svg))
}
if (geom %in% c("GeomLine", "GeomSmooth", "Background")) {
rough_els <- append(rough_els, parse_lines(svg))
}
if (geom %in% c("Background")) {
rough_els <- append(rough_els, parse_texts(svg))
}
purrr::map(rough_els, ~purrr::list_modify(.x, geom = geom))
}
Teste:
library(ggplot2)
library(ggrough)
uspopage <- gcookbook::uspopage
p <- ggplot(uspopage, aes(x=Year, y=Thousands, fill=AgeGroup)) +
geom_area(alpha=0.8) +
scale_x_continuous(expand=c(0,0)); p
options <- list(GeomArea=list(fill_style="hachure",
angle_noise=0.5,
gap_noise=0.2,
gap=1.5,
fill_weight=1))
get_rough_chart(p, options)
Teste adicional para geom_ribbon:
# using example from geom_ribbon help page
pp <- data.frame(year = 1875:1972, level = as.vector(LakeHuron)) %>%
ggplot(aes(year)) +
geom_ribbon(aes(ymin = level - 1, ymax = level + 1),
fill = "grey70")
options <- list(GeomRibbon=list(fill_style="hachure",
angle_noise=0.5,
gap_noise=0.2,
gap=1.5,
fill_weight=1))
get_rough_chart(pp, options)
Informações da sessão:
R version 4.0.1 (2020-06-06)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 15063)
Matrix products: default
locale:
[1] LC_COLLATE=English_Singapore.1252 LC_CTYPE=English_Singapore.1252
[3] LC_MONETARY=English_Singapore.1252 LC_NUMERIC=C
[5] LC_TIME=English_Singapore.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] gdtools_0.2.2 dplyr_1.0.0 ggrough_0.1.0 ggplot2_3.3.2
loaded via a namespace (and not attached):
[1] Rcpp_1.0.5 cpp11_0.2.1 pillar_1.4.6 compiler_4.0.1
[5] plyr_1.8.6 Rmisc_1.5 forcats_0.5.0 tools_4.0.1
[9] boot_1.3-25 digest_0.6.25 jsonlite_1.7.1 lifecycle_0.2.0
[13] tibble_3.0.3 gtable_0.3.0 lattice_0.20-41 pkgconfig_2.0.3
[17] rlang_0.4.7 rstudioapi_0.11 yaml_2.2.1 xml2_1.3.2
[21] withr_2.2.0 stringr_1.4.0 htmlwidgets_1.5.1 systemfonts_0.3.1
[25] generics_0.0.2 vctrs_0.3.4 grid_4.0.1 tidyselect_1.1.0
[29] data.table_1.12.8 svglite_1.2.3.2 glue_1.4.2 R6_2.4.1
[33] gcookbook_2.0 tidyr_1.1.0 reshape2_1.4.4 purrr_0.3.4
[37] farver_2.0.3 magrittr_1.5 htmltools_0.5.0 scales_1.1.1
[41] ellipsis_0.3.1 fortunes_1.5-4 colorspace_1.4-1 labeling_0.3
[45] stringi_1.5.3 munsell_0.5.0 crayon_1.3.4
Estou escrevendo isso como uma resposta, porque seria muito longo para os comentários.
Também experimentei o ggrough pacote para você:
O exemplo a seguir do leia-me do github funciona perfeitamente:
library(ggplot2)
count(mtcars, carb) %>%
ggplot(aes(carb, n)) +
geom_col() +
labs(title="Number of cars by carburator count") +
theme_grey(base_size = 16) -> p
p
library(ggrough)
options <- list(
Background=list(roughness=8),
GeomCol=list(fill_style="zigzag", angle_noise=0.5, fill_weight=2))
get_rough_chart(p, options)
No entanto, quando estou testando seu exemplo:
library(hrbrthemes)
library(tidyverse)
library(gcookbook)
library(ggplot2)
library(ggrough)
ggplot(uspopage, aes(x=Year, y=Thousands, fill=AgeGroup)) +
geom_area(alpha=0.8) +
scale_fill_ipsum() +
scale_x_continuous(expand=c(0,0)) +
scale_y_comma() -> p
p
Está tudo bem até aqui, isso daria a seguinte imagem:
Agora precisaríamos adicionar a parte ggrough.
options <- list(GeomArea=list(fill_style="hachure",
angle_noise=0.5,
gap_noise=0.2,
gap=1.5,
fill_weight=1))
get_rough_chart(p, options)
Eu obtenho praticamente o mesmo resultado que você:
Cheguei à mesma conclusão que você:
Portanto, parece que algo está errado com o processamento do ggrough da geom_area
Poderia até usar todas as mesmas configurações para a parte ggrough com sucesso (com a única diferença GeomCol) para o exemplo do número de carros acima.
Como diz a página do Github:
ggrough é um trabalho em andamento e ainda tem grandes bugs. As contribuições são bem-vindas! "
Eles fizeram seu último commit no Git 2 anos atrás.
Agora, como o enredo que você queria criar é a partir de seus próprios exemplos, tenho certeza de que funcionou antes. (Quero dizer, por que eles carregariam enredos falsos)
Então, se você estiver realmente desesperado, pode tentar:
Instale uma versão ggplot2 (e outros pacotes necessários) de 2 anos atrás
Instale uma versão de commit mais antiga do
ggroughpacote. Talvez eles tenham feito um commit que quebrou o exemplo que funcionava antes.
Ou você tenta consertar o pacote deles;)