it-swarm.com.de

Wie zentriert man gestapelte Prozent-Barchart-Etiketten?

Ich versuche, Nice stacked percent barchart mit ggplot2 zu zeichnen. Ich habe einiges Material gelesen und habe es fast geschafft zu plotten, was ich will. Außerdem lege ich das Material bei, es könnte an einer Stelle nützlich sein:

Wie bezeichne ich ein gestapeltes Balkendiagramm in ggplot2, ohne einen zusammenfassenden Datenrahmen zu erstellen?

Gestapelte Balkendiagramme erstellen, bei denen jeder Stapel so skaliert wird, dass er 100% ergibt

R gestapelte prozentuale Balkendarstellung mit prozentualem Binärfaktor und Beschriftungen (mit ggplot)

Mein Problem ist, dass ich labels nicht dort platzieren kann, wo ich will - in der Mitte der Bars.  enter image description here

Sie können das Problem in der Abbildung oben sehen - Etiketten sehen schlecht aus und überlappen sich auch.

Was ich gerade suche, ist:

  1. So platzieren Sie Etiketten in der Mitte der Balken (Bereiche)

  2. Wie zeichnet man nicht alle Etiketten, die zum Beispiel besser als 10% sind?

  3. Wie löst man ein überlappendes Problem?

Für den Q 1. @MikeWise wurde eine mögliche Lösung vorgeschlagen. Ich kann dieses Problem jedoch immer noch nicht lösen.

Ich füge auch ein reproduzierbares Beispiel bei, wie ich diesen grahp gezeichnet habe.

library('plyr')
library('ggplot2')
library('scales')
set.seed(1992)
n=68

Category <- sample(c("Black", "Red", "Blue", "Cyna", "Purple"), n, replace = TRUE, prob = NULL)
Brand <- sample("Brand", n, replace = TRUE, prob = NULL)
Brand <- paste0(Brand, sample(1:5, n, replace = TRUE, prob = NULL))
USD <- abs(rnorm(n))*100

df <- data.frame(Category, Brand, USD)

# Calculate the percentages
df = ddply(df, .(Brand), transform, percent = USD/sum(USD) * 100)


# Format the labels and calculate their positions
df = ddply(df, .(Brand), transform, pos = (cumsum(USD) - 0.5 * USD))

#create Nice labes
df$label = paste0(sprintf("%.0f", df$percent), "%")  



ggplot(df, aes(x=reorder(Brand,USD,
                              function(x)+sum(x)),  y=percent, fill=Category))+
  geom_bar(position = "fill", stat='identity',  width = .7)+
  geom_text(aes(label=label, ymax=100, ymin=0), vjust=0, hjust=0,color = "white",  position=position_fill())+
  coord_flip()+
  scale_y_continuous(labels = percent_format())+
  ylab("")+
  xlab("")
20
AK47

So zentrieren Sie die Etiketten und vermeiden Sie das Plotten von Etiketten für kleine Prozentsätze. Ein zusätzliches Problem in Ihren Daten ist, dass Sie für jede Farbe mehrere Balkenabschnitte haben. Stattdessen scheint es mir, dass alle Stababschnitte einer bestimmten Farbe kombiniert werden sollten. Der folgende Code verwendet dplyr anstelle von plyr, um die Daten für das Plotten einzurichten:

library(dplyr)

# Initial data frame   
df <- data.frame(Category, Brand, USD)

# Calculate percentages and label positions
df.summary = df %>% group_by(Brand, Category) %>% 
  summarise(USD = sum(USD)) %>%   # Within each Brand, sum all values in each Category
  mutate(percent = USD/sum(USD),
         pos = cumsum(percent) - 0.5*percent)

Verwenden Sie zum Plotten der Daten eine ifelse-Anweisung, um zu bestimmen, ob eine Beschriftung geplottet wird oder nicht. In diesem Fall habe ich es vermieden, ein Etikett mit Prozentsätzen von weniger als 7% zu plotten.

ggplot(df.summary, aes(x=reorder(Brand,USD,function(x)+sum(x)), y=percent, fill=Category)) +
  geom_bar(stat='identity',  width = .7, colour="black", lwd=0.1) +
  geom_text(aes(label=ifelse(percent >= 0.07, paste0(sprintf("%.0f", percent*100),"%"),""),
                y=pos), colour="white") +
  coord_flip() +
  scale_y_continuous(labels = percent_format()) +
  labs(y="", x="")

 enter image description here

UPDATE: Bei ggplot2 Version 2 ist es nicht mehr erforderlich, die Koordinaten der Textbeschriftungen zu berechnen, um sie zentrieren zu können. Stattdessen können Sie position=position_stack(vjust=0.5) verwenden. Zum Beispiel:

ggplot(df.summary, aes(x=reorder(Brand, USD, sum), y=percent, fill=Category)) +
  geom_bar(stat="identity", width = .7, colour="black", lwd=0.1) +
  geom_text(aes(label=ifelse(percent >= 0.07, paste0(sprintf("%.0f", percent*100),"%"),"")),
                position=position_stack(vjust=0.5), colour="white") +
  coord_flip() +
  scale_y_continuous(labels = percent_format()) +
  labs(y="", x="")

 enter image description here

30
eipi10

Ich folgte dem Beispiel und fand den Weg, wie man Nice-Labels für einfache gestapelte Balkendiagramme einfügt. Ich denke, es könnte auch nützlich sein.

df <- data.frame(Category, Brand, USD)

# Calculate percentages and label positions
df.summary = df %>% group_by(Brand, Category) %>% 
  summarise(USD = sum(USD)) %>%   # Within each Brand, sum all values in each Category
  mutate( pos = cumsum(USD)-0.5*USD)

ggplot(df.summary, aes(x=reorder(Brand,USD,function(x)+sum(x)), y=USD, fill=Category)) +
  geom_bar(stat='identity',  width = .7, colour="black", lwd=0.1) +
  geom_text(aes(label=ifelse(USD>100,round(USD,0),""),
                y=pos), colour="white") +
  coord_flip()+
  labs(y="", x="")

 enter image description here

1
AK47