본문 바로가기

Programming/Data mining

5. Scatterplots, Line plots, Bar charts _ python

Coursera.org 에서 Michigan University의 Applied Data Science with Python의 강의를 토대로 정리한 내용입니다.

이번 포스팅에서는 기본적인 파이썬을 이용하여 기본적인 데이터들의 plot을 그려보도록 하려고 한다.
Scatter plot(산점도 분포 그래프), Line plot(선 그래프), Bar charts(막대 그래프)에 대해서 순서대로 알아보자.

1. Scatter plot
산점도 분포 그래프를 그릴 때 plt.plot과 차이점은 plt.plot 기본적으로 line plot의 object를 가지게 된다. 따라서 scatter라는 명명이 필요하다.
이제부터 plot을 그릴 때는 numpy의 array를 적극적으로 활용하도록 하겠다.
먼저 (1,1)부터 (8,8)까지의 scatter plot을 그려보자.

import numpy as np

x = np.array([1,2,3,4,5,6,7,8])
y = x

plt.figure()
plt.scatter(x, y) # similar to plt.plot(x, y, '.'), but the underlying child objects in the axes are not Line2D

#여기서 우리는 마지막 (8,8)의 좌표만 빨간색으로 바꿔볼 수도 있다.

# create a list of colors for each point to have
# ['green', 'green', 'green', 'green', 'green', 'green', 'green', 'red']
colors = ['green']*(len(x)-1)
colors.append('red')

plt.figure()

# plot the point with size 100 and chosen colors
plt.scatter(x, y, s=100, c=colors)

 

여기서 한가지 유용한 함수를 소개하자면 바로 zip이다.
zip은 두 array의 값들을 하나씩 취하여 좌표를 만들 수 있다. 예를 들면 x좌표의 리스트와 y좌표의 리스트를 zip시키면 (x,y) 의 좌표 리스트가 완성된다.
이는 좌표리스트를 unzip하는데도 이용 가능하다. 예제를 바로 살펴보자

# convert the two lists into a list of pairwise tuples
zip_generator = zip([1,2,3,4,5], [6,7,8,9,10])

print(list(zip_generator))
# the above prints:
# [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]

zip_generator = zip([1,2,3,4,5], [6,7,8,9,10])
# The single star * unpacks a collection into positional arguments
print(*zip_generator)
# the above prints:
# (1, 6) (2, 7) (3, 8) (4, 9) (5, 10)

# use zip to convert 5 tuples with 2 elements each to 2 tuples with 5 elements each
print(list(zip((1, 6), (2, 7), (3, 8), (4, 9), (5, 10))))
# the above prints:
# [(1, 2, 3, 4, 5), (6, 7, 8, 9, 10)]


zip_generator = zip([1,2,3,4,5], [6,7,8,9,10])
# let's turn the data back into 2 lists
x, y = zip(*zip_generator) # This is like calling zip((1, 6), (2, 7), (3, 8), (4, 9), (5, 10))
print(x)
print(y)
# the above prints:
# (1, 2, 3, 4, 5)
# (6, 7, 8, 9, 10)

 

xlabel, ylabel, 주석, 그래프 제목도 다음과 같이 설정이 가능하다.

plt.figure()
# plot a data series 'Tall students' in red using the first two elements of x and y
plt.scatter(x[:2], y[:2], s=100, c='red', label='Tall students')
# plot a second data series 'Short students' in blue using the last three elements of x and y 
plt.scatter(x[2:], y[2:], s=100, c='blue', label='Short students')
# add a label to the x axis
plt.xlabel('The number of times the child kicked a ball')
# add a label to the y axis
plt.ylabel('The grade of the student')
# add a title
plt.title('Relationship between ball kicking and grades')
# add a legend (uses the labels from plt.scatter)
plt.legend()
# add the legend to loc=4 (the lower right hand corner), also gets rid of the frame and adds a title
plt.legend(loc=4, frameon=False, title='Legend')

 

2. Line plot
이번엔 일차함수와 이차함수를 비교하는 선 그래프를 그려보도록 하자.
앞서 말했듯이 바로 plot 함수를 이용하면 된다.

import numpy as np

linear_data = np.array([1,2,3,4,5,6,7,8])
exponential_data = linear_data**2

plt.figure()
# plot the linear data and the exponential data
plt.plot(linear_data, '-o', exponential_data, '-o')

#아래의 코드를 활용하여 두 함수 사이의 간격을 파란색으로 칠할 수도 있다. alpha는 투명도를 의미한다.
# fill the area between the linear data and exponential data
plt.gca().fill_between(range(len(linear_data)), 
                       linear_data, exponential_data, 
                       facecolor='blue', 
                       alpha=0.25)
                       
#만약 x축의 좌표로 날짜를 설정하고 싶을 때는 pandas의 to_datetime 함수를 활용해 다음과 같이 설정한다.

import pandas as pd

plt.figure()
observation_dates = np.arange('2017-01-01', '2017-01-09', dtype='datetime64[D]')
observation_dates = list(map(pd.to_datetime, observation_dates)) # trying to plot a map will result in an error
plt.plot(observation_dates, linear_data, '-o',  observation_dates, exponential_data, '-o')

# rotate the tick labels for the x axis
for item in x.get_ticklabels():
    item.set_rotation(45)
    
# adjust the subplot so the text doesn't run off the image
plt.subplots_adjust(bottom=0.25)

 

3. Bar Charts
막대그래프를 그리는 것은 matplotlib에서 꽤나 귀찮은 일입니다.

plt.figure()
xvals = range(len(linear_data))
plt.bar(xvals, linear_data, width = 0.3)

new_xvals = []

# plot another set of bars, adjusting the new xvals to make up for the first set of bars plotted
for item in xvals:
    new_xvals.append(item+0.3)

plt.bar(new_xvals, exponential_data, width = 0.3 ,color='red')

#다음과 같이 error의 정도도 표현할 수 있다.

from random import randint
linear_err = [randint(0,15) for x in range(len(linear_data))] 

# This will plot a new set of bars with errorbars using the list of random error values
plt.bar(xvals, linear_data, width = 0.3, yerr=linear_err)

#다음과 같이 다른 차트 위에 쌓을 수도 있다.

plt.bar(xvals, exponential_data, width = 0.3, bottom=linear_data, color='r')

#다음과 같이 가로차트로 만들 수도 있다.

# or use barh for horizontal bar charts
plt.figure()
xvals = range(len(linear_data))
plt.barh(xvals, linear_data, height = 0.3, color='b')
plt.barh(xvals, exponential_data, height = 0.3, left=linear_data, color='r')