데이터 스토리텔링을 위한 색상: 기본 차트 색상을 넘어서
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://colorfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://colorfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://colorfyi.com/entity//)
Use the native HTML custom element.
차트 라이브러리의 기본 색상 팔레트는 시각적 차별성이라는 한 가지 목적으로 설계되었습니다. 한 눈에 쉽게 구분할 수 있도록 인접한 데이터 계열 색상을 제공합니다. 이는 유용한 출발점입니다. 이는 또한 이러한 기본값에 기반한 디자인 사고의 종말이기도 합니다.
기본 팔레트는 데이터 유형, 청중, 전달하는 스토리, 주제에 적합한 감정 기록, 빨간색과 녹색을 구별할 수 없는 사용자의 경험을 고려하지 않습니다. 기본값을 의도적인 색상 선택으로 바꾸는 것은 데이터 시각화를 만드는 모든 사람이 사용할 수 있는 가장 활용도 높은 개선 사항 중 하나입니다.
이 가이드에서는 데이터 시각화를 위한 세 가지 기본 팔레트 유형, 각 유형에 액세스할 수 있게 만드는 방법, D3.js 및 Chart.js에서 사용자 정의 색상 스케일을 구성하는 방법을 다룹니다.
기본 차트 색상이 실패하는 이유
그들은 범주형 데이터를 가정합니다.
대부분의 차트 라이브러리 기본값은 "제품 A, 제품 B, 제품 C"와 같이 개별적이고 순서가 지정되지 않은 그룹인 범주형 데이터용으로 설계되었습니다. 각 카테고리에 시각적으로 구별되는 색상을 제공합니다. 데이터가 실제로 순차적(추위에서 더위까지)이거나 발산(투표 여백이 강한 민주당에서 강한 공화당으로)되는 경우 범주형 팔레트는 오해의 소지가 있습니다. 이는 실제로 의미 있는 순서나 의미 있는 중심점이 있을 때 모든 값이 서로 동등하게 다르다는 것을 의미합니다.
그들은 거짓 동등성을 창조합니다
모든 데이터 계열이 굵고 채도가 높은 색상으로 표시되면 모든 계열이 시각적으로 동일한 중요성을 주장하는 것입니다. 그러나 대부분의 데이터 스토리에는 계층 구조가 있습니다. 차트의 한 줄이 스토리입니다. 다른 것들은 맥락이다. 색상 가중치를 동일하게 처리하면 독자가 색상에 주의를 기울이는 대신 데이터 자체를 분석하게 됩니다.
색각 장애 테스트를 거치지 않았습니다.
적록색맹(청색맹과 흑색맹을 합쳐서 남성의 약 8%에 영향을 미침)은 기본 팔레트의 고전적인 빨간색/녹색 조합을 구분할 수 없게 만듭니다. D3의 "Category10" 팔레트에는 #E15759(음소거된 빨간색)과 #76B7B2(음소거된 청록색)이 모두 포함되어 있어 대부분의 색맹 시청자가 구별할 수 있습니다. 그러나 유사한 "Tableau10"에는 중수소동물과 거의 동일한 빨간색과 녹색이 포함되어 있습니다. 이러한 차이점은 중요하며 기본값으로 인해 차이점이 명확해지지는 않습니다.
순차 색상 스케일
순차 팔레트는 낮은 범위에서 높은 범위의 정량적 데이터를 인코딩합니다. 단일 색상 또는 제어된 다중 색상 진행에 걸쳐 밝기(때로는 채도)를 변경하여 작동합니다. 관례는 다음과 같습니다. 밝은 = 낮은 값, 어두운 = 높은 값(밝은 배경에서). 어두운 배경에서는 이를 반대로 바꿔보세요. 어두운 = 낮음, 밝은 = 높음.
단일 색조 순차
가장 간단한 순차 팔레트는 밝기 범위 전체에 걸쳐 하나의 색상을 사용합니다.
Light to dark blue:
#EFF6FF → #DBEAFE → #BFDBFE → #93C5FD → #3B82F6 → #1D4ED8 → #1E3A8A
#EFF6FF부터 #1E3A8A까지 연속 수량으로 읽습니다. 인구 밀도에 대해 이러한 색상을 사용하는 등치 지도는 방향을 즉시 전달합니다. 즉, 어두운 영역이 더 밀도가 높습니다.
단일 색상 팔레트는 보는 사람의 디코딩 작업을 단일 차원(밝기)으로 줄여주기 때문에 지각적으로 간단합니다. 단점은 인접한 값을 세밀하게 구분하려면 세심한 검사가 필요하다는 것입니다.
다중 색조 순차
다중 색상 순차 팔레트는 색상과 밝기를 모두 다양하게 만들어 직관성을 희생하면서 지각 해상도를 높입니다. 전형적인 예는 노란색-녹색-파란색입니다.
#FFFFE0 → #C7E9B4 → #7FCDBB → #41B6C4 → #1D91C0 → #225EA8 → #0C2C84
연한 노란색 #FFFFE0부터 포화 파란색 #0C2C84까지 이 팔레트를 사용하면 뷰어는 순서대로 읽는 동안 단일 색상 버전보다 더 많은 그라데이션을 구별할 수 있습니다. ColorBrewer의 YlGnBu는 이 스타일에 대한 표준 참조 팔레트입니다.
다중 색조 순차는 연속 범위에 걸쳐 미세한 구별이 필요하고 색상 범례를 포함할 공간이 있는 등치 및 히트맵에서 특히 유용합니다.
순차 팔레트의 지각적 균일성
순차적 팔레트의 중요한 요구 사항은 지각적 균일성입니다. 즉, 각 시각적 단계는 수량의 동일한 변화처럼 느껴져야 합니다. RGB의 녹색 채널에 불균형적인 지각 가중치가 있기 때문에 RGB 보간은 이 테스트에 실패합니다. #0000FF에서 #FF0000까지 RGB로 보간된 팔레트는 중간점 값을 정확하게 표현하지 못하는 불편할 정도로 선명한 녹색 중간점을 통과합니다.
대신 OKLCH 또는 CIELAB에서 순차 팔레트를 보간하세요.
// D3.js — interpolate in OKLCH for perceptual uniformity
import { scaleSequential, interpolateOklch } from 'd3';
const colorScale = scaleSequential()
.domain([minValue, maxValue])
.interpolator(d3.interpolateOklch("#EFF6FF", "#1E3A8A"));
다양한 색상 스케일
다양한 팔레트는 의미 있는 중간점(0, 목표 값, 기준선, 평균)이 있는 데이터를 인코딩합니다. 중립 중심에서 갈라지는 두 가지 색상을 사용하여 중간점 위와 아래의 값을 방향이 다른 것으로 즉시 인식할 수 있도록 합니다.
분기 팔레트를 사용해야 하는 경우
중간점이 스토리에 의미가 있을 때 다양한 팔레트를 사용하세요.
- 투표 마진: 공화당 성향의 경우 빨간색, 민주당 성향의 경우 파란색, 거의 균등한 경우 흰색 또는 밝은 회색
- 온도 이상: 평균 이하인 경우 파란색, 평균 이상인 경우 빨간색, 평균에 가까운 경우 흰색에 가까움
- 이익/손실: 빨간색은 마이너스, 녹색은 플러스, 흰색은 손익분기점
- 감정 점수: 부정적인 감정은 차가움, 긍정적인 감정은 따뜻함, 중립 중심
중간점이 임의적일 때 분기 팔레트를 사용하지 마십시오. 0-100 척도가 중간에 있다는 이유만으로 50으로 분할한다면 50이 무엇인가를 의미한다는 것을 암시하는 것이며 아마도 그렇지 않을 것입니다.
접근 가능한 분기 팔레트 구성
다양한 팔레트에 대한 가장 중요한 두 가지 요구 사항은 다음과 같습니다.
-
두 끝점 색상은 색맹 시청자가 구별할 수 있어야 합니다. 빨간색-녹색은 약 8%의 시청자에게 실패합니다. 파란색-주황색, 파란색-빨간색 및 보라색-녹색은 모든 주요 형태의 색맹이 유지하는 파란색 채널 강도가 다르기 때문에 모두 작동합니다.
-
중간점은 시각적으로 중립적이어야 합니다. 즉 긍정적이거나 부정적인 극단을 나타내는 것처럼 보일 수 있는 밝은 색상보다는 흰색에 가깝거나 밝은 회색이어야 합니다.
잘 구조화된 파란색에서 빨간색으로 분기되는 팔레트:
#053061 → #2166AC → #4393C3 → #92C5DE → #D1E5F0 → #F7F7F7 → #FDDBC7 → #F4A582 → #D6604D → #B2182B → #67001F
진한 파란색 #053061부터 중성 밝은 회색 #F7F7F7, 진한 빨간색 #67001F까지입니다. 중간점은 분명히 중립적입니다. 양쪽 끝은 동일한 시각적 가중치를 갖습니다. 파란색과 빨간색은 색조가 충분히 다르기 때문에 중수소 동물은 여전히 두 방향을 구분할 수 있습니다(빨간색 면을 다르게 인식하지만 항상 값 레이블이 있는 범례를 포함합니다).
접근 가능한 데이터 시각화 팔레트
배송 전 시뮬레이션
데이터 시각화를 위한 가장 효과적인 접근성 방법은 배송 전에 색각 장애를 시뮬레이션하는 것입니다. 색맹 시뮬레이터를 사용하여 녹색맹, 백색맹, 삼색맹, 색맹 조건에서 팔레트를 테스트하세요. 시뮬레이션에서 차트의 색상 차이가 구별할 수 없는 음영으로 축소되면 실제 사용자에게도 축소됩니다.
오카베-이토 팔레트
Masataka Okabe와 Kei Ito의 8색 팔레트는 데이터 시각화를 위해 가장 널리 권장되는 색맹 안전 범주형 팔레트입니다. 이 제품은 모든 주요 형태의 색각 이상에 따른 구별 가능성에 명시적으로 주의를 기울여 설계되었습니다.
#000000 Black
#E69F00 Orange
#56B4E9 Sky blue
#009E73 Bluish green
#F0E442 Yellow
#0072B2 Blue
#D55E00 Vermilion
#CC79A7 Reddish purple
처음 두 개의 고유한 색상으로 #E69F00 및 #56B4E9로 시작하는 이 팔레트는 빨간색-녹색 대비가 아닌 파란색-노란색 대비의 차이에 의존하기 때문에 녹색맹에서도 견딜 수 있는 시각적 분리를 달성합니다.
이 팔레트는 기본 의미에서 최대한 아름답지는 않습니다. 미학이 아닌 기능에 최적화되었습니다. 그러나 이는 컬러 비전 시뮬레이터에 대해 테스트하는 동안 조정할 수 있는 신뢰할 수 있는 시작점입니다.
색상 너머: 모양, 패턴 및 라벨
색상은 데이터 구별에 사용할 수 있는 유일한 채널이 아닙니다. 접근성이 중요한 차트에서는 색상을 다음과 결합하세요.
도형 마커: 분산형 차트 및 선 차트에 대한 다양한 점 마커(원, 사각형, 삼각형, 다이아몬드, 더하기, 십자)입니다. 각 데이터 시리즈는 고유한 색상과 고유한 마커 모양을 모두 갖습니다.
선 패턴: 실선, 점선, 점선, 점선 — 색상과 결합되어 선 차트에 두 개의 직교 구별 채널을 제공합니다.
직접 라벨: 각 줄의 끝에 시리즈 라벨을 배치하면 색상 범례를 완전히 상호 참조할 필요가 없으므로 (색맹 사용자뿐만 아니라) 모든 사용자에게 도움이 됩니다.
채우기 패턴: 막대형 차트 및 영역형 차트의 경우 색상과 함께 텍스처 또는 크로스해칭 패턴이 두 번째 인코딩을 제공합니다.
// Chart.js — combining color with border dash patterns
const datasets = [
{
label: 'Revenue',
data: revenueData,
borderColor: '#2166AC',
borderDash: [], // solid
pointStyle: 'circle',
},
{
label: 'Expenses',
data: expenseData,
borderColor: '#D6604D',
borderDash: [6, 3], // dashed
pointStyle: 'rect',
},
{
label: 'Profit',
data: profitData,
borderColor: '#009E73',
borderDash: [2, 2], // dotted
pointStyle: 'triangle',
},
];
강조와 설명을 위한 색상
데이터 시각화 색상은 카테고리를 구분하는 것만이 아닙니다. 서술형 도구이기도 합니다. 데이터 스토리텔링에서 색상을 가장 강력하게 사용하는 것은 주의를 집중시키는 것입니다. 즉, 스토리에 중요한 데이터 포인트를 시각적으로 두드러지게 만들고 다른 모든 것에는 종속되도록 만듭니다.
원-브라이트 규칙
일반적이고 효과적인 기술: 모든 컨텍스트 데이터에 대해 음소거되고 채도가 낮은 팔레트를 사용하고 스토리를 전달하는 데이터 포인트 또는 시리즈에 대해 하나의 밝거나 채도가 높은 색상을 예약합니다.
제품군별 수익을 표시하는 막대형 차트는 제품 C가 최고 성능을 발휘한다는 이야기입니다.
Product A: #CBD5E1 (muted gray-blue)
Product B: #CBD5E1
Product C: #2563EB (saturated brand blue — the story)
Product D: #CBD5E1
Product E: #CBD5E1
차트는 모든 값을 균등하게 외치지 않습니다. "여기에 맥락이 있고 여기에 요점이 있습니다." 독자는 내러티브를 더 빨리 파악하고 더 안정적으로 유지합니다.
정렬된 순위에 대한 순차적 색상
순서가 중요한 순위(측정항목별 상위 10개 국가, 최고에서 최악까지 정렬된 시계열)를 표시할 때 순차 팔레트는 순위 정렬을 인지적으로 강화합니다. 가장 높은 값은 가장 어두운 음영을 얻습니다. 가장 낮은 것이 가장 가벼워집니다. 색상과 위치는 독립적으로 작동하기보다는 함께 작동합니다.
빨간색을 신중하게 사용하기
빨간색은 데이터 시각화에서 가장 문화적으로 로드된 색상입니다. 대부분의 시청자는 라벨이나 범례를 읽기 전에 빨간색을 "나쁜" 것으로 해석합니다. 이는 정확할 때 강력하고(음수 값은 빨간색, 위험 임계값 초과는 빨간색) 부수적일 때(빨간색은 양호/불량 축이 없는 범주형 팔레트의 첫 번째 범주 색상임) 혼란스럽습니다.
정말로 부정적이거나 긴급한 데이터에는 빨간색을 예약하세요. 빨간색이 범주형 계열의 한 색상일 경우 데이터가 지원하지 않는다는 의미의 유령을 생성합니다.
D3.js 색상 스케일 구성
D3는 전문적으로 설계된 순차, 발산 및 범주형 팔레트를 포함하는 d3-scale-chromatic 모듈을 통해 포괄적인 색상 스케일 시스템을 제공합니다.
D3의 순차적 스케일
import { scaleSequential } from 'd3-scale';
import { interpolateBlues, interpolateYlOrRd, interpolateViridis } from 'd3-scale-chromatic';
// Blues — single-hue sequential
const blueScale = scaleSequential()
.domain([0, 100])
.interpolator(interpolateBlues);
blueScale(0); // lightest blue
blueScale(50); // mid blue
blueScale(100); // darkest blue
// Viridis — perceptually uniform, colorblind-safe
const viridisScale = scaleSequential()
.domain([minValue, maxValue])
.interpolator(interpolateViridis);
Viridis는 특별히 언급할 가치가 있습니다. 이는 회색조로 읽을 수 있고 모든 주요 형태의 색각 이상에서 구별할 수 있도록 설계된 지각적으로 균일한 순차 팔레트입니다. 이러한 이유로 Python matplotlib의 기본값이며 D3에 이를 포함하면 JavaScript 시각화 작업에서도 동일하게 액세스할 수 있습니다.
D3의 다양한 스케일
import { scaleDiverging } from 'd3-scale';
import { interpolateRdBu, interpolatePiYG } from 'd3-scale-chromatic';
// Red-Blue diverging — good for political maps, temperature anomalies
const rdBuScale = scaleDiverging()
.domain([-1, 0, 1]) // [min, midpoint, max]
.interpolator(interpolateRdBu);
rdBuScale(-1); // saturated red
rdBuScale(0); // near-white neutral
rdBuScale(1); // saturated blue
// Custom diverging scale with explicit colors
import { interpolateRgb } from 'd3-interpolate';
const customDiverging = scaleDiverging()
.domain([-100, 0, 100])
.interpolator(t => {
// t goes 0 → 1 across the full domain
if (t < 0.5) {
return interpolateRgb('#B2182B', '#F7F7F7')(t * 2);
} else {
return interpolateRgb('#F7F7F7', '#2166AC')((t - 0.5) * 2);
}
});
D3의 범주형 척도
import { scaleOrdinal } from 'd3-scale';
import { schemeTableau10, schemeSet2, schemePastel1 } from 'd3-scale-chromatic';
// Tableau 10 — good general-purpose categorical
const categoricalScale = scaleOrdinal()
.domain(['A', 'B', 'C', 'D', 'E'])
.range(schemeTableau10);
// Custom Okabe-Ito for maximum accessibility
const okabeItoScale = scaleOrdinal()
.domain(categories)
.range(['#E69F00', '#56B4E9', '#009E73', '#F0E442', '#0072B2', '#D55E00', '#CC79A7', '#000000']);
Chart.js 색상 스케일 구성
Chart.js는 D3와 다르게 색상 값을 사용하여 작동합니다. 즉, 스케일 함수가 아닌 색상 배열을 기대합니다. 순차 또는 분기 팔레트에 대한 배열을 생성하려면 스케일 기능(D3의 전체 차트 라이브러리 없이 D3의 보간기를 사용할 수 있음) 또는 수동 팔레트 정의가 필요합니다.
Chart.js의 사용자 정의 범주형 팔레트
// Accessible categorical palette (Okabe-Ito)
const accessibleColors = [
'#E69F00', // Orange
'#56B4E9', // Sky blue
'#009E73', // Bluish green
'#F0E442', // Yellow
'#0072B2', // Blue
'#D55E00', // Vermilion
'#CC79A7', // Reddish purple
];
const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: categories,
datasets: [{
label: 'Values',
data: values,
backgroundColor: categories.map((_, i) => accessibleColors[i % accessibleColors.length]),
borderColor: categories.map((_, i) => accessibleColors[i % accessibleColors.length]),
borderWidth: 1,
}],
},
});
Chart.js에서 순서가 지정된 막대 차트의 연속 색상
// Generate a blue sequential palette for N bars
function generateSequentialBlues(n) {
// D3 interpolator used standalone
const interpolator = d3.interpolateBlues;
// Use 0.2 to 0.9 range to avoid too-light and too-dark extremes
return Array.from({ length: n }, (_, i) => interpolator(0.2 + (0.7 * i / (n - 1))));
}
const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: rankedItems,
datasets: [{
data: rankedValues,
backgroundColor: generateSequentialBlues(rankedItems.length),
}],
},
});
Chart.js의 강조 색상 지정
// Highlight one bar, mute all others
const highlightIndex = 2; // index of the story bar
const chart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
data: values,
backgroundColor: values.map((_, i) =>
i === highlightIndex ? '#2563EB' : '#CBD5E1'
),
}],
},
});
요약
기본 차트 색상을 의도적인 선택으로 바꾸려면 데이터의 구조(범주형, 순차적 또는 분기형), 전달하려는 스토리, 대상이 누구인지 이해해야 합니다. 주요 원칙:
- 데이터 구조에 팔레트 유형 일치: 순서가 지정되지 않은 그룹에 대한 범주형 팔레트, 방향이 있는 수량에 대해 순차적, 의미 있는 중심이 있는 수량에 대해 분기.
- 배송 전에 색각 이상 시뮬레이션을 통해 모든 팔레트를 테스트하세요.
- 색상과 함께 보조 인코딩 채널로 모양, 패턴 또는 직접 레이블을 추가합니다.
- 색상 가중치(채도 및 밝기)를 사용하여 스토리를 전달하는 데이터에 주의를 집중시키세요.
- 시각적 정확성이 아닌 시각적 다양성을 위해 설계된 기본값을 대체하도록 D3의 지각적으로 균일한 보간기 또는 Chart.js 사용자 정의 색상 배열을 구성합니다.
데이터 시각화 색상은 궁극적으로 미적인 결정이 아니라 커뮤니케이션 결정입니다. 올바른 팔레트는 사용자가 색상 선택의 의미를 해독하지 않고도 데이터의 구조와 스토리를 읽기 쉽게 만듭니다. 데이터 시각화에서 색상이 잘 작동하면 독자는 이를 거의 알아차리지 못합니다. 즉 통찰력을 알아차리는 것입니다.