티스토리 뷰
ggplot2 로 정규분포표, 확률밀도함수 그래프를 그려보기로 한다. 아래 그림은 인터넷 서핑해서 구해놓은 그래프인데, R - ggplot2 로 똑같이 구현할 예정이다. 그래프만 그리는 건 아니고, 화살표며 f(x) 같은 수식 등 다 넣어보려 한다.
분포함수, 확률밀도함수
하기전에 알아야 할 몇가지 함수가 있다. dnorm, pnorm, qnorm 을 알아야 한다. 위 그래프 기준으로 우선 참고해서 이해하면 쉽다.
# x축의 값을 입력하면, 확률밀도함수의 f(x) 의 값을 리턴.
dnorm(1) # [1] 0.2419707 --> y 값을 뜻함.
# x축의 값을 입력하면, x값이하의 f(x)의 적분값(확률밀도함수의 넓이)를 리턴
pnorm(1) # [1] 0.8413447 --> x <= 1 이하인 면적, 84.13%을 뜻함.
# f(x)의 적분값(확률밀도함수의 넓이)를 입력하면, x값를 역으로 리턴
qnorm(0.8413447) # [1] 0.9999998 --> 약 x = 1 이 리턴됨.
정규분포표 그래프를 그려보자
위 함수가 이해가 되었다면, 확률밀도함수를 그리고, 원하는 면적에 파란색으로 색칠까지만 우선 만든다.
library(tidyverse)
ggplot(tibble(x = c(-4,4)), aes(x)) +
geom_area(stat = "function", fun = dnorm, fill = 4,
alpha = 0.5, xlim = c(qnorm(0.93),-4)) +
geom_function(fun = dnorm, n = 1001) +
theme_minimal()
x축에도 눈금 하나만 남기고 다 지우고, expansion 이용해서 x 축과 y 축에 있던 공백을 조정한다. 그리고 x축에 너무 붙다보니 그림이 안맞아서, my_fun 을 정의해서 y 값을 + 0.02 했다.
# 너무 x축 하고 딱 붙어있다보니 임의로 0.02 y 값을 이동했다.
my_fun = function(i){
dnorm(i) + 0.02
}
ggplot(tibble(x = c(-4,4)), aes(x)) +
geom_area(stat = "function", fun = my_fun, fill = 4,
alpha = 0.5, xlim = c(qnorm(0.93),-4)) +
geom_function(fun = my_fun, n = 1001) +
scale_x_continuous(breaks = qnorm(0.93), labels = "x",
expand = expansion(0)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
theme_minimal()
1차로 만든것도 괜찮지만, 따라해보고자한 그래프에는 수식도 있고 화살표도 있다. 더 구현해본다. labs, theme 와 annotate 를 추가해서 그래프에 대한 디자인을 하고, 여백도 좀 주고 필요한 표식과 수식도 추가한다. (화살표, 수식 등)
ggplot(tibble(x = c(-4,4)), aes(x)) +
geom_area(stat = "function", fun = my_fun, fill = 4,
alpha = 0.5, xlim = c(qnorm(0.93),-4)) +
geom_function(fun = my_fun, n = 1001) +
scale_x_continuous(breaks = qnorm(0.93), labels = "x",
expand = expansion(0)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.05))) + # 0.05 가 디폴트임.
theme_minimal() +
labs(y = "", sec.y = "") +
theme(axis.text.y = element_blank(),
axis.text.x = element_text(size = 15),
axis.title.x = element_blank(),
axis.title.y.left = element_text(margin = margin(0, .3, 0, 0, "cm")),
axis.title.y.right = element_text(margin = margin(0, .3, 0, 0, "cm")),
panel.grid = element_blank(),
axis.ticks.x = element_line(),
axis.ticks.length.x = unit(3, "mm"),
axis.line.x = element_line()) +
annotate(geom = "curve", x = 2, y = 0.3, xend = 0, yend = 0.25,
curvature = .3, arrow = arrow(length = unit(3, "mm"))) +
annotate(geom = "text", x = 2.4, y = 0.3, label = "F(x)", size = 5) +
annotate(geom = "text", x = -3.6, y = 0.29, label = "확률 밀도 함수",
hjust = "left", family = "Apple SD Gothic Neo", size = 4.3) +
annotate("segment", x = -2, xend = -0.9,
y = 0.29, yend = 0.29, size = 0.6,
arrow = arrow(angle = 30, length = unit(0.3,"cm"))) +
annotate("segment", x = qnorm(0.93), xend = qnorm(0.93),
y = my_fun(qnorm(0.93)), yend = 0, size = 0.6,
arrow = arrow(angle = 20, ends = "both", length = unit(0.3,"cm"), type = "closed")) +
annotate(geom = "curve", x = 3, y = 0.17, xend = qnorm(0.93), yend = 0.07,
curvature = -0.3, arrow = arrow(length = unit(3, "mm"))) +
annotate(geom = "text", x = 3, y = 0.2, label = "f(x)", size = 4.5)
거의 똑같이 구현했다. 사실 ggplot 으로 더 디자인이 잘나온듯 하다. 여백주고, x 축만남기고, 한글을 표현하는 폰트를 지정하는 등 생각보다 시행착오를 많이 겪었고 오랜시간이 걸렸다. 그래도 ggplot 으로 계속 구현하다보니, 데이터를 시각화하고 디자인하는데 전혀 부족함이 없다. 그래프에 대한 대부분의 옵션을 제공하고 있는 듯하고, 몰라서 못쓰는 기능이 많다보니 더 찾아서 연습이 필요할 듯 하다.
- Total
- Today
- Yesterday
- java
- MySQL
- SVN
- vagrant
- Spring
- javascript
- 마인크래프트
- Google Chart Tools
- github
- 셀프개통
- eclipse
- 자급제폰
- 맥북
- python
- 이클립스
- heroku
- ggplot
- ipTIME
- 아이맥
- ubuntu
- 알뜰요금제
- MongoDB
- 도넛차트
- Oracle
- ggplot2
- docker
- MyBatis
- R
- 막대그래프
- ktm모바일
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |