Matlib 실습 210407¶
1. matplot 그리기¶
In [47]:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, FuncFormatter)
tips = sns.load_dataset("tips")
tips.head()
Out[47]:
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
In [6]:
tips_day = tips.groupby("day").mean().reset_index() #group_by로 요일별 평균 데이터를 만든다. #reset_index()로 인덱스(1,2,3) 만들어줌.
tips_day
Out[6]:
day | total_bill | tip | size | |
---|---|---|---|---|
0 | Thur | 17.682742 | 2.771452 | 2.451613 |
1 | Fri | 17.151579 | 2.734737 | 2.105263 |
2 | Sat | 20.441379 | 2.993103 | 2.517241 |
3 | Sun | 21.410000 | 3.255132 | 2.842105 |
In [12]:
fig, ax = plt.subplots()
ax.bar(tips_day["day"], tips_day["tip"], color="lightgray")
ax.set_title("tip (mean)", fontsize=16, pad=12)
Out[12]:
Text(0.5, 1.0, 'tip (mean)')
In [ ]:
fig, ax = plt.subplots() # 틀 그리기.
#fig는 figure로써 전체 subplot을 말한다. 서브플롯 안에 몇개의 그래프가있던지 그걸 담는 틀.
#ax는 axe로써 전체중 낱낱개를 말한다. 그래프의 수가 많아지면 배열 형태로 저장. ex) ax[1], ax[3]
ax.bar(tips_day["day"], tips_day["tip"], color="lightgray") #bar그리기
ax.set_title("tip (mean)", fontsize=16, pad=12) #타이틀 그리기
plt.show()
In [13]:
ax.patches#ax에 있는 patches? 서브플롯 안의 객체를 말하는 듯.
Out[13]:
[<matplotlib.patches.Rectangle at 0x7f3e844b0450>, <matplotlib.patches.Rectangle at 0x7f3e844f47d0>, <matplotlib.patches.Rectangle at 0x7f3e844b0890>, <matplotlib.patches.Rectangle at 0x7f3e8443d310>]
Rectangle 객체가 4개 있다는 뜻이다. 높이를 확인하면 요일별 평균 데이터가 그대로 있다.
In [14]:
for i in range(len(ax.patches)):
print(f"height of patch[{i}] = {ax.patches[i].get_height()}")
height of patch[0] = 2.771451612903226 height of patch[1] = 2.734736842105263 height of patch[2] = 2.993103448275862 height of patch[3] = 3.255131578947369
2. 지정 그래프의 색 바꾸기¶
In [15]:
#일요일 데이터만 골라서 짙은 빨강 칠하기
fig, ax = plt.subplots()
ax.bar(tips_day["day"], tips_day["tip"], color="lightgray")
ax.set_title("tip (mean)", fontsize=16, pad=12)
# Sunday
#sunday는 4번째 객체이므로 patches[3]
ax.patches[3].set_facecolor("darkred") #facecolor. 안의 바탕색
ax.patches[3].set_edgecolor("black") #edgecolor 외관선 색
plt.show()
3. 그래프에 텍스트 부여하기¶
In [16]:
fig, ax = plt.subplots()
ax.bar(tips_day["day"], tips_day["tip"], color="lightgray")
ax.set_title("tip (mean)", fontsize=16, pad=12)
# Values
h_pad = 0.1#글자 배치를 위한 패드를 깔아주기
for i in range(4):
fontweight = "normal"
color = "k"
if i == 3: # Sunday
fontweight = "bold" #sunday일때 굵은 글씨
color = "darkred" #어두운 붉은 글씨
#그래프 객체에 텍스트 붙이는 함수 ax.text
ax.text(i, tips_day["tip"].loc[i] + h_pad, f"{tips_day['tip'].loc[i]:0.2f}", #글자 색 지정
horizontalalignment='center', fontsize=12, fontweight=fontweight, color=color)
#글자 색 지정 tips_day['tip']은 tip열거 뽑아낸거, loc은 그중에 i번째, 0.2f는 소숫점 두자리까지만.
# Sunday
ax.patches[3].set_facecolor("darkred")
ax.patches[3].set_edgecolor("black")
# set_range
ax.set_ylim(0, 4)
plt.show()
ax.spines 활용에 집중하기 위해서 시각화 코드를 함수로 만든다.
In [48]:
def plot_example(ax, zorder=0):
ax.bar(tips_day["day"], tips_day["tip"], color="lightgray", zorder=zorder)
ax.set_title("tip (mean)", fontsize=16, pad=12)
# Values
h_pad = 0.1
for i in range(4):
fontweight = "normal"
color = "k"
if i == 3:
fontweight = "bold"
color = "darkred"
ax.text(i, tips_day["tip"].loc[i] + h_pad, f"{tips_day['tip'].loc[i]:0.2f}",
horizontalalignment='center', fontsize=12, fontweight=fontweight, color=color)
# Sunday
ax.patches[3].set_facecolor("darkred")
ax.patches[3].set_edgecolor("black")
# set_range
ax.set_ylim(0, 4)
return ax
In [23]:
fig, ax = plt.subplots()
ax = plot_example(ax)
4. SPINES¶
In [24]:
type(ax.spines)
Out[24]:
collections.OrderedDict
OrderedDict의 객체. dictionary의 일종이다.
In [27]:
for k,v in ax.spines.items():
print(f"spines[{k}] = {v}")
ax.spines.values()
spines[left] = Spine spines[right] = Spine spines[bottom] = Spine spines[top] = Spine
Out[27]:
odict_values([<matplotlib.spines.Spine object at 0x7f3e84001650>, <matplotlib.spines.Spine object at 0x7f3e840b35d0>, <matplotlib.spines.Spine object at 0x7f3e8414af90>, <matplotlib.spines.Spine object at 0x7f3e84096f50>])
key는 네개의 테두리를 가졌고 value는 matplotlib.spines,Spine객체이다.
공식 문서에따르면 Spine은 Patch의 subclass이고 set_patch_circle,set_patch_arc가 호출되면 원이나 호를 그리기도 한다. 선을 그리는 set_patch_line이 기본값이다.
Spine 숨기기? : set_visible(False)
In [28]:
fig, ax = plt.subplots()
ax = plot_example(ax)
ax.spines["top"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.spines["right"].set_visible(False)
#위,옆 축들을 다 지워버렸다.
In [29]:
fig, ax = plt.subplots()
ax = plot_example(ax)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_bounds(1, 3) #set_bounds를 이용해서 1~3까지만 축을 그렸다.
In [30]:
ax.spines["left"].get_position() #spines["left"]의 설정. ("outward")0만큼 나가있다?
Out[30]:
('outward', 0.0)
In [ ]:
#포지션을 통해서 left축(y축)과 그래프 간격을 띄운다
fig, ax = plt.subplots()
ax = plot_example(ax)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_position(("outward", 10))##set_position을 이용해 left 축을 10만큼 띄운다.
In [31]:
#만약 축을 안쪽으로 당겨오고 싶으면 outward 음수 값을 넣는다.
fig, ax = plt.subplots(ncols=3, figsize=(15, 3))
for i in range(3): # 그래프 세개 한번에 그리기
ax[i] = plot_example(ax[i])
ax[i].spines["top"].set_visible(False)
ax[i].spines["right"].set_visible(False)
# ax[0] : spine을 data 영역에서 ^지정된 거리^만큼 이동
ax[0].spines["left"].set_position(("outward", -50))
# ax[1] : spine을 ^axes의 지정된 위치^에 설정
ax[1].spines["left"].set_position(("axes", 0.3))
# ax[2] : spine을 ^data의 지정된 위치^에 설정
ax[2].spines["left"].set_position(("data", 2.5))
5. Grid깔기¶
In [32]:
fig, ax = plt.subplots(ncols=3, figsize=(15, 3))
for i in range(3): # 그래프 세개 한번에 그리기
ax[i] = plot_example(ax[i])
ax[i].spines["top"].set_visible(False)
ax[i].spines["right"].set_visible(False)
ax[0].spines["left"].set_position(("outward", 10))
# axis={“both”, “x”, “y”} 인자로 방향을 지정한다.
# ax[0] : x, y 둘 다
ax[0].grid(axis="both")
# ax[1] : x축에서만
ax[1].grid(axis="x")
# ax[2] : y축에서만
ax[2].grid(axis="y")
major grid와 minor grid 구분해서 깔기¶
In [56]:
# !!! 오류나는 코드임 !!!
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
fig, ax = plt.subplots()
ax = plot_example(ax)
# top, right, left spines 안보이기
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
# y축 tick 설정
ax.yaxis.set_major_locator(MultipleLocator(1)) # major tick을 1 단위로 설정
ax.yaxis.set_major_formatter('{x:0.2f}') # major tick format 지정
ax.yaxis.set_minor_locator(MultipleLocator(0.5)) # minor tick을 0.5 단위로 지정
plt.plot()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-56-33d5c6f4fbaf> in <module>() 11 # y축 tick 설정 12 ax.yaxis.set_major_locator(MultipleLocator(1)) # major tick을 1 단위로 설정 ---> 13 ax.yaxis.set_major_formatter('{x:0.2f}') # major tick format 지정 14 ax.yaxis.set_minor_locator(MultipleLocator(0.5)) # minor tick을 0.5 단위로 지정 15 /usr/local/lib/python3.7/dist-packages/matplotlib/axis.py in set_major_formatter(self, formatter) 1626 formatter : `~matplotlib.ticker.Formatter` 1627 """ -> 1628 cbook._check_isinstance(mticker.Formatter, formatter=formatter) 1629 self.isDefault_majfmt = False 1630 self.major.formatter = formatter /usr/local/lib/python3.7/dist-packages/matplotlib/cbook/__init__.py in _check_isinstance(_types, **kwargs) 2126 ", ".join(names[:-1]) + " or " + names[-1] 2127 if len(names) > 1 else names[0], -> 2128 type_name(type(v)))) 2129 2130 TypeError: 'formatter' must be an instance of matplotlib.ticker.Formatter, not a str
세팅 환경에 의해서 ax.yaxis.set_major_formatter(formatter) 에서 오류 발생.
TypeError: 'formatter' must be an instance of matplotlib.ticker.Formatter, not a str
set_major_formatter에는 matplotlib.ticker.Formatter의 형식으로 들어가야 한다.
해결방법
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, FuncFormatter)
을 설치하고,
def major_formatter(x, pos):
return "{%.2f}" % x
formatter = FuncFormatter(major_formatter)
이라는 함수를 따로 만들어 준다.
In [ ]:
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, FuncFormatter)
def major_formatter(x, pos):
return "{%.2f}" % x
formatter = FuncFormatter(major_formatter)
In [49]:
#정상 작동
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
fig, ax = plt.subplots()
ax = plot_example(ax)
# top, right, left spines 안보이기
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
# y축 tick 설정
#여기서 major 라인, minor 라인 먼저 설정한다.
ax.yaxis.set_major_locator(MultipleLocator(1)) # major tick을 1 단위로 설정
ax.yaxis.set_major_formatter(formatter) # major tick format 지정 (오류가 나면 matplotlib upgrade)
ax.yaxis.set_minor_locator(MultipleLocator(0.5)) # minor tick을 0.5 단위로 지정
plt.plot()
Out[49]:
[]
In [52]:
fig, ax = plt.subplots(ncols=3, figsize=(15, 3))
for i in range(3): # 그래프 세개 한번에 그리기
ax[i] = plot_example(ax[i], zorder=2) # zorder: bar를 grid 앞으로.
ax[i].spines["top"].set_visible(False)
ax[i].spines["right"].set_visible(False)
ax[i].spines["left"].set_position(("outward", 10))
ax[i].yaxis.set_major_locator(MultipleLocator(1))
ax[i].yaxis.set_major_formatter(formatter)
ax[i].yaxis.set_minor_locator(MultipleLocator(0.5))
# ax[0] : major, minor 둘 다
ax[0].grid(axis="y", which="both")
# ax[1] : major만
ax[1].grid(axis="y", which="major")
# ax[2] : major만 + 여러 옵션
ax[2].grid(axis="y", which="major", color="r", ls=":", lw=0.5, alpha=0.5) #clolor red, 점선, 투명도 낮추기.
plt.show()
In [55]:
fig, ax = plt.subplots()
ax = plot_example(ax, zorder=2)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.yaxis.set_major_locator(MultipleLocator(1))
ax.yaxis.set_major_formatter(formatter)
ax.yaxis.set_minor_locator(MultipleLocator(0.5))
ax.grid(axis="y", which="major", color="lightgray") # major line에는 강조하기위해 회색줄
ax.grid(axis="y", which="minor", ls=":") # minor라인에는 점선 줄
You need to set
install_url
to use ShareThis. Please set it in _config.yml
.