Jakiś czas temu pisałem o kubku, na którym nadrukowałem różne charakterystyki związane z Polską (więcej informacji tutaj). Dzisiaj napiszę o tym jak powstawał wykres przedstawiający wyniki w Mistrzostwach Europy w piłce siatkowej.
Będzie technicznie, będzie kod w R, będzie o szlifowaniu szczegółów, będzie ciekawie!
Dane
Dane odczytamy bezpośrednio z Wikipedii. Trzeba przyznać, że na wiele tematów, szczególnie związanych ze sportem, znaleźć można tam interesujące podsumowania.
Mamy więc dwie strony z Wikipedii, z wynikami w ME mężczyzn (link tutaj) i kobiet (link tutaj).
Dane wczytamy używając funkcji readHTMLTable(XML).
Wykres
Zacząłem od wersji wykresu poniżej. Chciałem pokazać i wyniki dla mężczyzn i dla kobiet, stąd pomysł by użyć trójkątów i kółek na oznaczenia płci. Aby wyróżnić wysokie pozycje zdecydowałem się na zwiększanie wielkości znaczka proporcjonalnie do miejsca w rankingu. Ponieważ trójkąty optycznie wyglądały na mniejsze niż kółka (dla tego samego parametru cex) to ręcznie skorygowałem wielkość dla trójkątów by wyglądały na obiekty o zbliżonym rozmiarze.
Ponieważ nie na każdych mistrzostwach był nasza reprezentacja (patrz rok 97) ważne było i narysowanie linii, ułatwiających śledzenie wyników dla określonej płci, i punktów, by wiedzieć w których latach mamy informacje o miejscu w rankingu.

Po jakimś czasie stwierdziłem, że szary jest nudny, trudno czasem rozpoznać czy miejsce jest trzecie czy czwarte, warto więc dodać kolory.
I linie pomocnicze.
Miejsca medalowe zostały więc oznaczone złotym, srebrnym i brązowym kolorem (choć niestety na kubku trochę skala barw się rozjechała, efekt podkładu).

Minęło kilka dni, pokazałem ten wykres wspomnianemu już wcześniej PCh, co skończyło się komentarzami n.t. miejsc gdzie płcie są kojarzone z trójkątami i kołami (nie wiem czy już pisałem jak ważne jest móc skonfrontować to co się robi z kimś bezpośrednim ;-)).
I jak się okazało słusznie. Bardziej naturalne jest użycie standardowych symboli płci. W kroju czcionki 'HersheySerif’ symbole \VE i \MA odpowiadają symbolom planet Wenus i Mars, aktualnie używanym jako symbole płci.
Wykres ścisnąłem bo na kubku nie było na niego dużo miejsca i powstała kolejna wersja.

Ta wersja miała jednak kilka istotnych wad.
Pozycje dalekie w rankingu były mało widoczne, trzeba było je powiększyć, koniec końców zdecydowałem, że wszystkie niemedalowe miejsca powinny być w tym samym rozmiarze.
Kolejny problem, to wyrównanie symboli. Domyślnie funkcja text() pozwala na określenie położenia przez punkt, będący środkiem symbolu w osi pionowej i poziomej (argument adj=). Ale wydaje się, że bardziej naturalne byłoby wyśrodkowanie względem środków okręgów będących składowymi tych symboli. To wymagało odrobiny zabawy, ponieważ w symbolu określającym płeć żeńską ten okrąg jest wyżej a w symbolu określającym płeć męską niżej i bardziej po lewej stronie, ale koniec końców się udało.
Kolejna sprawa, to że na kubku lepiej wyglądają większe plamy, a nie drobne linie, więc symbole obu płci wypadało wypełnić, by bardziej się rzucały w oczy. Udało się i to zrobić wrysowując w nie koła (a dokładniej punkty z pch=19), co ponownie wymagało pewnej zabawy ze względnym wyśrodkowaniem i punktów i symboli opisujących płcie.
Trochę gimnastyki i mamy wersję czwartą.

W ostatniej wersji zmieniłem już tylko wielkość napisów na etykietach, by pasowały do innych napisów na kubku. Ach, i mały lifting kolorów.

