Observable 사용하기
개요
Quarto는 Observable JS를 기본 지원합니다. Observable JS는 Mike Bostock(D3의 저자)가 만든 일반 JavaScript의 확장 기능 집합입니다. Observable JS는 반응형 런타임이 특징이며, 특히 인터랙티브 데이터 탐색과 분석에 적합합니다.
Observable JS 제작사(Observable, Inc.)는 https://observablehq.com/에서 노트북을 만들고 배포할 수 있는 호스팅 서비스를 제공합니다. 또한 Observable JS(“OJS”)는 코어 라이브러리를 통해 독립형 문서와 웹사이트에서도 사용할 수 있습니다. Quarto는 렌더링 시 실행되는 컴파일러와 함께 이 라이브러리를 사용해 Quarto 문서에서 OJS를 사용할 수 있게 합니다.
OJS는 모든 Quarto 문서(일반 마크다운, Jupyter, Knitr 문서)에서 동작합니다. {ojs} 실행 코드 블록에 코드를 넣기만 하면 됩니다. 이 문서는 Quarto에서 OJS를 사용하는 기본을 설명합니다.
예시
Allison Horst의 Palmer Penguins 데이터셋을 기반으로 간단한 예시를 살펴보겠습니다. 여기서는 펭귄의 체중이 성별과 종에 따라 어떻게 달라지는지 살펴봅니다(제공된 입력을 사용해 부리 길이와 섬으로 데이터셋을 필터링합니다).
이 예시의 소스 코드를 살펴봅시다. 먼저 FileAttachment를 사용해 CSV 파일(e.g., palmer-penguins.csv)을 읽는 {ojs} 셀을 만듭니다.
```{ojs}
data = FileAttachment("palmer-penguins.csv").csv({ typed: true })
```위 예시는 전체 데이터가 아니라 필터링된 부분만 그립니다. 필터를 만들기 위해 입력값이 필요하며, 이 입력값을 필터링 함수에서 사용해야 합니다. 이를 위해 viewof 키워드와 표준 Inputs를 사용합니다.
```{ojs}
viewof bill_length_min = Inputs.range(
[32, 50],
{value: 35, step: 1, label: "Bill length (min):"}
)
viewof islands = Inputs.checkbox(
["Torgersen", "Biscoe", "Dream"],
{ value: ["Torgersen", "Biscoe"],
label: "Islands:"
}
)
```이제 bill_length_min과 island 값으로 data를 변환하는 필터링 함수를 작성합니다.
```{ojs}
filtered = data.filter(function(penguin) {
return bill_length_min < penguin.bill_length_mm &&
islands.includes(penguin.island);
})
```여기서 반응형이 작동하는 것을 볼 수 있습니다. 동적 입력 값을 참조하기 위한 별도 문법이 필요 없으며, 입력이 바뀌면 필터링 코드가 자동으로 다시 실행됩니다. 이는 스프레드시트에서 셀을 변경하면 관련된 셀이 자동으로 재계산되는 것과 비슷합니다.
마지막으로 Observable Plot(탭ular 데이터를 빠르게 시각화하는 오픈소스 JavaScript 라이브러리)을 사용해 필터링된 데이터를 그립니다.
```{ojs}
Plot.rectY(filtered,
Plot.binX(
{y: "count"},
{x: "body_mass_g", fill: "species", thresholds: 20}
))
.plot({
facet: {
data: filtered,
x: "sex",
y: "species",
marginRight: 80
},
marks: [
Plot.frame(),
]
}
)
```입력과 마찬가지로 filtered 변수를 참조할 때 특별한 문법이 필요 없으며, filtered가 바뀔 때마다(입력이 바뀌면 업데이트됨) 플롯 코드가 자동으로 다시 실행됩니다.
이것이 OJS의 기본적인 end-to-end 사용법입니다(전체 소스 코드는 Penguins 예제를 참고하세요).
Penguins 코드를 보면 흥미로운 점이 있습니다. 입력과 플롯 코드가 데이터 처리 코드보다 먼저 정의되어 있습니다. 이는 OJS 셀 실행과 전통적인 노트북의 중요한 차이를 보여줍니다. OJS에서는 셀을 특정 순서로 정의할 필요가 없습니다.
실행이 완전히 반응형이므로, 런타임은 셀 간 참조 관계에 따라 올바른 순서로 자동 실행합니다. 이는 선형 셀 실행을 사용하는 전통적인 노트북보다 스프레드시트에 더 가깝습니다.
라이브러리
위 예시에서는 다음과 같은 표준 라이브러리를 사용했습니다.
Observable stdlib — DOM 조작, 파일 처리, 코드 임포트 등 핵심 기능.
Observable Inputs — 슬라이더, 드롭다운, 테이블, 체크박스 등 표준 입력 컨트롤.
Observable Plot — 탐색적 데이터 시각화를 위한 상위 수준 플로팅 라이브러리.
이 라이브러리들은 https://observablehq.com 노트북과 Quarto 문서의 {ojs} 셀에서 자동으로 사용할 수 있습니다.
다른 JavaScript 라이브러리를 사용하는 것도 간단합니다. 명시적으로 임포트하기만 하면 됩니다. 예를 들어 아래는 require 함수를 사용해 라이브러리를 임포트합니다(이는 jsDelivr에서 NPM 모듈을 로드합니다).
```{ojs}
d3 = require("d3@7")
topojson = require("topojson")
```표준 및 서드파티 라이브러리 사용법은 라이브러리 문서를 참고하세요.
데이터 소스
초기 예시에서는 FileAttachment를 데이터 소스로 사용했습니다. 파일 첨부는 CSV, TSV, JSON, Arrow(비압축), SQLite 등 다양한 포맷을 지원하므로, 이미 분석 준비가 된 데이터셋을 읽는 데 편리합니다.
종종 시각화에 앞서 Python이나 R에서 데이터를 전처리해야 합니다. Quarto에서는 문서 렌더링 중에 전처리를 수행하고, 결과를 OJS에서 사용할 수 있게 할 수 있습니다.
Python 또는 R에서 ojs_define() 함수를 사용해 JavaScript에서 사용할 변수를 정의하세요. 예를 들어 Python에서 간단한 CSV 읽기를 재현하려면 다음과 같이 작성할 수 있습니다.
```{python}
import pandas as pd
penguins = pd.read_csv("palmer-penguins.csv")
ojs_define(data = penguins)
```ojs_define(data = penguins) 호출은 penguins 데이터 프레임을 값으로 하는 data 변수를 OJS에서 사용할 수 있게 한다는 의미입니다.
시각화 라이브러리에 따라 JavaScript에서 데이터를 사용할 때 추가 단계가 필요할 수 있습니다. 이 경우 Plot 함수는 열이 아니라 행 기준 데이터를 기대하므로, 필터링 전에 transpose()를 사용합니다.
```{ojs}
filtered = transpose(data).filter(function(penguin) {
return bill_length_min < penguin.bill_length_mm &&
islands.includes(penguin.island);
})
```데이터를 준비하고 읽는 다양한 방법은 데이터 소스 문서를 참고하세요.
OJS 셀
{ojs} 코드 셀의 동작을 사용자 정의하는 옵션은 다양합니다. 코드 표시/숨김/접기, 출력의 가시성과 레이아웃 제어 등이 포함됩니다.
가장 중요한 셀 옵션은 소스 코드 표시 여부를 제어하는 echo입니다. 아티클에 시각화를 임베드하는지, 노트북이나 튜토리얼을 만드는지에 따라 선호가 달라질 수 있습니다.
{ojs} 셀의 코드는 기본적으로 표시됩니다. 문서 전체에서 코드 표시를 끄려면 YAML 메타데이터에 echo: false를 설정하세요.
---
title: "My Document"
execute:
echo: false
---셀별로도 지정할 수 있습니다. 예:
```{ojs}
//| echo: false
data = FileAttachment("palmer-penguins.csv").csv({ typed: true })
```사용 가능한 모든 옵션은 OJS 셀 문서를 참고하세요.
마크다운 흐름을 끊는 OJS 셀 외에도 인라인 코드를 포함할 수 있습니다. 인라인 코드에 대한 자세한 내용은 인라인 코드 문서를 참고하세요.
더 알아보기
다음 문서에서 Quarto 문서에서 OJS를 사용하는 방법을 더 깊이 다룹니다.
라이브러리: 표준 라이브러리 및 외부 JavaScript 라이브러리 사용법
데이터 소스: 데이터를 읽고 전처리하는 다양한 방법
OJS 셀: 셀 실행, 출력, 레이아웃에 대한 상세 설명
Shiny Reactives: OJS와 Shiny 통합 방법
코드 재사용: 여러 문서에서 OJS 코드를 재사용하는 방법
반응형의 내부 동작을 더 알고 싶다면, Mike Bostock의 다음 노트북을 확인하세요.