Matplot Library 사용법 (Descriptive Statistics)

김신영·2024년 6월 2일
0
post-thumbnail

Matplot Library

Matplotlib은 Python에서 정적, 애니메이션 및 인터랙티브 시각화를 생성하기 위한 종합적인 라이브러리입니다.

Matplotlib은 쉬운 것은 더욱 쉽게, 어려운 것도 가능하게 합니다.

Matplotlib — Visualization with Python

Install

pip install matplotlib

matplotlib 한글 및 스타일 세팅

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams['font.family'] = 'AppleGothic' # 윈도우에서는 'Malgun Gothic'
mpl.rcParams['axes.unicode_minus'] = False
plt.style.use('_mpl-gallery')

Graph 종류

https://matplotlib.org/stable/plot_types/index

Plot

https://matplotlib.org/stable/plot_types/basic/plot.html#sphx-glr-plot-types-basic-plot-py

EMPTY

plt.plot(x, y, fmt, …)

  • 펼쳐보기 (docs)
    Signature:
    plt.plot(
        *args: 'float | ArrayLike | str',
        scalex: 'bool' = True,
        scaley: 'bool' = True,
        data=None,
        **kwargs,
    ) -> 'list[Line2D]'
    Docstring:
    Plot y versus x as lines and/or markers.
  • x, y 기준으로 그래프를 그린다.
  • fmt 옵션 목록
    • Markers
      CharacterDescription
      '.'포인트 마커
      ','픽셀 마커
      'o'원형 마커
      'v'아래쪽 삼각형 마커
      '^'위쪽 삼각형 마커
      '<'왼쪽 삼각형 마커
      '>'오른쪽 삼각형 마커
      '1'아래쪽 작은 삼각형 마커
      '2'위쪽 작은 삼각형 마커
      '3'왼쪽 작은 삼각형 마커
      '4'오른쪽 작은 삼각형 마커
      '8'팔각형 마커
      's'사각형 마커
      'p'오각형 마커
      'P'플러스 (채워진) 마커
      '*'별 마커
      'h'육각형1 마커
      'H'육각형2 마커
      '+'플러스 마커
      'x'X 마커
      'X'X (채워진) 마커
      'D'다이아몬드 마커
      'd'얇은 다이아몬드 마커
      `''`
      '_'수평선 마커
    • Line Styles
      CharacterDescription
      '-'실선 스타일
      '--'대시선 스타일
      '-.'대시-점선 스타일
      ':'점선 스타일
    • Colors
      CharacterColor
      'b'blue
      'g'green
      'r'red
      'c'cyan
      'm'magenta
      'y'yellow
      'k'black
      'w'white
  • 코드 예시
    # make data
    x = np.linspace(-5, 5, 20)
    y1 = x ** 3
    y2 = 5 * x + 30
    y3 = 4 * (x ** 2) - 20
    y4 = -25 * x + 20 
    
    # plot
    
    plt.xlim()
    plt.plot(x, y1, '--g')
    plt.plot(x, y2, ':b')
    plt.plot(x, y3, '-.r')
    plt.plot(x, y4)
    
    # plt.xlim(-5, 5)
    # plt.ylim(-10, 100)
    # plt.xticks(np.arange(-5, 6))
    # plt.yticks(np.arange(-100, 121, 20))
    plt.grid(True) # plt.grid()
    plt.show()

plt.xlim(), plt.ylim()

  • 그래프에서 x축, y축 값의 최대, 최소값 지정
  • 인자를 넘겨주지 않으면, get 함수
  • 인자를 넘겨주면, set 함수
left, right = xlim()  # return the current xlim
xlim((left, right))   # set the xlim to left, right
xlim(left, right)     # set the xlim to left, right

xlim(right=3)  # adjust the right leaving left unchanged
xlim(left=1)  # adjust the left leaving right unchanged

plt.xticks(), plt.yticks()

  • 그래프에서 x축, y축 그래프 tick 단위 선정
  • 인자를 넘겨주지 않으면, get 함수
  • 인자를 넘겨주면, set 함수
locs, labels = xticks()  # Get the current locations and labels.

xticks(np.arange(0, 1, step=0.2))  # Set label locations.
xticks(np.arange(3), ['Tom', 'Dick', 'Sue'])  # Set text labels.
xticks([0, 1, 2], ['January', 'February', 'March'], rotation=20)  # Set text labels and properties.
xticks([])  # Disable xticks.

