준호가 노트북을 열었습니다.
"나는 국가별 GDP와 기대수명 관계를 분석하는 거야. 데이터 변수가 세 개야. GDP, 기대수명, 인구."
지윤이 바로 답했습니다.
"산점도. 인구는 점 크기로 표현하면 돼. 버블 차트야."
px.scatter() 기본
px.scatter()는 x축과 y축에 수치형 변수를 놓아 두 변수 간의 관계를 나타냅니다.
# 파일: scatter_basic.pyimport plotly.express as pxdf = px.data.gapminder().query("year == 2007")fig = px.scatter( df, x="gdpPercap", y="lifeExp", title="2007년 국가별 GDP vs 기대수명", labels={"gdpPercap": "1인당 GDP (USD)", "lifeExp": "기대수명 (세)"})fig.show()
각 점이 하나의 국가를 나타냅니다. GDP가 높을수록 기대수명이 높은 경향이 보입니다.
color로 범주 구분
color 파라미터에 범주형 컬럼을 지정하면 대륙별로 색상이 구분됩니다.
# 파일: scatter_color.pyimport plotly.express as pxdf = px.data.gapminder().query("year == 2007")fig = px.scatter( df, x="gdpPercap", y="lifeExp", color="continent", title="2007년 국가별 GDP vs 기대수명", labels={ "gdpPercap": "1인당 GDP (USD)", "lifeExp": "기대수명 (세)", "continent": "대륙" })fig.show()
범례에서 대륙 이름을 클릭하면 해당 대륙의 점들이 토글됩니다.
size로 버블 차트
size 파라미터에 수치형 컬럼을 지정하면 값에 비례하는 크기의 버블이 만들어집니다.
# 파일: scatter_bubble.pyimport plotly.express as pxdf = px.data.gapminder().query("year == 2007")fig = px.scatter( df, x="gdpPercap", y="lifeExp", color="continent", size="pop", size_max=60, title="2007년 국가별 GDP vs 기대수명 (버블 크기: 인구)", labels={ "gdpPercap": "1인당 GDP (USD)", "lifeExp": "기대수명 (세)", "continent": "대륙", "pop": "인구" })fig.show()
size_max는 가장 큰 버블의 최대 픽셀 크기를 지정합니다. 기본값은 20이고, 데이터 범위에 따라 조정합니다.
hover_name으로 호버에 이름 표시
버블 위에 마우스를 올리면 기본적으로 x, y, size 값이 표시됩니다. hover_name에 컬럼을 지정하면 팝업 상단에 해당 값이 굵게 표시됩니다.
# 파일: scatter_hover.pyimport plotly.express as pxdf = px.data.gapminder().query("year == 2007")fig = px.scatter( df, x="gdpPercap", y="lifeExp", color="continent", size="pop", size_max=60, hover_name="country", title="2007년 국가별 GDP vs 기대수명", labels={ "gdpPercap": "1인당 GDP (USD)", "lifeExp": "기대수명 (세)", "continent": "대륙" })fig.show()
이제 버블에 마우스를 올리면 팝업 상단에 국가 이름이 표시됩니다.
trendline으로 추세선 추가
trendline="ols"를 추가하면 OLS(최소제곱법) 회귀선이 각 그룹마다 자동으로 그려집니다. 이 기능을 사용하려면 statsmodels 패키지가 설치되어 있어야 합니다. 설치하지 않았다면 먼저 실행합니다.
pip install statsmodels
# 파일: scatter_trend.pyimport plotly.express as pxdf = px.data.gapminder().query("year == 2007")fig = px.scatter( df, x="gdpPercap", y="lifeExp", color="continent", hover_name="country", trendline="ols", title="2007년 국가별 GDP vs 기대수명 (추세선 포함)", labels={ "gdpPercap": "1인당 GDP (USD)", "lifeExp": "기대수명 (세)", "continent": "대륙" })fig.show()
추세선 위에 마우스를 올리면 R² 값과 회귀식이 표시됩니다.
trendline에 사용할 수 있는 값은 다음과 같습니다.
| 값 | 설명 |
|---|---|
"ols" |
OLS 선형 회귀 |
"lowess" |
비모수 로컬 평활 |
"rolling" |
이동 평균 |
"expanding" |
누적 평균 |
"ewm" |
지수 가중 이동 평균 |
trendline="ols"를 사용하려면 statsmodels 패키지가 설치되어 있어야 합니다.
pip install statsmodels
실전: 준호의 GDP-기대수명 버블 차트
준호가 최종 요청을 했습니다. 아시아 국가를 특별히 강조하고, 로그 스케일로 x축을 표시하고 싶다고 했습니다.
# 파일: gapminder_final.pyimport plotly.express as pxdf = px.data.gapminder().query("year == 2007")fig = px.scatter( df, x="gdpPercap", y="lifeExp", color="continent", size="pop", size_max=55, hover_name="country", log_x=True, # x축 로그 스케일 title="2007년 국가별 GDP vs 기대수명", labels={ "gdpPercap": "1인당 GDP (USD, 로그 스케일)", "lifeExp": "기대수명 (세)", "continent": "대륙", "pop": "인구" })fig.update_layout( xaxis_title="1인당 GDP (USD, 로그 스케일)", yaxis_title="기대수명 (세)")fig.show()
log_x=True를 추가하면 x축이 로그 스케일로 바뀌어 GDP 범위가 넓은 데이터를 고르게 표현합니다. log_y=True도 동일하게 사용할 수 있습니다.
준호가 화면을 보며 말했습니다.
"아프리카 국가들이 왼쪽 아래에 몰려 있네. GDP도 낮고 기대수명도 낮아."
"그게 바로 데이터가 말하는 이야기야." 지윤이 답했습니다.
px.scatter() 주요 파라미터 정리
| 파라미터 | 설명 | 예시 |
|---|---|---|
x, y |
축 컬럼 | x="gdpPercap" |
color |
범주별 색상 | color="continent" |
size |
버블 크기 컬럼 | size="pop" |
size_max |
버블 최대 크기 | size_max=60 |
hover_name |
호버 팝업 제목 컬럼 | hover_name="country" |
trendline |
추세선 종류 | trendline="ols" |
log_x |
x축 로그 스케일 | log_x=True |
log_y |
y축 로그 스케일 | log_y=True |