web-dev-qa-db-fra.com

Affichage des valeurs de données sur l'histogramme empilé dans ggplot2

J'aimerais afficher les valeurs de données sur un graphique à barres empilées dans ggplot2. Voici ma tentative de code

Year      <- c(rep(c("2006-07", "2007-08", "2008-09", "2009-10"), each = 4))
Category  <- c(rep(c("A", "B", "C", "D"), times = 4))
Frequency <- c(168, 259, 226, 340, 216, 431, 319, 368, 423, 645, 234, 685, 166, 467, 274, 251)
Data      <- data.frame(Year, Category, Frequency)
library(ggplot2)
p <- qplot(Year, Frequency, data = Data, geom = "bar", fill = Category,     theme_set(theme_bw()))
p + geom_text(aes(label = Frequency), size = 3, hjust = 0.5, vjust = 3, position =     "stack") 

enter image description here

J'aimerais afficher ces valeurs de données au milieu de chaque partie. Toute aide à cet égard sera très appréciée. Merci

96
MYaseen208

De ggplot 2.2.0 les étiquettes peuvent facilement être empilées en utilisant position = position_stack(vjust = 0.5) dans geom_text.

ggplot(Data, aes(x = Year, y = Frequency, fill = Category, label = Frequency)) +
  geom_bar(stat = "identity") +
  geom_text(size = 3, position = position_stack(vjust = 0.5))

enter image description here

Notez également que "position_stack() et position_fill() empilent maintenant les valeurs dans l'ordre inverse du regroupement, ce qui fait que l'ordre de pile par défaut correspond à la légende".


Réponse valide pour les anciennes versions de ggplot:

Voici une approche qui calcule les points médians des barres.

library(ggplot2)
library(plyr)

# calculate midpoints of bars (simplified using comment by @DWin)
Data <- ddply(Data, .(Year), 
   transform, pos = cumsum(Frequency) - (0.5 * Frequency)
)

# library(dplyr) ## If using dplyr... 
# Data <- group_by(Data,Year) %>%
#    mutate(pos = cumsum(Frequency) - (0.5 * Frequency))

# plot bars and add text
p <- ggplot(Data, aes(x = Year, y = Frequency)) +
     geom_bar(aes(fill = Category), stat="identity") +
     geom_text(aes(label = Frequency, y = pos), size = 3)

Resultant chart

161
Ramnath

Comme l'a mentionné Hadley, il existe des moyens plus efficaces de communiquer votre message que les étiquettes dans des graphiques à barres empilées. En fait, les graphiques empilés ne sont pas très efficaces car les barres (chaque catégorie) ne partagent pas un axe, ce qui rend la comparaison difficile.

Dans ces cas, il est presque toujours préférable d'utiliser deux graphiques, partageant un axe commun. Dans votre exemple, je suppose que vous souhaitez afficher le total général, puis les proportions apportées par chaque catégorie au cours d’une année donnée.

library(grid)
library(gridExtra)
library(plyr)

# create a new column with proportions
prop <- function(x) x/sum(x)
Data <- ddply(Data,"Year",transform,Share=prop(Frequency))

# create the component graphics
totals <- ggplot(Data,aes(Year,Frequency)) + geom_bar(fill="darkseagreen",stat="identity") + 
  xlab("") + labs(title = "Frequency totals in given Year")
proportion <- ggplot(Data, aes(x=Year,y=Share, group=Category, colour=Category)) 
+ geom_line() + scale_y_continuous(label=percent_format())+ theme(legend.position = "bottom") + 
  labs(title = "Proportion of total Frequency accounted by each Category in given Year")

# bring them together
grid.arrange(totals,proportion)

Cela vous donnera un affichage à 2 panneaux comme ceci:

Vertically stacked 2 panel graphic

Si vous souhaitez ajouter des valeurs de fréquence, un tableau est le meilleur format.

22
AndrewMinCH