A tutaj jest kod w R, wczytujący dane i rysujący ostateczną wersję.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | # # wczytujemy dane o wynikach mezczyzn library(XML) tables <- readHTMLTable('http://pl.wikipedia.org/wiki/Mistrzostwa_Europy_w_pi%C5%82ce_siatkowej_m%C4%99%C5%BCczyzn',encoding='UTF-8') ranking <- tables[[2]] rokM <- as.numeric(as.character(ranking[,2])) miejsceM <- as.character(sapply(strsplit(as.character(ranking[,7]), split=". "), `[`, 1)) # # parsujemy napisy srebro / zloto / braz na liczbowy opis miejsca miejsceM[grep(miejsceM, pattern="Srebr")] = "2" miejsceM[grep(miejsceM, pattern="Br")] = "3" miejsceM[grep(miejsceM, pattern="Z")] = "1" miejsceM <- as.numeric(miejsceM) rokM <- as.numeric(as.character(ranking[,2]))[!is.na(miejsceM)] miejsceM <- miejsceM[!is.na(miejsceM)] # # wczytujemy dane o wynikach kobiet tables = readHTMLTable('http://pl.wikipedia.org/wiki/Mistrzostwa_Europy_w_pi%C5%82ce_siatkowej_kobiet',encoding='UTF-8') ranking <- tables[[2]] miejsceK <- as.numeric(as.character(sapply(strsplit(as.character(ranking[,7]), split=". "), `[`, 1))) rokK <- as.numeric(as.character(ranking[,2]))[!is.na(miejsceK)] miejsceK <- miejsceK[!is.na(miejsceK)] # # rysujemy wlasciwy rysunek par(cex.lab=0.5) plot(rokK, miejsceK, type="o", pch=19, las=1, ylim=c(10,1),ylab="", bty="n",yaxt="n",xaxt="n",cex=8.5/(miejsceK+1),lty=3,xlab="",col="white",xlim=c(1970,2011)) axis(3,seq(2011,1971,-2),las=1,col="white",col.ticks="black",cex.lab=0.5,line=1.5) axis(4,1:10,las=1,col="white",cex.lab=0.5) par(xpd=NA) kol <- rep("black",length(rokM)) kol[miejsceM == 1] = "gold3" kol[miejsceM == 2] = "grey80" kol[miejsceM == 3] = "brown4" lines(rokM[-1:-5], miejsceM[-1:-5], type="l", lty="36", lwd=2, col="grey") points(rokM, miejsceM, type="p", pch=19,col="white",cex=10/(miejsceM+1)) kolM = kol kol <- rep("black",length(rokK)) kol[miejsceK == 1] = "gold3" kol[miejsceK == 2] = "grey80" kol[miejsceK == 3] = "brown4" lines(rokK[-1:-7], miejsceK[-1:-7], type="l", lty="36", lwd=2, col="grey") points(rokK, miejsceK, type="p", pch=19,col="white",cex=10/(miejsceK+1)) cxK <- pmax(11/(miejsceK[-1:-7]+1),2) cxM <- pmax(12/(miejsceM[-1:-5]+1),2) text(rokK[-1:-7], miejsceK[-1:-7], "\\VE",family = "HersheySerif", cex = cxK,col=kol[-1:-7],adj=c(0.5,0.7)) points(rokK[-1:-7], miejsceK[-1:-7], pch=19, cex = cxK*.9, col=kol[-1:-7]) text(rokM[-1:-5], miejsceM[-1:-5], "\\MA",family = "HersheySerif", cex = cxM,col=kolM[-1:-5],adj=c(0.4,0.35)) points(rokM[-1:-5], miejsceM[-1:-5], pch=19, cex = cxM*.9,col=kolM[-1:-5]) |
Mam pytanie – czy możliwe jest wczytanie bardziej rozbudowanych tabel, np. z wikipedii do R?
(Przykładowo tabele z karierą sportową, jak http://en.wikipedia.org/wiki/Ryan_Giggs, posiadają zróżnicowaną ilość kolumn i wierszy wewnątrz).
D.
Tak, co najwyżej, jeżeli się źle wczyta” trzeba ją później ,,ręcznie” poprawić.
W tym przypadku zdecydowanie szybciej będzie skopiować same dane do MS Excel/OO Calc i usunąć formatowanie, niż bawić się w R. No chyba, że chcemy w ten sposób czegoś się nauczyć, to już inna kwestia. 🙂
Robienie tego ,,półautomatycznie” pozwoli na automatyzację i automatyczne uaktualniania statystyk.
Do jednorazowych analiz z pewnością szybciej będzie tabelę skopiować do jakiegoś office’a.
Przynajmniej do czasu gdy wikipedia będzie miało proste programistyczne API do danych tabelarycznych.