달나라 노트

Python matplotlib : xscale, yscale, set_xscale, set_yscale (x축 scale 조절, y축 scale 조절, log scale, subplot log scale) 본문

Python/Python matplotlib

Python matplotlib : xscale, yscale, set_xscale, set_yscale (x축 scale 조절, y축 scale 조절, log scale, subplot log scale)

CosmosProject 2024. 2. 24. 16:59
728x90
반응형

 

 

 

데이터 분석을 하다보면 시각화는 꽤 중요한 부분 중 하나입니다.

 

근데 간혹 x축 값과 y축 값이 너무 커지게 되면 값들을 좌표평면 상에 나타낸다고 해도 그 경향성을 시각화하기가 어려울 수 있습니다.

 

예를들어 y = 1500 / x 라는 함수를 만족하는 값들을 가지고 있고, 이 값들을 그래프로 나타내본다고 해봅시다.

 

 

 

import matplotlib.pyplot as plt
import numpy as np


list_x = np.linspace(0, 2000, 10000)
list_y = []

for x in list_x:
    val_result = 1500 / x

    list_y.append(val_result)


plt.plot(list_x, list_y,
         color='gray')

plt.show()

 

 

matplotlib를 이용해 y = 1500 / x 그래프를 x = 0 ~ 2000 구간에서 그리면 위와 같습니다.

 

위 그래프는 올바른 그래프입니다. 또한 우리는 이미 유리함수가 어떻게 생겼는지 알고 있기 때문에 굳이 그래프를 그리지 않아도 y = 1500 / x가 어떤 모양일지 짐작은 가죠.

 

근데 위 그래프를 보면 별로 시각화라는 의미와는 좀 다른 것 같습니다.

왜냐면 x축 범위가 너무 넓고 그에 따른 y값 또한 너무 커서 정말 너무 큰 규모의 경향성만 보일 뿐 좀 더 작은 단위의 경향성은 보이지 않습니다.

 

이것은 매우 당연한 현상입니다.

x값의 범위가 0~2000이며, y = 1500 / x 함수에서 x가 0에 가까운 값일수록 y값은 거의 무한대로 커지니까요.

또한 x값이 커지면 커질수록 y = 1500 / x 함수의 y값도 0에 수렴하므로 그 차이가 매우 적어질겁니다.

즉, 위처럼 그래프가 그려지는 것은 정상이라는거죠.

 

 

 

뭔가 위 이미지처럼 흔히 알고 있는 곡선의 곡률이라던지 이런 변화를 좀 더 눈에 띄게 보고싶은데 그럴 수가 없죠.

 

 

 

위 그래프에서 x축의 값을 좀 더 압축할 수 있으면, 즉, x축 눈금 사이의 간격을 똑같은 간격이 아니라 더 압축시켜서 나타낼 수 있으면 뭔가 그 경향성이 더 잘 나타날 수 있을 것 같습니다.

 

 

 

 

이럴 때 사용할 수 있는 유용한 설정이 바로 xscale, yscale입니다.

 

아래 예시를 보시죠.

 

import matplotlib.pyplot as plt
import numpy as np


list_x = np.linspace(0, 2000, 10000)
list_y = []

for x in list_x:
    val_result = 1500 / x

    list_y.append(val_result)


plt.plot(list_x, list_y,
         color='gray')

plt.xscale('log')

plt.show()

 

plt.xscale('log')라는 부분을 추가했습니다.

이것은 x축의 scale을 log scale로 나타내겠다는 의미입니다.

 

그리고 그 결과를 봅시다.

보면 아까보다 그래프의 곡률이 훨씬 더 잘 보이는 그래프가 되었습니다.

그리고 x축에는 큰 눈금이 총 4개가 있고 각각 1, 10, 100, 1000이 되었습니다.

x축을 log scale로 설정했기 때문입니다.

 

 

 

이전 그래프를 보면 x축눈금 하나마다 0, 250, 500, ... 등으로 x축 값이 선형으로 증가하는 것을 볼 수 있습니다.

이것이 기본적인 그래프이며 보통 저희가 다룰 때 이렇게 하죠.

 

그러나 위 그래프를 보면 x축에 총 4개의 큰 눈금이 있고 그 값은 각각

1

10

100

1000

입니다.

 

log scale의 의미가 여기서 나오는데 위 x눈금 값에 log를 씌우면 아래와 같습니다.

 

0 = log1

1 = log10

2 = log100

3 = log1000

즉, log scale이란 각 x축 눈금의 값에 log를 씌우면 0, 1, 2, 3 같은 선형 log값이 되도록 나타내는 방식입니다.

물론 실제 의미하는 값은 log를 씌우기 전인 1, 10, 100, 1000이 되는것이구요.

 

이렇게되면 그래프 상에서 1, 10, 100, 1000 각각의 x축 눈금의 간격은 동일하게 보이더라도

실제 그 값의 차이는 점점 커지므로 x축의 값들이 마치 압축되어서 보이는 효과가 있습니다.

(1 -> 10은 9 차이이지만 100 -> 1000 차이는 900이죠. 따라서 100 ~ 1000 구간에는 그래프 상에서 동일한 간격 안에 훨씬 더 많은 x축 값들이 압축되어있다고 보시면 됩니다.)

 

