iBetter Books
수정

"민수야, 데이터 날짜 형식이 어떻게 돼?"

지윤이 물었습니다. 민수가 스프레드시트를 열었습니다. 2022-01-01, 2022-02-01 형식으로 월별 첫날이 날짜로 기록되어 있었습니다.

"날짜 타입이면 Plotly가 자동으로 시계열 축으로 잡아줘. 그리고 주가 데이터로도 연습해볼 거야. Plotly 내장 데이터셋에 딱 맞는 게 있거든."


px.data.stocks()로 주가 데이터 불러오기

Plotly는 px.data.stocks()로 여러 기업의 주가 데이터를 내장하고 있습니다. 날짜와 주가 컬럼이 포함되어 있어 시계열 연습에 적합합니다.

# 파일: stocks_explore.pyimport plotly.express as pxdf = px.data.stocks()print(df.head())print(df.dtypes)
         date      GOOG      AAPL      AMZN        FB      NFLX      MSFT
0  2018-01-01  1.000000  1.000000  1.000000  1.000000  1.000000  1.000000
1  2018-01-08  1.018172  1.011943  1.061881  0.959968  1.053526  1.015988
...
date    object
GOOG    float64
...

날짜가 문자열(object)로 저장되어 있습니다. Plotly는 날짜 문자열을 자동으로 인식하지만, 명시적으로 변환해두면 더 안전합니다.


다중 라인으로 주가 비교

px.data.stocks()의 데이터는 wide 형식(컬럼별 기업)입니다. color로 그룹핑하려면 long 형식으로 변환해야 합니다.

# 파일: stocks_multi.pyimport plotly.express as pximport pandas as pddf = px.data.stocks()# wide → long 변환df_long = df.melt(    id_vars="date",    var_name="company",    value_name="price")fig = px.line(    df_long,    x="date",    y="price",    color="company",    title="기업별 주가 변화 (2018 기준 정규화)",    labels={"date": "날짜", "price": "주가 (정규화)", "company": "기업"})fig.show()

실행 결과

모든 기업의 주가가 2018년 1월 1일 기준 1.0으로 정규화되어 있어, 상대적인 성장률을 비교할 수 있습니다.


날짜 축 서식 지정

x축이 날짜이면 tickformat으로 표시 형식을 조정할 수 있습니다. update_xaxes()tickformat을 지정합니다.

# 파일: stocks_format.pyimport plotly.express as pximport pandas as pddf = px.data.stocks()df_long = df.melt(id_vars="date", var_name="company", value_name="price")fig = px.line(    df_long,    x="date",    y="price",    color="company",    title="기업별 주가 변화")fig.update_xaxes(    tickformat="%Y년 %m월",  # 예: 2018년 01월    dtick="M3"               # 3개월 간격으로 눈금 표시)fig.show()

실행 결과

tickformat은 Python strftime 형식을 따릅니다. 자주 쓰는 패턴은 아래 표를 참고합니다.

패턴 출력 예시
%Y 2024
%m 03
%d 15
%Y-%m 2024-03
%Y년 %m월 2024년 03월

dtick은 눈금 간격을 설정합니다. 날짜 축에서 "M3"은 3개월, "M1"은 1개월 간격입니다.


범위 슬라이더 추가

데이터 기간이 길면 특정 구간을 확대해서 보고 싶을 때가 있습니다. 범위 슬라이더를 추가하면 아래에 작은 미니맵이 생겨 드래그로 보고 싶은 구간을 선택할 수 있습니다.

# 파일: stocks_slider.pyimport plotly.express as pximport pandas as pddf = px.data.stocks()df_long = df.melt(id_vars="date", var_name="company", value_name="price")fig = px.line(    df_long,    x="date",    y="price",    color="company",    title="기업별 주가 변화 (범위 슬라이더 포함)")fig.update_xaxes(    tickformat="%Y년 %m월",    dtick="M3",    rangeslider=dict(visible=True))fig.show()

실행 결과

차트 아래에 슬라이더가 생깁니다. 슬라이더 양쪽 끝을 드래그하면 보고 싶은 기간만 확대됩니다.


실전: 민수의 매출 시계열 차트

연습이 끝나자 지윤은 민수의 실제 데이터로 넘어갔습니다. 월별 매출 데이터를 연도별로 비교하는 차트였습니다.

# 파일: sales_timeseries.pyimport plotly.express as pximport pandas as pd# 2022~2024년 월별 매출 (단위: 만원)months = pd.date_range("2022-01-01", "2024-12-01", freq="MS")import numpy as npnp.random.seed(42)base = [800, 750, 900, 950, 1100, 1300, 1200, 1250, 1100, 950, 1000, 1500]sales = []for year_offset in range(3):    for m_val in base:        sales.append(int(m_val * (1 + year_offset * 0.12) + np.random.randint(-50, 50)))df = pd.DataFrame({    "date": months,    "sales": sales,    "year": [str(d.year) + "년" for d in months]})fig = px.line(    df,    x="date",    y="sales",    color="year",    markers=True,    title="연도별 월간 매출 비교",    labels={"date": "날짜", "sales": "매출 (만원)", "year": "연도"})fig.update_xaxes(    tickformat="%m월",    dtick="M1",    rangeslider=dict(visible=True))fig.update_layout(yaxis_tickformat=",")  # 천 단위 구분 쉼표fig.show()

실행 결과

민수가 차트를 보고 눈을 크게 떴습니다.

"12월에 항상 피크가 오네. 그리고 매년 조금씩 오르고 있어."

"그게 바로 시계열 차트가 보여주는 거야."


rangeslider vs relayout

범위 슬라이더 외에도 Plotly는 차트 위에서 드래그로 직접 확대할 수 있습니다. 우측 상단 툴바에서 돋보기 아이콘을 클릭하면 확대 모드가 활성화됩니다. 두 방식 모두 사용 가능하니 상황에 맞게 선택합니다.

방법 장점 단점
범위 슬라이더 전체 범위를 보면서 구간 선택 가능 차트 높이를 차지함
드래그 확대 별도 공간 불필요 전체 범위 파악이 어려움