직사각형 막대를 사용하여 데이터 값을 표현하는 차트(그래프)
Category에 따른 수치 값을 비교하기에 적합한 방법
Bar 사이 Gap이 0이라면, histogram(.hist())를 활용
그룹이 5 ~ 7개 이하일 경우 효과적 ⇒ 수가 적은 그룹을 ETC로 처리
막대 방향에 따른 분류
모양에 따른 분류
정확한 Bar Plot 그리기
x = np.array([1,2,3,4,5]) # Category를 의미함
y1 = np.array([1,3,5,3,1]) # Value1
y2 = np.array([2,4,6,8,10]) # Value2
ax[0].bar(x,y1) # 수직 Bar Plot
ax[1].barh(x,y2) # 수평 Bar Plot

설명
수평 Bar Plot에서 ndarray의 가장 앞쪽의 값이 그래프의 가장 아래쪽에 존재하는
것을 볼 수 있다.(1이 가장 아래에 존재)
하지만 수평 Bar Plot의 경우 대부분 맨 위에 1부터 시작하는 것을 선호하기 때문에
sort에 대한 Function을 수행하되 ascending=False로 지정하여 내림 차순으로
정렬시키는 경우가 많다
y축의 Size를 동일하게 만들기(이유 : Principle of Proportion Ink를 지키기 위해)
# 방법 1 : 한 번에 모든 Ax size를 맞추기
fig, ax = plt.subplots(1,2, sharey=True)
# sharey Parameter 값을 True로 설정하면 subplots로 만들어지는 모든 Ax의 y축
# size는 동일함
# sharex = True를 통해 x축 크기도 일치 시킬 수 있음
x = np.array([1,2,3,4,5])
y1 = np.array([1,3,5,3,1])
y2 = np.array([2,4,6,8,10])
ax[0].bar(x,y1)
ax[1].bar(x,y2)

방법 2 : 모든 Ax에 대해 y축의 size를 직접 지정해주는 방식
fig, ax = plt.subplots(1,2, figsize=(12,7))
for sub_ax in ax:
sub_ax.set_ylim(0,15)
x = np.array([1,2,3,4,5])
y1 = np.array([1,3,5,3,1])
y2 = np.array([2,4,6,8,10])
ax[0].bar(x,y1)
ax[1].bar(x,y2)

Stacked graph 생성
x = np.array([1,2,3,4,5])
y1 = np.array([1,3,5,3,1])
y2 = np.array([2,4,6,8,10])
ax[0].bar(x,y2, bottom = y1)
ax[0].set_title("Only y2")
# botttom Parameter를 활용하여, 아래에 깔(Stack 시킬) Data 값을 입력한다
# 위 예시에서는 y1을 Bottom으로 설정했으니, Bottom만큼 빈 공간으로 만든 뒤
# y2에 대한 Bar Plot을 그린다
ax[1].bar(x,y2, bottom = y1)
ax[1].bar(x,y1)
ax[1].set_title("y1 AND y2")
# 위와는 다르게, y1에 대한 Bar Plot도 그렸기 때문에
# Stacked Graph로 생성이 되었을 것이다

Grouped Bar Plot 그리기
Bar가 존재해야 하는 위치 공식 :
width : (Bar의) 너비
x : x축 값
N : 총 Graph 개수
index : 몇번째 그래프를 그리는가
width = 0.2
N = 2
def f(idx, x):
return x + width * ((-N+1+2*idx)/2)
# Bar 1개당 존재해야 하는 위치값을 반환
fig, ax = plt.subplots(1,1, sharey=True)
x = np.array([1,2,3,4,5])
y = np.array([[1,3,5,3,1], [2,4,6,8,10]])
for idx in range(N):
ax.bar(f(idx, x), y[idx], width = width)
# idx번째 그래프에 대한 위치를 구한 뒤 Bar Plot을 구함
plt.show()

기타 Bar Plot Parameter
fig, ax = plt.subplots(1,1, sharey=True)
x = np.array([1,2,3,4,5])
y = np.array([1,3,5,3,1])
ax.bar(x,y,
width = 0.3, # Bar Plot의 너비에 대한 Paramter : width
linewidth = 2,
# Bar Plot "테두리" 너비에 대한 Parameter : linewidth
edgecolor = 'r',
# Bar Plot "테두리" 색깔에 대한 Parameter : edgecolor
)
ax.bar(x,y,color='black', alpha=0.2)
# Bar의 투명도에 대한 Parameter : alpha -> 0 ~ 1 사이의 값
for value in ['top', 'right']:
ax.spines[value].set_visible(False)
"""
Ax의 테두리 없애는 메서드 : .spines[S].set_visible(False)
주로 top과 right을 지우는 경우가 많음
이전 강의의 spines 참조
"""
ax.grid(zorder=0)
# Grid 추가. 하지만 Text를 추가하는 것을 더 추천함
# zorder : 차트를 그릴 때 바깥쪽에 그려지는 차트일 수록 zorder 값이 커야함
plt.show()

capsize Parameter를 활용하여 Errorbar의 최대, 최소 위치에 가로선을 그어줄 수 있음x = np.arange(1,6)
y = x**2
ax.plot(x,y)

x = np.sin(np.linspace(0,2*np.pi, n))
y = np.cos(np.linspace(0,2*np.pi, n))
ax.plot(x,y)
# 결과적으로 정 (n-1)각형이 만들어진다
# n이 매우 커지면 원과 매우 유사하게 된다(아래 출력 결과는 n=4일때의 결과)

