Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags more
Archives
Today
Total
관리 메뉴

StudyStudyStudyEveryday

[Python] 그래프 그리기 - 3D plots / Interactive plots 본문

Python/데이터 시각화

[Python] 그래프 그리기 - 3D plots / Interactive plots

따듯한붕어빵 2022. 4. 20. 11:08

 

 

 

 

3D plots

산점도, 선 그래프 등은 간혹 2차원 평면상에 표현하는 것이 제한적일 수 있다. 이럴 경우 더 많은 정보를 제공하고자 3차원 공간상에서의 산점도 및 선 그래프 등을 생각할 수 있다.

 

 

3차원 산점도 그리기

matplotlib의 pyplot을 통해 3차원 산점도를 그려보겠다. pyplot에서 3차원 산점도를 그리려면 먼저 3차원 축을 생성해야한다. axes변수를 통해 3차원 객체를 생성하고 scatter을 이용해 x, y, z축을 입력으로 받아 3차원 산점도를 그린다.

mtcars = sm.datasets.get_rdataset('mtcars', 'datasets')
mtcars_dat = mtcars.data.copy()


# 3d 그래프 그리기
fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')

# 같은 3d 그래프 다른 방법
#fig, axes = fig.subplots(1, 1, subplot_kw = dict(projection='3d'))

axes.scatter(mtcars_dat.wt, # x
             mtcars_dat.disp,  # y
             mtcars_dat.mpg,  # z
             depthshade=False) # 깊이에 따라 색 선명도 다르게 하기

 

 

zdir을 이용해 축을 고정시킨 3D plot 생성

zdir은 특정 축을 고정시켜 3차원 축에 2차원 그래프를 그릴 수 있도록 해주는 인자이다.

 

다음은 y축을 고정시킨 그래프를 그리는 코드이다.

fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')

axes.scatter(mtcars_dat.wt, 
             mtcars_dat.disp, 
             mtcars_dat.mpg,
             depthshade=False) # 깊이에 따라 색 선명도 다르게 하기

axes.scatter(mtcars_dat.wt, 
             mtcars_dat.mpg,
             zdir = 'y', # y축 고정
             zs = mtcars_dat.disp.max(), # disp의 max값 고정
             depthshade=False,
             alpha=0.25)

y축 고정

 

 

x축을 고정시킨 그래프 그리기

fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')

axes.scatter(mtcars_dat.wt, 
             mtcars_dat.disp, 
             mtcars_dat.mpg,
             depthshade=False) # 깊이에 따라 색 선명도 다르게 하기

axes.scatter(mtcars_dat.disp, 
             mtcars_dat.mpg, 
             zdir = 'x', # x축 고정
             zs = mtcars_dat.wt.min(),
             depthshade=False,
             alpha=0.25)

 

 

z축을 고정시킨 그래프 그리기

fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')

axes.scatter(mtcars_dat.wt, 
             mtcars_dat.disp, 
             mtcars_dat.mpg,
             depthshade=False) # 깊이에 따라 색 선명도 다르게 하기

axes.scatter(mtcars_dat.wt, 
             mtcars_dat.disp, 
             zdir = 'z',
             zs = mtcars_dat.mpg.min(),
             depthshade=False,
             alpha=0.25)

 

축 범위 설정 / label 설정

fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')

axes.scatter(mtcars_dat.wt, 
             mtcars_dat.disp, 
             mtcars_dat.mpg,
             depthshade=False) # 깊이에 따라 색 선명도 다르게 하기

axes.scatter(mtcars_dat.wt, #x
             mtcars_dat.mpg, #z
             zdir = 'y', # y축 고정
             zs = mtcars_dat.disp.max(), # disp의 max값 고정
             depthshade=False,
             alpha=0.25)

axes.scatter(mtcars_dat.disp, #y
             mtcars_dat.mpg, #z
             zdir = 'x', # x축 고정
             zs = mtcars_dat.wt.min(),
             depthshade=False,
             alpha=0.25)

axes.scatter(mtcars_dat.wt, #x
             mtcars_dat.disp, #y
             zdir = 'z',
             zs = mtcars_dat.mpg.min(),
             depthshade=False,
             alpha=0.25)

# 축 범위
axes.set_xlim([mtcars_dat.wt.min(), mtcars_dat.wt.max()])
axes.set_ylim([mtcars_dat.disp.min(), mtcars_dat.disp.max()])
axes.set_zlim([mtcars_dat.mpg.min(), mtcars_dat.mpg.max()])

# label 설정
axes.set_xlabel('wt')
axes.set_ylabel('disp')
axes.set_zlabel('mpg')

 

 

plot 회전시키기

Axes3DSubplot 객체의 view_init method로 plot을 회전시킬 수 있다

fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')

axes.scatter(mtcars_dat.wt, 
             mtcars_dat.disp, 
             mtcars_dat.mpg,
             depthshade=False)
             
axes.scatter(mtcars_dat.wt, #x
             mtcars_dat.mpg, #z
             zdir = 'y', # y축 고정
             zs = mtcars_dat.disp.max(), # disp의 max값 고정
             depthshade=False,
             alpha=0.25)

axes.scatter(mtcars_dat.disp, #y
             mtcars_dat.mpg, #z
             zdir = 'x', # x축 고정
             zs = mtcars_dat.wt.min(),
             depthshade=False,
             alpha=0.25)

axes.scatter(mtcars_dat.wt, #x
             mtcars_dat.disp, #y
             zdir = 'z',
             zs = mtcars_dat.mpg.min(),
             depthshade=False,
             alpha=0.25)