plt.xlabel(xlabel), plt.ylabel(ylabel)

  • x축, y축에 이름을 지정해준다.

plt.title(title)

  • 그래프 제목을 지정해준다.

plt.legend(loc=None)

  • loc 옵션 목록
    Location StringLocation Code
    'best' (Axes only)0
    'upper right'1
    'upper left'2
    'lower left'3
    'lower right'4
    'right'5
    'center left'6
    'center right'7
    'lower center'8
    'upper center'9
    'center'10

plt.figure(num = None)

  • 현재까지 plot한 그래프 창을 생성한다.
  • 만약 이미 존재한다면, 해당 그래프(Figure)를 지정한다.
  • 펼쳐보기 (docs)
    Signature:
    plt.figure(
        num: 'int | str | Figure | SubFigure | None' = None,
        figsize: 'tuple[float, float] | None' = None,
        dpi: 'float | None' = None,
        *,
        facecolor: 'ColorType | None' = None,
        edgecolor: 'ColorType | None' = None,
        frameon: 'bool' = True,
        FigureClass: 'type[Figure]' = <class 'matplotlib.figure.Figure'>,
        clear: 'bool' = False,
        **kwargs,
    ) -> 'Figure'
    Docstring:
    Create a new figure, or activate an existing figure.

plt.clf()

  • 현재 선택된 Figure 삭제
  • 코드 예시
    # make data
    x = np.linspace(-5, 5, 20)
    y1 = x ** 3
    y2 = 5 * x + 30
    y3 = 4 * (x ** 2) - 20
    y4 = -25 * x + 20 
    
    plt.figure("y=x^3")
    plt.plot(x, y1, '--g')
    plt.grid()
    
    plt.figure("y=5x+30")
    plt.plot(x, y2, ':b')
    plt.grid()
    
    plt.clf() # (x, y2) 그래프는 삭제됨
    
    plt.figure("y=4x^2-20")
    plt.plot(x, y3, '-.r')
    plt.grid()
    
    plt.figure("y=-25x+20")
    plt.plot(x, y4)
    plt.grid()
    
    plt.clf() # (x, y4) 그래프는 삭제됨
    
    plt.show()

