파이썬(Python)/에어컨 계절 수요 흐름

[무역|4|Plotly] 에어컨 계절 수출입 수요 - plotly bar plot & subplot (3부)

JJ Goh[Certified customs broker] 2020. 6. 28. 06:00

[무역|4|Plotly] 에어컨 계절 수출입 수요 - plotly bar plot & subplot (3부)

 
plotly의 시각화 코드를 한 줄씩 살펴 보시겠습니다.
fig = make_subplots(rows=1, cols=2, specs=[[{"type": "bar"}, {"type": "bar"}]])
fig.add_trace(go.Bar(y=y1, x=z1, name="수출실적"), row=1, col=1)
fig.add_trace(go.Bar(y=y2, x=z1, name="수입실적"), row=1, col=1)
fig.add_shape(type="line",x0=z1.iloc[0],x1=z1.iloc[z1.count()-1],y0=y1.mean(),y1=y1.mean(), line=dict(color="blue"),
              row=1, col=1)
fig.add_shape(type="line",x0=z1.iloc[0],x1=z1.iloc[z1.count()-1],y0=y2.mean(),y1=y2.mean(), line=dict(color="red"),
              row=1, col=1)
fig.add_annotation(row=1,col=1, x= z1.iloc[9], y=y1.mean(),
                   text="수출평균 : "+y1.mean().astype('int').astype('str'))
fig.add_annotation(row=1,col=1, x= z1.iloc[11], y=y2.mean(),
                   text="수입평균 : "+y2.mean().astype('int').astype('str'))

fig.add_trace(go.Bar(y=y3, x=z1, name="무역수지"), row=1, col=2)
fig.add_shape(type="line", x0=z1.iloc[0], x1=z1.iloc[z1.count()-1], y0=y3.mean(), y1=y3.mean(),
              line=dict(color="green"),row=1, col=2, name="무역수지평균 : "+y3.mean().astype('int').astype('str'))
fig.add_annotation(row=1,col=2, x= z1.iloc[z1.count()-25], y=y3.mean(),
                   text="무역수지평균 : "+y3.mean().astype('int').astype('str'))

fig.update_layout(template="plotly_white", margin=dict(r=10, t=25, b=40, l=60), barmode='group', bargap=0)

plotly.offline.plot(fig)

 

 

make_subplots()   subplot 만들기

 

 

1) fig = make_subplots(rows=1, cols=2, specs=[[{"type": "bar"}, {"type": "bar"}]])

 

 fig라는 변수에 make_subplots() 메소드를 사용하였습니다. make_subplots()는 지난 포스팅에서 설명 드렸던 바와 같이, 한 개의 canvas에 여러개의 plot들을 그리고 싶을 때 사용하게 됩니다. 

 제시된 코드상에 사용된 parameter는 다음과 같은 기능을 합니다.

 

 a) rows 인자는 설정된 갯수 만큼의 행을 만듭니다. 1이 설정되어 있으므로 plot은 가로 1줄로 모두 나타납니다.

 

 b) cols 인자는 설정된 갯수 만큼의 열을 만듭니다. 2가 설정되어 있으므로 plot은 이제 가로 1줄에 세로 2줄로 나타납니다. 즉, subplot은 1 X 2 형태로 2개의 plot이 한번의 실행으로 한 개의 canvas안에 그려지게 됩니다. 

 

 c) specs 인자는 리스트 형태로 각 subplots들에 대한 세부 설정을 줍니다. 이 코드에서는 "type":"bar"로 주어 각 subplot의 타입은 bar plot(수직막대그래프)으로 그리겠다고 설정한 것입니다.

 

 기타 subplot의 다양한 생성예제는 아래 링크의 공식문서를 참조해 주시면 되겠습니다.

 

 

링크 : Subplots in Python

 

 

 

add.trace() 와 go.Bar()    수직 막대그래프 그리기

 

 

