코딩하는 해맑은 거북이
[데이터시각화] Color 본문
본 게시물의 내용은 '부스트캠프 AI Tech - Data Visualization(안수빈)' 강의를 듣고 작성하였다.
해당 글은 아래의 4가지를 다룬다.
🍀 Color
🍀 Color Palette
🚩 Student Score Dataset
🟨 범주형 (Categorical)
🟨 연속형 (Sequential)
🟨 발산형 (Diverge)
🍀 강조, 색상 대비
🍀 색각 이상
- 위치와 색은 가장 효과적인 채널 구분
- 위치는 시각화 방법에 따라 결정되고, 색은 우리가 직접적으로 골라야 한다.
- 사람이 공통적으로 색이 가지는 느낌은 다르다.
- 심미적으로 화려한 것은 분명 매력적이다. 하지만, 화려함은 시각화의 일부 요소!
- 가장 중요한 것은 독자에게 원하는 인사이트를 전달!
→ 전하고 싶은 내용을 모두 전달했는가 + 그 과정에서 오해는 없었는가
- 우리는 살면서 이미 많은 색을 사용했다. 즉, 기존 정보와 느낌을 잘 활용하는 것이 중요
ex) 높은 온도에는 파랑, 낮은 온도에는 빨강이라면?
ex) 카X오가 초록색, 네X버가 노란색이라면?
- 무슨 색을 사용할지 모르겠다면, 다른 사례 스터디를 통해 색상 선택하거나 이미 사용하는 색을 사용할 것.
- HSI 색상
- Hue(색조) : 빨강, 파랑, 초록 등 색상으로 생각하는 부분
- 빨강에서 보라색까지 있는 스펙트럼에서 0-360으로 표현
- Saturate(채도) : 무채색과의 차이
- 선명도라고 볼 수 있음 (선명하다와 탁하다.)
- Lightness(광도) : 색상의 밝기
🚩 앞서 데이터셋 준비! Student Score Dataset
student = pd.read_csv('./StudentsPerformance.csv')
student.head()
- Discrete, Qualitative 등 다양한 이름으로 불림
- 독립된 색상으로 구성되어 범주형 변수에 사용
- 최대 10개의 색상까지 사용하고, 그 외에는 기타로 묶는다
- 색의 차이로 구분하는 것이 특징이다. 채도, 명도를 개별적 조정은 지양한다
- 일반적으로 tab10과 Set2가 가장 많이 사용된다
* Built-in Colormap 사용하기 : plt.cm.get_cmap(범주형컬러맵종류).colors
# Group to Number
groups = sorted(student['race/ethnicity'].unique())
gton = dict(zip(groups , range(5)))
# Group에 따라 색 1, 2, 3, 4, 5
student['color'] = student['race/ethnicity'].map(gton)
from matplotlib.colors import ListedColormap
qualitative_cm_list = ['Pastel1', 'Pastel2', 'Accent', 'Dark2', 'Set1', 'Set2', 'Set3', 'tab10']
fig, axes = plt.subplots(2, 4, figsize=(20, 8))
axes = axes.flatten()
student_sub = student.sample(100)
for idx, cm in enumerate(qualitative_cm_list):
pcm = axes[idx].scatter(student_sub['math score'], student_sub['reading score'],
c=student_sub['color'], cmap=ListedColormap(plt.cm.get_cmap(cm).colors[:5])
)
cbar = fig.colorbar(pcm, ax=axes[idx], ticks=range(5))
cbar.ax.set_yticklabels(groups)
axes[idx].set_title(cm)
plt.show()
- 정렬된 값을 가지는 순서형, 연속형 변수에 적합
- 연속적인 색상을 사용하여 값을 표현
→ 어두운 배경에서는 밝은 색이, 밝은 배경에서는 어두운 색이 큰 값을 표현
- 색상은 단일 색조로 표현하는 것이 좋고, 색의 밝기를 조정한다
- 균일한 색상 변화가 중요
- Heatmap, Contour Plot, 지리지도 데이터, 계층형 데이터에도 적합
sequential_cm_list = ['Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']
fig, axes = plt.subplots(3, 6, figsize=(25, 10))
axes = axes.flatten()
student_sub = student.sample(100)
for idx, cm in enumerate(sequential_cm_list):
pcm = axes[idx].scatter(student['math score'], student['reading score'],
c=student['reading score'],
cmap=cm,
vmin=0, vmax=100
)
fig.colorbar(pcm, ax=axes[idx])
axes[idx].set_title(cm)
plt.show()
* imshow
- colormap의 디폴트 값이 viridis로 설정
- viridis colormap은 최솟값이 보라, 최댓값이 노랑
- 우리가 입력한 숫자를 0~1 사이로 노멀라이즈하여 색으로 나타낸다
im = np.arange(100).reshape(10, 10)
fig, ax = plt.subplots(figsize=(10, 10))
ax.imshow(im)
plt.show()
이를 활용해서 github 잔디밭을 만들 수 있다.
im = np.random.randint(10, size=(7, 52))
fig, ax = plt.subplots(figsize=(20, 5))
ax.imshow(im, cmap='Greens')
ax.set_yticks(np.arange(7)+0.5, minor=True)
ax.set_xticks(np.arange(52)+0.5, minor=True)
ax.grid(which='minor', color="w", linestyle='-', linewidth=3)
plt.show()
- 연속형과 유사하지만 중앙을 기준으로 발산
- 상반된 값(ex. 기온)이나, 서로 다른 2개(ex. 지지율)을 표현하는 데 적합
- 양 끝으로 갈수록 색이 진해지며, 중앙의 색은 양쪽의 점에서 편향되지 않아야 함
- 중앙의 색은 꼭 무채색일 필요는 없음.
from matplotlib.colors import TwoSlopeNorm
diverging_cm_list = ['PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']
fig, axes = plt.subplots(3, 4, figsize=(20, 15))
axes = axes.flatten()
offset = TwoSlopeNorm(vmin=0, vcenter=student['reading score'].mean(), vmax=100)
# 평균값을 0.5로, 작아질수록 0, 클수록 1에 가깝게 바꾸는 것
student_sub = student.sample(100)
for idx, cm in enumerate(diverging_cm_list):
pcm = axes[idx].scatter(student['math score'], student['reading score'],
c=offset(student['math score']),
cmap=cm,
)
cbar = fig.colorbar(pcm, ax=axes[idx],
ticks=[0, 0.5, 1],
orientation='horizontal'
)
cbar.ax.set_xticklabels([0, student['math score'].mean(), 100])
axes[idx].set_title(cm)
plt.show()
- 데이터에서 다름을 보이기 위해 Highlighting 가능
- 강조를 위한 방법 중 하나. 색상 대비(Color Contrast) 사용
fig = plt.figure(figsize=(18, 15))
groups = student['race/ethnicity'].value_counts().sort_index()
ax_bar = fig.add_subplot(2, 1, 1)
ax_bar.bar(groups.index, groups, width=0.5)
ax_s1 = fig.add_subplot(2, 3, 4)
ax_s2 = fig.add_subplot(2, 3, 5)
ax_s3 = fig.add_subplot(2, 3, 6)
ax_s1.scatter(student['math score'], student['reading score'])
ax_s2.scatter(student['math score'], student['writing score'])
ax_s3.scatter(student['writing score'], student['reading score'])
for ax in [ax_s1, ax_s2, ax_s3]:
ax.set_xlim(-2, 105)
ax.set_ylim(-2, 105)
plt.show()
a_color, nota_color = 'black', 'lightgray'
# 그룹A는 black, 아니면 lightgray
colors = student['race/ethnicity'].apply(lambda x : a_color if x =='group A' else nota_color)
color_bars = [a_color] + [nota_color]*4
fig = plt.figure(figsize=(18, 15))
groups = student['race/ethnicity'].value_counts().sort_index()
ax_bar = fig.add_subplot(2, 1, 1)
ax_bar.bar(groups.index, groups, color=color_bars, width=0.5)
ax_s1 = fig.add_subplot(2, 3, 4)
ax_s2 = fig.add_subplot(2, 3, 5)
ax_s3 = fig.add_subplot(2, 3, 6)
ax_s1.scatter(student['math score'], student['reading score'], color=colors, alpha=0.5)
ax_s2.scatter(student['math score'], student['writing score'], color=colors, alpha=0.5)
ax_s3.scatter(student['writing score'], student['reading score'], color=colors, alpha=0.5)
for ax in [ax_s1, ax_s2, ax_s3]:
ax.set_xlim(-2, 105)
ax.set_ylim(-2, 105)
plt.show()
- 명도 대비 : 밝은 색과 어두운 색을 배치하면 밝은 색은 더 밝게, 어두운 색은 더 어둡게 보임 (회색검정)
- 위 코드에서 색상만 변경 : a_color, nota_color = 'black', 'lightgray'
- 색상 대비 : 가까운 색은 차이가 더 크게 보임 (파랑보라, 빨강보라)
- 위 코드에서 색상만 변경 : a_color, nota_color = 'purple', 'blue'
- 채도 대비 : 채도의 차이. 채도가 더 높아보임 (회색주황)
- 위 코드에서 색상만 변경 : a_color, nota_color = 'orange', 'lightgray'
- 보색 대비 : 정반대 색상을 사용하면 더 선명해 보인다. (빨강초록)
- 위 코드에서 색상만 변경 : a_color, nota_color = 'tomato', 'lightgreen'
- 삼원색 중에 특정 색을 감지 못하면 색맹
- 부분적 인지 이상이 있다면 색약
- 색 인지가 중요한 분야(과학/연구 등)에 있어서는 이에 대한 고려가 필수
'Data Analysis & Viz' 카테고리의 다른 글
[데이터시각화] Grid, 선/면 추가, 테두리 설정, Setting 변경 (0) | 2023.03.22 |
---|---|
[데이터시각화] Facet (0) | 2023.03.22 |
[데이터시각화] Text (0) | 2023.03.22 |
[데이터시각화] Scatter Plot (0) | 2023.03.22 |
[데이터시각화] Line Plot (0) | 2023.03.22 |