Ch2 서울시 CCTV 현황 데이터 분석 12-20 (CCTV4-5)

김민지·2023년 3월 28일
0
  1. matplotlib의 기초
  • 파이썬의 대표 시각화 도구
import matplotlib.pyplot as plt

# %matplotlib inline (or)
get_ipython().run_line_magic("matplotlib", "inline")
# black 권고 : 정식 코드로 호출해서 사용하라는 의미
import matplotlib.pyplot as plt
from matplotlib import rc

rc("font", family="malgun Gothic")  # 한글폰트
%matplotlib inline
  • 삼각함수 그리기
import numpy as np
t = np.arrange(0, 12, 0.01)    # t에는 1200개의 수가 들어감
y = np.sin(t)                  # sin함수에 1200개의 수를 넣음

np.arange(a,b,s) -> a부터 b까지의 s의 간격
np.sin(value)

plt.figure(figsize=(10, 6))  # 그래프 사이즈를 정합(x축,y축)
t = np.arange(0, 5, 0.5)
plt.plot(t, t, "r--")     # (t,t)좌표를 찍어라. "r--":빨간색점선으로 표시
plt.plot(t, t ** 2, "bs")  # "bs": blue square
plt.plt(t, t ** 3, "g^"    # "g^": greeen triangle
colormap = t

def drawGraph():
    
    plt.figure(figsize=(10, 6))
    plt.scatter(t, y, s=70, c=colormap, marker=">") # 사이즈 70, t를 기준으로 colormap 표시(수치에 따라 색깔이 다름)
    plt.colorbar()
    plt.show()
    
drawGraph()
  1. CCTV 데이터 그래프로 표현하기
import matplotlib.pyplot as plt
# import matplotlib as mpl
from matplotlib import rc

plt.rcParams["axes.unicode_minus"] = False # 마이너스 부호 때문에 한글이 깨질 수 있어서 주는 설정
rc("font", family="Malgun Gothic")
%matplotlib inline
data_result["소계"].plot(kind="barh", grid=True, figsize=(10, 10));

-> 세미콜롬(;)을 해주면 그래프가 설명없이 깔끔하게 나옴

def drawGraph():
    data_result["CCTV비율"].sort_values().plot(
        kind="barh", grid=True, title="가장 CCTV가 많은 구", figsize=(10, 10));
drawGraph()

-> 내림차순 정렬, 그래프 제목 달기

  1. 데이터 경향을 직선으로 표현하기
  • Numpy를 이용한 1차 직선 만들기
    -> numpy가 제공하는 간단한 함수를 이용해서 1차직선 그래프 만들기
  • np.polyfit : 직선을 구성하기 위한 계수 계산
  • np.poly1d : polyfit으로 찾은 계수로 python에서 사용할 함수로 만들어 줌
  • np.linspace(a,b,n) : a부터 b까지 n개의 등간격 데이터 생성
import numpy as np
fp1 = np.polyfit(data_result["인구수"], data_result["소계"], 1)
f1 = np.poly1d(fp1)
f1(400000)

-> 인구가 40만인 구에서 서울시의 전체 경향에 맞는 적당한 CCTV 수를 구함

fx = np.linspace(100000, 700000, 100)

-> 경향선을 그리기 위한 x데이터 생성

def drawGraph():
    
    plt.figure(figsize=(14, 10))
    plt.scatter(data_result["인구수"], data_result["소계"], s=50)
    plt.plot(fx, f1(fx), ls="dashed", lw=3, color="g")
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.grid(True)
    plt.show()
drawGraph()
  1. 경향에서 벗어난 데이터 강조하기
  • 경향과의 오차 만들기
  • CCTV수 경향은 f1 함수에 해당 인구를 입력: f1(data_result["인구수"])
  • 현재값: data_result["소계"]
  • 오차: 현재값 - 경향(예측값)
fp1 = np.polyfit(data_result["인구수"], data_result["소계"], 1)
f1 = np.poly1d(fp1)
fx = np.linspace(100000, 700000, 100)
data_result["오차"] = data_result["소계"] - f1(data_result["인구수"])
# 경향과 비교해서 데이터의 오차가 너무 나는 데이터를 계산
df_sort_f = data_result.sort_values(by="오차", ascending=False) # 내림차순
df_sort_t = data_result.sort_values(by="오차", ascending=True)  # 오름차순
# 경향 대비 CCTV를 많게 가진 구
df_sort_f.head()
# 경향 대비 CCTV를 적게 가진 구
df_sort_t.head()
from matplotlib.colors import ListedColormap

# colormap을 사용자 정의(user define)로 세팅
color_step = ["#e74c3c", "#2ecc71", "#95a9a6", "#2ecc71", "#3498db", "#3498db"]
my_cmap = ListedColormap(color_step)
def drawGraph():
    
    plt.figure(figsize=(14, 10))
    plt.scatter(data_result["인구수"], data_result["소계"], s=50, c=data_result["오차"], cmap=my_cmap)
    plt.plot(fx, f1(fx), ls="dashed", lw=3, color="g")
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.colorbar()
    plt.grid(True)
    plt.show()
drawGraph()
plt.text(df_sort_f["인구수"][0] * 1.02, df_sort_f["소계"][0] * 0.98, data_result.index[0], fontsize=15)

-> 1.02, 0.98을 곱한건 텍스트가 마커를 가리지 않게 마커로부터 조금 텍스트를 떨어뜨려놓기 위함
-> x,y좌표를 오차를 내림차순으로 sort한 0번째 인덱스로 지정(강남구)

    for n in range(5):
        
        # 상위 5개
        plt.text(
            df_sort_f["인구수"][n] * 1.02,  # x좌표
            df_sort_f["소계"][n] * 0.98,    # y좌표
            df_sort_f.index[n],            # title
            fontsize=15
        ) 
    
    
        # 하위 5개
        plt.text(
            df_sort_t["인구수"][n] * 1.02,
            df_sort_t["소계"][n] * 0.98,
            df_sort_t.index[n],
            fontsize=15
        ) 

-> 반복문으로 상위,하위 5개씩 출력하도록 하기

<제로베이스 데이터 취업 스쿨>

0개의 댓글