멀티캠퍼스부트캠프

4주차 Note: 데이터 시각화

가라어퍼 2026. 5. 1. 17:27

똥손이슈 반짝눈 대실패

 

🗓️ 4주차: 4월 27일 - 4월 30일

멀티캠퍼스 부트캠프 4주차 요약✍️

[ 4/27 ] Web: Flask

[ 4/28 ] 웹, 데이터 시각화: PythonAnywhere, matplotlib, drinks 데이터셋 활용

[ 4/29 ] 데이터 시각화: offline, online, aapl 데이터셋 활용

[ 4/30 ] 데이터 시각화: tableau, GA

[ 5/1 ] 근로자의 날 휴강


4월 27일 👩🏻‍💻

오늘의 소감: 코드가 길어지면 어지럽기는 마찬가지...😵 py js html 문법 통일해줬으면🥹 (그럴리가...)


 

본격적인 시각화 툴을 다루기 전, 시각화 결과를 구현할 수 있는 웹을 구축하는 방법을 배웠다.

오늘 사용한 파일들

▪️app.py (이번 시간에 새로 생성한 웹 구축 모듈)
▪️db.py (4/20일에 만들어둔 sql 연결 모듈)
▪️index.html, main.html (웹 구현 html 코드)

 


 

# flask 프레임워크 안에서 특정 기능을 로드
from flask import Flask, render_template, request, redirect, url_for
# render_template → templates 폴더 안에 html 문서를 가져오기 위한 기능
# request → 유저가 보낸 데이터에 접근하기 위한 기능
# redirect → 특정 주소로 이동
# url_for → 특정 주소를 지정하기 위한 기능
    # (상대 경로 지정 → app.py 위치로부터 경로를 설정)
    # html 문서 안에서 사용 (render_template() 함수를 이용해서 app.py에서 실행)

from db import MyDB
from querys import user
import pandas as pd

환경 구축
# Flask class 생성 → 웹 서버를 구축 기능
# class 생성 시 생성자 함수 호출
    # 필수 인자 1개 → 현재 실행이 되는 파일의 이름(app.py)
    # 파일의 이름을 그대로 사용할 시 파일의 이름이 변경될 때 매번 수정 작업 필요
    # __name__ → 현재 파일의 이름
    
app = Flask(__name__)
db = MyDB()
db.sql_query(user.create_query)
db.commit()

 

# 회원 테이블 생성 쿼리문 하나 작성
create_query = """
    CREATE TABLE IF NOT EXISTS `user` (
        `id` varchar(32) primary key,
        `password` varchar(32) not null,
        `name` varchar(32)
    )
"""

# 로그인 조회 쿼리문 작성
# id, password를 이용하여 데이터가 존재하는가?
login_query = """
    SELECT *
    FROM `user`
    WHERE `id` = %s AND `password` = %s
"""

# 회원 가입 쿼리문
    # 아이디 중복 체크
    # id, password, name 입력하고 회원가입
id_check_query = """
    SELECT *
    FROM `user`
    WHERE `id` = %s
"""

signup_query = """
    INSERT INTO `user` VALUES (%s, %s, %s)
"""

API 생성 1: index()

 

# 웹 서버의 api 목록들 생성
# 데코레이션(내비게이션 함수) → @함수
    # 특정 주소와 함수를 연결
    # 주소 → base_url(127.0.0.1:5000) + sub_url()
        # 이 주소로 요청이 들어왔을 때 함수를 호출
        
@app.route("/")
def index():
    # HTML로 하이퍼 링크 생성
    # return "<a href='https://www.google.com'>Google</a>"
    return render_template("index.html")
    # templates 폴더 안에 html 문서를 불러와서 되돌려준다.(render_template())
    # render_template에서 {{변수명}}은 python에서의 변수를 담겠다.
    # {%python code} code를 인식하여 조건에 맞는 경우에만 html을 추가
        # 반복문을 이용해서 html을 반복적으로 추가

