ggplot2 Geoms 직접 만들기 입문

R-Blogger · 블로그·해설 · 2025-11-22

R-Blogger블로그·해설한국어2025-11-22

ggplot2 Geoms 직접 만들기 입문

An Introduction to Writing Your Own ggplot2 Geomsggplot2를 사용한다면 geom_line()과 geom_point()으로 플롯을 만드는 데 익숙하실 겁니다. ggridges의 geom_density_ridges()나 ggsignif의 geom_signif()와 같이 ggplot2 생태계의 다른 geom을 사용해 보셨을 수도 있습니다. 그런데 이런 확장 기능이 어떻게 만들어졌는지 궁금해 보신 적 있나요? 저자들은 새로운 geom을 만들기 위해 어디서 방법을 찾았을까요? 그리고 원하는 플롯이 존재하지 않을 때는 어떻게 직접 만들 수 있을까요? 바로 여러분만의 ggplot2 확장 기능을 만드는 흥미로운 세계가 시작됩니다.저는 Posit(당시 RStudio)에서 처음 일을 시작할 때 Gina Reynolds를 만났고, 그녀는 flipbookr에 관한 블로그 글을 기고하고 있었습니다. 그 이후로 우리는 ggextenders 확장 클럽을 통해 연락을 유지하고 있습니다. 클럽은 몇 달에 한 번 가상 모임을 열어 ggextender(ggplot2 확장 작업을 하는 사람)에게 발표 기회를 제공합니다. 발표자는 자신이 만든 커스텀 geom이나 보다 일반적인 R 시각화 주제에 대해 이야기합니다. 각 발표는 유익하고 흥미롭습니다. 저는 ggstats와 같은 멋진 패키지를 알게 되었습니다. 설문지를 작성해 주시면 언제든지 참여하실 수 있습니다! 저는 아직 ggextender가 된 적은 없었지만(그저 사용만 하고 개발은 하지 않았습니다), 확장 기능을 만드는 것이 막연하게 어려워 보였습니다. 최근에 Gina가 Easy geom 레시피라는 ggplot2 확장 튜토리얼 시리즈를 진행했을 때 그 생각이 바뀌었습니다. “레시피”를 따라가면 세 가지 확장을 차례대로 만들면서 핵심 지식 포인트를 체계적으로 익히고 새로운 변형을 도입할 수 있습니다.Step 0. ‘base’ ggplot2로 작업을 완성하기먼저 확장 구조에 들어가기 전에 해야 할 일을 명확히 합니다. tidyverse와 palmerpenguins패키지를 로드하고, x 변수(bill_length_mm)와 y 변수(bill_depth_mm)의 중앙값을 계산합니다. 그런 다음 기본 ggplot2를 사용해 플롯을 그립니다. 여기서는 geom_point()안의 aes()에 앞서 만든 bill_depth_mm_median과 bill_length_mm_median을 지정합니다.Step 1. Compute 정의 및 테스트플롯을 그리기 전에 입력 데이터를 “아래에서” 변환할 compute 함수를 정의합니다. 그 후 compute가 기대한 출력을 내는지 테스트합니다. 여기서는 x와 y이름이 반드시 필요합니다.Step 2. 새로운 Stat 정의 및 테스트ggplot2::ggproto()함수를 사용해 새로운 Stat 객체를 만듭니다. 직접 구현할 필요는 없으며, 제공되는 보일러플레이트 코드를 수정하면 됩니다. 만든 Stat를 geom_*()함수 안에서 사용해 테스트합니다.Step 3. 사용자용 함수 정의 및 테스트이제 사용자에게 노출될 함수를 정의합니다. 역시 보일러플레이트 코드를 상황에 맞게 수정하면 됩니다. stat_*()함수 이름은 Stat 객체 이름을 스네이크 케이스로 변환한 것이며, geom인자는 기본값으로 point가 지정됩니다. 따라서 사용자가 별도로 지정하지 않으면 ggplot2::geom_point()이 레이어에 적용됩니다. StatMedians는 새로운 레이어 함수를 정의하므로, 레이어가 렌더링되기 전에 중앙값 요약이 수행됩니다. ggplot2 v4.0.0부터 제공되는 make_constructor()를 이용하면 위 보일러플레이트 코드를 대부분 자동으로 생성할 수 있습니다. 사용자는 ‘geom’ 접두어가 붙은 레이어에 익숙하므로 make_constructor()를 이용해 거의 동일한 속성을 가진 geom함수도 정의할 수 있습니다. stat_medians와 geom_medians의 차이는 앞쪽은 stat이 고정되고, 뒤쪽은 geom이 고정된다는 점입니다.아래는 전체 과정을 보여주는 예시 코드입니다.library(tidyverse) library(palmerpenguins) # Compute penguins_medians penguins_medians <- summarize( bill_length_mm_median = median(bill_length_mm, na.rm = TRUE), bill_depth_mm_median = median(bill_depth_mm, na.rm = TRUE) ) # Plot with base ggplot2 penguins |> ggplot() + aes(x = bill_depth_mm, y = bill_length_mm) + geom_point() + geom_point( data = penguins_medians, aes(x = bill_depth_mm_median, y = bill_length_mm_median), size = 8, color = "red" ) + labs(title = "Created with base ggplot2")# Define compute compute_group_medians <- function(data) { summarize(data, x = median(x, na.rm = TRUE), y = median(y, na.rm = TRUE)) } # Test compute penguins |> select(x = bill_depth_mm, y = bill_length_mm) |> compute_group_medians() #> # A tibble: 1 × 2 #> x y #> <dbl> <dbl> #> 1 17.3 44.4# Define StatMedians and test StatMedians <- ggproto("StatMedians", Stat, compute_group = compute_group_medians, required_aes = c("x", "y") ) ggplot() + aes(x = bill_depth_mm, y = bill_length_mm) + geom_point() + geom_point(stat = StatMedians, size = 7) + labs(title = "Testing StatMedians")# Define geom_medians (using make_constructor if available) geom_medians <- make_constructor("geom_medians", StatMedians, default_geom = "point") ggplot() + aes(x = bill_depth_mm, y = bill_length_mm) + geom_point() + geom_medians(size = 8) + labs(title = "Testing geom_medians()")이렇게 하면 첫 번째 ggplot2 확장이 완성됩니다 🥳. 레시피를 따라가며 직접 구현해 보면 ggplot2 확장 제작이 생각보다 쉽다는 것을 체감하실 수 있습니다.
원문 URL
전체 글은 원문 페이지에서 이어서 읽을 수 있습니다.
원문에서 전체 글 읽기
작성자
R-Blogger
출처
R-Blogger
플랫폼
R-Blogger
분류
블로그·해설
언어
한국어
발행일
2025-11-22