2012-07-02 5 views
15
df <- structure(list(ID = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 
5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L), .Label = c("1", 
"2", "3", "4", "5", "6", "7"), class = "factor"), TYPE = structure(c(1L, 
2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 
1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 
5L, 6L, 1L, 2L, 3L), .Label = c("1", "2", "3", "4", "5", "6", 
"7", "8"), class = "factor"), TIME = structure(c(2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 
1L, 1L, 1L), .Label = c("1", "5", "15"), class = "factor"), VAL = c(0.937377670081332, 
0.522220720537007, 0.278690102742985, 0.967633064137772, 0.116124767344445, 
0.0544306698720902, 0.470229141646996, 0.62017166428268, 0.195459847105667, 
0.732876230962574, 0.996336271753535, 0.983087373664603, 0.666449476964772, 
0.291554537601769, 0.167933790013194, 0.860138458199799, 0.172361251665279, 
0.833266809117049, 0.620465772924945, 0.786503327777609, 0.761877260869369, 
0.425386636285111, 0.612077651312575, 0.178726130630821, 0.528709076810628, 
0.492527724476531, 0.472576208412647, 0.0702785139437765, 0.696220921119675, 
0.230852259788662, 0.359884874196723, 0.518227979075164, 0.259466265095398, 
0.149970305617899, 0.00682218233123422, 0.463400925742462, 0.924704828299582, 
0.229068386601284)), .Names = c("ID", "TYPE", "TIME", "VAL"), row.names = c(NA, 
-38L), class = "data.frame") 

Jeśli utworzyć następujące działki:ggplot2: Usuń nieużywane czynniki w aspektach bar działki, ale nie mają różnych szerokościach pasek między ściankami

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_wrap(~ TIME, ncol=1) + 
    geom_bar(position="stack") + 
    coord_flip() 

plot

I wtedy zdecydować miałbym idealnie jak aby nie pokazywać żadnych czynników w aspektach, w których nie mają żadnych danych. Mam odwoływać różne pytania i odpowiedzi, które twierdzą, że metoda scale="free" jest droga (w przeciwieństwie do drop=TRUE który spadnie pustych aspektów odpowiadających niewykorzystanych wartości w TIME), więc dalej:

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_wrap(~TIME, ncol=1, scale="free") + 
    geom_bar(position="stack") + 
    coord_flip() 

plot

Moje pytanie brzmi: jak zapobiegać przeskalowaniu prętów, które występują dla aspektu, który ma 4 bary w stosunku do aspektu z trzema paskami. Efekt jest subtelny w tym spreparowanym przykładzie, znacznie gorzej z moimi rzeczywistymi danymi. Idealny wynik miałby aspekt dolny z współczynnikami ID 1,4 i 6 na osi pionowej z prętami mającymi taką samą szerokość jak powierzchnia górna, a więc całkowity wymiar pionowy ścianki byłby zmniejszony.

punkty, jeśli możesz mi pomóc z dlaczego liczy są ułożone zamiast wartości liczbowych (Fixed teraz)

aktualizacja Bounty:

Jak wspomniano w moim obserwacji question wygląda lepszym rozwiązaniem może być użycie ggplot_build i ggplot_table i modyfikacja obiektu podlegającego łączeniu. Jestem pewien, że mógłbym to rozgryźć w danym momencie, ale mam nadzieję, że nagroda może zmotywować kogoś, kto mi pomoże. Koshke opublikował kilka przykładów: this.

+2

dla punktu bonusowego: Może małymi literami 'y' zamiast' Y' wraz z 'stat = "tożsamości"'? – joran

+0

Dzięki! Argument tożsamości nie był jednak potrzebny. –

+0

istnieje również argument 'space = 'free'' do' facet_wrap', który może być tym, czego szukasz. Było doskonałe pytanie dotyczące tego wcześniej, ale użytkownik go skasował ... – Justin

Odpowiedz

14

Jak o tym:

df$w <- 0.9 
df$w[df$TIME == 5] <- 0.9 * 3/4 
ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_wrap(~TIME, ncol=1, scale="free") + 
    geom_bar(position="stack",aes(width = w),stat = "identity") + 
    coord_flip() 

enter image description here

Nie wiem, czy mam tam arytmetyki, ale masz pomysł.

+0

Sprytny! Wizualnie to wygląda dobrze i podążam za tym, co zrobiłeś. Problemem, który widzę, jest to, że szerokość prętów jest regulowana ręcznie, aby zrekompensować różną ilość czynników między fasetkami. Jednak wydaje się to problematyczne, gdy różnica jest znacznie większa, np. Co by się stało, gdyby 7 aspektów w porównaniu z 2? W tym przypadku wyobrażam sobie, że dolny aspekt miałby dwa paski o właściwej szerokości, ale wiele białych znaków. To zależy od dopasowania ogólnego rozmiaru faceta, ale wydaje się to niemożliwe. –

+0

@ mindless.panda Tak, wygląda na to, że szukasz argumentu "przestrzeni", ale dla 'facet_wrap', którego nie uważam (jeszcze). – joran

+0

Dzięki - dzięki ręcznemu dostosowaniu to na razie się uda, miejmy nadzieję, że 'facet_wrap' dostaje' spację' oraz 'etykieciarkę'. Dla doskonałości prawdopodobnie generowałbym oddzielne wątki i wyrównywałbym je (za pośrednictwem siatki lub inkscape, zakładam, ponieważ nigdy tak naprawdę tego nie robiłem). –

10

Jeśli jesteś ok z pionowymi kreskami, facet_grid działa perfekcyjnie:

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_grid(.~TIME, scale="free_x", space = "free_x") + 
    geom_bar(position="stack") 

enter image description here

Aby przejść nieco dalej, można następnie obracać wszystkie elementy wykresu. Teraz masz co chcesz, jeśli obrócić głowę o 90 ° :-)

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    facet_grid(.~TIME, scale="free_x", space = "free_x") + 
    geom_bar(position="stack") + 
    opts(legend.text = theme_text(angle=90), 
     legend.title = theme_text(angle=90), 
     strip.text.x = theme_text(angle=90), 
     axis.text.x = theme_text(angle=90), 
     axis.text.y = theme_text(angle=90), 
     axis.title.x = theme_text(angle=90) 
     ) 

enter image description here

2

w ciągu pięciu lat od pierwotnego pytania, tak, że powinien on zapewnić bardziej aktualne i czystszego wersji robienia tego.To jest zasadniczo zgodny z zaleceniami zawartymi tutaj: http://ggplot2.tidyverse.org/reference/facet_grid.html

Dwa główne argumenty są space="free_y" który pozwala wysokość każdego panelu, aby być proporcjonalna do długości skali i scales="free_y" który pozwala łuski zmieniać dla każdej kolumny.

coord_flip() pozwala na plątanie plomb w poziomie i jako osobistą preferencję etykieta do aspektu jest obracana w ramach opcji theme.

ggplot(df, aes(x=ID, y=VAL, fill=TYPE)) + 
    geom_bar(stat="identity") + 
    coord_flip() + 
    facet_grid(TIME~., scales = "free_y", space = "free_y") + 
    theme(strip.text.y = element_text(angle = 0)) 

enter image description here

Powiązane problemy