plt.subplots(nrows=1, ncols=1)

  • 하나의 그래프 창을 하위 그래프 영역으로 나눈다.
  • 코드 예시
    # using the variable ax for single a Axes
    fig, ax = plt.subplots()
    
    # using the variable axs for multiple Axes
    fig, axs = plt.subplots(2, 2)
    
    axs[0, 0].plot(x, y1)
    axs[0][1].plot(x, y2
    
    # using tuple unpacking for multiple Axes
    fig, (ax1, ax2) = plt.subplots(1, 2)
    fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
    
    # make data
    x = np.linspace(0, 10, 100)
    y1 = 4 + 1 * np.sin(2 * x)
    x2 = np.linspace(0, 10, 25)
    y2 = 4 + 1 * np.sin(2 * x2)
    y3 = 4 + 1 * np.cos(2 * x)
    y4 = 4 + 1 * np.cos(2 * x2)
    
    # plot
    fig, axs = plt.subplots(2,2)
    
    axs[0, 0].plot(x, y1, 'x', markeredgewidth=2)
    axs[0][1].plot(x2, y2, linewidth=2.0)
    axs[1, 0].plot(x, y3, 'o-', linewidth=2)
    axs[1][1].plot(x2, y4)
    
    for ax in axs:
        for x in ax:
            x.set(xlim=(0, 8), xticks=np.arange(1, 8), ylim=(0, 8), yticks=np.arange(1, 8))
    
    plt.show()

plt.subplot(nrows, ncols, index)

  • index : 1부터 시작하는 인덱스
  • subplot을 직접 추가
  • plt.subplots(nrows, ncols, index) 한번에 모든 subplot을 만드는 반면
    • 이 함수는 한번에 하나씩 만들고 plot함
  • 코드 예시
    # make data
    x = np.linspace(-5, 5, 20)
    y1 = x ** 3
    y2 = 5 * x + 30
    y3 = 4 * (x ** 2) - 20
    y4 = -25 * x + 20 
    
    # subplot
    nrows, ncols = (2, 2)
    
    plt.subplot(nrows, ncols, 1)
    plt.plot(x, y1, '--g')
    plt.subplot(nrows, ncols, 2)
    plt.plot(x, y2, ':b')
    plt.subplot(nrows, ncols, 3)
    plt.plot(x, y3, '-.r')
    plt.subplot(nrows, ncols, 4)
    plt.plot(x, y4)
    
    plt.show()

plt.text(x, y, text)

  • Axes 에 텍스트를 추가한다.

Bar Chart

https://matplotlib.org/stable/plot_types/basic/bar.html#sphx-glr-plot-types-basic-bar-py

  • 코드 예시
    # make data:
    ids = np.arange(4) + 1
    member_ids = list(map(lambda x: f"m_{x:02d}", ids))
    
    before_ex = [27, 35, 40, 33]
    after_ex = [30, 38, 42, 37]
    
    # plot
    bar_width = 0.3
    line_width = 1
    
    plt.bar(ids, before_ex, label = 'before', width=bar_width, color = 'm', edgecolor="white", linewidth=line_width)
    # plt.barh(ids, before_ex, label = 'before', height=bar_width, color = 'm', edgecolor="white", linewidth=line_width)
    plt.bar(ids + bar_width, after_ex, label = 'after', width=bar_width, color = 'c', edgecolor="white", linewidth=line_width)
    # plt.barh(ids + bar_width, after_ex, label = 'after', height=bar_width, color = 'c', edgecolor="white", linewidth=line_width)
    
    plt.xticks(ids + bar_width, member_ids)
    plt.xlabel('회원 ID')
    plt.ylabel('윗몸일으키기 횟수')
    plt.title('운동 시작 전과 후의 근지구력 변화 비교')
    plt.legend()
    
    plt.show()

Pie Chart

https://matplotlib.org/stable/plot_types/stats/pie.html#sphx-glr-plot-types-stats-pie-py

  • 코드 예시
    fruit = ['사과', '바나나', '딸기', '오렌지', '포도']
    result = [7, 6, 3, 2, 2]
    
    # colors = plt.get_cmap('Blues')(np.linspace(0.2, 0.7, len(fruit)))
    
    explode_value = (0.3, 0.1, 0.1, 0.1, 0.1) # the radius with which to offset each wedge.
    plt.figure(figsize=(3,3))
    plt.pie(result, labels=fruit, colors=['m', 'y', 'r', 'c', 'g'], autopct='%.0f%%', startangle=90, counterclock=False, explode=explode_value, shadow=True)
    
    plt.title("과일 판매량 비율")
    plt.legend(loc=4)
    plt.show()

plt.get_cmap(colorName)

  • 색깔을 매핑시켜주는 함수를 리턴
    • [0, 1] 사이의 값을 주면, 색깔 RGB값을 리턴한다.
  • plt.get_cmap('Reds')
  • plt.get_cmap('Greens')
  • plt.get_cmap('Blues')
colors = plt.get_cmap('Blues')(np.linspace(0.2, 0.7, 5))

Histogram

https://matplotlib.org/stable/plot_types/stats/hist_plot.html#sphx-glr-plot-types-stats-hist-plot-py

  • 코드 예시
    def round_score(x):
        if x > 100: 
            return 100 
        elif x < 0:
            return 0
        else: 
            return round(x) 
    
    math_scores = list(map(lambda x: round_score(x), 10 * np.random.randn(100) + 70))
    
    fig, ax = plt.subplots()
    plt.hist(math_scores, bins=8, linewidth=0.5, edgecolor="white")
    plt.xlabel('수학 점수')
    plt.ylabel('frequency')
    plt.title('수학 점수 histogram')
    fig.set_size_inches(3, 3)

Box Plot

https://matplotlib.org/stable/plot_types/stats/boxplot_plot.html#sphx-glr-plot-types-stats-boxplot-plot-py

https://seaborn.pydata.org/generated/seaborn.boxplot.html

  • plt.boxplot 코드 예시
    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.style.use('_mpl-gallery')
    
    # make data:
    np.random.seed(10)
    D =np.random.normal((3, 5, 4), (1.25, 1.00, 1.25), (100, 3))
    
    # plot
    fig,ax =plt.subplots()
    VP =ax.boxplot(D, positions=[2, 4, 6], widths=1.5, patch_artist=True,
                    showmeans=False, showfliers=False,
                    medianprops={"color": "white", "linewidth": 0.5},
                    boxprops={"facecolor": "C0", "edgecolor": "white",
                              "linewidth": 0.5},
                    whiskerprops={"color": "C0", "linewidth": 1.5},
                    capprops={"color": "C0", "linewidth": 1.5})
    
    ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
           ylim=(0, 8), yticks=np.arange(1, 8))
    
    plt.show()
  • sns.boxplot 코드 예시
    import seaborn as sns
    
    before_ex = np.random.randn(100) * 10 + 30
    before_ex = list(map(lambda x: round(x), before_ex))
    
    after_ex = list(map(lambda x: x + np.random.randint(0, 21), before_ex))
    
    data = np.array([before_ex, after_ex]).transpose()
    
    df = pd.DataFrame(data, columns=['before_ex', 'after_ex'])
    
    sns.boxplot(df, orient="h", palette="Set2")

