데이터의 시각화는 데이터를 관찰하는 과정에서 선택 사항이 아니라 반드시 거쳐야 하는 필수 과정이다.
추가 옵션을 이용해 마커(Marker)의 색상이나 모양을 서로 다르게 지정하여 구분할 수 있다.
시각화는 데이터를 올바로 해석할 수 있게 해주는 동시에 ,많은 양의 데이터를 효과적으로 관찰할 수 있게 해주는 역할을 한다.
최근의 데이터 과학은 신뢰도를 높이기 위해 점점 더 많은 데이터를 다루면서 복잡도도 더욱 높아졌다.
시각화의 효과
직관(insight)을 얻을 수 있다.
핵심을 명확하게 이해할 수 잇다.
평균적인 경향과 더불어 이상값 outlier도 발견할 수 있다.
데이터에서 문제를 빨리 찾아낼 수 있다.
원데이터의 속성들을 가능한 그대로 사용하여 모든 샘플들을 그래프에 표시하되 대륙 혹은 국가에 따라 구별된 마커를 사용해 gdpPercap, lifeExp, pop 항목의 범위와 특징, 상대적인 차이, 대략의 상관관계도 확인 가능하다.
gdpPercap 값의 전체 범위에 비해 낮은 범위에 샘플들이 많이 몰려 있어 관찰이 쉽지 않은 경우에는 로그 스케일(log scale)을 이용해 샘플들을 고르게 관찰 가능하다.
시각화의 공통 목적은 데이터에 내재된 의미, 즉 변화.구성.분포.상관관계 등을 명확히 드러내는 것이다.
인간의 인지 능력에는 한게가 있기 때문에 데이터에 표함된 '모든 변수의 모든 변화를 한 번에 확인하는 거은 불가능하다.
따라서 데이터의 사각화는 반복적으로, 또 여러 관점에서 시도되어야 한다. 데이터를 바라보는 시각화 관점에 변화를 주면 데이터에 포함된 여러 가지 의미에 대한 통찰이 생긴다.
다양한 시각화 방법은 데이터 과학의 핵심 기술이다.
데이터 시각화는 체계적이고 논리적인 방식을 통해 데이터 값을 시각적 속성으로 변환한 다음, 최종 그래프를 만드는 과정으로 이루어진다.
모든 데이터 시각화는 데이터 값을 정량화 가능한 속성으로 나타내 그래픽으로 표현한 결과물이다.(시각적 속성)
데이터 값을 시각적 속성으로 나타내려면, 각 데이터 값을 어떤 시각적 속성과 연결할지 구체적으로 정해야 한다.
데이터 값을 시각적 요소로 전환 할 때 필요한 것이 스케일 즉 척도이다.
데이터와 스케일이 일대일로 대응하지 않으면 데이터 시각화의 결과가 모호해진다.
데이터를 시각화 할 때에는 항상 위치 스케일을 정의해야 한다. 위치 스케일은 그래프 안에서 데이터 값들의 위치를 결정한다.
위치 스케일을 모은 하나의 집합과 이 스케일들의 기하학적인 배열 관계를 좌표계라고 부른다.
데이터 시각화에서 가장 흔히 쓰이는 좌표계는 x값과 y값을 조합해 고유의 위치 값들을 명시하는 데카르트 좌표계(직교 좌표계)이다.
비선형 스케일에서는 데이터의 단위를 표시하는 간격이 일정하지만 그 단위를 의미하는 그래프 눈금 간격은 일정하지 않거나, 또는 그래프 눈금 간격은 일정하지만, 그 간격이 의미하는 데이터 단위는 일정하지 않다.
비선형 스케일은 로그 스케일이다.
로그 스케일은 곱셈을 통해 선형적으로 값이 변하기 때문에 눈금의 단위가 고정된 값의 배수에 대응한다.
극 좌표계는 워점으로부터의 거리와 방향을 통해 위치를 표시하기 때문에 축이 원형을 이룬다.
극좌표계는 특정 기간에 생성되는 데이터를 다룰 때 유용하다.
데이터 시각화에 색을 사용하는 경우는 첫째 데이터군을 서로 구분하기 위해, 둘째 데이터 값을 나타내기 위해, 셋째 데이터 값을 강조하기 위해서다.
색을 활용한 데이터 구분
색을 활용한 데이터 값 표현
소득, 기온, 속력 같은 정량적 데이터 값도 색으로 나타낼 수 있다. 이 경우에는 순차적 색상 스케일을 사용한다.
차적 색상 스케일은 색에 순서를 부여해서 값의 크기 차이, 특정한 두 값 사이의 거리를 명확하게 보여준다.
색을 활용한 강조
-색은 데이터와 특정 요소를 강조할 때 효과적인 요소다.
-데이터 셋에서 도표의 주제에 대한 핵심 정보를 담은 값이나 범주를 알아보기 쉽게 표현하면 도표를 통해 전하려는 메시지가 더 탄탄 해진다. 해당 값에 다른 값과 확실하게 구별되는 색을 부여하면 원하는 부분을 쉽게 갖오할 수 있다.
-이럴 때에는 은은한 색 모음, 은은한 색과 짝을 이루면서 더 강렬하고 선명한 색 모음이 함께 있는 강조 색상 스케일을 사용한다.
데이터 시각화 작업에서는 수치 집합의 크기를 나타내야 할 때가 많다. 예를 들면 자동차 브랜드별 총 판매량, 도시별 총 거주 인구 등이 있다.
이 경우에는 막대 도표나 점도표와 히트맵을 사용할 수 있다.
데이터 중에는 범주형 변수 두가지를 동시에 다루는 경우도 있다. 이런 데이터는 묶은 막대도표로 나타낼 수 있다.
누적 막대 도표는 막대를 쌓아서 도출한 합계 값이 그 자체로 의미 있는 정보일 때 유용하다.
점 도표와 히트맵
데이터 셋 안에서 특정 변수가 어떻게 분포되어 있는 파악해야 하는 경우 아래의 그래프로 시각화 할 수 있다.
단일 분포 상태의 시각화
스토그램은 단일 분포 상태를 표현할 때 사용한다.
연속적인 곡선으로 데이터의 내재된 확률 분포를 나타내는 것을 밀도 도표라고 한다. 이 곡선은 데이터를 바탕으로 추산해야 하므로 커널 밀도 추정을 사용한다.
여러 분포 상태의 시각화
둘 이상의 변수에 따른 데이터의 여러 분포 상태를 경우에는 누적 히스토그램을 사용할 수 있다.
누적 히스토그램 방식은 막대의 시작위치가 정확하게 파악하기 힘들다는 단점을 가지고 있다.
이럴 때는 중첩 밀도 도표를 이용하여 위와 같은 문제를 피할 수 있다.
여러 분포 상태의 결합 시각화
여러 의 분포 상태를 다룰 때에는 항상 반응 변수와 하나 이상의 그룹화 변수를 고려해야 한다.
반응 변수는 우리가 도표를 통해 분포 상태를 보여주려고 하는 변수이고, 그룹화 변수는 반응 변수의 분포가 뚜렷이 구분되는 데이터의 부분 집합을 정의하는 변수이다.
여러 분포 상태의 결합시각화
어떤 집단, 조직체, 수량이 개개의 조각으로 나뉘었을 때 전체에서 차지하는 비율을 표현할 때 아래와 같은 그래프를 이용할 수 있다.
시각화 작업은 데이터 분석에서 무척 중요한 부분 중에 하나이다.
matplotlib는 matlab과 유사한 인터페이스를 지원하기 위해 만들어진 파이썬패키지이다.
Matplotlib는 다양한 GUI 백엔드를 지원하고 있으며 pdf, svg, jpg, png, gmp, gif 등 일반적으로 널리 사용되는 포맷으로 도표를 저장할 수 있다.
가장 간단한 플롯은 선을 그리는 라인플롯(line plot)이다. 라인 플롯은 데이터가 시간, 순서 등에 따라 어떻게 변화하는지 보여주기 위해 사용한다.
명령은 pyplot, pylab 서브패키지의 Plot 명령을 사용한다.
데이터가 1,4,19,15 으로 변화하였따면 다음과 같이 plot 명령에 데이터 리스트 혹인 ndarray객체를 넘긴다.
import matplotlib.pyplot as plt
plt.title('pltEx1')
plt.plot([1,4,19,15])
plt.show()

