iBetter Books
수정

분포 분석이 끝나가는 무렵, 준호가 마지막 데이터를 꺼냈습니다.

"교수님이 과목 간 상관관계도 분석해서 넣으라고 했어. 수강한 다섯 과목의 성적 데이터야."

"그건 히트맵이야. 상관관계 행렬을 색으로 표현하는 거."

지윤이 설명했습니다. 숫자로 가득한 행렬보다 색으로 표현하면 강한 양의 상관과 강한 음의 상관이 한눈에 들어왔습니다.


상관관계 행렬 계산

먼저 pandas의 .corr()으로 상관관계 행렬을 만듭니다.

# 파일: heatmap_corr.pyimport plotly.express as pximport numpy as npimport pandas as pdnp.random.seed(7)n = 100df_scores = pd.DataFrame({    "통계학": np.random.normal(72, 10, n),    "확률론": np.random.normal(70, 11, n),    "선형대수": np.random.normal(68, 12, n),    "프로그래밍": np.random.normal(75, 9, n),    "데이터분석": np.random.normal(73, 10, n)})# 통계학-확률론 상관 높게, 프로그래밍-통계학 낮게 설정df_scores["확률론"] = df_scores["통계학"] * 0.7 + np.random.normal(0, 8, n)df_scores["데이터분석"] = (df_scores["통계학"] + df_scores["프로그래밍"]) * 0.5 + np.random.normal(0, 7, n)corr = df_scores.corr()print(corr.round(2))
           통계학  확률론  선형대수  프로그래밍  데이터분석
통계학      1.00   0.83   0.05    0.02    0.64
확률론      0.83   1.00   0.02   -0.04    0.47
선형대수    0.05   0.02   1.00    0.07    0.10
프로그래밍  0.02  -0.04   0.07    1.00    0.57
데이터분석  0.64   0.47   0.10    0.57    1.00

px.imshow()로 히트맵

px.imshow()는 2차원 배열이나 데이터프레임을 색으로 표현합니다. 상관관계 행렬을 그대로 넘기면 됩니다.

# 파일: heatmap_basic.pyimport plotly.express as pximport numpy as npimport pandas as pdnp.random.seed(7)n = 100df_scores = pd.DataFrame({    "통계학": np.random.normal(72, 10, n),    "확률론": np.random.normal(70, 11, n),    "선형대수": np.random.normal(68, 12, n),    "프로그래밍": np.random.normal(75, 9, n),    "데이터분석": np.random.normal(73, 10, n)})df_scores["확률론"] = df_scores["통계학"] * 0.7 + np.random.normal(0, 8, n)df_scores["데이터분석"] = (df_scores["통계학"] + df_scores["프로그래밍"]) * 0.5 + np.random.normal(0, 7, n)corr = df_scores.corr()fig = px.imshow(    corr,    title="과목 간 상관관계 히트맵",    color_continuous_scale="RdBu_r",    zmin=-1,    zmax=1)fig.show()

실행 결과

색이 진한 빨간색일수록 강한 양의 상관(1에 가까움), 진한 파란색일수록 강한 음의 상관(-1에 가까움)입니다. 흰색에 가까울수록 상관이 없습니다.


text_auto로 값 표시

히트맵 각 칸에 수치를 표시하면 정확한 값을 바로 읽을 수 있습니다.

# 파일: heatmap_text.pyimport plotly.express as pximport numpy as npimport pandas as pdnp.random.seed(7)n = 100df_scores = pd.DataFrame({    "통계학": np.random.normal(72, 10, n),    "확률론": np.random.normal(70, 11, n),    "선형대수": np.random.normal(68, 12, n),    "프로그래밍": np.random.normal(75, 9, n),    "데이터분석": np.random.normal(73, 10, n)})df_scores["확률론"] = df_scores["통계학"] * 0.7 + np.random.normal(0, 8, n)df_scores["데이터분석"] = (df_scores["통계학"] + df_scores["프로그래밍"]) * 0.5 + np.random.normal(0, 7, n)corr = df_scores.corr()fig = px.imshow(    corr,    title="과목 간 상관관계 히트맵",    color_continuous_scale="RdBu_r",    zmin=-1,    zmax=1,    text_auto=".2f"  # 소수점 2자리로 값 표시)fig.show()

실행 결과

text_auto=True로 기본 형식, text_auto=".2f"로 소수점 자릿수를 지정할 수 있습니다.


color_continuous_scale 선택

color_continuous_scale로 색상 팔레트를 지정합니다. 상관관계처럼 음수와 양수가 모두 있는 데이터는 발산형(diverging) 팔레트가 적합합니다.

팔레트 이름 특징
"RdBu_r" 빨강-흰색-파랑 (발산형, 반전)
"RdBu" 파랑-흰색-빨강 (발산형)
"Viridis" 보라-노랑 (순차형)
"Blues" 흰색-진한 파랑 (순차형)
"Hot" 검정-빨강-노랑 (순차형)

발산형 팔레트를 쓸 때는 zmin=-1, zmax=1처럼 중심값 기준으로 범위를 고정해야 흰색이 0(무상관)에 정확히 대응합니다.


실전: 과목 간 상관관계 최종

# 파일: subject_heatmap_final.pyimport plotly.express as pximport numpy as npimport pandas as pdnp.random.seed(7)n = 100df_scores = pd.DataFrame({    "통계학": np.random.normal(72, 10, n),    "확률론": np.random.normal(70, 11, n),    "선형대수": np.random.normal(68, 12, n),    "프로그래밍": np.random.normal(75, 9, n),    "데이터분석": np.random.normal(73, 10, n)})df_scores["확률론"] = df_scores["통계학"] * 0.7 + np.random.normal(0, 8, n)df_scores["데이터분석"] = (df_scores["통계학"] + df_scores["프로그래밍"]) * 0.5 + np.random.normal(0, 7, n)corr = df_scores.corr().round(2)fig = px.imshow(    corr,    title="과목 간 성적 상관관계",    color_continuous_scale="RdBu_r",    zmin=-1,    zmax=1,    text_auto=".2f",    aspect="auto")fig.update_layout(    coloraxis_colorbar=dict(        title="상관계수",        tickvals=[-1, -0.5, 0, 0.5, 1],        ticktext=["-1.0", "-0.5", "0.0", "0.5", "1.0"]    ))fig.show()

실행 결과

준호가 히트맵을 보며 말했습니다.

"통계학이랑 확률론이 진한 빨간색이네. 당연하지. 내용이 겹치니까."

"데이터분석이 통계학, 프로그래밍 둘 다 관련 있는 것도 나오네."

지윤이 고개를 끄덕였습니다. 숫자 행렬로는 한참을 들여다봐야 알 수 있는 것을 색 하나로 바로 보여줄 수 있었습니다.


px.imshow() 주요 파라미터 정리

파라미터 설명 예시
color_continuous_scale 색상 팔레트 "RdBu_r"
zmin, zmax 색상 범위 zmin=-1, zmax=1
text_auto 칸에 값 표시 ".2f"
aspect 칸 가로세로 비율 "auto" or "equal"