index.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <!-- title 태그는 탭에 나타나는 이름 -->
        <title>Document</title>
    </head>
    <body>
        <!-- 실제 화면에 나타나는 부분 -->
         <h1>Hello Flask</h1>
         <p>이 페이지는 메인 페이지입니다.</p>
        <!-- 유저가 입력할 수 있는 공간 생성(input) -->
        <!-- 입력한 데이터를 서버에게 보낸다(form) -->
        <!-- form 태그: action 속성-어디로 데이터를 보낼 것인가?(주소값) -->
        <!-- method 속성-어떤 방식으로 데이터를 보낼 것인가? (get/post) -->
        <!-- 웹 서버의 데이터를 key: value 형태로 보낸다. -->
        <!-- 뒤에 나올 login의 login 과정 -->
        <form action="/login" method="get">
            <!-- 유저의 id 입력하는 공간 -->
            <label>ID</label>
            <input type="text" name='input_id'>
            <br>
            <!-- 유저의 password 입력하는 공간 -->
            <label>PASSWORD</label>
            <input type="password" name="input_pass">
            <br>
            <!-- 데이터를 보낸다 → 제출 버튼이 필요 -->
            <input type="submit">
        </form>
        <h3>post 방식으로 데이터 보내기 </h3>
        <!-- 뒤에 나올 login2의 login 과정 -->
        <!-- post 방식으로 데이터를 보낸다. -->
        <form action="/login2" method = "post">
            <label>ID</label>
            <input type="text" name='input_id'>
            <br>
            <label>PASSWORD</label>
            <input type="password" name="input_pass">
            <br>
            <input type="submit">
        </form>
    </body>
</html>

API 생성 2: login 1
# /login 주소를 생성 (get 방식)

@app.route('/login')
def login():
    # 유저가 보낸 데이터를 받아온다. (flask 프레임워크에서 기능을 불러와서 사용)
    print(request.args)
    print("유저가 입력한 ID: ", request.args['input_id'])
    print("유저가 입력한 password : ", request.args['input_pass'])
    # DataBase server에 해당하는 아이디, 패스워드가 모두 일치하는 데이터가 존재하는가?
    # 조건문을 이용하여 로그인 성공/실패
    if request.args['input_id'] == 'admin' and request.args['input_pass'] == '1234':
        #로그인 성공
        return "로그인 성공"
    else:
        return "ID, PASSWORD를 확인해주세요"

 

이 방식은 주소창에 ID와 PASSWORD가 노출되므로 이후 과정에서 사용하지 않는다.


API 생성 3: login 2
# /login2 주소를 생성 (post 방식)
# post 방식은 데이터를 숨겨서 보내고,
    # 웹 브라우저에서 주소창에 입력하는 방식으로 확인이 불가능
    
@app.route('/login2', methods=['post'])
def login2():
    print(request.form)
    _id = request.form['input_id']
    _pass = request.form['input_pass']
    sql_result = db.sql_query(user.login_query, _id, _pass)
    db.commit()
    print(sql_result)
    
    if sql_result:
        # 로그인한 계정의 이름을 화면에 표시 
        sql_name = sql_result[0]['name']
        df = pd.read_csv("../csv/AAPL.csv")
        df2 = df.tail(10)
        x_data = df2['Date'].tolist()
            # Series는 html에서 사용 불가능
        y_data = df2['Adj Close'].tolist()
        th_data = df.columns.tolist()
        td_data = df2.to_dict('records')
        return render_template('main.html',
                               name = sql_name,
                               x = x_data,
                               y = y_data,
                               th_data = th_data,
                               td_data = td_data)
    else:
        return redirect('/')