import matplotlib.pyplot as plt
plt.title('pltEx1')
plt.plot([10,20,30,40],[1,4,19,15])
plt.show()

플롯 명령어는 보는 사람이 그림을 더 알아보기 쉽게 하기 위해 다양한 스타일(style)을 지원한다. plot 명령어에서는 다음과 같이 추가 문자열 인수를 사용하여 스타일을 지원한다.
plt.title("'rs--'스타일의 plot')
plt.plot([10,20,30,40],[1,4,9,16],'rs--')
plt.show()
import matplotlib.pyplot as plt
x = range(100)
y = [x**2 for x in x]
plt.plot(x,y)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,2*np.pi,100)
y = np.sin(x)
plt.plot(x,y)
plt.show()

색깔을 지정하는 방법은 색 이름 혹은 약자를 사용하거나 # 문자로 시작되는 RGB 코드를 사용한다.
색상표 사이트 : https://matplotlib.org/stable/gallery/color/named_colors.html
Blue : b
Green : g
Red : r
Cyan : c
Magenta : m
Yellow : y
Black : k
white : w
import matplotlib.pyplot as plt
plt.plot([10,20,30,40],[1,3,12,17],'rs--')
plt.show()

데이터 위치를 나타내는 기호를 마커(marker)라고 한다. 마커의 종류는 다음과 같다.
. : Point marker
, : Pixel marker
o : Circle marker
v : Triangle_down marker
^ : Triangle up marker
< : Triangle left marker
> : Triangle right marker
s : Square marker
P : Pentagon marker
* : Star marker
h : Hexagon marker
+ : Plus marker
x : X marker
선 스타일에는 실선(solid), 대시선(dashed), 점선(dotted), 대시-점선(dash-dit)이 있다. 지정 문자열은 다음과 같다.
- : 실선스타일
-- : 대시선(dashed) 스타일
-. : 대시 점선 스타일
: : 점선 스타일
라인 플롯에서는 앞서 설명한 세 가지 스타일 이외에도 여러 가지 스타일을 지정할 수 있지만 이 경우에는 인수 이름을 정확하게 지정해야 한다.
color : c (선 색깔)
lienwidth : lw (선 굵기)
linestyle : ls (선 스타일)
marker : marker (마커 종류)
markersize : ms (마커 크기)
markeredgecolor : mec(마커 선 색깔)
markeredgewidth : mew(마커 선 굵기)
markerfacecolor : mfc(마커 내부 색깔)
import matplotlib.pyplot as plt
import numpy as np
plt.plot([10,20,30,40],[4,2,9,12],
color='orange',lw=5, ls='--',marker='d',ms=12,mec='green',mew=5,mfc='red')
plt.show()

import matplotlib.pyplot as plt
import numpy as np
x = range(5)
y = [2,5,7,8,3]
plt.plot(x,y,'o-')
x2 = [2]
y2 = [7]
plt.plot(x2,y2,'rs')
plt.show()

플롯 그림을 보면 몇몇 점들은 그림의 범위 경계선에 있어서 잘 보이지 않는 경우가 있을 수 있다. 그림의 범위를 수동으로 지정하려면 xlim 명령과 ylim 명령을 사용한다.
import matplotlib.pyplot as plt
import numpy as np
plt.plot([10,20,30,40],[4,2,9,12],
color='k',lw=5, ls='--',marker='^',ms=12,mec='b',mew=5,mfc='white')
plt.xlim(0,50)
plt.ylim(-10,30)
plt.show()

플롯이나 차트에서 축상의 위치 표시 지점을 틱(tick)이라고 하고 이 틱에 써진 숫자 혹은 글자를 틱 라벨(tick label)이라고 한다. 틱의 위치나 틱 라벨은 Matplotlib가 자동으로 정해주지만 만약 수동으로 설정하고 싶다면 xticks 명령이나 yticks 명령을 사용한다.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-np.pi, np.pi,256)
y = np.cos(x)
plt.plot(x,y)
plt.xticks([-np.pi,-np.pi/2,0,np.pi/2,np.pi],
['-pi','-pi/2','0','pi/2','pi'])
plt.yticks([-1,0,1],
['low',0,'high'])
plt.grid(True)
plt.show()

라인 플로셍서 선을 하나가 아니라 여러개를 그리고 싶은 경우에는 x 데이터, y데이터, 스타일 문자열을 반복하여 인수로 넘긴다. 이 경우에는 하나의 선을 그릴 때 처럼 x 데이터나 스타일 문자열을 생략할 수 없다.
import matplotlib.pyplot as plt
import numpy as np
data = np.arange(0,5,0.2)
plt.plot(data, data,'b--', data, 0.1*data**2, 'go:', data, 0.1*data**3, 'rs-')
plt.show()

import matplotlib.pyplot as plt
import numpy as np
plt.plot([10,20,30,40],[4,2,9,12],
color='k',lw=5, ls='--',marker='^',ms=12,mec='y',mew=5,mfc='blue')
plt.plot([10,20,30,40],[22,7,15,2],
color='red',lw=5, ls='--',marker='^',ms=12,mec='b',mew=5,mfc='yellow')
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
my_score = [(50,90,95),(60,75,100),(75,85,90),(85,75,90),(95,80,85),(90,85,88),(95,80,75)]
df = pd.DataFrame(my_score, columns=['kor','math','eng'])
print(df)
df.plot(kind='line')
plt.show()
kor math eng
0 50 90 95
1 60 75 100
2 75 85 90
3 85 75 90
4 95 80 85
5 90 85 88
6 95 80 75

여러개의 라인 플롯을 동시에 그리는 경우에는 각 선이 무슨 자료를 표시 하는지를 보여주기 위해 legend 명령으로 범례(legend)를 추가할 수 있다. 범례의 위치는 자동으로 정해지지만 수동으로 설정하고 싶으면 loc 인수를 사용한다.
best : 0
upper right : 1
upper left : 2
lower left : 3
lower right : 4
rigth : 5
center left : 6
center right : 7
lower center : 8
upper center : 9
center : 10
import matplotlib.pyplot as plt
import numpy as np
x= np.linspace(-np.pi,np.pi,256)
y1,y2 = np.cos(x), np.sin(x)
plt.plot(x,y1, ls='--',label='cosine')
plt.plot(x,y2, ls=':', label='sine')
plt.legend(loc=1)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
x= np.linspace(-np.pi,np.pi,256)
y1,y2 = np.cos(x), np.sin(x)
# plt.plot(x,y1, ls='--',label='cosine')
# plt.plot(x,y2, ls=':', label='sine')
plt.plot(x,y1, ls='--')
plt.plot(x,y2, ls=':')
plt.xlabel('x axis')
plt.ylabel('result')
plt.legend(['cosine','sine'],loc='best',fontsize=14)
plt.show()

import matplotlib.pyplot as plt
plt.plot([2,3,5,7],label='value1')
plt.plot([8,1,7,3],label='value2')
plt.plot([5,6,9,5],label='value3')
plt.plot([7,5,8,4],label='value4')
plt.legend(loc=2, ncol=3)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
def plot_slope(x,y):
xs = x[1:] - x[:-1]
ys = y[1:] - y[:-1]
plt.plot(x[1:],ys/xs)
x = np.linspace(-3,3,100)
y = np.exp(-x**2)
plt.plot(x,y)
plot_slope(x,y)
plt.show()

Matplotlib 가 그리는 그림은 Figure 객체, Axes 객체, Axis 객체 등으로 구성된다. Figure 객체는 한 개 이상의 Axes 객체를 포함하고 Axes 객체는 다시 두 개 이상의 Axis 객체를 포함한다.
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('sample.txt')
print(data)
print(type(data))
print()
# plt.plot(data[:,0],data[:,1])
# plt.plot(data)
# plt.show()
for column in data.T:
plt.plot(data[:,0], column)
plt.show()

모든 그림은 Figure 객체. 정식으로는 Matplotlib.figure.Figure 클래스 객체에 포함되어 있다. 내부 플롯(inline plot)이 아닌 경우에는 하나의 Figure는 하나의 아이디 숫자와 윈도우(window)를 가진다.
하나의 Figure당 하나의 윈도우를 별도로 가진다.
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(10,2))
plt.title('figure size = (10, 2)', fontsize=14)
plt.plot(np.random.randn(200))
plt.show()

