# (3-4) More Tips

## 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`
* [여기](https://medium.com/nightingale/gotta-gridem-all-2f768048f934)에 많은 예시가 있다.

기본적인 Grid

![](https://2275555537-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNN4u9o9noCQwX8pO35%2F-MhqQJyWIH3kCtIRRveI%2F-MhqViSh2CB_GULeXfFx%2Fimage.png?alt=media\&token=c5c70c86-9a8a-4247-9e37-a054bf51ccf9)

두 변수의 합이 중요한 그리드

![](https://2275555537-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNN4u9o9noCQwX8pO35%2F-MhqQJyWIH3kCtIRRveI%2F-MhqW3ZBUpUZJXN0pccN%2Fimage.png?alt=media\&token=a240b4be-7387-4d77-87a1-d201a20ab208)

* 축구선수의 공격력과 수비력 비교
* 고등학생의 수학점수와 영어점수 비교

비율이 중요한 그리드

![](https://2275555537-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNN4u9o9noCQwX8pO35%2F-MhqQJyWIH3kCtIRRveI%2F-MhqW08e9debT02SXL2V%2Fimage.png?alt=media\&token=bea80dd3-6214-4463-a2f4-f6013185479d)

* 가파를수록 Y/X 가 커지며, Feature의 비율이 중요한 경우 사용한다.
* 투자대비 얻을 수 있는 예상 수익량

특정 데이터가 중심인 그리드

![](https://2275555537-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNN4u9o9noCQwX8pO35%2F-MhqQJyWIH3kCtIRRveI%2F-MhqWLAxnD9UNNv9TwkJ%2Fimage.png?alt=media\&token=a2f7e42f-0bd1-4e98-b411-b3101989ff03)

* 클러스터를 표현할 때 좋다.
* `circle` 로도 표현할 수 있지만 `plot` 으로 표현할 것임

## 2. 심플한 처리

### 2.1 선 추가하기

![](https://2275555537-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNN4u9o9noCQwX8pO35%2F-MhqQJyWIH3kCtIRRveI%2F-MhqWYd_O5Eopwhnjkdb%2Fimage.png?alt=media\&token=d07504da-2382-4add-bd20-10d074c926ac)

* 상한과 하한을 표현하는 대시선
* 평균을 표현하기 위한 점선
* 원점이 중심이라는 것을 표현하기 위해 y축과 평행하게 그은 실선

### 2.2 면 추가하기

![Netflix 영화 상영 등급 분포](https://2275555537-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNN4u9o9noCQwX8pO35%2F-MhqQJyWIH3kCtIRRveI%2F-MhqWoGOB1dUfghBpYrf%2Fimage.png?alt=media\&token=2802d578-2a3d-428f-8d80-ae957fe62109)

* 연령별로 구분해서 정보를 제공하니 가독성이 좋아지는 모습

## 3. Setting 바꾸기

### 3.1 Theme

![](https://2275555537-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNN4u9o9noCQwX8pO35%2F-MhqQJyWIH3kCtIRRveI%2F-MhqXVnAl4jsjCwZXky-%2Fimage.png?alt=media\&token=d821a0c3-aa92-42f8-b217-724c5e9e8949)

대표적으로 fivethirtyeight이나 ggplot을 사용한다.

## 3-4-More Information <a href="#id-3-4-more-information" id="id-3-4-more-information"></a>

정보량을 늘리고, 더 깔끔한 matplotlib을 위한 팁들을 알아봅시다.

### 1. Grid <a href="#id-1.-grid" id="id-1.-grid"></a>

강의에서 소개한 내용을 코드로 살펴보겠습니다.

```python
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
```

#### 1-1. grid <a href="#id-1-1.-grid" id="id-1-1.-grid"></a>

기본적인 Grid부터 살펴보겠습니다.

기본적인 그리드에서는 다음 파라미터를 살펴보겠습니다.

* `which` : major ticks, minor ticks
* `axis` : x, y
* `linestyle`
* `linewidth`
* `zorder`

```python
fig, ax = plt.subplots()
ax.grid()
plt.show()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2F3i4ezQBCFq81bvR6RVLP%2Ffile.png?alt=media)

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2F6tfx74lcNUHH9VquihO0%2Ffile.png?alt=media)

#### 1-2. x + y = c <a href="#id-1-2.-x--y-c" id="id-1-2.-x--y-c"></a>

그리드 변경은 grid 속성을 변경하는 방법도 존재하지만 간단한 수식을 사용하면 쉽게 그릴 수 있습니다.

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FnYsXiaw6prqhTFHJL44x%2Ffile.png?alt=media)

#### 1-3. y = cx <a href="#id-1-3.-y-cx" id="id-1-3.-y-cx"></a>

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FqGL1b1GdCCj6eGLJZkOY%2Ffile.png?alt=media)

#### 1-4. 동심원 <a href="#id-1-4" id="id-1-4"></a>

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FXFBUMsan0mrIqdq55LmE%2Ffile.png?alt=media)

### 2. Line & Span <a href="#id-2.-line-and-span" id="id-2.-line-and-span"></a>

우선 필요한 데이터를 불러오겠습니다.

```python
import pandas as pd 

student = pd.read_csv('./StudentsPerformance.csv')
student.head()
```

|   | gender | race/ethnicity | parental level of education | lunch        | test preparation course | math score | reading score | writing score |
| - | ------ | -------------- | --------------------------- | ------------ | ----------------------- | ---------- | ------------- | ------------- |
| 0 | female | group B        | bachelor's degree           | standard     | none                    | 72         | 72            | 74            |
| 1 | female | group C        | some college                | standard     | completed               | 69         | 90            | 88            |
| 2 | female | group B        | master's degree             | standard     | none                    | 90         | 95            | 93            |
| 3 | male   | group A        | associate's degree          | free/reduced | none                    | 47         | 57            | 44            |
| 4 | male   | group C        | some college                | standard     | none                    | 76         | 78            | 75            |

#### 2-1. Line <a href="#id-2-1.-line" id="id-2-1.-line"></a>

* `axvline()`
* `axhline()`

직교좌표계에서 평행선을 원하는 부분 그릴 수도 있습니다.

선은 Plot으로 그리는게 더 편할 수 있기에 원하는 방식으로 그려주시면 됩니다.

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2Fi8eCjUhWa6Usy4K18jcj%2Ffile.png?alt=media)

ax의 전체 구간을 0, 1로 삼아 특정 부분에만 선을 그릴 수도 있습니다.

다만 다음과 같이 특정 부분을 선으로 할 때는 오히려 plot이 좋습니다.

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FdX0aKxueSAV3O4h1dOY4%2Ffile.png?alt=media)

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FlEW1fekejQCCNL07DHDQ%2Ffile.png?alt=media)

평균보다 높은 점들에 대해서만 색을 표현했다.

#### 2-2. Span <a href="#id-2-2.-span" id="id-2-2.-span"></a>

* `axvspan`
* `axhspan`

선과 함께 다음과 같이 특정 부분 면적을 표시할 수 있습니다.

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FWHWGhJbbAPWI2j2Gw3SL%2Ffile.png?alt=media)

```
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2F07nJVEzZ1lfKadY0xzC0%2Ffile.png?alt=media)

특정 부분을 강조할 수도 있지만, 오히려 특정 부분의 주의를 없앨 수도 있습니다.

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FQkyw5C8QIxdN4MkiIUt5%2Ffile.png?alt=media)

#### 2-3. Spines <a href="#id-2-3.-spines" id="id-2-3.-spines"></a>

* `ax.spines` : 많은 요소가 있지만 대표적인 3가지를 살펴봅시다.
  * `set_visible : 축을 안보이게함`
  * `set_linewidth : 축의 두꼐를 설정`
  * `set_position : 축의 위치를 옮긴다`

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2Fd0BBEBTPIqNMzBYYbbbW%2Ffile.png?alt=media)

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2F7tK2BgODSe5RdbvrdXvk%2Ffile.png?alt=media)

축은 꼭 중심 외에도 원하는 부분으로 옮길 수 있습니다.

* `'center'` -> `('axes', 0.5)`
* `'zero'` -> `('data', 0.0)`

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2Fd8BiW0RVm60xMVxblKI9%2Ffile.png?alt=media)

비율적인 측면에서 바꿀 떄는 axes를, 특정 데이터에 위치로 바꿀 때에는 데이터의 위치에 tuple형태로 설정하면 된다.

```python
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()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FDz6DvvMsEeqpP2H0myrm%2Ffile.png?alt=media)

### 3. Settings <a href="#id-3.-settings" id="id-3.-settings"></a>

* [Customizing Matplotlib with style sheets and rcParams](https://matplotlib.org/stable/tutorials/introductory/customizing.html)

#### 3-1. mpl.rc <a href="#id-3-1.-mpl.rc" id="id-3-1.-mpl.rc"></a>

```python
plt.rcParams['lines.linewidth'] = 2
plt.rcParams['lines.linestyle'] = ':'

# plt.rcParams['figure.dpi'] = 150
```

```python
plt.rc('lines', linewidth=2, linestyle=':')
```

```python
plt.rcParams.update(plt.rcParamsDefault)
```

#### 3-2. theme <a href="#id-3-2.-theme" id="id-3-2.-theme"></a>

```python
print(mpl.style.available)

mpl.style.use('seaborn')
# mpl.style.use('./CUSTOM.mplstyle') # 커스텀을 사용하고 싶다면

plt.plot([1, 2, 3])
```

```python
['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']
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2F8gui6Zu8CmufdEdbCSJH%2Ffile.png?alt=media)

```python
with plt.style.context('fivethirtyeight'):
    plt.plot(np.sin(np.linspace(0, 2 * np.pi)))
plt.show()
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FpnqAsktgsYbfOTs9pIoC%2Ffile.png?alt=media)

```python
plt.plot(np.sin(np.linspace(0, 2 * np.pi)))
```

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MNN4u9o9noCQwX8pO35%2Fuploads%2FmWxTh3u2lW90HVUZd9RD%2Ffile.png?alt=media)