main.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <h1>Main Page</h1>
        <!-- 로그인한 유저의 이름을 대입 -->
        <p>{{name}}님 안녕하세요!</p>

        <!-- 그래프가 그려지는 영역을 먼저 선택 -->
        <div>
            <canvas id="myChart"></canvas>
        </div>

        <!-- 외부의 라이브러리를 호출 -->
        <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

        <!-- 실제 그래프를 canvas에 그려주는 부분 -->
        <script>
            // id가 myChart인 태그를 선택해서 상수 ctx에 대입
            // 변수는 let이나 var를 이용하여 변수를 생성
          const ctx = document.getElementById('myChart');

        //   Chart class를 생성 → 그래프를 그려주는 부분
        new Chart(
            ctx,
            {
            type: 'line',
            data: {
            labels: {{x | tojson}},
            datasets: [{
                label: '# of Votes',
                data: {{y | tojson}},
                borderWidth: 1
            }]
         }
      });
    </script>

    <!-- 표를 생성 -->
    <!-- table 태그, tr 태그: 행을 표시, th/td 태그: 열을 표시 -->
    <table border = 1>
        <tr>
            <!--
                반복문을 이용해서 작업을 하면 짧고 유동성 있게 사용 가능
                python에서 for문은 들여쓰기를 요함 
             -->
            <!-- 그래서 필요한 반복문의 시작과 -->
            {% for col in th_data%}
                <th>{{col}}</th>
            <!-- 반복문의 끝 -->
            {% endfor %}
        </tr>


        {% for row in td_data %}
        <tr>
            {% for col in th_data %}
                <td>{{row[col]}}</td>
            {% endfor %}
        </tr>
        {% endfor %}
    </table>
</body>
</html>

API 생성 4: html 실행
@app.route('/dashboard')
def dashboard():
    return render_template('dashboard.html')

# 웹 서버를 시작한다. (구동한다.)
app.run(debug=True)
	# debug 매개변수 → 디버그 모드를 사용할 것인가? (기본값 False)
    # True 변경 시 개발 모드로 변경 → 파일이 수정됐을 때 서버가 재시작

4월 28일 👩🏻‍💻

오늘의 소감: 드디어 시각화 시작!! 정신 단단히 차리자 - ̗̀( ˶'ᵕ'˶) ̖́-

 


💻 html

오전 시간에는 어제 했던 app.py 파일의 html을 업그레이드하는 작업을 수행하였다.


💻 시각화

matplotlib 활용

 

라이브러리 로드
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 현재 컴퓨터의 os를 확인하기 위한 라이브러리 로드
import platform

라인 그래프 생성

 

  • plt.plot
  • 인자를 1개만 입력하면 y축에 데이터 입력, 이때 x축은 0부터 1씩 증가
  • 인자가 2개인 경우 첫번째 인자가 x축, 두번째 인자가 y축의 데이터
    • 이 때 두 인자의 길이가 같아야 한다.
  • ipynb의 경우 plt.show를 사용하지 않아도 그래프가 출력됨
plt.plot( [5,4,3,2,1] )
plt.show()

 

 


선의 종류와 색깔 지정
x = [1, 2, 3, 4]
y = [70, 80, 100, 60]

plt.plot(x, y, '.-')
plt.show()
plt.plot(x, y, 'r')
plt.show()


그래프 두 개 동시에 그리기
plt.plot(x, y)
plt.plot(x, [100, 60, 80, 40], 'r--')
plt.show()


제목, x축, y축 이름 지정

 

matplotlib 기본 폰트는 한글을 지원하지 않음

따라서 폰트 설정을 변경한 후에 제목, 축 이름에 한글을 사용할 수 있다.

이때 platform lib을 사용한다.

if platform.system() == 'Windows':
    plt.rc('font', family='Malgun Gothic')
else:
    plt.rc('font', family='AppleGothic')

plt.plot(x, y)
plt.title('그래프 제목')
plt.xlabel('x축 이름')
plt.ylabel('y축 이름')

plt.show()

 


마이너스 기호의 깨짐방지
# 둘이 같은 기능
plt.rc('axes', unicode_minus = False)
# plt.rcParams['axes.unicode_minus'] = False

plt.plot(x, [-10, 10, -20, 0])
plt.show()


범례

 

하나의 영역에서 데이터가 2개 이상인 경우 → 각각의 데이터들이 어떤 데이터인지 의미를 알아야한다.

x = [1,2,3]
y1 = [10, 6, 3]
y2 = [5, 8, 17]

# plt.plot(x, y1, label='A')
# plt.plot(x, y2, label='B')
# plt.legend()

plt.plot(x, y1)
plt.plot(x, y2)
plt.legend(['a', 'b'], loc='upper center')