Scatter Plot (산점도)

https://matplotlib.org/stable/plot_types/basic/scatter_plot.html#sphx-glr-plot-types-basic-scatter-plot-py

  • 코드 예시
    sample_size = 1000
    
    base_normal_sample = np.random.randn(sample_size)
    
    def transform_normal_sample(loc, scale):
        return list(map(lambda x: round(x), loc + scale * base_normal_sample))
    
    height = list(map(lambda x: round(x), 170 + 10 * base_normal_sample))
    weight = list(map(lambda x: round(x), 70 + 5 * base_normal_sample))
    
    weight = list(map(lambda x: x + np.random.randint(0, 21), weight)) # 오차 적용
    
    fig, ax = plt.subplots()
    fig.set_size_inches(3,3)
    plt.scatter(height, weight, s=2)
    ax.set(xlabel="키", ylabel="체중", title="체중과 키 산점도")
    
    plt.show()

Measurement를 이용한 자료의 정리

Mean, Median, Mode

  • Mean: 평균
  • Median: 중앙값
  • Mode: 최빈값

Mean

  • np.mean(arr)
  • np.average(arr)
  • ser.mean()
  • df.mean()

Median

  • np.median(arr)
  • ser.median()
  • df.median()

Mode

  • statistics.mode(arr)
  • ser.mode()
  • df.mode()

Variability (산포)

Variance

  • np.var(arr, ddof=1)

Standard Deviation

  • np.std(arr, ddof=1)

Range (max, min)

  • np.max(arr)
  • np.min(arr)
  • ser.max()
  • ser.min()
  • df.max()[0]
  • df.min()[0]

IQR (Quartile, Quantile, Percentile)

  • np.quantile(arr, [0.25, 0.5, 0.75])
  • np.percentile(arr, [25, 50, 75])
  • ser.quantile([0.25, 0.5, 0.75]).to_numpy()
  • df.quantile([0.25, 0.5, 0.75]).to_numpy()

Shape

Skewness (왜도)

  • scipy.stats.skew(arr)
  • skewness 가 음수이면,
    • mean < median < mode
  • skewness 가 양수이면,
    • mode < median < mean

Kurtosis (첨도)

  • scipy.stats.kurtosis(arr)

  • Mesokurtic : 이 분포는 정규 분포와 유사한 첨도 통계량을 가지고 있다. 분포의 극단값이 정규 분포 특성과 유사하다는 뜻이다. 표준 정규 분포는 3의 첨도 갖는다.
  • Leptokurtic (Kurtosis > 3) : 분포가 길고, 꼬리가 더 뚱뚱하다. 피크는 Mesokurtic보다 높고 날카롭기 때문에 데이터는 꼬리가 무겁거나 특이치(outlier)가 많다는 것을 의미한다.특이치(outlier)는 히스토그램 그래프의 수평 축을 확장하여 데이터의 대부분이 좁은 수직 범위로 나타나도록 하여 Leptokurtic 분포의 "skinniness"을 부여한다.
  • Platykurtic (Kurtosis < 3) : 분포는 짧고 꼬리는 정규 분포보다 얇다. 피크는 Mesokurtic보다 낮고 넓으며, 이는 데이터가 가벼운 편이나 특이치(outlier)가 부족하다는 것을 의미한다.이유는 극단값(extream value)이 정규 분포의 극단값보다 작기 때문이
profile
Hello velog!

0개의 댓글

관련 채용 정보