Temat: R - przycinanie opisów osi X,Y
Damian B.:
Witam,
bardzo proszę o pomoc - przy budowie zwykłego wykresu barplot:
Postaramy się coś zaradzić.
Najpierw wygenerujemy sobie jakieś przykładowe dane:
dane <- data.frame(Kliki=10000000*runif(10), Kategoria=paste("Bardzo długa nazwa kategorii", 1:10), stringsAsFactors=FALSE)
Wykonanie na tych danych barplota skutkuje dokładnie tym, co napisałeś. Notacja inżynierska, za długie etykiety kategorii.
Najpierw zajmiemy się liczbami na osi OY. W tym celu narysujemy wykres bez osi OY, a następnie sami dobierzemy odpowiednie jej parametry, w tym - etykiety. Nie wiem, jakie etykiety preferujesz, czy np. "1 000 000" czy może np. "1 mln" albo "1000 tys.". To już sobie dobierzesz. Etykiety są co milion, ale możesz sobie dowolnie ustawić sekwencję "od-do-krok".
# zwiększymy nieco lewy (5.6) i dolny (7.1) margines, żeby wszystko się zmieściło (dolny przyda się na później)
par(mar=c(7, 5.5, 4, 2) + 0.1)
# wykres na początku ma nie mieć osi 0Y
barplot(dane$Kliki, cex.names=0.8, main="Liczba klików", names.arg=dane$Kategoria, las=2, ylim=c(0, maxY), yaxt="n")
# Teraz wyliczymy wszystkie potrzebne wartości do narysowania osi OY i narysujemy ją
mult <- 1000000 # liczymy w milionach
maxVal <- max(dane$Kliki)
maxY <- ((maxVal %/% mult)+1) * mult
seqY <- seq(0, maxY, by=mult)
# etykiety dla naszej nowej osi 0Y
# labsY <- paste0(seqY/mult, " mln.") # <-- spróbuj też tego sposobu
labsY <- format(seqY, scientific=FALSE, big.mark=" ")
axis(2, at=seqY, labels=labsY, las=2)
Efekt jest już lepszy, ale nadal problemem pozostają zbyt długie nazwy kategorii. Obracanie ich, zmniejszanie czcionki to tylko częściowy sposób. Dobrze byłoby podzielić napis na 2 linie, najlepiej w połowie, ale też dobrze by było, aby podział wypadał na spacji (jeśli są).
dane$nowaKategoria <- sapply(dane$Kategoria, FUN=function(x) {
halfLen <- round(nchar(x)/2)
diff <- halfLen - gregexpr(pattern=" ", x)[[1]]
minDiff <- diff[abs(diff) == min(abs(diff))]
splitPos <- halfLen - minDiff[1]
splitPos <- ifelse(splitPos <= 0, halfLen, splitPos) # gdyby nie było spacji
paste0(substring(x, 1, splitPos), "\n", substring(x, splitPos+1, 2*halfLen))
})
Jeśli wszystko Ci jedno, gdzie będzie podział, uprość kod do paste0(substring(x, 1, halfLen), "\n", substring(x, halfLen+1, 2*halfLen))
Teraz wyświetl nowe dane:
barplot(dane$Kliki, cex.names=0.8, main="Liczba klików", names.arg=dane$nowaKategoria, las=2, ylim=c(0, maxY), yaxt="n")
axis(2, at=seqY, labels=labsY, las=2)
Powinieneś otrzymać podobny efekt:
Albo np. taki: (dodałem grid i box, zmniejszyłem odrobinę lewy margines i poszerzyłem wykres)
Sugerowałbym umieścić powyższy kod w funkcji, np. MyBarPlot <- function(dane) { .... }
PS: co do komendy, to owszem, jest - par(mar=...) - służy do ustawiania marginesów.
Ten post został edytowany przez Autora dnia 18.11.14 o godzinie 21:34