바 그래프 생성
# 수직
plt.bar(x, y1)
plt.show()

# 수평
plt.barh(x, y1)
plt.show()


막대의 색상과 너비를 지정
plt.bar(x, y1, width=0.4, color=['red', 'yellow', 'green'])
plt.show()


특정 막대의 색상을 변경
bar_graph = plt.bar(x, y1)
bar_graph[1].set_color("#FE6B00")

plt.show()

vscode는 색상 지정이 편하다🤩


산점도 그래프 생성
x = np.random.random(100)
y = np.random.random(100)

plt.scatter(x, y)
plt.show()


💻 drinks 데이터셋을 통한 여러가지 시각화

 

데이터 로드, 확인
df = pd.read_csv('../csv/drinks.csv')
df.head()

df.info()


결측치 확인, 대체
flag = df['continent'].isna()
df.loc[flag, ]

# 결측치의 모든 데이터를 'OT' 로 대체
df.fillna('OT', inplace=True)

왼: isna(), 오른: fillna('OT')


데이터간 상관계수 확인
# 문자열 데이터 drop
df2 = df.drop(columns=['country', 'continent'])
df2.corr()


산점도 그려보기
x = df['beer_servings']
y = df['total_litres_of_pure_alcohol']
plt.scatter(x, y)
plt.show()


heatmap
import seaborn as sns

corr = df.iloc[:, 1:5].corr()

plt.figure(figsize=(12, 8))
sns.heatmap(data=corr,
            annot=True,
            square=True,
            fmt='0.3f',
            annot_kws={'size': 10},
            cbar = True,
            cmap = 'Blues',
            xticklabels=['맥주', '위스키', '와인', '순수알콜'],
            yticklabels=['맥주', '위스키', '와인', '순수알콜']
            )

# annot: 주석 표시 유무
# square: 히트탭 정사각형 표시 유무
# fmt = 주석의 소수점 자리수를 지정
# annot_kws = 주석의 환경 설정 (size: 글자의 크기를 변경)
# cbar = 사이드바 표시여부

 


pairplot
sns.pairplot(
    df.loc[:, '맥주소비량':'순수알콜'],
    corner = True,              # 중복이 되는 산점도 그래프 제거
    kind = 'reg',               # 추세선 추가
    plot_kws = {
        'line_kws' : {
            'color' : 'red'     # 추세선의 색상을 변경
        }
    }
)

plt.show()


연습 문제

 

1. 컬럼의 이름들을 변경
2. 파생변수 → 총 술 소비량: 맥주소비량+위스키소비량+와인소비량
3. 파생변수 → 도수: (순수알콜/총술소비량)*100
4. 대륙별 그룹화하여 도수의 평균을 구한다 → 가장 독한 술을 먹는 대륙은 어디인가?

# 1)
df.columns = ['국가', '맥주소비량', '위스키소비량', '와인소비량', '순수알콜', '대륙']

# 2)
df['총술소비량'] = df['맥주소비량']+df['위스키소비량']+df['와인소비량']

# 3)
df['도수'] = df['순수알콜']/df['총술소비량']*100

#4)
df[df['총술소비량'] == 0]

우리나라의 총 술 소비량은 전세계 몇 위일까?
# 총 술 소비량을 기준으로 내림차순 정렬
df.sort_values('총술소비량', ascending=False, inplace=True)
# 인덱스를 초기화하고 기존의 인덱스를 제거
df.reset_index(drop=True, inplace=True)

# 순위 → 위치 값에 +1
# 국가의 이름이 'South Korea' 인 데이터를 추출해서 인덱스를 확인

flag = df['국가'] == 'South Korea'
korea_index = df.loc[flag,].index[0]
korea_rank = korea_index + 1
korea_value = df.loc[korea_index, '총술소비량']

그래프 생성
x = df.index
y = df['총술소비량']

flag = df['국가'] == 'South Korea'
korea_index = df.loc[flag,].index[0]
korea_rank = korea_index + 1
korea_value = df.loc[korea_index, '총술소비량']

