1. Grid ์ดํดํ๊ธฐ
1.1 Default Grid
๊ธฐ๋ณธ์ ์ธ Grid๋ ์ถ๊ณผ ํํํ ์ ์ ์ฌ์ฉํ์ฌ ๊ฑฐ๋ฆฌ ๋ฐ ๊ฐ ์ ๋ณด๋ฅผ ๋ณด์กฐ์ ์ผ๋ก ์ ๊ณตํ๋ค.
์์ ๋ค๋ฅธ ํํ๋ค์ ๋ฐฉํดํ์ง ์๋๋ก ๋ฌด์ฑ์
ํญ์ Layer ์์ ์ ๋งจ ๋ฐ์ ์ค๋๋ก zorder๋ฅผ ์กฐ์
ํฐ ๊ฒฉ์์ ์ธ๋ถ ๊ฒฉ์๋ which=
๋ก major
์ minor
๊ทธ๋ฆฌ๊ณ both
๋ก ์ค์ ํ ์ ์๋ค
X์ถ, Y์ถ๋ axis=
๋ก x
์ y
๊ทธ๋ฆฌ๊ณ both
๋ก ์ค์ ํ ์ ์๋ค.
1.2 ๋ค์ํ ํ์
์ Grid
์ ํ์ ์ธ Grid๋ ์๋์ง๋ง ์ฌ๋ฌ ํํ๋ก ์กด์ฌํ๋ค.
๋ ๋ณ์์ ํฉ์ด ์ค์ํ๋ค : x+y=c
๋น์จ์ด ์ค์ํ๋ค : y=cx
๋ ๋ณ์์ ๊ณฑ์ด ์ค์ํ๋ค : xy = c
ํน์ ๋ฐ์ดํฐ๋ฅผ ์ค์ฌ์ผ๋ก ๋ณด๊ณ ์ถ๋ค : (x-x')^2 + (y-y')^2 = c
์ ๋ง์ ์์๊ฐ ์๋ค.
๊ธฐ๋ณธ์ ์ธ Grid
๋ ๋ณ์์ ํฉ์ด ์ค์ํ ๊ทธ๋ฆฌ๋
์ถ๊ตฌ์ ์์ ๊ณต๊ฒฉ๋ ฅ๊ณผ ์๋น๋ ฅ ๋น๊ต
๊ณ ๋ฑํ์์ ์ํ์ ์์ ์์ด์ ์ ๋น๊ต
๋น์จ์ด ์ค์ํ ๊ทธ๋ฆฌ๋
๊ฐํ๋ฅผ์๋ก Y/X ๊ฐ ์ปค์ง๋ฉฐ, Feature์ ๋น์จ์ด ์ค์ํ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ค.
ํฌ์๋๋น ์ป์ ์ ์๋ ์์ ์์ต๋
ํน์ ๋ฐ์ดํฐ๊ฐ ์ค์ฌ์ธ ๊ทธ๋ฆฌ๋
ํด๋ฌ์คํฐ๋ฅผ ํํํ ๋ ์ข๋ค.
circle
๋ก๋ ํํํ ์ ์์ง๋ง plot
์ผ๋ก ํํํ ๊ฒ์
2. ์ฌํํ ์ฒ๋ฆฌ
2.1 ์ ์ถ๊ฐํ๊ธฐ
์ํ๊ณผ ํํ์ ํํํ๋ ๋์์
ํ๊ท ์ ํํํ๊ธฐ ์ํ ์ ์
์์ ์ด ์ค์ฌ์ด๋ผ๋ ๊ฒ์ ํํํ๊ธฐ ์ํด y์ถ๊ณผ ํํํ๊ฒ ๊ทธ์ ์ค์
2.2 ๋ฉด ์ถ๊ฐํ๊ธฐ
์ฐ๋ น๋ณ๋ก ๊ตฌ๋ถํด์ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ๊ฐ๋
์ฑ์ด ์ข์์ง๋ ๋ชจ์ต
3. Setting ๋ฐ๊พธ๊ธฐ
3.1 Theme
๋ํ์ ์ผ๋ก fivethirtyeight์ด๋ ggplot์ ์ฌ์ฉํ๋ค.
์ ๋ณด๋์ ๋๋ฆฌ๊ณ , ๋ ๊น๋ํ matplotlib์ ์ํ ํ๋ค์ ์์๋ด
์๋ค.
1. Grid
๊ฐ์์์ ์๊ฐํ ๋ด์ฉ์ ์ฝ๋๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค.
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
1-1. grid
๊ธฐ๋ณธ์ ์ธ Grid๋ถํฐ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๊ธฐ๋ณธ์ ์ธ ๊ทธ๋ฆฌ๋์์๋ ๋ค์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
which
: major ticks, minor ticks
fig, ax = plt.subplots()
ax.grid()
plt.show()
np.random.seed(970725)
x = np.random.rand(20)
y = np.random.rand(20)
fig = plt.figure(figsize=(16, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)
# scatter๋ ์ ์ด ๋๋ฌด ํฌ๋ฉด grid์ ์ ์ด์ธ๋ฆฌ์ง ์๋๋ค
ax.scatter(x, y, s=150,
c='#1ABDE9',
linewidth=1.5,
edgecolor='black', zorder=10)
# ax.set_xticks(np.linspace(0, 1.1, 12, endpoint=True), minor=True)
ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)
# ๊ฒน์น์ง ์๊ฒ ํ๊ธฐ ์ํด zorder๋ฅผ ์ค์ , plot์ฒ๋ผ linestyle ์ฌ์ฉ๊ฐ๋ฅ
# axis๋ก ์ถ์ ์ ํด์ค ์๋ ์๋ค : y, x, both
# linewidth๋ก grid์ ์ ๋๊ป๋ฅผ ์ ํด์ค ์ ์๋ค. ์์ผ๋ฉด ์ธ๋ จ๋๋ณด์ด๊ณ ํฌ๋ฉด ๋งํ๊ฐ์ ๋ณด์ธ๋ค
ax.grid(zorder=0, linestyle='--')
ax.set_title(f"Default Grid", fontsize=15,va= 'center', fontweight='semibold')
plt.tight_layout()
plt.show()
1-2. x + y = c
๊ทธ๋ฆฌ๋ ๋ณ๊ฒฝ์ grid ์์ฑ์ ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ๋ ์กด์ฌํ์ง๋ง ๊ฐ๋จํ ์์์ ์ฌ์ฉํ๋ฉด ์ฝ๊ฒ ๊ทธ๋ฆด ์ ์์ต๋๋ค.
fig = plt.figure(figsize=(16, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)
ax.scatter(x, y, s=150,
c=['#1ABDE9' if xx+yy < 1.0 else 'darkgray' for xx, yy in zip(x, y)],
linewidth=1.5,
edgecolor='black', zorder=10)
## Grid Part
x_start = np.linspace(0, 2.2, 12, endpoint=True)
for xs in x_start:
ax.plot([xs, 0], [0, xs], linestyle='--', color='gray', alpha=0.5, linewidth=1)
ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)
ax.set_title(r"Grid ($x+y=c$)", fontsize=15,va= 'center', fontweight='semibold')
plt.tight_layout()
plt.show()
1-3. y = cx
fig = plt.figure(figsize=(16, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)
ax.scatter(x, y, s=150,
c=['#1ABDE9' if yy/xx >= 1.0 else 'darkgray' for xx, yy in zip(x, y)],
linewidth=1.5,
edgecolor='black', zorder=10)
## Grid Part
radian = np.linspace(0, np.pi/2, 11, endpoint=True)
for rad in radian:
ax.plot([0,2], [0, 2*np.tan(rad)], linestyle='--', color='gray', alpha=0.5, linewidth=1)
ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)
ax.set_title(r"Grid ($y=cx$)", fontsize=15,va= 'center', fontweight='semibold')
plt.tight_layout()
plt.show()
1-4. ๋์ฌ์
fig = plt.figure(figsize=(16, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)
ax.scatter(x, y, s=150,
c=['darkgray' if i!=2 else '#1ABDE9' for i in range(20)] ,
linewidth=1.5,
edgecolor='black', zorder=10)
## Grid Part
rs = np.linspace(0.1, 0.8, 8, endpoint=True)
for r in rs:
xx = r*np.cos(np.linspace(0, 2*np.pi, 100))
yy = r*np.sin(np.linspace(0, 2*np.pi, 100))
ax.plot(xx+x[2], yy+y[2], linestyle='--', color='gray', alpha=0.5, linewidth=1)
ax.text(x[2]+r*np.cos(np.pi/4), y[2]-r*np.sin(np.pi/4), f'{r:.1}', color='gray')
ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)
ax.set_title(r"Grid ($(x-x')^2+(y-y')^2=c$)", fontsize=15,va= 'center', fontweight='semibold')
plt.tight_layout()
plt.show()
2. Line & Span
์ฐ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ฒ ์ต๋๋ค.
import pandas as pd
student = pd.read_csv('./StudentsPerformance.csv')
student.head()
parental level of education
2-1. Line
์ง๊ต์ขํ๊ณ์์ ํํ์ ์ ์ํ๋ ๋ถ๋ถ ๊ทธ๋ฆด ์๋ ์์ต๋๋ค.
์ ์ Plot์ผ๋ก ๊ทธ๋ฆฌ๋๊ฒ ๋ ํธํ ์ ์๊ธฐ์ ์ํ๋ ๋ฐฉ์์ผ๋ก ๊ทธ๋ ค์ฃผ์๋ฉด ๋ฉ๋๋ค.
fig, ax = plt.subplots()
ax.set_aspect(1)
ax.axvline(0, color='red')
ax.axhline(0, color='green')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
plt.show()
ax์ ์ ์ฒด ๊ตฌ๊ฐ์ 0, 1๋ก ์ผ์ ํน์ ๋ถ๋ถ์๋ง ์ ์ ๊ทธ๋ฆด ์๋ ์์ต๋๋ค.
๋ค๋ง ๋ค์๊ณผ ๊ฐ์ด ํน์ ๋ถ๋ถ์ ์ ์ผ๋ก ํ ๋๋ ์คํ๋ ค plot์ด ์ข์ต๋๋ค.
fig, ax = plt.subplots()
ax.set_aspect(1)
ax.axvline(0, ymin=0.3, ymax=0.7, color='red')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
plt.show()
fig, ax = plt.subplots(figsize=(10, 10))
ax.set_aspect(1)
math_mean = student['math score'].mean()
reading_mean = student['reading score'].mean()
ax.axvline(math_mean, color='gray', linestyle='--')
ax.axhline(reading_mean, color='gray', linestyle='--')
ax.scatter(x=student['math score'], y=student['reading score'],
alpha=0.5,
color=['royalblue' if m>math_mean and r>reading_mean else 'gray' for m, r in zip(student['math score'], student['reading score'])],
zorder=10,
)
ax.set_xlabel('Math')
ax.set_ylabel('Reading')
ax.set_xlim(-3, 103)
ax.set_ylim(-3, 103)
plt.show()
ํ๊ท ๋ณด๋ค ๋์ ์ ๋ค์ ๋ํด์๋ง ์์ ํํํ๋ค.
2-2. Span
์ ๊ณผ ํจ๊ป ๋ค์๊ณผ ๊ฐ์ด ํน์ ๋ถ๋ถ ๋ฉด์ ์ ํ์ํ ์ ์์ต๋๋ค.
fig, ax = plt.subplots()
ax.set_aspect(1)
ax.axvspan(0,0.5, color='red')
ax.axhspan(0,0.5, color='green')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
plt.show()
fig, ax = plt.subplots()
ax.set_aspect(1)
ax.axvspan(0,0.5, ymin=0.3, ymax=0.7, color='red')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
plt.show()
ํน์ ๋ถ๋ถ์ ๊ฐ์กฐํ ์๋ ์์ง๋ง, ์คํ๋ ค ํน์ ๋ถ๋ถ์ ์ฃผ์๋ฅผ ์์จ ์๋ ์์ต๋๋ค.
fig, ax = plt.subplots(figsize=(8, 8))
ax.set_aspect(1)
math_mean = student['math score'].mean()
reading_mean = student['reading score'].mean()
ax.axvspan(-3, math_mean, color='gray', linestyle='--', zorder=0, alpha=0.3)
ax.axhspan(-3, reading_mean, color='gray', linestyle='--', zorder=0, alpha=0.3)
ax.scatter(x=student['math score'], y=student['reading score'],
alpha=0.4, s=20,
color=['royalblue' if m>math_mean and r>reading_mean else 'gray' for m, r in zip(student['math score'], student['reading score'])],
zorder=10,
)
ax.set_xlabel('Math')
ax.set_ylabel('Reading')
ax.set_xlim(-3, 103)
ax.set_ylim(-3, 103)
plt.show()
2-3. Spines
ax.spines
: ๋ง์ ์์๊ฐ ์์ง๋ง ๋ํ์ ์ธ 3๊ฐ์ง๋ฅผ ์ดํด๋ด
์๋ค.
set_visible : ์ถ์ ์๋ณด์ด๊ฒํจ
set_linewidth : ์ถ์ ๋๊ผ๋ฅผ ์ค์
set_position : ์ถ์ ์์น๋ฅผ ์ฎ๊ธด๋ค
fig = plt.figure(figsize=(12, 6))
_ = fig.add_subplot(1,2,1)
ax = fig.add_subplot(1,2,2)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_linewidth(1.5)
ax.spines['bottom'].set_linewidth(1.5)
plt.show()
fig = plt.figure(figsize=(12, 6))
_ = fig.add_subplot(1,2,1)
ax = fig.add_subplot(1,2,2)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
plt.show()
์ถ์ ๊ผญ ์ค์ฌ ์ธ์๋ ์ํ๋ ๋ถ๋ถ์ผ๋ก ์ฎ๊ธธ ์ ์์ต๋๋ค.
'center'
-> ('axes', 0.5)
fig = plt.figure(figsize=(12, 6))
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
for ax in [ax1, ax2]:
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax1.spines['left'].set_position('center')
ax1.spines['bottom'].set_position('center')
ax2.spines['left'].set_position(('data', 0.3))
ax2.spines['bottom'].set_position(('axes', 0.2))
ax2.set_ylim(-1, 1)
plt.show()
๋น์จ์ ์ธ ์ธก๋ฉด์์ ๋ฐ๊ฟ ๋๋ axes๋ฅผ, ํน์ ๋ฐ์ดํฐ์ ์์น๋ก ๋ฐ๊ฟ ๋์๋ ๋ฐ์ดํฐ์ ์์น์ tupleํํ๋ก ์ค์ ํ๋ฉด ๋๋ค.
fig = plt.figure(figsize=(12, 9))
ax = fig.add_subplot(aspect=1)
x = np.linspace(-np.pi, np.pi, 1000)
y = np.sin(x)
ax.plot(x, y)
ax.set_xlim(-np.pi, np.pi)
ax.set_ylim(-1.2, 1.2)
ax.set_xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
ax.set_xticklabels([r'$\pi$', r'-$-\frac{\pi}{2}$', r'$0$', r'$\frac{\pi}{2}$', r'$\pi$'],)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
plt.show()
3. Settings
3-1. mpl.rc
plt.rcParams['lines.linewidth'] = 2
plt.rcParams['lines.linestyle'] = ':'
# plt.rcParams['figure.dpi'] = 150
plt.rc('lines', linewidth=2, linestyle=':')
plt.rcParams.update(plt.rcParamsDefault)
3-2. theme
print(mpl.style.available)
mpl.style.use('seaborn')
# mpl.style.use('./CUSTOM.mplstyle') # ์ปค์คํ
์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด
plt.plot([1, 2, 3])
['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']
with plt.style.context('fivethirtyeight'):
plt.plot(np.sin(np.linspace(0, 2 * np.pi)))
plt.show()
plt.plot(np.sin(np.linspace(0, 2 * np.pi)))