때로는 하나의 윈도우(Figure) 안에 여러 개의 플롯을 배열 형태로 보여야하는 경우도 있다. Figure 안에 있는 각각의 플롯은 Axes 라고 불리는 객체에 속한다. 하나의 Figure 당 하나의 윈도우를 별도로 가진다.
Figure 안에 Axes를 생성하려면 원래 subplot 명령을 사용하여 명시적으로 Axes 객체를 얻어야 한다. 그러나 plot 명령을 바로 사용해도 자동으로 Axes를 생성해 준다.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 3,50)
y1 = np.cos(3 * np.pi * x) * np.exp(-2*x)
y2 = np.cos(3 * np.pi * x)
plt.subplot(2,1,1)
plt.plot(x,y1,'yo-')
plt.title('multi graph')
plt.xlabel('x1')
plt.ylabel('result')
plt.subplot(2,1,2)
plt.plot(x,y2,'r-.')
plt.xlabel('time')
plt.ylabel('result2')
# plt.tight_layout()
plt.subplots_adjust(hspace=0.7)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
plt.subplot(221)
plt.title('axes1')
plt.plot(np.random.randn(50))
plt.subplot(222)
plt.title('axes2')
plt.plot(np.random.randn(50))
plt.subplot(223)
plt.title('axes3')
plt.plot(np.random.randn(50))
plt.subplot(224)
plt.title('axes4')
plt.plot(np.random.randn(50))
plt.tight_layout()
plt.suptitle(f'mutli view', fontsize=16)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-4,4,1024)
y = 0.25 * (x*4) * (x+1) * (x-2)
plt.text(-0.5, 1.25, 'black text mark', fontsize=12)
plt.plot(x,y,c='k')
plt.show()

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-4,4,1024)
y = 0.25 * (x*4) * (x+1) * (x-2)
box = {
'facecolor':'g',
'alpha': 0.5,
'edgecolor':'k',
'boxstyle':'square'
}
plt.text(-0.5,1.25,'black text mark', bbox=box, fontsize=12)
plt.plot(x,y,c='k')
plt.show()

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-4,4,1024)
y = 0.25 * (x * 4) * (x + 1) * (x - 2)
plt.annotate('annotate text!!!!!',
ha='left', va='bottom',
xytext=(-1.5,20),
xy=(1.75,-2.8 ),
arrowprops={'facecolor':'r','shrink':0.1})
plt.plot(x,y,c='k')
plt.show()

import matplotlib.pyplot as plt
import numpy as np
align_list = ['center', 'left', 'right']
ax1 = plt.gca()
ax1.axes.get_xaxis().set_visible(False)
ax1.axes.get_yaxis().set_visible(False)
for i, align in enumerate(align_list):
plt.text(0,i,f'align={align}',ha=align, fontsize=14)
plt.plot([0,0],[-1,len(align_list)],c='#808080', ls='--')
plt.scatter([0] * len(align_list), range(len(align_list)))
plt.show()

import matplotlib.pyplot as plt
import numpy as np
arrow_style_list = ['<->','<-','->','wedge','fancy','simple']
plt.scatter([0] * len(arrow_style_list),range(len(arrow_style_list)), c='k')
for i , arrow_style in enumerate(arrow_style_list):
plt.annotate('arrowstyle=%s'%arrow_style,
ha='left',va='center',
xytext=(0.75, i+0.5),
xy=(0.025,i),
arrowprops={'arrowstyle':arrow_style, 'facecolor':'k'})
plt.xlim(-0.5,2)
plt.ylim(-0.5,6.5)
plt.show()

import numpy as np
import matplotlib.pyplot as plt
shape = plt.Circle((0,0),radius=1,color='#00ff00')
plt.gca().add_patch(shape)
# plt.xlim(-1,1)
# plt.ylim(-1,1)
plt.axis('scaled')
plt.show()

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
shape = patches.Circle((0,0),radius=1,color='0.2')
plt.gca().add_patch(shape)
shape2 = patches.Rectangle((2.5,-0.5),2,1,color='0.5')
plt.gca().add_patch(shape2)
shape3 = patches.Ellipse((0,-2),2,1,angle=45,color='0.7')
plt.gca().add_patch(shape3)
plt.axis('scaled')
plt.grid()
plt.show()

import matplotlib.pyplot as plt
N=16
for i in range(N):
plt.gca().add_line(plt.Line2D((0, i), (N-i, 0), color='r'))
plt.axis('scaled')
plt.grid()
plt.show()

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
point = np.array([[1,1],[3,0],[8,3],[5,5],[1,1]])
shape = patches.Polygon(point, lw=3, edgecolor='k',ls='--',facecolor='r')
plt.gca().add_patch(shape)
plt.axis('scaled')
plt.grid()
plt.show()

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker
x = np.linspace(-15,15,1024)
y = np.sinc(x)
# ax = plt.gca()
ax = plt.axes()
ax.xaxis.set_major_locator(ticker.MultipleLocator(5))
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1))
plt.plot(x,y,c='k')
plt.show()

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker
ax = plt.gca()
def make_label(value, pos):
return f'{100 * value:.1f}%'
ax.xaxis.set_major_formatter(ticker.FuncFormatter(make_label))
x = np.linspace(0,1,256)
plt.plot(x,np.exp(-10 * x), c='k')
plt.show()

막대 그래프는 범주형 데이터의 수치를 요약한다.
일반적으로 가로, 세로, 누적, 그룹화된 막대 그래프 등을 사용한다.
import matplotlib.pyplot as plt
import numpy as np
plt.rc('font',family='Malgun Gothic')
customer = ['김길동','홍길동','최길동','이길동','오길동']
customer_index = range(len(customer))
y_data = [130,90,200,110,230]
fig =plt.figure(figsize=(6,4))
ax1 = fig.add_subplot(111)
ax1.bar(customer_index, y_data, color='darkblue')
plt.xticks(customer_index, customer)
plt.xlabel('고객 이름')
plt.ylabel('수요')
plt.show()