plt.figure(figsize=(20, 8))
bar_graph = plt.bar(x, y, color='gray')

# 한국 위치의 막대를 선택해서 색상 변경
bar_graph[korea_index].set_color('red')

# 그래프에 주석 추가 (화살표로 주석이 가리키는 곳을 표시)
plt.annotate(
    f"South Korea \n rank: {korea_rank} \n 총술소비량: {korea_value}",
    xy = (korea_index, korea_value),
    xytext= (korea_index+10, korea_value+150),
    arrowprops= {
        'facecolor' : 'pink',       # 화살표 안쪽 색상
        'edgecolor' : 'grey',       # 화살표 테두리 색상
        'headwidth' : 20,           # 화살표 머리 너비
        'headlength' : 20,          # 화살표 머리길이
        'width': 10,                # 화살표 꼬리의 너비
        'shrink': 0.1               # 화살표와 xy, xytext 간의 간격 조정
    }
)

# annotate 첫번째 인자: 주석이 들어갈 텍스트 지정
# 두번째 인자: 주석이 어느 부분을 설명하는가? (좌표)
# 세번째 인자: 주석 문구의 위치
# 네번째 인자: 주석과 해당 데이터를 화살표로 연결

plt.show()


4월 29일 👩🏻‍💻

오늘의 소감:

고수님들이 하는 짱멋진 시각화 - 엄청 많은 레이어도 깔끔하게 처리해서 한눈에 확 들어오게 함

내가 하는 시각화 - 색깔놀이 히히히

 

...센스가 하늘에서 내려올 수 있다면 얼마나 좋을까🥹


💻 offline 데이터 활용 시각화

라이브러리 로드
import pandas as pd
import platform
import matplotlib.pyplot as plt

데이터 로드, 확인
offline = pd.read_csv('../csv/card/오프라인.csv', encoding='cp949')
offline


데이터 전처리
컬럼명 변경
# 항목정의서 엑셀 파일을 로드

col_info = pd.read_excel('../csv/card/항목정의서.xlsx')
col_info


col_info['데이터 컬럼'].to_list()
# ['기준년월', '업종 구분', '성별', '연령대', '이용 건수', '이용 금액']

offline.columns = col_info['데이터 컬럼'].to_list()
offline


결측치 확인
offline.info()


# 항목정의서를 기준으로 성별에서 '-'가 결측치이다.

(offline['성별']=='-').sum()		# np.int64(0)

offline['성별'].value_counts()

결측치가 없는 것으로 파악되었다.


컬럼 타입 변경
from datetime import datetime
offline['기준년월'] = pd.to_datetime(offline['기준년월'], format='%Y%m')

그래프의 한글 깨짐 방지
if platform.system() == 'Windows':
    plt.rc('font', family = 'Malgun Gothic')
else:
    plt.rc('font', family = 'AppleGothic')

데이터 시각화

 

월별, 성별을 기준으로 이용 금액의 평균을 그래프로 표시
pd.pivot_table(
    offline,
    index = '기준월',
    columns = '성별',
    values = '이용 금액',
    aggfunc = 'mean'
).plot(kind='bar', color=("#ffa9a9", "#b0bfff"))


기준년월별 업종별로 이용 금액의 합계를 그래프로 표시
pd.pivot_table(
    offline,
    index = '기준년월',
    columns = '업종 구분',
    values = '이용 금액',
    aggfunc = 'sum'
).plot(color=("#FFA4A4", "#A1BAFF", "#78E26A", "#FFEC95"))


여러 개의 데이터를 한 캔버스 안에서 따로따로 그릴 때
# subplots() → 영역을 나눠주는 함수 → 영역을 나눈 캔버스를 생성
    # → 앞에서 생성한 캔버스의 크기는 초기화하고 새로 생성
    # 2개의 데이터를 되돌려준다. // 1. 캔버스, 2. 캔버스 영역


fig, axes = plt.subplots(2, 2, figsize=(20,8))
axes[0][0].plot([1,2,3,4], color="#FFB2B2")
axes[0][1].plot([1,2,3,4], color="#C0CBFF")
axes[1][0].plot([1,2,3,4], color="#97D48F")
axes[1][1].plot([1,2,3,4], color="#FFE89E")