x = np.arange(1,21)
y = np.random.rand(20)
ax.plot(x,y,
color='gray',
marker='*',
linestyle='solid'
)

x = np.arange(1,21)
y = np.random.rand(20)
z = np.random.rand(20)+ 20
ax.plot(x,y, color = 'red', label='Main')
ax.legend()
# 먼저, 내가 원래 그릴 Line Plot을 그림
ax2 = ax.twinx()
# .twinx() 명령어를 통해 새로운 ax를 생성함.
# twin에서 예측할 수도 있었겠지만, 쌍둥이처럼 같은 공간에서 그려지되,
# 자신만의 y축 값을 가지고 있는 것이다. x축 값은 공유한다
ax2.plot(x,z, color = 'blue', label = 'Add')
ax2.legend()

def deg2rad(x):
# degree -> Radian으로 바꾸는 함수
return x * np.pi / 180
def rad2deg(x):
# radian -> degree로 바꾸는 함수
return x * 180 / np.pi
fig, ax = plt.subplots(constrained_layout=True)
x = np.arange(0, 360, 1)
y = np.sin(2 * x * np.pi / 180)
ax.plot(x, y)
ax.set_xlabel('angle [degrees]')
ax.set_ylabel('signal')
ax.set_title('Sine wave')
// 먼저, degree 값을 통한 sin(x) 그래프를 그린다
secax = ax.secondary_xaxis('top', functions=(deg2rad, rad2deg))
"""
이후, x축을 secondary_xaxis를 통해 하나 더 추가해준다.
'top' : 추가할 x축의 위치를 표현하는 것이다. 이외에도 'bottom',
y축일 경우 'left', 'right'이 가능하다
functions : 추가할 x축에 대해 값을 대응시켜주는 것이다
예를 들어, 180도 일경우 Radian에서 파이의 위치와 매치시켜줘야
할 것이다. 이를 위한 함수이다
첫번째 함수는 원래 그렸던 x값 -> 추가할 함수의 x값,
두번째 함수는 추가할 함수의 x값 -> 원래 그렸던 x값으로 전환해주는
Function을 입력해준다
이 Case의 경우 "먼저" 그렸던 x값은 Degree였으므로,
deg2rad을 첫번째 함수로 지정하였다
"""
secax.set_xlabel('angle [rad]')
# x축을 추가했고, 추가한 "x축"에 대하여 Label을 붙였다
plt.show()
"""
아래 결과 그래프를 보면, Data 자체는 sin(x)로 동일하지만 위에는 Radian 단위로,
아래에는 Degree 단위로 설정되어 있음을 볼 수 있다.
Function을 통해 매칭시켰으므로, 한 x축의 값을 다른 단위로 전환시켜보면
다른 x축의 값과 동일한 값이 도출될 것이다
"""

# Data 전처리
x = np.arange(0,1,0.01)
y = pd.DataFrame(np.random.rand(x.shape[0]))
y = y.rolling(window=3).mean()
# (과거 + 현재) 인접한 3개 데이터를 묶어, 그 평균을 낸 값으로 DataFrame을 생성
y.head()
설명
위에서 말했듯, rolling에서 window를 지정하면 해당 개수만큼 데이터를 묶어서 새로운
DataFrame을 형성하는 것이다
즉, 첫번째 값과 두번째 값은 (-1,0,1), (0,1,2) Data를 뽑을 수는 없기 때문에
평균도 존재하지 않는다
따라서, 0,1 값은 NaN이 되는 것을 아래 결과에서 확인할 수 있을 것이다

fig, ax = plt.subplots(1,2, figsize=(12,7))
x = np.arange(0,1,0.01)
y = np.random.rand(x.shape[0])
ax[0].plot(x,y, color='gray', linestyle=':')
"""
원래 Data 전체에 대해 그래프를 그림
아래 출력값을 확인하면 알겠지만 너무 변화가 많다.
나는 Trend에 대해서 알고 싶기 때문에 Moving Average 방법을 활용해 데이터를
전처리하고, 실 Data보다는 Trend에 집중하려 한다
"""
z = pd.DataFrame(y)
# rolling을 쓰기 위해서 DataFrame으로 변환
z = z.rolling(window=10).mean()
ax[1].plot(z.index, z, color='blue', linestyle=':')
"""
중요한 점은, 원래 Data를 rolling(Moving Average)하면 x축의 값도 바뀐다는 것이다
위에서 볼 수 있듯, 앞쪽에 존재하는 Data들이 없어지기 때문이다
따라서, z.index를 x축으로 활용하여 Line Plot을 그려야 한다
"""
plt.show()
# 오른쪽 그래프가 그나마 Trend 파악이 쉬움을 알 수 있다



for i in range(0, 7):
plt.scatter(0.2*i, 0, color=colors[i], s=50000, zorder=i)
# 빨간색이 가장 마지막에 그려진 scatter plot. zorder 값이 가장 크기 때문에
# 가장 앞에 존재

x = np.random.rand(20)
y = np.random.rand(20)
ax.scatter(x,y,
marker='^',
linewidth = 1,
edgecolor = 'r',
color = ['royalblue' if yy <= y.mean() else 'gray' for yy in y]
, s = 150)
# y 값이 평균보다 높으면 gray, 낮으면 royalblue로 칠했다