import matplotlib.pyplot as plt
women_pop = [5,30,45,22]
men_pop = [-5,-25,-50,-20]
x = range(4)
plt.barh(x,women_pop,color='0.25')
plt.barh(x,men_pop,color='0.75')
plt.show()

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv',encoding='utf-8',index_col='국가')
print(data['4월06일'])
chartdata = data['4월06일']
def makeBarchart1(x,y,color,xlabel,ylabel,title):
plt.figure(figsize=(8,6))
plt.bar(x,y,color=color,alpha=0.7)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.title(title, fontsize=16)
YTICK_INTERVAL = 50000
maxlim = (int(y.max() / YTICK_INTERVAL)+1) * YTICK_INTERVAL
values = np.arange(0,maxlim +1, YTICK_INTERVAL)
plt.yticks(values,['%s'%format(val,',') for val in values])
ratio = 100 * y / y.sum()
for idx in range(y.size):
value = format(y[idx],',') + '건'
ratioval = f'{ratio[idx]:.1f}%'
plt.text(x=idx, y=y[idx] + 2000, s=value, ha='center', fontsize=9)
plt.text(x=idx, y=y[idx] / 2, s=ratioval, ha='center', fontsize=9)
meanval = y.mean()
meantext = f'평균:{int(meanval)}건'
plt.axhline(y=meanval, color='r', linewidth=1, linestyle='--')
plt.text(x=y.size-1,y=meanval+3000, s=meantext, ha='center', fontsize=11)
plt.show()
colors = ['b','g','r','c','m','y','k']
makeBarchart1(x=chartdata.index, y=chartdata,color=colors,xlabel='국가명',ylabel='발생 수'
,title='국가별 코로나 발생 수(4월6일)')

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
datachart = data.loc[['프랑스','중국','영국','이란'],'4월06일':'4월08일']
def makeBarChart2(chartdata, rotation, title, ylim=None, stacked=False, yticks_interval=10000):
plt.figure(figsize=(8,6))
chartdata.plot(kind='bar', rot=rotation, legend=True, stacked=stacked)
if stacked == False:
maxlim = (int(max(chartdata.max())/yticks_interval)+1) * yticks_interval
else:
maxlim = (int(max(chartdata.sum(axis=1))/yticks_interval)+1)*yticks_interval
values = np.arange(0, maxlim+1, yticks_interval)
plt.yticks(values,['%s'%format(val,',') for val in values])
if ylim != None:
plt.ylim(ylim)
plt.show()
makeBarChart2(datachart, rotation=0, title='국가별 일별 발생 수')

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
datachart = data.loc[['프랑스','중국','영국','이란'],'4월06일':'4월08일']
def makeBarChart2(chartdata, rotation, title, ylim=None, stacked=False, yticks_interval=10000):
plt.figure(figsize=(8,6))
chartdata.plot(kind='bar', rot=rotation, legend=True, stacked=stacked)
if stacked == False:
maxlim = (int(max(chartdata.max())/yticks_interval)+1) * yticks_interval
else:
maxlim = (int(max(chartdata.sum(axis=1))/yticks_interval)+1)*yticks_interval
values = np.arange(0, maxlim+1, yticks_interval)
plt.yticks(values,['%s'%format(val,',') for val in values])
if ylim != None:
plt.ylim(ylim)
plt.show()
#makeBarChart2(datachart, rotation=0, title='국가별 일별 발생 수')
makeBarChart2(datachart, rotation=0, stacked=True, title='국가별 일별 발생 수', yticks_interval=50000)

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
datachart = data.loc[['미국']].T
# print(datachart)
fig, axes = plt.subplots(nrows=2,ncols=1,figsize=(8,6))
datachart.plot(kind='bar', ax=axes[0], rot=0, alpha=0.7)
datachart.plot(kind='barh', ax=axes[1], color='m', alpha=0.7)
fig.suptitle('서브 플로팅',fontsize=16)
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
datachart = data.loc[['프랑스','영국','중국']]
column_names = datachart.columns.tolist()
print(column_names)
chartdata = {}
for row in datachart.index:
chartdata[row] = data.loc[row].values
print(chartdata)
labels = list(chartdata.keys())
data = np.array(list(chartdata.values()))
category_colors = plt.get_cmap('RdYlGn')(np.linspace(0.15,0.85, data.shape[1]))
print(category_colors)
fig, ax = plt.subplots(figsize=(9,5))
ax.set_xlim(0,np.sum(data, axis=1).max())
ax.xaxis.set_visible(False)
data_sum = data.cumsum(axis=1)
print(data_sum)
for i, (columnname, color) in enumerate(zip(column_names,category_colors)):
widths = data[:,i]
start = data_sum[:,i] - widths
ax.barh(labels,widths,left=start, height=0.5, label=columnname,color=color)
r,g,b,_=color
text_color = 'white' if r*g*b < 0.5 else 'darkgrey'
xcenters = start + widths / 2
for y,(x,c) in enumerate(zip(xcenters, widths)):
ax.text(x,y,str(int(c)), ha='center',color=text_color)
# ax.legend(ncols=len(column_names),loc=(0,1))
ax.legend(ncols=len(column_names),bbox_to_anchor = (0, 1), loc=3)
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
datachart = data.loc[['스페인','프랑스','중국','영국','이란'], '4월06일':'4월10일']
rows = [x for x in datachart.index]
columns = [x for x in datachart.columns]
print(rows)
print(columns)
LEFT_MARGIN = 0.3
bar_width = 1 - 2 * LEFT_MARGIN
index = np.arange(len(columns)) + LEFT_MARGIN
y_offset = np.zeros(len(columns))
plt.figure(figsize=(6,6))
cell_text = []
for row in datachart.index:
chartdata = datachart.loc[row].tolist()
plt.bar(index, chartdata, bar_width, bottom=y_offset, label=row)
y_offset += chartdata
cell_text.append([format(x,',')for x in chartdata])
plt.legend(loc='best')
cell_text.reverse()
rows = [rows[idx] for idx in range(len(rows)-1, -1, -1)]
plt.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom')
plt.xticks([])
plt.tight_layout()
plt.title('테이블 데이터 & 막대 그래프')
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
chartdata = data.loc[['독일','프랑스','중국','영국'],'4월06일' ]
mylabel = chartdata.index
mycolors = ['blue','#6aff00','yellow','#ff113c']
plt.figure(figsize=(5,5))
plt.pie(chartdata,
labels=mylabel,
startangle=90,
colors=mycolors,
autopct='%.2f%%',
counterclock=False,
explode=(0,0.1,0,0),
shadow=True)
plt.legend(loc='best')
plt.xlabel('국가명')
plt.title('주요 국가 코로나 발생 비율(4월 6일)')
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
chartdata = data.loc[['독일','프랑스','중국','영국'],'4월06일' ]
fig, ax = plt.subplots(figsize=(8,4))
mylabel = chartdata.index
def getlabelFormat(pct, allvals):
absolute = int(pct / 100 * np.sum(allvals))
return f'{pct:.2f}%\n({absolute}명)'
wedges,texts,autotexts = ax.pie(chartdata,
autopct=lambda pct:getlabelFormat(pct,chartdata),
textprops=dict(color='grey'),
labels=mylabel)
plt.setp(autotexts, size=10, weight='bold')
plt.legend(title='국가명', loc='best')
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
chartdata = data.loc[['독일','프랑스','중국','영국','이탈리아'],['4월06일','4월07일']]
chartdata = chartdata.values
color_su = 5
cmap = plt.get_cmap('tab20c')
outer_colors = cmap(np.arange(color_su)*4)
inner_colors = cmap(np.arange(color_su*2))
INNER_VACANT_CIRCLE_SIZE = 0.3
OUTER_PCTDISTANCE = 0.85
INNER_PCTDISTANCE = 0.75
cum_sum = chartdata.sum(axis=1)
fig, ax = plt.subplots(figsize=(6,6))
ax.pie(cum_sum, radius=1, colors=outer_colors,
labels=['독일','프랑스','중국','영국','이탈리아'],
autopct='%.2f%%',
pctdistance=OUTER_PCTDISTANCE,
wedgeprops=dict(width=INNER_VACANT_CIRCLE_SIZE, edgecolor='w'))
ax.pie(chartdata.flatten(),radius=1 - INNER_VACANT_CIRCLE_SIZE, colors=inner_colors,
wedgeprops=dict(width=INNER_VACANT_CIRCLE_SIZE, edgecolor='w'),
autopct='%.2f%%',
pctdistance=INNER_PCTDISTANCE)
ax.set_title('주요 국가별 중첩 파이 그래프')
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rc('font',family='Malgun Gothic')
data = pd.read_csv('covid_data.csv', index_col='국가')
COUNTRY = ['독일','프랑스','중국','영국']
when = ['4월06일','4월07일','4월08일']
data = data.loc[COUNTRY]
filtered_data = data[when]
pieData = filtered_data.sum(axis=1)
barData = filtered_data.loc['독일'].values
barData = barData / sum(barData)
# print(barData)
fig = plt.figure(figsize=(9,5))
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
ax1.pie(pieData, autopct='%1.1f%%',startangle=90,labels=COUNTRY, explode=[0.05,0,0,0] ,counterclock=False)
xpos = 0
bottom = 0
width = 0.2
colors = ['r','g','b']
for j in range(len(barData)):
height = barData[j]
ax2.bar(xpos, height, width ,bottom=bottom, color=colors[j])
ypos = bottom + ax2.patches[j].get_height()/2
bottom += height
ax2.text(xpos,ypos, f'{ax2.patches[j].get_height() * 100:.2f}%', ha='center', fontsize=10, color='w')
ax2.set_title(COUNTRY[0]+'의 일자별 비율')
ax2.set_xlim(-2.5*width, 2.5*width)
ax2.axis('off')
theta1, theta2 = ax1.patches[0].theta1, ax1.patches[0].theta2
center, r = ax1.patches[0].center, ax1.patches[0].r
bar_height = sum([item.get_height() for item in ax2.patches])
x = r * np.cos(np.pi / 180 * theta2) + center[0]
y = r * np.sin(np.pi / 180 * theta2) + center[1]
from matplotlib.patches import ConnectionPatch
con = ConnectionPatch(xyA=(-0.1, bar_height-0.005), coordsA=ax2.transData,
xyB=(x,y), coordsB=ax1.transData)
con.set_color([0.1,0.2,0.2])
con.set_linewidth(1)
ax2.add_artist(con)
x = r * np.cos(np.pi / 180 * theta1) + center[0]
y = r * np.sin(np.pi / 180 * theta1) + center[1]
con = ConnectionPatch(xyA=(-0.1, 0), coordsA=ax2.transData,
xyB=(x,y), coordsB=ax1.transData)
con.set_color([0.1,0.2,0.2])
con.set_linewidth(1)
ax2.add_artist(con)
plt.show()

