2016-01-20 17 views
18

Próbuję wykreślić ładne stacked percent barchart przy użyciu ggplot2. Czytałem trochę materiału i prawie udało mi się spiskować, czego chcę. Również Załączam materiału, może być przydatny w jednym miejscu:Jak wyśrodkować stos etykiet procentowych w postaci wykresu słupkowego

How do I label a stacked bar chart in ggplot2 without creating a summary data frame?

Create stacked barplot where each stack is scaled to sum to 100%

R stacked percentage bar plot with percentage of binary factor and labels (with ggplot)

Moim problemem jest to, że nie mogę umieścić labels gdzie chcę - w środek barów. enter image description here

Możesz zobaczyć problem na powyższym obrazku - etykiety wyglądają okropnie, a także nakładają się na siebie.

Co szukam teraz jest:

  1. Jak umieszczać etykiety w midde barów (obszarów)

  2. Jak wykreślić nie wszystkie etykiety, ale dla przykładu, który są lepsze niż 10%?

  3. Jak rozwiązać problem nakładania się?

Dla Q 1. @MikeWise sugeruje możliwą solution. Jednak nadal nie mogę poradzić sobie z tym problemem.

Ponadto załączam powtarzalny przykład, w jaki sposób wykreśliłem ten grahp.

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("") 

Odpowiedz

27

Oto jak wyśrodkować etykiety i unikać drukowania etykiet dla małych wartości procentowych. Dodatkowym problemem w twoich danych jest to, że masz wiele sekcji prętów dla każdego koloru. Zamiast tego wydaje mi się, że wszystkie odcinki kreskowe danego koloru powinny zostać połączone. Poniższy kod wykorzystuje dplyr zamiast plyr skonfigurować dane do kreślenia:

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) 

Aby wykreślić dane, należy użyć oświadczenie ifelse celu ustalenia, czy etykieta jest naniesiona lub nie. W tym przypadku uniknąłem wykreślania etykiety dla wartości procentowych poniżej 7%.

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: Z ggplot2 wersji 2, nie jest już konieczne, aby obliczyć współrzędne etykiet tekstowych, aby je skupionych. Zamiast tego możesz użyć position=position_stack(vjust=0.5). Na przykład:

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

+0

addtional zapytania. Czy istnieje prosty sposób na drukowanie etykiet w pudełkach? Wydaje się, że funkcje 'geom_label' nie działają. [Ten link] (http://stackoverflow.com/questions/7660893/boxed-geom-text-with-ggplot2) też nie pomagają. Sposób wygląda naprawdę kompleksowo – AK47

+1

Jakieś przemyślenia na temat tego, jak to osiągnąć dzięki nowej wersji? Ostatnia "Odpowiedź" na tej stronie pokazuje podobny problem, który mam, gdzie wygląda, jak etykiety są umieszczane w odwrotnej kolejności. Z powodzeniem używałem tej metody od miesięcy. –

+0

Zobacz aktualizację mojej odpowiedzi. – eipi10

1

ja za przykładem i znalazł sposób, jak umieścić ładne etykiety dla prostego ułożone BarChart. Myślę, że to też może być przydatne.

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

-3

sam przykład w Macos Sierra z RStudio 1.0.44 i R wersja 3.3.1 pokazuje inny układ:

enter image description here

+0

Co ciekawe, użyłem tego samego rozwiązania w ciągu ostatnich 6 miesięcy i zadziałało fantastycznie. Dopiero najnowsze aktualizacje, które się zepsuły, z tym samym problemem. Wygląda na to, że procent etykiet jest odwracany od miejsca, w którym powinien być. –

Powiązane problemy