본문 바로가기

Python

[Python]Plotly를 이용해 극좌표 그래프 그리기

반응형

오늘은 Google Colab. 환경에서 Plotly를 이용해 극좌표 그래프를 그리는 방법에 대해 알아본다. 

Plotly를 이용해 극좌표 그래프를 그리는 방법에는 두 가지 정도가 있다.

한가지는 Plotly.express package를 사용하는 방법, 다른 한가지는 plotly.graph_objects 를 이용하는 방법이다. 

이름에서도 유추할 수 있듯이, express package를 사용하면 빠르게 그릴 수 있는 대신, 세부적인 옵션은 조절하기 어렵다. 반면 graph_objects는 세세하게 조절할 수 있는 대신 처음부터(?) 그려야한다.

그림에 비유하면 Plotly express는 컬러링 북을 사서 색칠만 하는 느낌이고, Plotly graph_objects는 직접 스케치부터 하는 느낌이다. 

무슨말인지 직접 해보면서 알아보자.

 

먼저 오늘 사용할 Package를 install해주자. 

!pip install chart_studio

chart_studio에는 plotly package가 들어있다.

다음 우리가 사용할 package를 불러오자.

import numpy as np              
import matplotlib.pyplot as plt
import chart_studio
chart_studio.tools.set_credentials_file(username='username',api_key='api_key')
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd

먼저 Plotly express를 이용해 graph를 그려보자. 코드 부터 보면,

a = np.random.rand(36)

df = pd.DataFrame(dict(
    r=a,
    theta=list(np.arange(0,360,10))
    )
)

fig = px.line_polar(df, r='r', theta='theta', line_close=True, )
fig.update_layout(
    title = {
        'text': 'Sample title',
        'y':0.97,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'},
    showlegend = True,
)
fig.show()

한줄씩 살펴보자. 

a = np.random.rand(36)

먼저 a라는 변수에 np.random.rand 를 이용해 0부터 1사이의 난수 36개를 만들었다. 

df = pd.DataFrame(dict(
    r=a,
    theta=list(np.arange(0,360,10))
    )
)

다음, 0부터 350까지 각도를 theta라는 list로 만들고, 각도마다 a라는 값이 대응된 DataFrame을 만들었다. 

굳이 DataFrame을 만드나? 싶겠지만, 실제 그래프를 그릴 때 DataFrame을 사용하는 일이 많기 때문에 이런식으로 해 보았다. 

df.head()를 통해 어떻게 생겼는지 확인해보면,

요렇게 생겼을 것이다. 

이제 데이터가 준비되었으니 그래프를 그려보자.

fig = px.line_polar(df, r='r', theta='theta', line_close=True)

plotly.express를 px로 불러왔는데, px에 있는 line_polar를 이용해서 단 한줄로 (!) 그래프를 완성했다.

괄호안에 들어있는 옵션은 어떤 데이터를 사용할건지, 그리고 r값과 theta값을 그 데이터에서 어떤 column을 이용해서 정해줄건지를 말한다.

line_close의 경우 0도와 350도를 이어주는 역할을 한다. 무슨 말이냐면, 우리가 np.random.rand로 36개, 그리고 theta는 0부터 350도까지 만들었기때문에, 0도와 350사이의 line이 비게 된다. line_close=True로 두게 되면 0도와 350도 사이를 자동으로 연결해준다.

fig.update_layout(
    title = {
        'text': 'Sample title',
        'y':0.97,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'},
    showlegend = True,
)

다음은 그래프에 제목을 넣어봤다. showlegend=True로 두었지만 legend를 설정하지 않았기 때문에 legend는 아마 보이지 않을 것이다. 결과물을 보자.

fig.show()

실행시키면

 

다음과 같은 그래프를 그릴 수 있다. 

 

이제 Plotly.grpah_objects를 이용해서 그려보자. 코드는 다음과 같다. 

a = np.random.rand(36)

fig = go.Figure()

fig.add_trace(go.Scatterpolar(
      r=a,
      theta=list(np.arange(0,370,10)),
      mode='lines',
      name='Sample 1')
)

fig.update_layout(
    title = {
        'text': 'Sample title',
        'y':0.97,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'},
    showlegend = True,
)

fig.show()

graph_objects를 사용할때는 그릴 도화지를 선언해줘야한다. 그 코드가 바로 이것이다.

fig = go.Figure()

다음, 도화지에 Polar를 그려준다. 

fig.add_trace(go.Scatterpolar(
      r=a,
      theta=list(np.arange(0,370,10)),
      mode='lines',
      name='Sample 1')
)

mode를 통해 line으로 그릴건지, scatter할건지 등을 결정해 줄 수 있다. 또 이번에는 legend도 설정해주었다.

마찬가지로 title과 legend를 설정해주자.

fig.update_layout(
    title = {
        'text': 'Sample title',
        'y':0.97,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'},
    showlegend = True,
)


fig.show()

결과물은 다음과 같다. 

우리의 도화지 fig.에 add_trace를 더해서 여러개를 그릴 수도 있겠다.

 

 

a=np.random.rand(37)
b=np.random.rand(37)
c=np.random.rand(37)
fig = go.Figure()

fig.add_trace(go.Scatterpolar(
      r=a,
      theta=list(np.arange(0,370,10)),
      mode='lines',
      name='Sample 1')
)

fig.add_trace(go.Scatterpolar(
      r=b,
      theta=list(np.arange(0,370,10)),
      mode='markers',
      name='Sample 2')
)

fig.add_trace(go.Scatterpolar(
      r=c,
      theta=list(np.arange(0,370,10)),
      mode='lines+markers',
      name='Sample 3')
)

fig.update_layout(
    title = {
        'text': 'Sample title',
        'y':0.97,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'},
    showlegend = True,
)

fig.to_show()

 

이외에도 graph의 선 두께, 색상, 형태, opacity, size 등 굉장히 세세하게 - 생각할 수 있는 거의 모든 옵션을 건드릴 수 있다. 자세한 내용은 공식문서를 참고하는 것이 좋겠다.

plotly.github.io/plotly.py-docs/generated/plotly.graph_objects.Scatterpolar.html

 

plotly.graph_objects.Scatterpolar — 4.13.0 documentation

[0, ‘0’, ‘circle’, 100, ‘100’, ‘circle-open’, 200, ‘200’, ‘circle-dot’, 300, ‘300’, ‘circle-open-dot’, 1, ‘1’, ‘square’, 101, ‘101’, ‘square-open’, 201, ‘201’, ‘square-dot’, 301, ‘301’, ‘square-

plotly.github.io

 

마지막으로 이를 이용한 예시 그래프를 하나 남기고 이만 글을 마쳐보겠다. 

 

위의 그래프는 다음과 같은 fig.updat_layout을 이용해 업데이트 해주었다. polar의 옵션들을 dict로 넣어주면 된다. 

radialaxis의 font, angularaxis의 font, rotation, direction(시계or반시계) 등을 정해줄 수 있다. 

fig.update_layout(
    title ={
        'text': 'HWP의 Fast axis각도 별 빛의 세기 분포',
        'y':0.97,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'},
    showlegend = True,
        polar = dict(
            radialaxis_tickfont_size = 8,
            angularaxis = dict(
                tickfont_size=8,
                rotation=90, # start position of angular axis
                direction="clockwise")
      )
)