상자 수염 그림 (box-and-whisker plot, box-and-whisker diagram) 또는 상자 그림( box plot, boxplot) 또는 상자 수염 그림, 상자 도표는 다섯 숫자 요약으로 그린, 자료의 특성을 요약하는 그래프 입니다.
상자 수염을 설명하기 전에 이상치(outlier)/ 극단치에 대ㅐ하여 우선 살펴 보도록 합니다.
예를 들어서, 사람의 나이가 300살 또는 키가 3미터 등 표현은 가능하지만 현실적으로 불가능한 값들을 이상치/극단치 라고 합니다.
outlier : 극단치 (upper, lower whisker 바깥 영역을 의미합니다)
upper whisker : 극단치와의 경계 ( 상자 외부 가로선으로 3사분위수 외부에 있는 1.5IQR 내부의 최대값)
상단 세로 점선 : 상단 수염 (Q3 위의 값들을 의미합니다. 제 3사분위수(75%)~100% 내에 존재하는 데이터를 의미합니다.
Q3 : 제3 사분위수 (제 3사분위수(75%)에 해당하는 값을 의미합니다.)
Q2 : 중앙 값 ( 상자 내에 있는 제 2사분위수(50%)로 중앙 값을 의미합니다.)
Q1 : 제1 사분위수 (제 1사분위수(25%)에 해당 하는 값을 의미합니다.)
하단 세로 점선 : 하단 수염 (Q1 아래 값들을 의미합니다. 0~제1사분위수(25%) 내에 존재하는 데이터를 의미합니다.
lower whisker : 극단치와의 경계(상자 외부 가로선으로 1사분위수 외부에 있는 1.5IQR 내부의 최소값)
import matplotlib.pyplot as plt
import numpy as np
data = np.random.randn(1000)
plt.boxplot(data)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
N = 500
normal1 = np.random.normal(loc=100, scale=15, size=N)
normal2 = np.random.normal(loc=88, scale=30, size=N)
fig = plt.figure(figsize=(7,5))
ax1 = fig.add_subplot(111)
ax1.boxplot([normal1, normal2],labels=['normal1','normal2'],vert=False, showmeans=True)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
frame = pd.read_csv('../day2/tips.csv', index_col=0)
frame1 = frame.loc[frame['time'] == 'Dinner', 'total_bill']
frame1.index.name = 'Dinner'
frame2 = frame.loc[frame['time'] == 'Lunch', 'total_bill']
frame2.index.name = 'Lunch'
chartdata = [np.array(frame1), np.array(frame2)]
tick_label = ['Dinner', 'Lunch']
fig, (ax1,ax2) = plt.subplots(1,2,figsize=(9,4))
ax1.boxplot(chartdata, labels=tick_label, vert=True)
ax1.set_title('vertical boxplot(tip)')
ax2.boxplot(chartdata, labels=tick_label, vert=False)
ax2.set_title('horizontal boxplot(tip)')
plt.show()

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
np.random.seed(777)
frame = pd.DataFrame(np.random.rand(5,3),
index=['customer1', 'customer2','customer3','customer4','customer5'],
columns=['metric1','metric2','metric3'])
print(frame)
fig, (ax1,ax2) = plt.subplots(1,2,figsize=(7,5))
frame.plot(kind='bar', ax=ax1, alpha=0.75, title='bar plot')
ax1.set_xlabel('customer')
ax1.set_ylabel('value')
plt.setp(ax1.get_xticklabels(), rotation=45)
colors = dict(boxes='blue', whiskers='grey', medians='orange', caps='green')
frame.plot(kind='box', ax=ax2, title='box plot',color=colors)
ax2.set_xlabel('metrics')
ax2.set_ylabel('value2')
plt.tight_layout()
plt.show()

히스토그램은 수치형 데이터 분포를 나타낸다.
빈도, 빈도밀도, 확률, 확률밀도 등의 분포를 그릴 때 사용한다.
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family='Malgun Gothic')
x = np.random.randn(10000)
plt.hist(x, bins=30)
plt.show()

import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(10000)
plt.hist(x, bins=30, density=True)
plt.show()

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
human = pd.read_csv('human_height.csv')
# human.info()
man = human['man']
woman = human['woman']
plt.figure(figsize=(7,5))
plt.hist(man,bins=20,alpha=0.5,label='man',rwidth=1)
plt.hist(woman,bins=20,alpha=0.5,label='man',rwidth=1)
plt.xlabel('height')
plt.ylabel('frequency')
plt.title('man height distribution')
plt.show()

선 그래프는 수치의 변화를 선으로 이어 그린다.
일반적으로 시간에 따른 데이터 변화 추세를 보여준다.(시계열 데이터)
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker
import datetime
start_time = datetime.datetime(2025,1,1)
ax = plt.gca()
def make_label(value, pos):
time = start_time + datetime.timedelta(days=365 * value)
return time.strftime('%b %y')
ax.xaxis.set_major_formatter(ticker.FuncFormatter(make_label))
x = np.linspace(0,1,256)
plt.plot(x,np.exp(-10 * x), c='k')
xlabels = ax.get_xticklabels()
plt.setp(xlabels,rotation=30, fontsize=12)
plt.show()

산점도는 예를 들어 키와 몸무게, 수요와 공급 등 두 변수 간의 관계를 표현한다.
두 변수가 양의 상관관계인지, 음의 상관관계인지를 파악 할 수 있다.
산점도 위에 회귀선을 그리면 하나의 변수 값에 따른 다른 변수 값이 어떻게 변하는지 예측 할 수 있다.
import matplotlib.pyplot as plt
import numpy as np
dataA = np.random.randn(100,2)
dataA += np.array((-1,-1))
dataB = np.random.randn(100,2)
dataB += np.array((1,1))
plt.scatter(dataA[:,0],dataA[:,1], color='0.25')
plt.scatter(dataB[:,0],dataB[:,1], color='0.75', edgecolors='k')
plt.show()

import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font',family='Malgun Gothic')
mpg = pd.read_csv('mpg.csv',encoding='utf-8')
print(mpg)
xdata = mpg.loc[:,['displ']]
ydata = mpg.loc[:,['hwy']]
plt.plot(xdata,ydata, marker='o',linestyle='None')
plt.title('선점도 그래프',fontsize=15)
plt.xlabel('엔진 크기')
plt.ylabel('고속도로 주행 마일 수')
plt.show()

import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font',family='Malgun Gothic')
mpg = pd.read_csv('mpg.csv',encoding='utf-8')
mpg.info()
print()
print(mpg.drv.unique())
mycolor = ['r','g','b']
label_dict = {'f':'전륜 구동', '4':'4륜 구동', 'r':'후륜 구동'}
for idx, finditem in enumerate(mpg.drv.unique()):
xdata = mpg.loc[mpg['drv'] == finditem,'displ']
ydata = mpg.loc[mpg['drv'] == finditem,'hwy']
plt.plot(xdata,ydata,color=mycolor[idx], marker='o', linestyle='None', label=label_dict[finditem])
plt.legend(loc='best')
plt.xlabel('엔진 크기')
plt.ylabel('고속도로 주행 마일 수')
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
plt.rc('font',family='Malgun Gothic')
kbo = pd.read_csv('kbo.csv',encoding='cp949')
xdata = kbo.loc[:,['AVG']]
ydata = kbo.loc[:,['HR']]
plt.plot(xdata,ydata, marker='o',linestyle='None')
plt.title('선점도 그래프',fontsize=15)
plt.xlabel('타율')
plt.ylabel('홈런')
plt.grid()
plt.show()

import matplotlib.pyplot as plt
import numpy as np
label_list = ['Iris-setosa','Iris-versicolor','Iris-virginica']
def read_label(label):
return label_list.index(label)
data = np.loadtxt('iris.data.txt',
delimiter=',',
converters={4:read_label})
color_set = ('b','g','r')
color_list = [color_set[int(label)] for label in data[:,4]]
# print(color_list)
plt.scatter(data[:,0], data[:,1],color=color_list)
import matplotlib.patches as patches
plt.legend(handles = [patches.Patch(color='b',label='iris-setosa'),
patches.Patch(color='g',label='iris-versicolor'),
patches.Patch(color='r',label='iris-virginica')],
loc='best',edgecolor='k')
plt.show()

import pandas as pd
import matplotlib.pyplot as plt
diamonds = pd.read_csv('diamonds.csv')
# diamonds.info()
diamonds = diamonds.sample(frac=0.01)
diamonds.info()
cut_list = diamonds['cut'].unique()
print(cut_list)
my_color = ['r','g','b','y','m']
cut_dict = {cut_list[idx]: my_color[idx] for idx in range(len(cut_list))}
print(cut_dict)
diamonds['newcut'] = diamonds['cut'].map(cut_dict)
print(diamonds.head())
def recode_table(table):
if table >= 60:
return 100
elif table >= 58:
return 30
elif table >= 54:
return 5
else:
return 1
diamonds['newtable']=diamonds['table'].apply(recode_table)
#print(diamonds.head(10))
fig = plt.figure(figsize=(8,6))
ax1 = fig.add_subplot(111)
xdata = diamonds['price']
ydata = diamonds['depth']
ax1.scatter(xdata,ydata, s=diamonds['newtable'], c=diamonds['newcut'],alpha=0.7)
plt.xlabel('price')
plt.ylabel('depth')
import matplotlib.patches as patches
plt.legend(handles=[patches.Patch(color='r', label='Very Good'),
patches.Patch(color='g', label='Good'),
patches.Patch(color='b', label='Ideal'),
patches.Patch(color='y', label='Premium'),
patches.Patch(color='m', label='Fair')],
loc='best',edgecolor='k')
plt.show()

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rc('font',family='Malgun Gothic')
mpg = pd.read_csv('../day2/mpg.csv')
fig = plt.figure(figsize=(10,7))
grid = plt.GridSpec(4,4, hspace=0.7, wspace=0.4)
ax_main = fig.add_subplot(grid[:-1, :-1])
ax_right = fig.add_subplot(grid[:-1,-1], xticklabels=[], yticklabels=[])
ax_bottom = fig.add_subplot(grid[-1,:-1],xticklabels=[], yticklabels=[])
ax_main.scatter('displ','hwy',data=mpg, edgecolors='k')
ax_bottom.hist(mpg.displ, bins=40, color='orange')
ax_bottom.invert_yaxis()
ax_right.hist(mpg.hwy, bins=40, color='pink',orientation='horizontal')
ax_main.yaxis.tick_right()
ax_main.yaxis.set_label_position('right')
ax_main.set_xlabel('엔진의 크기')
ax_main.set_ylabel('마일 수',rotation=270)
ax_main.set_title('grid spec',fontsize=16)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
fig = plt.figure(figsize=(6,4))
grid = plt.GridSpec(nrows=2,ncols=2,width_ratios=[3,1], height_ratios=[1,3])
ax1 = fig.add_subplot(grid[0])
ax1.plot(np.random.rand(50))
ax2 = fig.add_subplot(grid[1])
ax2.plot(np.random.rand(50))
ax3 = fig.add_subplot(grid[2])
ax3.plot(np.random.rand(50))
ax4 = fig.add_subplot(grid[3])
ax4.plot(np.random.rand(50))
plt.show()

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
data = np.linspace(-np.pi, np.pi, 1024)
grid_size = (4,2)
plt.subplot2grid(grid_size, (0,0), rowspan=3, colspan=1)
plt.plot(np.sin(2 * data), np.cos(0.5 * data), c='r')
plt.subplot2grid(grid_size, (0,1), rowspan=3, colspan=1)
plt.plot(np.sin(2 * data), np.cos(0.5 * data), c='b')
plt.subplot2grid(grid_size, (3,0), rowspan=1, colspan=2)
plt.plot(np.sin(5 * data), np.cos(7 * data), c='g')
plt.show()

Pandas 도 시리즈와 데이터프레임 자료형을 시각화하는 plot 함수를 제공한다.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
frame = pd.read_excel('fine_dust.xlsx',index_col='area')
print(frame)
frame2018 = frame[2018]
plt.figure(figsize=(15,4))
plt.plot(frame2018,color='b',marker='o')
plt.xlabel('area')
plt.ylabel('micrometer')
plt.title('2018 Fine dust line graph')
plt.tight_layout()
plt.grid(True)
plt.show()

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np
plt.rc('font', family='Malgun Gothic')
tipsfile = 'tips.csv'
myframe = pd.read_csv(tipsfile)
xrange = range(len(myframe))
data_bill = myframe.loc[:,['total_bill']]
data_tip = myframe.loc[:,['tip']]
fig,ax1 = plt.subplots()
ax1.set_title('결재 금액과 Tip(이동 축)')
color = 'tab:red'
ax1.set_ylabel('결재 금액',color=color)
ax1.plot(xrange, data_bill, color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('팁(tip)',color=color, rotation=0)
ax2.plot(xrange, data_tip, color=color)
ax2.tick_params(axis='y',labelcolor=color, labelrotation=270, labelsize=15)
fig.tight_layout()
plt.show()

ggplot 는 R용 시각화 패키지인 ggplot2 및 그래픽 문법에 기반을 둔 파이썬용 시각화 패키지이다.
ggplot 는 데이터와 화면에 출력되는 시각화 요소를 명확하게 구분한다.
pyplot의 플로팅 함수
수직 바 플롯 : bar()
수평 바 플롯 : barh()
"위스커"가 붙은 박스 플롯 : boxplot()
오류 바 플롯 : errorbar()
히스토그램(수직 혹은 수평) : hist()
로그-로그 플롯 : loglog()
x 축 로그 플롯 : semilogx()
y 축 로그 플롯 : semilogy()
파이 차트 : pie()
라인 플롯 : plot()
날짜 플롯 : plot_dates()
폴라 플롯 : polar()
스캐터 플롯(크기와 색상 조절 가능) : scatter()
스텝 플롯 : step()
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(777)
plot_data1 = np.random.randn(50).cumsum()
plot_data2 = np.random.randn(50).cumsum()
plot_data3 = np.random.randn(50).cumsum()
plot_data4 = np.random.randn(50).cumsum()
fig= plt.figure()
ax1= fig.add_subplot(1,1,1)
ax1.set_title('Line Plots: Markers,Colors, and Linestyles', fontsize=17)
ax1.plot(plot_data1,c='b',marker='o',ls='-')
ax1.plot(plot_data2,c='r',marker='+',ls='--')
ax1.plot(plot_data3,c='g',marker='*',ls='-.')
ax1.plot(plot_data4,c='orange',marker='s',ls=':')
# ax1.xaxis.set_ticks_position('top')
# ax1.yaxis.set_ticks_position('right')
plt.xlabel('Draw')
plt.ylabel('Random Number')
plt.legend(['Blue Solid','Red Dashed','Green Dash Dot','orange Dotted'],loc=1,fontsize=10)
# plt.savefig('line_plot_quiz.png',dpi=400, bbox_inches='tight')
plt.show()

import matplotlib.pyplot as plt
ax1 = plt.gca()
ax2 = ax1.twinx()
line1, = ax1.plot([10,5,3,12,7],'r--',label='y1')
ax1.set_ylabel('y1')
line2, = ax2.plot([100,200,220,170,120],'b:',label='y2')
ax2.set_ylabel('y2')
ax1.legend(handles=[line1,line2],loc='best')
plt.show()

matplotlib API 함수는 matplotlib.pyplot 모듈에 들어 있습니다.
일반적으로 다음 문장처럼 'plt'라는 이름으로 import 해서 사용합니다.
axhline(y=0, xmin=0,
xmax=1, **kwargs) : y는 수평선이 그려 지는 y 축의 좌표를 의미합니다.
axvline(x=0, ymin=0,
ymax=1, **kwargs) : plt.axvline(x=1,color='blue',linewidth=2,linestyle='dotted'
grid(boolean) : 그리드를 표시할 것인지의 Boolean 값을 지정합니다.
rcdefaults() : Matplotlib 스타일에 대한 파라미터를 초기 값으로 되돌립니다.
show() : 그래프 객체를 화면에 보여 줍니다.
title(sometitle) : sometitle이라는 문장을 그래프의 제목으로 설정합니다.
xlabel(str) : x축에 str 이라는 라벨(문구)을 설정합니다.
xlim([하한값,상한값]) : x축의 상한/하한 값을 설정합니다.
xticks(리스트) : x 축의 눈금 라벨에 대한 개수 설정을 합니다.
ylabel(str) : y 축에 str이라는 라벨을 설정합니다.
ylim([하한값,상한값]) : y 축의 상한/하한 값을 설정합니다.
yticks(리스트) : y축의 눈금 라벨에 대한 개수 설정을 합니다.
plt.savefig()메소드는 그래프를 파일로 저장하기 위한 옵션입니다.
사용 형식 : plt.svefig(filename, dpi=400, bbox_inches='tight')
fname : 파일 경로나 파이썬의 파일과 유사한 객체를 나타내는 문자열. 저장되는 포맷은 파일의 확장자를 통하여 결정이 됩니다.
dpi : Figure의 해상도 dpi(기본 값:100)를 지정합니다. dpi는 dots per inch를 의미합니다.
facecolor, edge color : 서브 플롯 바깥 배경 색상, (기본값 w(흰색)) 입니다.
format : 명시적인 파일 포맷('png','pdf','svg' 등등) 을 지정합니다.
bbox_inches : Figure 에서 저장할 부분을 지정하는 옵션입니다. 'tight' 는 Figure의 둘레의 비어 있는 공간을 모두 제거합니다.
그래프란 서로 연관성이 있는 1개 또는 그 이상의 양에 대한 상대 값을 도형으로 나타낸 것을 말합니다.
다양한 종류의 그래프에 대하여 얘기 하기 전에 우선 변수의 종류 및 개수에 따른 유형을 살펴 보도록 합니다.
우선적으로 데이터의 구조를 파악하고, 변수명, 변수별 데이터 유형(숫자형,문자형,논리형), 결측값의 여부, 이상치(outlier) 여부 등을 이용하여 전처리를 수행합니다.
이후 이러한 데이터들을 직관적으로 살펴 보려면 일반적으로 시각화를 수행하게 됩니다.
데이터의 유형 및 갯수에 따라서 그래프의 종류는 다를 수 밖에 없습니다.
일변량(1개)
연속형 - 히스토 그램(histogram)
- 상자 수염 그래프(boxplot)
- 바이올린 그래프(violin)
- 커널 밀도 그래프 (kernel density curve)
범주형 - 막대 그래프(bar chart)
- 파이 그래프(pie chart)
다변량(>=2)
연속형 - 산점도(scatter plot)
- 선 그래프(line)
- 시계열 그래프
범주형 - 모자이크 그래프(mosaic graph)
- Tree Map 그래프
막대 그래프가 양의 상대적인 크기를 비교하는데 사용되는 것이라면 연속적으로 변화하는 데이터를 살펴 보고자 할 때에는 꺽은 선 그래프가 제격입니다,
일반적으로 꺽은 선 그래프는 시간에 따른 데이터의 연속적인 변화량을 관찰하고자 할 때 자주 사용되는 그래프입니다.
예를 들어서 매 시간에 따른 기온의 변화, 물을 끓인 다음 식히면서 시간에 따른 물의 온도 변화 등을 그리고자 할 때 유용하게 사용합니다.
꺽은 선 그래프는 수량을 점으로 우선 표시한 다음 해당 점들을 선분으로 이어서 그리기 때문에 증가와 감소의 상태를 쉽게 찾을 수 있습니다.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
plt.rc('font',family='Malgun Gothic')
april = 'covid_data.csv'
frame = pd.read_csv(april,index_col='국가')
print(frame['4월06일'])
chardata = frame['4월06일']
YTICK_INTERVAL = 50000
maxlim = (int(chardata.max() / YTICK_INTERVAL)+1) * YTICK_INTERVAL
print(maxlim)
values = np.arange(0,maxlim+1,YTICK_INTERVAL)
plt.plot(frame['4월06일'],c='b',ls='solid',marker='o')
plt.yticks(values,['%s'%format(val,',') for val in values])
plt.grid()
plt.xlabel('국가명')
plt.ylabel('발생 수')
plt.title('4월 6일 국가별 코로나 발생 수', fontsize=20)
plt.show()

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
plt.rc('font',family='Malgun Gothic')
april = 'covid_data.csv'
data = pd.read_csv(april,index_col='국가')
COUNTRY = ['스페인','프랑스','독일','중국','영국','이란']
chartdata = data.loc[COUNTRY, '4월06일':'4월10일']
print(chartdata.T)
chartdata.T.plot(title='일자 & 국가별 코로나 발생 수' ,figsize=(10,6), legend=True, marker='o')
plt.grid()
plt.show()

seaborn은 파이썬에서 통계 그래프와 그림을 만드는 과정을 단순하게 해주는 패키지이다.
이 패키지는 matplotlib 기반으로 만들어져 numpy 및 pandas의 자료구조를 지원한다.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rc('font',family='Magun Gothic')
welfare = pd.read_csv('welfare_python.csv', encoding='utf-8')
welfare.info()
print(welfare.head())
welfare.loc[welfare['gender'] == 1, ['gender']] = '남성'
welfare.loc[welfare['gender'] == 2, ['gender']] = '여성'
# print(welfare.head())
# welfare['ch_gender'] = welfare['gender'].map({1:'남성',2:'여성'})
thisyear = 2000
welfare['age'] = thisyear - welfare['birth']
# welfare['marriage'] = welfare['marriage'].map(lambda x : {1:'결혼',3:'미혼'}.get(x,'무응답'))
#print(welfare.head())
def setMarriage(x):
if x== 1:
return '결혼'
elif x == 3:
return '이혼'
else:
return '무응답'
welfare['marriage'] = welfare['marriage'].map(setMarriage)
welfare.loc[welfare['income'].isnull(),'income'] = welfare['income'].mean()
#print(welfare.head())
print()
jobFrame = pd.read_csv('welfare_job.csv', encoding='cp949')
jobFrame.info()
print(jobFrame.head())
welfare = pd.merge(welfare, jobFrame, on='code_job')
#print(welfare.head(10))
def setReligion(x):
if x== 1:
return '있음'
else:
return '없음'
welfare['religion'] = welfare['religion'].map(setReligion)
def setCR(x):
if int(x) == 1:
return '서울'
elif int(x) == 2:
return '수도권'
elif int(x) == 3:
return '부산/경남/울산'
elif int(x) == 4:
return '대구/경북'
elif int(x) == 5:
return '대전/충남'
elif int(x) == 6:
return '강원도/충북'
elif int(x) == 7:
return '광주/전남/전북/제주도'
welfare['code_religion'] = welfare['code_religion'].map(setCR)
# print(welfare.iloc[4])
def newAge(x):
if x < 30:
return '청년'
elif x >= 30 and x < 60:
return '중년'
else:
return '노년'
welfare['ageg'] = welfare['age'].apply(newAge)
print(welfare.iloc[4])
col_mapping={'gender':'성별','birth':'생일','marriage':'결혼 유무','religion':'종교 유무','code_job':'직업 코드','income':'소득',
'code_religion':'지역구','age':'나이','job':'직업','ageg':'연령대'}
welfare = welfare.rename(columns=col_mapping)
welfare.to_csv('welfareClean.csv',index=False,encoding='cp949')

생성
각종 그래프
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font',family='Malgun Gothic')
welfare = pd.read_csv('welfareClean.csv', encoding='cp949')
# welfare.info()
# print(welfare.head(10))
#
# result = welfare.groupby('결혼 유무')['결혼 유무'].count()
# print(result)
#
# plt.bar(result.index,result.values)
# plt.show()
import seaborn as sns
# sns.countplot(data=welfare, x='결혼 유무',order=['결혼','이혼','무응답'], hue='종교 유무', palette='Paired')
# plt.title('count plot')
# plt.show()
# x = welfare['나이']
# sns.displot(x, hist=True)
# sns.histplot(data=welfare, x='나이',bins=10)
# plt.show()
pdata = welfare.pivot_table(index='성별',columns='결혼 유무',values='나이',aggfunc='mean')
# print(pdata)
# sns.heatmap(data=pdata, annot=True)
# plt.show()
# corr = welfare[['생일','소득','나이']].corr()
# print(corr)
# sns.heatmap(data=corr,annot=True)
# sns.heatmap(data=corr,annot=True,cmap='YlGnBu')
# plt.show()
# nwelfare = welfare.loc[:,['생일','소득','나이','결혼 유무']]
# sns.pairplot(data=nwelfare, hue='결혼 유무')
# plt.show()
# sns.violinplot(x='성별',y='나이',data=welfare, hue='종교 유무')
# plt.show()
# sns.lmplot(x='나이',y='소득',data=welfare, hue='결혼 유무', col='성별', row='연령대')
# plt.savefig('lmplot.png',dpi=400)
# plt.show()
# sns.jointplot(x='나이', y='소득',data=welfare)
# plt.show()
sns.boxplot(x='성별',y='소득', data=welfare, hue='종교 유무')
plt.show()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font',family='Malgun Gothic')
df = pd.read_csv('medical.csv')
df.info()
print()
print(df.describe())
df = df[df['Age'] >= 0]
print(df.describe())
print(df['No-show'].unique())
df['No-show'] = df['No-show'].map({'Yes':1,'No':0})
# print(df['No-show'].unique())
# print(df['No-show'].value_counts())
df['AppointmentDay']= pd.to_datetime(df['AppointmentDay'])
df['ScheduledDay']= pd.to_datetime(df['ScheduledDay'])
# df.info()
# print(df[['ScheduledDay','AppointmentDay']])
df['waiting_day']=df['AppointmentDay'].dt.dayofyear - df['ScheduledDay'].dt.dayofyear
print(df.head(10))
df = df[df['waiting_day'] >= 0]
print(df.describe()['Age'])
import seaborn as sns
'''100살이 넘는 사람 빼고 표현'''
df=df[df.Age <= 100]
plt.figure(figsize=(14,2))
sns.boxplot(x=df.Age)
plt.show()
''' 당일날 노쇼한 사람들의 비율'''
wtotal = df[df.waiting_day==0]['waiting_day'].value_counts()
ntotal = df[(df['waiting_day']==0)&(df['No-show']==1)]['waiting_day'].value_counts()
# print(wtotal)
# print(ntotal/wtotal)
# dangil = df[df['waiting_day'] == 0]
# result = dangil['No-show'].sum() / len(dangil)
# print(f'{result * 100}%')
no_show = df[df['No-show']==1]
show = df[df['No-show']==0]
# no_show[no_show['waiting_day']<=10]['waiting_day'].hist(alpha=0.7,label='no_show')
# show[show['waiting_day']<=10]['waiting_day'].hist(alpha=0.3, label='show')
# plt.legend(loc='best')
# plt.show()
# no_show['ScheduledDay'].hist(alpha=0.7, label='no_show')
# show['ScheduledDay'].hist(alpha=0.7, label='show')
# plt.legend(loc='best')
# plt.show()
# sns.barplot(df,x='SMS_received',y='waiting_day',hue='No-show')
# plt.show()
# sns.countplot(x='Gender',hue='No-show', data=df)
# plt.show()
woman_noshow = df[(df['Gender']=='F')&(df['No-show']==1)]['Gender'].value_counts()
man_noshow = df[(df['Gender']=='M')&(df['No-show']==1)]['Gender'].value_counts()
woman_total = df[df['Gender']=='F']['Gender'].value_counts()
man_total = df[df['Gender']=='M']['Gender'].value_counts()
print(f'노쇼 여성 비율:{woman_noshow/woman_total}')
print(f'노쇼 남성 비율:{man_noshow/man_total}')





import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.pyplot import ylabel
plt.rc('font',family='Malgun Gothic')
df = pd.read_csv('exam2.csv', encoding='cp949')
print(df)
fig, ax = plt.subplots(1,1,figsize=(9,9))
HUNDRED = 80
MIN_HEIGHT = 30
MAX_HEIGHT = HUNDRED + 5
ax.vlines(x=1,ymin=MIN_HEIGHT,ymax=MAX_HEIGHT, color='k', alpha=0.7,linewidth=1,ls='dotted')
ax.vlines(x=3,ymin=MIN_HEIGHT,ymax=MAX_HEIGHT, color='k', alpha=0.7,linewidth=1,ls='dotted')
ax.scatter(x=np.repeat(1,df.shape[0]),y=df['midexam'], s=12, color='k', alpha=0.7)
ax.scatter(x=np.repeat(3,df.shape[0]),y=df['finalexam'], s=12, color='k', alpha=0.7)
left_label = [f'{c}({y}점)'for c, y in zip(df.name, df['midexam'])]
right_label = [f'{c}({y}점)'for c, y in zip(df.name, df['finalexam'])]
import matplotlib.lines as lines
def newline(p1,p2):
ax = plt.gca()
lo = lines.Line2D([p1[0],p2[0]], [p1[1],p2[1]],
color='red' if p1[1]- p2[1] > 0 else'green',
marker='o',
markersize=6)
ax.add_line(lo)
for idx, (p1,p2) in enumerate(zip(df['midexam'],df['finalexam'])):
newline([1,p1],[3,p2])
ax.text(1 - 0.05,p1, left_label[idx], ha='right', fontsize=14)
ax.text(3 + 0.05, p2, right_label[idx], ha='left', fontsize=14)
ax.set_title('시험 점수',fontsize=20)
ax.set(xlim=(0,4), ylim=(MIN_HEIGHT,MAX_HEIGHT),ylabel=('시험점수'))
ax.set_xticks([1,3])
ax.set_xticklabels(['중간 고사','기말 고사'])
plt.gca().spines['top'].set_alpha(0)
plt.gca().spines['bottom'].set_alpha(0)
plt.gca().spines['right'].set_alpha(0)
plt.gca().spines['left'].set_alpha(0)
plt.show()

import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.graphics.mosaicplot import mosaic
plt.rc('font',family='Malgun Gothic')
fig, ax = plt.subplots(figsize=(10,4))
# gender = ['male','male','male','female','female','female']
# pet = ['cat', 'dog', 'dog', 'cat', 'dog', 'cat']
# t_col = [2,3,4,5,6,7]
# data= pd.DataFrame({'gender':gender,
# 'pet':pet,
# 'tvalue':t_col})
# print(data)
# props = lambda key : {'color':'Lightblue' if 'cat' in key else 'red'}
# mosaic(data,['pet','gender'],title='mosaic graph',ax=ax, properties=props, gap=0.06, horizontal=False)
# plt.show()
url = 'https://raw.github.com/mattdelhey/kaggle-titanic/master/Data/train.csv'
titanic = pd.read_csv(url)
# titanic.info()
titanic = titanic[['survived','pclass','sex']]
# print(titanic.head(10))
titanic['survived'] = titanic.survived.map({0:'사망',1:'생존'})
titanic['class'] = titanic.pclass.map({1:'1등급',2:'2등급',3:'3등급'})
titanic['gender'] = titanic.sex.map({'male':'남성','female':'여성'})
# print(titanic.head(10))
props = lambda key:{'color':'orange' if '생존' in key else 'grey'}
mosaic(titanic.sort_values('class'),['survived','class'], properties=props, gap=0.04, ax=ax)
plt.title('객실 등급 비율에 따른 사망 비율', fontsize=14)
plt.show()

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font',family='Malgun Gothic')
import squarify
sizes = [50,20,17,11]
labels= ['서울','대구','인천','부산']
colors=['lightgreen','cornflowerblue','lightcoral','mediumpurple']
squarify.plot(sizes, 10,10,label=labels,color=colors,
bar_kwargs=dict(edgecolor='w',linewidth=3))
plt.axis('off')
plt.show()

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font',family='Malgun Gothic')
import squarify
sizes = [50,20,17,11]
welfare= pd.read_csv('../day4/welfareClean.csv', encoding='cp949')
welfare.info()
df = welfare.groupby('지역구').size().reset_index(name='counts')
print(df)
labels = df.apply(lambda x: f'{x[0]}\n({x[1]}',axis=1)
sizes = df['counts'].values.tolist()
colors = [plt.cm.Spectral(i /float(len(labels))) for i in range(len(labels))]
plt.figure(figsize=(10,6))
squarify.plot(sizes=sizes, label=labels, color=colors, alpha=0.8,
bar_kwargs=dict(linewidth=3, edgecolor='w'))
plt.title('Tree map(지역구)',fontsize=20)
plt.axis('off')
plt.show()

import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
df = px.data.tips()
print(df.head())
# fig = px.parallel_categories(df)
# fig.show()
fig = px.parallel_categories(df,dimensions=['sex','smoker','day'],
color='size',
labels={'sex':'payer_sex','smoker':'smoker at the table','day':'day of week'})
fig.show()