2) fig.add_trace(go.Bar(y=y1, x=z1, name="수출실적"), row=1, col=1)

 

 fig 변수의 subplot에 add_trace()로 특정의 그래프를 넣겠다는 것인데요. trace를 구글 번역하면 '흔적'이라고 나옵니다. 그래프를 그린 흔적을 추가하겠다는 의미가 되겠네요. 

 go.Bar()는 'go' 즉, plotly.graphic_objects의 Bar()메소드를 통해 막대 그래프를 그리겠다는 명령이 됩니다. x와 y에 각각 x축에 넣을 Series 를 대입해 줍니다. name이라는 인자는 그래프가 표출되면, legend로서 값이 나올 때 legend에 쓰여질 이름이 됩니다.

 

 그리고, row=1과 col=1의 값이 add_trace()의 인자로 쓰였는데요. 이는 이 bar plot을 subplot중 1행, 1열에 배치하겠다는 의미가 됩니다. 1행 2열에 비채할 subplot은 row=1, col=2로 설정하면 되겠습니다.

 

 

fig.add_shape()    그래프 외의 기타 형상 추가하기

 

 

 3) fig.add_shape(type="line",x0=z1.iloc[0],x1=z1.iloc[z1.count()-1],y0=y1.mean(),y1=y1.mean(), line=dict(color="blue"), row=1, col=1, name="수출평균 : "+y1.mean().astype('int').astype('str'))

 

 fig.add_shape()은 그래프 외의 기타 형상을 추가할 때 사용합니다. 필자는 '수출실적', '수입실적'과 '무역수지'의 평균값을 horizontal line(수평선)을 그어 표현해 주고 싶었습니다. 하여 이 메소드를 추가하였는데요.

 

 add_shape()을 통한 다양한 변형 사용의 예제는 아래 공식문서 링크를 참조해 주십시요.

 

 

 링크 : Shapes in Python

 

 

 사용된 인자의 간략한 설명은 다음과 같습니다.

 

 

 a) type은 어떤 형상을 쓸지를 설정합니다. "line"은 선을 의미합니다.

 

 

 b) x0 는 해당 형상의 x축 시작지점 값입니다. x1은 해당 형상의 x축 종료지점 값입니다. 하여 x축 값으로 해당 형상의 시작지점과 종료지점의 x축 좌표가 설정됩니다. 

 

    저는 x0을 z1.iloc[0]으로 썼는데요. 이는 사용되는 DataFrame d8의 x축 값인 '기간'값이 '연도-월'형식의 str으로 인식되어 있기 때문입니다. x축에 int나 float 값이 대입되면 시작지점은 단순히 정수나 실수값을 넣어주면 되지만, str로 인식되어 있기 때문에 이 그래프의 시작점은 해당 series의 시작 str값을 주어야 올바르게 인식하게 됩니다. 

   하여 pandas DataFrame에서 배웠던 iloc[0]을 사용해 첫번째 행의 값을 돌려 달라는 의미로 사용 하였습니다. 

 

    두번째로 x1=z1.iloc[z1.count()-1]로 하였는데요. z1.count()는 z1의 데이터개수를 센 것입니다. 총 41개 행이 있기 때문에 해당 값은 41이 되는데 거기서 다시 1을 뺐습니다. 결국 x1=z1.iloc[40]과 같은 의미가 됩니다. 이제 plotly는 그래프의 x축 종료지점값을 z1 series의 39번째 있는 값을 종료지점 좌표로 인식하게 되겠습니다.

 

 

 c) y0은 해당 형상의 y축 시작지점 값입니다. y1.mean()은 y1 series의 평균값입니다. y1은 해당 형상의 y축 종료지점 값입니다. 필자는 수평선을 그리고자 하였기 때문에 y1에도 y1.mean() 값을 넣어 y축 값의 변동이 없게 하였습니다. 

 

 

 d) line이라는 인자에는 dictionary형으로 값을 전달하는데요. 저는 일단 color만을 썼습니다. 점선으로 표현을 원할경우 dash같은 추가값을 설정할 수 있습니다. 추가적인 사용예는 공식문서를 참조해 주세요.

 

 

 e) row와 col인자는 앞선, add_trace()설정 때와 마찬가지로 이 shape을 어느 subplot위치에 넣을 건지를 설정해 줍니다. row=1이고 col=1이므로, 이 수평선은 첫번째 subplot에 그려지게 됩니다. 

 

 

 

 

