2 votes

ggplot2 - Barre empilée avec une largeur différente

Je veux produire un graphique en pyramide inversée où les barres sont empilées les unes sur les autres avec une largeur différente.

1. J'ai un graphique à barres empilées comme l'exemple de code ci-dessous

library(dplyr)
library(ggplot2)
sample <- data_frame(x=c(1, 1, 1, 1, 2, 2, 2, 2),
                     y=c(5,10,15, 20, 10, 5, 20, 10),
                     w=c(1, 2, 3, 4, 1, 2, 3, 4),
                     group=c("a", "b", "c", "d", "a", "b", "c", "d"))

ggplot() +
    geom_bar(data=sample,
             aes(x=x,y=y,group=group, fill=group),
             stat="identity", position=position_stack())

enter image description here

Puis j'ai ajouté la largeur à aes donc celui qui est le plus bas w sera plus petite alors qu'ils sont toujours empilés les uns sur les autres. Cependant, les barres ne se sont pas empilées avec les avertissements.

ggplot() +
geom_bar(data=sample,
         aes(x=x,y=y,group=group, fill=group, width=w/5),
         stat="identity", position=position_stack())

enter image description here

Warning: Ignoring unknown aesthetics: width
Warning message:
position_stack requires non-overlapping x intervals 

Toute aide pour rendre le diagramme à barres empilées ou toute idée sur un autre type de diagramme qui peut couvrir des concepts similaires serait très appréciée. Merci pour votre aide.

6voto

Andrey Kolyadin Points 1011

C'est un peu un hack.

Je vais utiliser geom_rect() au lieu de vraies colonnes. Je dois donc créer data.frame() avec des positions précalculées pour les limites du rectangle.

df_plot <- sample %>% 
  arrange(desc(group)) %>% # Order so lowest 'groups' firtst
  group_by(x) %>% 
  mutate(yc = cumsum(y), # Calculate position of "top" for every rectangle
         yc2 = lag(yc, default = 0) ,# And position of "bottom"
         w2 = w/5) # Small scale for width

# Plot itself

ggplot(df_plot) +
  geom_rect(
    aes(xmin = x - w2 / 2, xmax = x + w2 / 2,
        ymin = yc, ymax = yc2,
        group = group, fill=group))

Tracé résultant : enter image description here

3voto

Andrew Lavers Points 2618

Une version assez longue avec des rubans

library(dplyr)
library(ggplot2)
sample <- data_frame(x=c(1, 1, 1, 1, 2, 2, 2, 2),
                     y=c(5,10,15, 20, 10, 5, 20, 10),
                     w=c(1, 2, 3, 4, 1, 2, 3, 4),
                     group=c("a", "b", "c", "d", "a", "b", "c", "d"))

# make factors for non-numeic items
sample$x <- factor(sample$x)
sample$group <- factor(sample$group)

# calcualte cumulative sums
sample2 <- sample %>%
  group_by(x) %>%
  arrange(desc(group)) %>%
  mutate(ycum=cumsum(y)) %>%
  ungroup()  %>%
  select(x, group, ycum, w) 

# Ffor each point, make another row lagged  
sample2lead <- sample2 %>%
  group_by(x) %>%
  mutate(ycum = lag(ycum, default=0), w=lag(w, default=max(sample2$w))) %>%
  ungroup() %>%
  select(x, group, ycum, w) 

# combine   
combined <- bind_rows(sample2, sample2lead) %>%
  arrange(x, ycum, desc(group))

# plot a ribbon forming trapezoids
ggplot() +
  geom_ribbon(data=combined,
             aes(x=ycum, ymin=-w/2, ymax=w/2, fill=group)) +
  coord_flip() +
  facet_grid(~x)

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X