한 화면에 연령대 별로 그래프를 따로 생성
group_data2 = pd.pivot_table(
    offline,
    index = '기준년월',
    columns = '연령대',
    values = '이용 금액',
    aggfunc = 'sum'
)

group_data2.plot(figsize=(10,10))


성별, 업종별 총 이용금액의 합계를 라인 그래프로 표시
group_data3 = pd.pivot_table(
    offline,
    index = '업종 구분',
    columns = '성별',
    values = '이용 금액',
    aggfunc = 'sum'
)

group_data3 = offline.groupby(['기준년월', '성별', '업종 구분'])['이용 금액'].sum()
group_data3 = group_data3.unstack().unstack()
group_data3.iloc[:, 0]

plt.figure(figsize=(16, 20))

for i in range(len(group_data3.columns)):
    plt.subplot(4, 2, i+1)
    plt.plot(group_data3.iloc[:, i])
    plt.title(group_data3.columns[i])

plt.show()

 


💻 offline+online 데이터 활용 시각화

 

데이터 로드
offline = pd.read_csv('../csv/card/오프라인.csv', encoding='cp949')
online = pd.read_csv('../csv/card/온라인.csv', encoding='cp949')

 

데이터 프레임 컬럼명 변경
offline.columns = ['기준년월', '업종', '성별', '연령대', '이용건수', '이용금액']
online.columns = ['기준년월', '성별', '연령대', '이용건수', '이용금액']

 

online dataset에서는 업종 column이 없다.


데이터 결합
df = pd.concat( [offline, online], axis = 0, ignore_index = True )

# df 업종 column의 결측치 대체
df['업종'] = df['업종'].fillna('온라인')

# 기준연월 시계열로 변경
df['기준년월'] = pd.to_datetime(df['기준년월'], format='%Y%m')

 

모든 업종별로 이용건수 차이를 그래프로 확인
pd.pivot_table(
    df,
    index = '기준년월',
    columns = '업종',
    values = '이용건수',
    aggfunc = 'sum'
).plot(figsize=(16,10), color=("#FFB9B9", "#9ECBFF", "#96E4A3", "#FFE59C", "#CC9EDA"))


💻 AAPL 데이터 활용

  • 애플 주식 데이터
  • 목표: 이동 평균선 도출

import pandas as pd
import matplotlib.pyplot as plt
import platform

if platform.system() == 'Windows':
    plt.rc('font', family = 'Malgun Gothic')

df = pd.read_csv('../csv/AAPL.csv')

# 필요한 column만 불러오고 싶을 때는
df2 = pd.read_csv('../csv/aapl.csv', usecols=['Date', 'Adj Close'])

df2.info()


결측치 처리

 

 

결측치가 하나 뿐이라 결측치가 포함된 행은 drop

Date column은 datetime type으로 변경

df2.dropna(inplace=True)

df2['Date'] = pd.to_datetime(df2['Date'])
df2.info()

# Date column을 index로 설정
df2.set_index('Date', inplace=True)

df2.iloc[0:20, 0].mean()

# 이동평균값 컬럼을 먼저 생성 → 데이터는 0.0을 대입
	# (평균을 구할 것이기에 float 타입으로 만들기 위함)
df2['이동평균값'] = 0.0

for i in range(len(df2)-19):
    df2.iloc[i+19, 1] = df2.iloc[i:i+20, 0].mean()
   
