iBetter Books
수정

"차트가 내부적으로 어떻게 생겼는지 궁금하지 않아?"

강주원 선배의 메시지였다.

"그냥 fig.show() 하면 되는 거 아닌가요?"

"써보면 왜 알아야 하는지 느끼게 될 거야. update_layout이나 update_traces 쓸 때 어떤 이름으로 속성을 불러야 하는지 알아야 하거든. 그때 Figure 구조를 알면 훨씬 빠르게 찾을 수 있어."


Figure 딕셔너리 확인하기

Plotly Figure는 내부적으로 딕셔너리 구조를 가집니다. fig.to_dict()로 전체 구조를 확인할 수 있습니다.

# 파일: figure_structure.pyimport plotly.express as pximport pprintdf = px.data.iris()fig = px.scatter(    df,    x="sepal_width",    y="sepal_length",    color="species")pprint.pprint(fig.to_dict())

출력 결과는 길지만, 크게 두 부분으로 나뉩니다.

{
  'data': [...],    ← 트레이스(데이터 시리즈) 목록
  'layout': {...}   ← 전체 레이아웃 설정
}

data: 트레이스 목록

data는 리스트입니다. 각 항목이 하나의 트레이스(trace)입니다. 트레이스는 "차트에 그려지는 하나의 데이터 시리즈"를 뜻합니다.

iris 데이터를 세 종으로 색구분한 산점도라면 트레이스가 3개 생깁니다. 각 종이 하나의 트레이스입니다.

# 파일: figure_data.pyimport plotly.express as pxdf = px.data.iris()fig = px.scatter(    df,    x="sepal_width",    y="sepal_length",    color="species")print(f"트레이스 개수: {len(fig.data)}")print(f"첫 번째 트레이스 타입: {type(fig.data[0])}")print(f"첫 번째 트레이스 이름: {fig.data[0].name}")

출력 결과입니다.

트레이스 개수: 3
첫 번째 트레이스 타입: <class 'plotly.graph_objs._scatter.Scatter'>
첫 번째 트레이스 이름: setosa

각 트레이스에는 x, y 데이터와 마커 스타일, 이름 등이 담겨 있습니다.

layout: 전체 레이아웃

layout은 차트 전체에 적용되는 설정입니다. 제목, 축 레이블, 범례 위치, 배경색, 크기 등이 여기에 있습니다.

# 파일: figure_layout.pyimport plotly.express as pxdf = px.data.iris()fig = px.scatter(    df,    x="sepal_width",    y="sepal_length",    color="species",    title="붓꽃 산점도")print(fig.layout.title.text)    # "붓꽃 산점도"print(fig.layout.xaxis.title)   # 축 제목 객체

fig.layout은 딕셔너리가 아닌 객체입니다. 점 표기법으로 속성에 접근할 수 있습니다.

Figure 구조 요약

go.Figure
├── data: [Trace, Trace, ...]
│   ├── Trace 0: {type, x, y, name, marker, ...}
│   ├── Trace 1: {type, x, y, name, marker, ...}
│   └── ...
└── layout: Layout
    ├── title: {text, ...}
    ├── xaxis: {title, range, ...}
    ├── yaxis: {title, range, ...}
    ├── legend: {x, y, ...}
    └── ...

이 구조를 이해하면 update_layout()update_traces()에서 어떤 이름의 속성을 수정해야 하는지 바로 알 수 있습니다.

"이제 update 메서드 쓸 때 느낌이 오지?" 선배가 물었다.

"네, layout은 전체 설정이고, data 안에 각 트레이스가 있는 거군요."

"맞아. update_layout은 layout 딕셔너리를 수정하는 거고, update_traces는 data 안의 트레이스들을 수정하는 거야."


자주 묻는 질문

Q: fig.to_dict()fig.to_json()의 차이는 뭔가요?

to_dict()는 Python 딕셔너리를 반환하고, to_json()은 JSON 문자열을 반환합니다. 둘 다 같은 내용이지만, API나 파일로 저장할 때는 to_json()이 편하고, Python 코드에서 처리할 때는 to_dict()가 편합니다.

Q: 트레이스가 몇 개인지 확인하는 방법은 뭔가요?

len(fig.data)로 확인합니다. 또는 print(fig.data)로 전체 트레이스 목록을 볼 수 있습니다.

Q: 특정 트레이스만 꺼내서 수정할 수 있나요?

fig.data[0]처럼 인덱스로 접근할 수 있습니다. 단, 반환된 객체의 속성을 직접 수정하면 예상치 못한 동작이 생길 수 있습니다. update_traces(selector=dict(name="setosa"), ...)처럼 선택자를 사용하는 것이 더 안전합니다.