그니까 x값이 늘어날수록 x축 값이 압축되면서 그래프가 좌우로 늘어나는 것처럼 보이는 것이죠.

이를 이용해 우리는 그래프의 경향성을 더 잘 볼 수 있게 되는 것이구요.

 

 

 

 

xcale 말고 yscale도 존재합니다.

 

 

 

import matplotlib.pyplot as plt
import numpy as np


list_x = np.linspace(0, 2000, 10000)
list_y = []

for x in list_x:
    val_result = 1500 / x

    list_y.append(val_result)


plt.plot(list_x, list_y,
         color='gray')

plt.yscale('log')

plt.show()

 

yscale('log')로 지정하면 y축도 log scale로 나타낼 수 있습니다.

마찬가지로 원래 그래프보다 경향성이 잘 나타나는 것을 볼 수 있죠.

 

이렇듯 필요에 따라 xscale, yscale 중 어떤 것을 어떤 방식으로 지정할지 결정하면 됩니다.

 

 

 

 

 

 

scale 지정할 때 사용할 수 있는 키워드는 대표적으로 아래와 같습니다.

linear -> 우리가 기본적으로 사용하는 선형 scale입니다. matplotlib의 기본값입니다.

log -> log scale로 나타내줍니다. 다만 일반적인 log scale이기 때문에 양수만을 나타내주게 됩니다. (0 ~ +logX)

symlog -> 원점을 중심으로 음수, 양수가 대칭인 log scale을 나타내줍니다. (-logX ~ +logX)

logit -> 0~1 사이의 범위를 log scale로 나타내줍니다.

 

 

 

 

 

 

log scale은 subplot에도 적용할 수 있습니다.

다만 코드가 살짝 다릅니다.

 

import matplotlib.pyplot as plt
import numpy as np


list_x = np.linspace(0.1, 1000, 10000)
list_y = 1600 / list_x

fig, graph = plt.subplots(2, 2)

graph[0][0].plot(list_x, list_y)

graph[0][1].plot(list_x, list_y)
graph[0][1].set_xscale('log')

graph[1][0].plot(list_x, list_y)
graph[1][0].set_yscale('log')

graph[1][1].plot(list_x, list_y)
graph[1][1].set_xscale('log')
graph[1][1].set_yscale('log')


plt.show()

 

위 코드의 결과는 다음과 같습니다.

 

 

총 4개의 그래프가 있으며

왼쪽 위 그래프 = 원본 그래프

오른쪽 위 그래프 = x축만 log scale

왼쪽 아래 그래프 = y축만 log scale

오른쪽 아래 그래프 = x축, y축 모두 log scale

로 나타낸 것입니다.

 

 

 

 

 

 

 

 

 

 

 

 

import matplotlib.pyplot as plt
import numpy as np


list_x = np.linspace(-1000, 1000, 100000)
list_y = []

for x in list_x:
    val_result = 1500 / x

    list_y.append(val_result)


plt.plot(list_x, list_y,
         color='gray')

plt.xscale('linear')

plt.show()

 

y = 1500 / x 그래프를 그려보았습니다.

 

그래프가 마치 + 처럼 생겼지만 x축 스케일과 y값이 너무 커서 저렇게 보이는 것입니다.

 

 

 

 

 

import matplotlib.pyplot as plt
import numpy as np


list_x = np.linspace(-1000, 1000, 100000)
list_y = []

for x in list_x:
    val_result = 1500 / x

    list_y.append(val_result)


plt.plot(list_x, list_y,
         color='gray')

plt.xscale('symlog')

plt.show()

 

y = 1500 / x 그래프를 xscale = symlog로 설정했을 때의 그래프입니다.

우리가 흔히 보는 유리함수의 모습이 나타난 것을 볼 수 있습니다.

 

scale을 symlog로 설정했더니 -1000, -100, -10, -1의 음수 영역까지 나오는 것을 볼 수 있습니다.

 

 

 

 

 

 

 

 

import matplotlib.pyplot as plt
import numpy as np


list_x = np.linspace(-1000, 1000, 100000)
list_y = []

for x in list_x:
    val_result = x ** 3

    list_y.append(val_result)


plt.plot(list_x, list_y,
         color='gray')

plt.xscale('log')

plt.show()

 

이번엔 y = x ^ 3 그래프입니다.

 

그래프가 x > 0인 부분에 대해서만 나타내지는 것을 볼 수 있습니다.

xscale = log로 지정했기 때문에 x가 양수인 부분만 log scale로 나타내어진 것입니다.

 

 

 

 

import matplotlib.pyplot as plt
import numpy as np


list_x = np.linspace(-1000, 1000, 100000)
list_y = []

for x in list_x:
    val_result = x ** 3

    list_y.append(val_result)


plt.plot(list_x, list_y,
         color='gray')

plt.xscale('symlog')

plt.show()

 

이번에는 xscale = symlog로 설정한 결과입니다.

x축 값이 0을 기준으로 음수값, 양수값이 모두 나타내어져 y = x ^ 3 그래프가 그려진 것을 알 수 있습니다.

 

 

 

 

 

 

- 참고

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.xscale.html

 

 

 

 

 

 

728x90
반응형
Comments