fig.add_annotation()    그래프에 annotation(주석) 달기

  

 

 4) fig.add_annotation(row 1col 1, x= z1.iloc[9], y=y1.mean()text "수출평균 : "+y1.mean().astype('int').astype('str'))

 

 add_annotation() 메소드는 plot에 annotation을 붙이고 싶을 때 사용합니다. 

 "수출평균 : 00000"과 같은 형태로 그래프에 표출하고자 이와 같이 값을 부여 하였는데요. 

 먼저, mean()으로 평균을 냈고, 해당 평균값은 실수형으로 계산되어 나오는게 통상이겠지요. 소수점 이하 자리수가 많으면 보기 불편하기만 하겠기에, 다시 .astype('int')를 붙여 해당 실수를 정수자료형으로 변환해 줍니다. 이제, 소수점 이하 값은 다 떨어져 나갈 것입니다. 

 

 그런데, 이 숫자값은 text라는 인자에 곧바로 넣을 수 없습니다. 문자열(str)이 아닌 정수형(int)이기 때문에 덧셈(+) 연산자를 붙여서 값을 주면 자료형이 달라 값을 계산할 수 없다는 파이썬의 오류메시지를 접하게 됩니다. 텍스트로 주어야 그래프에 올바로 표현되기 때문에 다시 한번 .astype('str')을 붙여서 자료형 변환을 해준 것입니다.

 

 그리고 row, col 인자값은 마찬가지로 이번과 같이 subplot을 여러개 만들었을 때 어느 위치의 subplot에 해당 annotation을 달 것인지 지정해 주기 위해서 넣어 주었습니다.

 

 x와 y 좌표를 준 논리 또한 앞서 fig.add_shape()에서 설명드린 논리와 같습니다.

 

 

fig.update_layout()    그래프 캔버스 전체 스타일 꾸미기

 

 

 5) fig.update_layout(template="plotly_white", margin=dict(r=10, t=25, b=40, l=60), barmode='group', bargap=0)

 

 fig.update_layout은 기본 layout에서 전체적인 layout 꾸미기를 할 때 사용합니다. 

 인자값들을 보시면 그 사용된 용어가 layout을 꾸미는 요소들이 주를 이룬다는 사실을 알 수 있습니다.

 제가 사용한 인자들에 대한 간략한 설명은 아래와 같습니다.

 

 a) template 인자는 plotly에 built-in 되어 있는 전체적인 layout 스타일을 지정할 수 있습니다. 단지, plotly가 제공해 주는 template 이름만 입력함으로서 설정된 style을 그대로 사용할 수 있습니다. matplotlib에서는 온갖 코드들을 가져다 사용해야만 하는데, 이러한 부분은 저처럼 customizing에 약한 사람에게는 매우 편리한 방식입니다.

 

 b) margin은 바로 느끼시겠지만, 여백 조정입니다. dictionary형으로 right, top, bottom, left값을 지정해 주시면 되겠습니다.

 

 c) barmode 에 'group'을 주게 되면, 우리나라 말로 '묶은막대그래프' 형태로 표출됩니다.

 

 d) bargap에 준 값은 묶은막대그래프의 묶음 내 막대간의 간격을 조정해 줍니다.

 

 

 

 이제 4부에서는 결과물을 확인해 볼 수 있겠네요. 

 4부로 이어가도록 하겠습니다.

 

 

 (4부에서 계속..)

 

 

NPU(엔피유) 관세사무소

대표관세사 고장주

Tel) 031-986-7190

E-mail) sales@npucus.com

[NPU관세사무소 프로모션 페이지] https://www.tradenpu.com/npu_cus/

[무역비지니스 인텔리전스 서비스 | TradeNPU] https://www.tradenpu.com

[파이썬 실용 예제. 무역과 공공데이터] https://pdatinmylife.tistory.com

Certified Customs Broker JangJu Goh

Executive Customs Broker @ NPU Customs Consulting

CEO @ JG TradePlus

sales@npucus.com

Trade Compliance / Customs clearance management at foreign company

Working experience of Air export freight forwarding

Data Visualization / Independent development of business automation application – copyright of JGPO_Manager, JG Data Center, AutoCC and etc.

B2B consignment & direct export/import, B2C Overseas Buying Office consulting

Alibaba.com B2B trade / taobao B2C trade / Amazon.com global selling etc. Online trade regulation consulting.

Import license / Quarantine

English communication available

[TradeNPU for partnership proposal - JGTP] https://www.tradenpu.com/jgtp/

반응형