# 다른 방법으로 인덱스끼리 묶어서 연산을 해주는 함수가 존재: rolling(n)
df2['center2'] = df2['Adj Close'].rolling(20).mean().fillna(0

df2[['Adj Close', 'center2']].tail(100).plot(figsize=(30, 10))


그래프 꾸미기
plt.figure(figsize=(30, 10))
plt.plot(df2.tail(100)['Adj Close'], color='#000000')
plt.plot(df2.tail(100)['center2'], '--', color="#cf2424")

plt.show()


 

df2['ub'] = df2['center2'] + (2*df2['Adj Close'].rolling(20).std())
df2['lb'] = df2['center2'] - (2*df2['Adj Close'].rolling(20).std())

# 최근 100일치 데이터에서 상단밴드, 하단밴드, 이평선, 종가 그래프
df2.drop(['이동평균값'], axis=1).tail(100).plot()

 


이것도 좋지만 조금 더 깔끔하게 보고 싶어져서 따로 찾아본 버전
plt.figure(figsize=(30,10))
plt.plot(df2['ub'].tail(200), color="#52865F", label='ub')
plt.plot(df2['lb'].tail(200), color='#52865F', label='lb')
plt.plot(df2['center2'].tail(200), color="#FF00F2", label='이평선')
plt.plot(df2['Adj Close'].tail(200), marker = 'o', markersize=5, color="#C25555", label='종가')
plt.fill_between(df2.tail(200).index, df2['ub'].tail(200), df2['lb'].tail(200), color = 'green', alpha = 0.05)
plt.legend()
plt.show()

 

plt.fill_between을 사용하면 색깔이 채워져서 더욱 band 같아보일 것 같았다!

 


4월 30일 👩🏻‍💻

오늘의 소감: tableau는 코드가 불필요하다. (엑셀 기초 정도의 실력만 있으면 될 듯)

혼자서 tableau를 쓰려고 했을 때 가장 막막한 것은 시작이었다.

새로운 툴에 대한 마음적 장벽도 있지만, 어떤 데이터를 가지고 시작해야할지를 몰랐다고 해야할까...?

 

matplotlib의 디자인을 보다가 seaborn을 보고 놀랐고, seaborn을 보다가 tableau를 보니 더욱 놀랐다.

특히 지리 데이터를 다루는 것을 꼭 한번 시도해보고 싶었는데 tableau에서 해당 부분 시각화가 가능하다는 생각에 기뻤다.

 

GA는 웹을 관리하는 입장, 예를 들면 소형 쇼핑몰 등에서 아주 유용하게 사용할 수 있는 툴이었다.

아직 html과 많이 친하지 않아서... 또 tableau를 보다가 GA를 보려니까 훨씬 복잡한 느낌이긴 했다.

해당 부분 진도를 짧게 나간지라 아직 시스템과 친해질 시간이 많이 필요해보인다.

개인적으로는 looker와 GA를 어떻게 같이 사용하는지가 궁금했는데, 시간이 부족한 관계로 이 부분까지는 진도를 나가지 못했다. 추후에 수행할 기회가 왔으면 좋겠다.


 

Tableau가 워낙 직관적으로 구성이 잘 돼있어서 크게 작성할 것이 없다...! 그래서 신기했던 것 위주로 짤막하게 작성해보려 한다.


서울시의 행정구별 평균 할인율

처음 실행했을 때는 중구와 강서구의 데이터가 나오지 않았다.

다른 지역(ex. 부산광역시)에 중구, 강서구가 있었기 때문에 정확한 지역을 표시할 수 없다고 나온 것이었다.

이 때 세부정보로 Address SD(시도)를 추가하니 문제가 해결되었다.


폭포수 차트

2021년의 경우 적더라도 수익이 꾸준히 난 구조이기에 이게 뭐? 싶을수도 있는 결과가 도출되었다.


그래서 나름 다이나믹했던 2019년부터 2020년까지의 데이터를 보았다.

빨간색에 가까울 수록 이익이 마이너스, 파란색에 가까울 수록 이익이 플러스이다.

각 막대가 y=0에서 시작하는 것이 아닌, 전월의 마지막 시점에서 시작한다.

말해놓고 보니 주식 차트였네

 


4주차 소감

생각보다 시각화를 많이 하지 않은 느낌이라 아쉽긴 하지만...

새로운 것을 많이 배워갈 수 있는 시간이었다!

연휴 동안 복습 게을리하지말고, 지금까지 배운 것들을 빅분기 실기랑 내용 대조해가면서 공부도 조금씩 하자!

다음 주차는 머신러닝이다. 빅분기에서 써먹을 일 많을테니 열심히 하자! - ̗̀( ˶'ᵕ'˶) ̖́-