# 축 범위
axes.set_xlim([mtcars_dat.wt.min(), mtcars_dat.wt.max()])
axes.set_ylim([mtcars_dat.disp.min(), mtcars_dat.disp.max()])
axes.set_zlim([mtcars_dat.mpg.min(), mtcars_dat.mpg.max()])

# label 설정
axes.set_xlabel('wt')
axes.set_ylabel('disp')
axes.set_zlabel('mpg')

# 어디서 바라볼지
axes.view_init(None, 0) # y축에서 바라보기
axes.view_init(30, 0) # 위에서 바라보기

 

선 그래프 3D로 표현

x = np.linspace(-4 * np.pi, 4 * np.pi, 50)
y = np.linspace(-4 * np.pi, 4 * np.pi, 50)
z = x**2 + y**2

fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')

axes.plot(x, y, z)

 

 

3D surface

3d surface는 plot_surface method로 생성할 수 있다.

plot_surface는 입력되는 2차원 좌표값에 높이를 이용하여 표면을 그려준다.

x와 y인자는 2차원 좌표값으로 x에는 2차원 grid의 x좌표, y에는 y좌표를 입력한다.

* 2차원 grid의 x, y좌표는 numpy의 meshgrid 함수로 생성 가능하다.

volcano = sm.datasets.get_rdataset('volcano', 'datasets').data.copy()

volcano.shape
x = np.arange(1, volcano.shape[0] + 1) #volcano의 행 개수
y = np.arange(1, volcano.shape[1] + 1) #volcano의 열 개수

xx, yy = np.meshgrid(x, y) # 입력되는 좌표 벡터로부터 좌표 행렬 생성해줌
xx.shape


fig = plt.figure()
axes = fig.add_subplot(111, projection='3d')
axes.plot_surface(xx.T, yy.T, volcano.values)

 

 

Interactive plots

지금까지 학습했던 그래프들은 사용자와의 상호작용이 불가능한 고정된 그래프였다.

하지만 많은 경우 그래프 상의 점, 선 등의 값 또는 label을 확인하고자 하는 경우가 많으며 3D 그래프의 경우 그래프를 회전시켜 그래프를 확인하는 것이 요구된다. 앞서 언급한 기능을 포함하는 그래프를 interactive plot이라고 하며, 사용자와의 상호작용을 허용한다.

 

interactive plot을 제공해주는 라이브러리 중 plotly를 사용해보겠다.

plotly는 anaconda prompt에서 conda install plotly를 이용해 설치 가능하다.

 

추가로, spyder에서 interactive plot을 그리기 위해서는 plotly.io 모듈에서 renderers.default = 'browser'을 설정해준다.

 

산점도 그리기

import plotly.express as px
import plotly.io as pio
pio.renderers.default='browser'


fig = px.scatter(data_frame = mtcars_dat,
                 x = 'wt', y = 'mpg')
fig.show()

결과 : 실습을 통해 직접 확인해보길 바란다. 점 위에 마우스 커서를 놓으면 데이터에 대한 내용이 나온다.

 

 

점의 색과 모양을 지정할 수도 있으며, 그룹 변수가 입력되면 그룹별 점의 색상과 모양이 설정된다.

mtcars_dat.cyl = pd.Categorical(mtcars_dat.cyl)
fig = px.scatter(data_frame = mtcars_dat,
                 x = 'wt', y = 'mpg',
                 color = 'cyl',
                 symbol = 'cyl')
fig.show()

 

선 그래프

선 그래프는 line 함수를 이용해 그릴 수 있다.

import os
os.chdir(r'C:\Users\LG\Desktop\데이터시각화\data')

passengers = pd.read_csv('./AirPassengers.csv', header=0)
passengers.Month = pd.to_datetime(passengers.Month, format = '%Y-%m')
passengers.columns
passengers['cumsum'] = passengers.Passengers.cumsum() / 50 # 50명 단위로 누적 탑승객 수

fig = px.line(passengers,
              x = 'Month', y = 'Passengers')
fig.show()

 

 

passengers_melt = passengers.melt(id_vars = 'Month')

fig = px.line(passengers_melt,
              x = 'Month', y = 'value',
              color = 'variable',
              labels = {'variable' : 'Type', #variable이라는 label을 Type으로 바꿔라
                        'cumsum' : 'Passenger(fifty)'}) 
fig.show()

 

 

3D scatter plot

fig = px.scatter_3d(mtcars_dat,
                  x = 'wt', y = 'disp', z = 'mpg',
                  color = 'cyl',
                  symbol = 'cyl')
fig.show()

3D surface

3d surface는 일반적인 plotly.graph_objects 모듈을 사용해야한다.

graph_objects의 Figure 함수에 그래프를 그리기 위한 데이터와 layout을 입력하여 그래프를 생성한다.

입력하는 Figure 함수에 입력되는 데이터는 각 그래프 종류에 관한 클래스의 object가 입력되며 이때 그래프를 그리기 위한 데이터가 입력된다.

import plotly.graph_objects as go

volcano = sm.datasets.get_rdataset('volcano', 'datasets').data.copy()
x = np.arange(1, volcano.shape[0] + 1) #volcano의 행 개수
y = np.arange(1, volcano.shape[1] + 1) #volcano의 열 개수

obj = go.Surface(x=x, y=y, z=volcano.values)

fig = go.Figure(data = obj)
fig.show()

 

 

 

 

 

 

Comments