ggplot2::Position scales and axes
1. Limits
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
facet_wrap(vars(years))
이전에 공부한 내용에서 위의 코드로 displ과 hwy의 관계를 연도별로 Facet하여 볼 수 있었다.
하지만 우리에게 1999년 데이터가 불필요한 데이터라면?
library(dplyr)
mpg_99 <- mpg %>% filter(year == 1999)
mpg_08 <- mpg %>% filter(year == 2008)
base_99 <- ggplot(mpg_99, aes(displ, hwy)) +
geom_point()
base_08 <- ggplot(mpg_08, aes(displ, hwy)) +
geom_point()
base_99
filter()함수를 사용하기 위해 dplyr라이브러리를 불러주고
mpg에 파이프연산자와 filter로 year가 1999, 2008년인 것만 각각 mpg08,99에 객체화해보자.
원하는 연도만을 시각화할 수 있다. base_08을 부른다면 2008년도 산점도를 볼 수 있을 것이다.
다음은 base_99 object에 x축과 y축의 범위를 조정해보자.
base_99 +
scale_x_continuous(limits = c(1, 7)) +
scale_y_continuous(limits = c(10,45))
scale_x_continuous(), scale_x_continuous()함수는 각각 ggplot에서 x축과 y축의 스케일을 변경하기 위해 사용된다. x,y축의 범위를 변경하기 위해서는 limits 인자를 사용하면 된다.
여기서 주의해야할 점은 scale_x_continuous(limits) 인자를 사용하여 축의 범위를 변경할 경우 범위 밖에 데이터들을 NA취급한다는 것이다. 이것에 대한 내용은 이후에 다룰 것이다.
base_99 + lims(x =c(1,7), y=c(10,45))
base_08 + lims(x =c(1,7), y=c(10,45))
ggplot2에는 convenience function인 lims()가 있다.
lims()를 사용하면 scale_*_continuous(limits=c(a, b))를 사용하는 것보다 쉽게 축의 범위를 설정할 수 있다.
하지만 앞으로 공부하겠지만 scale_*_continuous()함수는 scale에 대한 다양한 option이 존재한다.
2. Zooming in / coord_cartesian()
scale에 limit을 주면 일부 데이터들은 limit으로 설정한 범위 밖에 존재하게 되며, ggplot2에서는 이놈들을 어떻게 처리할 것이냐에 대한 선택지를 제공한다. 한가지 방법은 벗어난 놈들을 NA(결측값)처리하는 것이다.
하지만 그래프의 일부분을 확대하기 위해 scale의 limit을 주는 경우도 있을 것이다. 이럴때는 coord_cartesian()함수를 사용하여 xlim, ylim을 컨트롤할 수 있다.
뭔 말인지 모르겠으면 직접 해보면서 느껴보자.
base <- ggplot(mpg, aes(drv, hwy)) +
geom_hline(yintercept = 28, colour = 'red') +
geom_boxplot()
base
drv f의 2사분위수에 수평선을 하나 그어놨다. scale에 Limit을 걸지 않았을 때 drv f의 2사분위 값은 28이다.
coord_cartesian()함수를 사용해서 scale을 limit해보자.
base + coord_cartesian(ylim = c(10, 35)) # works as expected
coord_cartesian()함수를 사용해 xlim, ylim을 변경하면 범위 밖에 데이터를 NA처리하지 않기 때문에 플롯의 2사분위수,중앙값 등이 바뀌지 않아 단순 zooming in이 가능하다.
반면에 기존에 공부했던 scale limit 방법들은?
base + ylim(10, 35) # distorts the boxplot
당연히 NA(결측치)로 처리하여 잘못된 해석의 여지가 된다.
3. Breaks
scale_*_continuous()에서 사용되는 또다른 옵션인 breaks다. 우린 앞서 limits 인자를 배웠다.
breaks를 인자를 사용하여 그래프의 축과 범례를 수정할 수 있다.
몬소린지 모르겠다면 실습을 하면서 이해해보자.
toy <- data.frame(
const = 1,
up = 1:4,
txt = letters[1:4],
big = (1:4)*1000,
log = c(2, 5, 10, 2000)
)
toy
일단 요런 dataframe을 하나 만들어줬다.
ggplot(toy, aes(big, const)) +
geom_point() +
labs(x = NULL, y = NULL)
labs()함수에 대해서는 이전에 한 번 공부한적 있는데 각 축에 위치하는 라벨링과 관련된 함수다. 나는 그래프에 x축과 y축이 각각 뭔지 알고싶지 않으므로 x,y에 NULL를 부여하겠다.
그럼 이렇게 x축 y축에 이름이 사라진다. 직접해보시오.. 그럼 이제 breaks 인자를 사용해보자.
base <- ggplot(toy, aes(big, const)) +
geom_point() +
labs(x = NULL, y = NULL) +
scale_y_continuous(breaks = NULL)
base
일단 차이를 느끼기 위해서 scale_y_continuous()로만 시행해보겠다.
y축의 눈금 범례가 사라졌다. 이제 몬말인지 알겠으면 끄덕이면 좋을 것 같다.
위와 같이 scale_*_continuous(breaks) 인자로 축,범례를 지울 수 있지만 다른 접근으로 커스튬할 수도 있다.
base + scale_x_continuous(breaks = c(1000, 2000, 4000))
요렇게 내가 원하는 값만 넣어서 표시할 수도 있다.
base + scale_x_continuous(breaks = c(1000, 1500, 2000, 4000))
몬말인지 알겠으면 끄떡여보자.
- scales::breaks_width
하지만 위에 사례처럼 하나하나 다 설정하기에 우리에겐 시간이 없다.
scales 패키지의 breaks_width()함수를 이용해보자.
base +
scale_x_continuous(breaks = scales::breaks_width(800))
요렇게하면 800을 단위로 x축을 생성한다. 하지만 위에 코드를 실행한 사람들은 알겠지만 첫 번째 데이터의 위치 800의 x축값이 보이지 않다는 것을 확인할 수 있다. 이것은 보는 이를 불편하게 할 수 있다. 이럴 때 사용할 수 있는 옵션이 offset이다.
base +
scale_x_continuous(breaks = scales::breaks_width(800, offset = 200))
아름답다고 할 수 있겠다.
- scale_*_log10()
이 함수는 교수님이 나중에 사용할 가능성이 높다고 하셔서 따로 적어놨다.
base <- ggplot(toy, aes(log, const)) +
geom_point() +
labs(x = NULL, y = NULL) +
scale_y_continuous(breaks = NULL)
base
위 코드같이 값들 차이가 갑자기 커지는 데이터를 시각화하는 경우 보기가 쉽지 않을 수 있다.
변수 log의 값들이 숫자 간 차이가 갑자기 커지는 구간이 존재하기 때문에 위의 시각화는 좋은 방법이 아니다.
base + scale_x_log10()
이렇게 피쳐의 scale을 변환하여 데이터를 파악하는 방법을 배워보았다.
4. Labels
이번엔 scale_*_continuous()함수의 labels 옵션을 공부해보자 이름 그대로 라벨링이다.
위에 배웠던 것을 복습하여 big, const 변수간 산점도 데이터를 객체화해보았다. labs()함수를 사용하여 x축,y축 제목을 지웠고, scale_y_continuous()함수를 사용해 y축 눈금을 지웠다.
base <- ggplot(toy, aes(big, const)) +
geom_point() +
labs(x = NULL, y = NULL) +
scale_y_continuous(breaks = NULL)
base
자.. 이제 라벨링을 해보자.
나는 x축에 2000과 4000만을 표시하고싶고 그 이름을 각각 2k와 4k로 커스튬 하고싶다.
base +
scale_x_continuous(
breaks = c(2000, 4000),
labels = c('2k', '4k')
)
짜잔. 하지만 역시나 라벨링 또한 매번 이렇게 만들어주기에는 시간이 없다. 이럴 때 사용하는 패키지가 scales패키지인 것 같다.
- scales::label_bytes()
- scales::label_comma()
- scales::label_dollar()
- scales::label_ordinal()
- scales::label_percent()
- scales::label_pvalue()
여러가지가 있지만 대표하여 percent()로 연습을 한 번 해보자.
base <- ggplot(toy, aes(big, const)) +
geom_point() +
labs(x = NULL, y = NULL) +
scale_x_continuous(breaks = NULL)
base + scale_y_continuous(labels = scales::label_percent())
base + scale_y_continuous(
labels = scales::label_dollar(prefix = "", suffix = "$")
)
접두사와 접미사에 각각 공백과 기호를 넣은 커스튬도 가능하다.
5. Transformations
앞에서 scale_x_log10() 함수를 이용하여 스케일 변환을 공부했었다.. 이 외 다양한 변환을 알아보자.
이번에 scale_*_continuous()함수에서 공부하는 마지막 인자인 trans도 사용하게 된다.
일단 실습 데이터를 만들어보자.
base <- ggplot(mpg, aes(displ, hwy)) + geom_point()
base
displ과 hwy의 관계를 보이는 산점도를 그려봤다.
base + scale_x_reverse()
scale_x_reverse()함수를 사용해 스케일을 반전시켜보았다. 결과를 보면 이해가 될 것이다.
정확히 y축을 기준으로 반전된 것을 확인할 수 있다.
base + scale_y_reverse()
같은 방법으로 x축을 기준으로 반전시킬 수도 있다.
이번엔 대망의 scale_*_continuous()의 trans인자에 대해서 공부해보자..
실습 데이터로는 mpg데이터로 hwy(연비)를 연료 소비량으로 변환해보자.
# convert from fuel economy to fuel consumption
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
scale_y_continuous(trans = "reciprocal")
위처럼 스케일을 역수로 변환해 역의 관계인 값을 시각화할 수도 있지만 큰 값의 영향을 적게하여 시각화하는 스케일 로그변환도 있을 수 있다.
# log transform x and y axes
ggplot(diamonds, aes(price, carat)) +
geom_bin2d() +
scale_x_continuous(trans = "log10") +
scale_y_continuous(trans = "log10")