Como ponto de partida, uso o código muito útil da resposta de Kat a esta pergunta ( Como adicionar menos aspereza às bordas de um mapa do que ao preenchimento do mapa ) para criar dois gráficos, com a intenção de que um dos gráficos seja sobreposto ao outro.
library(magrittr)
library(ggplot2)
#devtools::install_github("xvrdm/ggrough")
library(ggrough)
library(sf)
library(htmltools)
library(ggiraph)
trace(ggrough:::parse_rough, edit=TRUE)
#In the popup window, paste this so that parse_rough will use parse_sf for GeomSf.
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("GeomArea", "GeomViolin", "GeomSmooth",
"Background")) {
rough_els <- append(rough_els, parse_areas(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))
}
if (geom %in% c("GeomSf")) {
rough_els <- append(rough_els, parse_sf(svg))
}
purrr::map(rough_els, ~purrr::list_modify(.x, geom = geom))
}
# Create the function parse_sf.
parse_sf <- function (svg) {
shape <- "path"
keys <- NULL
ggrough:::parse_shape(svg, shape, keys) %>% {
purrr::map(.,
~purrr::list_modify(.x,
points = .x$d,
shape = "path"
))
}
}
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
b <- ggplot(nc) + geom_sf(color = "black") + theme_minimal() +
theme(panel.grid = element_line(color = NA), # not resized or removed! (keep spacing)
axis.text = element_text(color = NA))
options <- list(GeomSf = list(fill_style = "hachure", angle = 60, angle_noise = 1,
gap_noise = 0, gap = 6, fill_weight = 2, bowing = 5,
roughness = 30))
(xx <- get_rough_chart(b, options)) # from your question
fixer <- function(ggr) { # where ggr is the ggrough graph
nd <- lapply(1:length(ggr$x$data), function(j) {
if(!is.null(ggr$x$data[[j]]$lengthAdjust)) { # if a text element (axis label)
ggr$x$data[[j]]$content <- "" # remove text, but keep spacing
ggr$x$data[[j]] # return modified data element
} else {
ggr$x$data[[j]] # not text, return orig data
}
})
ggr$x$data <- nd # add mod data to graph
ggr # return mod graph
}
xx2 <- xx %>% fixer() # modify the plot, to hide text
(g2 <- ggplot(nc) +
geom_sf(fill = "transparent", color = "black", linewidth = 2) +
theme_minimal() +
theme(plot.background = element_rect(fill = NA, color = "transparent"), # no white background
panel.background = element_rect(fill = NA, color = "transparent"),
text = element_text(size = 9))) # text size to match defaults in ggrough
gg <- girafe(ggobj = g2, width_svg = 7, height_svg = 5) # h/w default w/ ggrough
browsable(div( # parent div, size matches ggrough's default
style = css(width = "960px", height = "500px", position = "relative"),
div(xx2, style = css(display = "block")), # ggrough graph
div(gg, style = css(position = "absolute", top = 0, padding.top = "54.2px", # layer behind
width = "610px", height = "500px", z.index = -2))
)) # size and padding found by trial and error with defaults for graph sizes
O gráfico na resposta parece estar sobreposto corretamente. No entanto, quando executo o mesmo código (no RStudio), a sobreposição que obtenho está incorreta:
Também testei no RStudio em outro computador, onde também obtive sobreposição imperfeita, mas em um grau diferente.
Tenho duas perguntas:
- Como posso sobrepor os gráficos corretamente, sem ter que recorrer à tentativa e erro?
- Como posso ajustar o código para que o plano de fundo atual seja alternado para o primeiro plano? Em outras palavras, como posso fazer as bordas pretas ficarem em cima dos rabiscos cinzas em vez do contrário? Tentei trocar a ordem dos dois
div
s perto do fim, mas isso não funcionou.
Não consegui encontrar nenhuma informação clara sobre como isso
ggrough
se traduz em tamanhos literais.Nesta resposta, usei uma proporção de largura x altura de 7 x 5 (polegadas), que é bem padrão (
browser
,knitr
, e similares). Não testei para ver se essas fórmulas se manteriam em diferentes proporções.Como não consegui definir o que parece ser jogar lama em um ventilador de teto
ggrough
, criei centenas de gráficos, alinhei-os e então determinei se havia uma fórmula que eu pudesse criar para identificar com precisão as dimensões corretas para o objeto ggplot.Quando me refiro ao,
ggplot
quero dizer a camada de borda que fica em cima. Quando me refiro ao,ggrough
quero dizer a camada de preenchimento que fica em baixo.As métricas a seguir mudam dependendo da altura e largura atribuídas ao grough.
Como esses elementos estão espalhados por diferentes funções, criei uma UDF que depende de três entradas: largura e altura do gráfico e os dados a serem plotados.
O valor que você atribui para largura e altura... Acredito que eles representam polegadas, mas eu não assumiria que 1 = 1 polegada. Não há nada na documentação deles que identifique o que esses valores representam, mas 1 equivale a cerca de 72 pixels, o que é preciso se 1 representa uma polegada.
Deixei uma mensagem que estava usando para validação no código, porque você pode achar que é uma informação útil. Ela apenas cospe todas as métricas calculadas no console ao processar os dados.
Embora o SO naturalmente maximize o tamanho da imagem para caber, você pode pelo menos ver a variação nos tamanhos das fontes.
Ou às 5, 5:
Ou às 9, 7:
Este é um exemplo de escurecimento da saída e de uma mensagem de erro que você pode ver.