Programming/Python

pymongo로 MongoDB에서 크롤링한 데이터 불러와 pyplot으로 3D 그래프 그리기

📝 작성 : 2021.03.22  ⏱ 수정 : 
반응형

pymongo로 MongoDB에서 크롤링한 데이터 불러와 pyplot으로 3D 그래프 그리기

 

shanepark.tistory.com/48?category=1191756

 

python 이용해 3차원 주식 그래프 그리기

3차원 공간에 파이썬을 이용해 주식가격의 변동을 기록한 그래프를 그리는 프로그램을 작성해보았습니다. 일단 주식가격에 대한 데이터를 주기적으로 크롤링 해 와서 데이터베이스에 저장을

shanepark.tistory.com

 

위의 글에서는 mysql 데이터베이스에 저장된 데이터를 이용해서 해 보았는데요,

이번에는 MongoDB에 저장된 데이터를 불러와 그래프를 그려보도록 하겠습니다.

shanepark.tistory.com/54?category=1191756

 

pymongo와 BeautifulSoup 이용해서 python에서 크롤링 하기

shanepark.tistory.com/48?category=1191756 python 이용해 3차원 주식 그래프 그리기 3차원 공간에 파이썬을 이용해 주식가격의 변동을 기록한 그래프를 그리는 프로그램을 작성해보았습니다. 일단 주식가격

shanepark.tistory.com

아직 크롤링 한 데이터가 없다면 위 링크를 확인해 데이터를 먼저 확보해야 합니다. 주식 시장이 열려있는 시간동안에만 변동이 있으니 혹시 밤시간이라면 해외의 주식 정보를 크롤링 하면 됩니다.

 


 

처음부터 한번에 다 하려고 하면 어려우니 일단 한개 종목만 그래프를 그려봅니다. 코드는 MYSQL 용으로 작성했던 내용을 필요한 부분만 변경해서 그대로 사용했습니다. 폰트설정쪽은 windows 사용자라면   font_location = 'c:/Windows/Fonts/malgun.ttf' 로 변경하시면 됩니다.

 

'''
Created on 19 Mar 2021
각 주식별 가격 변동을 기록해 그래프 그리기
일단 한개만 그려보기
@author: shane
'''
import pymongo
import matplotlib as mpl
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import numpy as np


# 라벨 한글깨짐 방지를 위한 폰트 설정
fm.get_fontconfig_fonts()
font_location = '/System/Library/Fonts/Supplemental/AppleMyungjo.ttf'
font_name = fm.FontProperties(fname=font_location).get_name()
mpl.rc('font', family=font_name)
mpl.rcParams['legend.fontsize'] = 10

# DB 정보 설정
myclient = pymongo.MongoClient("mongodb://localhost:27017")
mydb = myclient["python"]
mycol = mydb["mystock02"]

# stock 이름들 받아오기

stock = ['GS건설']

# 정보를 받아온 횟수 totalNum에 기록해서 time 배열만들기
results = mycol.find()
results_count = results.count()
time = range(0,results_count)

# stock 코드에 맞는 종목 검색해 가격변화 priceArr 배열에 기록하기.
priceArr = []

for i in range(len(stock)):
    stockName = stock[i];
    arr = []
    firstPrice = mycol.find({},{'_id':0,stockName:1})[0][stockName]
    for x in mycol.find({},{'_id':0,stockName:1}):
        price = x[stockName]
        priceGap = price - firstPrice
        priceGapPercent = priceGap / firstPrice * 100
        arr.append(priceGapPercent)
    priceArr.append(arr)    

fig = plt.figure()
ax = fig.gca(projection='3d')

#x 축은 0,1,2,... 고정
x = []
for i in range(len(stock)):
    x.append(np.zeros(len(time),dtype=int)+i)

# y축은 시간, z축은 가격

# 그래프 그려주기
for i in range(len(stock)):
    ax.plot(x[i],time,priceArr[i], label=stock[i])
ax.legend()

plt.show()

 

한개종목을 일단 그리면 여러종목을 그리는 것도 어렵지 않습니다. 하지만 한 종목을 출력 하더라도 하드코딩 하지 말고 최대한 재사용 가능하게끔 코드를 작성해야 확장하기에 편합니다.

 

일단 종목이름들을 불러올 수 있어야 하는데요,

keys()를 이용하면 모든 key들을 불러올 수 있습니다.

 

'''
Created on 22 Mar 2021
컬럼명 목록 불러오기
@author: shane
'''
import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017")
db = myclient["python"]
mycol = db["mystock02"]

document = mycol.find_one()
keys = document.keys()

for key in keys:
    print(key)

위의 코드를 실행해보면

위의 스샷과 같이 800여개의 종목명과 그 외 _id, in_date 값들을 불러 올 수 있습니다.

_id와 in_date 두 값만 제외하면 모두 종목명입니다. 

# stock 이름들 받아오기

stock = []

document = mycol.find_one()
keys = document.keys()

for key in keys:
    if(key != '_id' and key != 'in_date'):
        stock.append(key)

 

그래서 위와 같은 방법으로 종목명들을 모두 불러와 stock 배열에 넣어보았습니다.

 

이제 stock 배열들을 받아 왔으니, 따로 수정할 코드는 없어 그대로 위에서 해당 내용만 변경한 뒤에 코드를 실행해 보았습니다.

'''
Created on 19 Mar 2021
각 주식별 가격 변동을 기록해 그래프 그리기
모든 종목 출력하기
@author: shane
'''
import pymongo
import matplotlib as mpl
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import numpy as np


# 라벨 한글깨짐 방지를 위한 폰트 설정
fm.get_fontconfig_fonts()
font_location = '/System/Library/Fonts/Supplemental/AppleMyungjo.ttf'
font_name = fm.FontProperties(fname=font_location).get_name()
mpl.rc('font', family=font_name)
mpl.rcParams['legend.fontsize'] = 10

# DB 정보 설정
myclient = pymongo.MongoClient("mongodb://localhost:27017")
mydb = myclient["python"]
mycol = mydb["mystock02"]

# stock 이름들 받아오기

stock = []

document = mycol.find_one()
keys = document.keys()

for key in keys:
    if(key!='_id' and key!='in_date'):
        stock.append(key)


# 정보를 받아온 횟수 totalNum에 기록해서 time 배열만들기
results = mycol.find()
results_count = results.count()
time = range(0,results_count)

# stock 코드에 맞는 종목 검색해 가격변화 priceArr 배열에 기록하기.
priceArr = []

for i in range(len(stock)):
    stockName = stock[i];
    arr = []
    firstPrice = mycol.find({},{'_id':0,stockName:1})[0][stockName]
    for x in mycol.find({},{'_id':0,stockName:1}):
        price = x[stockName]
        priceGap = price - firstPrice
        priceGapPercent = priceGap / firstPrice * 100
        arr.append(priceGapPercent)
    priceArr.append(arr)    

fig = plt.figure()
ax = fig.gca(projection='3d')

#x 축은 0,1,2,... 고정
x = []
for i in range(len(stock)):
    x.append(np.zeros(len(time),dtype=int)+i)

# y축은 시간, z축은 가격

# 그래프 그려주기
for i in range(len(stock)):
    ax.plot(x[i],time,priceArr[i], label=stock[i])
ax.legend()

plt.show()

800여개 종목 모두 다 받아오다보니 화면을 띄우는데 제법 시간이 걸리긴 했는데, 데이터가 20개 밖에 없다 보니 800개도 거뜬하게 띄워 낼 수 있었습니다. 6분 가량만 크롤링을 했는데도, 6퍼센트 이상 상승한 종목도 있었네요.

 

마지막으로 800여개가 좀 과한 것 같아서, totalStocks  변수를 설정해서 그 만큼만 카운팅 한 뒤 그래프를 그리도록 코드를 조금 수정해 보았습니다.

'''
Created on 19 Mar 2021
주식 원하는 종목수 만큼만 출력하기
@author: shane
'''
import pymongo
import matplotlib as mpl
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import numpy as np

# 총 출력할 주식수 설정 // 800여개 다 출력시 감당을 못함
totalStocks = 30

# 라벨 한글깨짐 방지를 위한 폰트 설정
fm.get_fontconfig_fonts()
font_location = '/System/Library/Fonts/Supplemental/AppleMyungjo.ttf'
font_name = fm.FontProperties(fname=font_location).get_name()
mpl.rc('font', family=font_name)
mpl.rcParams['legend.fontsize'] = 10

# DB 정보 설정
myclient = pymongo.MongoClient("mongodb://localhost:27017")
mydb = myclient["python"]
mycol = mydb["mystock02"]

# stock 이름들 받아오기

stock = []

document = mycol.find_one()
keys = document.keys()
count = 0
for key in keys:
    count += 1
    if( count > totalStocks):
        break
    if(key!='_id' and key!='in_date'):
        stock.append(key)
        

# 정보를 받아온 횟수 totalNum에 기록해서 time 배열만들기
results = mycol.find()
results_count = results.count()
time = range(0,results_count)

# stock 코드에 맞는 종목 검색해 가격변화 priceArr 배열에 기록하기.
priceArr = []

for i in range(len(stock)):
    stockName = stock[i];
    arr = []
    firstPrice = mycol.find({},{'_id':0,stockName:1})[0][stockName]
    for x in mycol.find({},{'_id':0,stockName:1}):
        price = x[stockName]
        priceGap = price - firstPrice
        priceGapPercent = priceGap / firstPrice * 100
        arr.append(priceGapPercent)
    priceArr.append(arr)    

fig = plt.figure()
ax = fig.gca(projection='3d')

#x 축은 0,1,2,... 고정
x = []
for i in range(len(stock)):
    x.append(np.zeros(len(time),dtype=int)+i)

# y축은 시간, z축은 가격

# 그래프 그려주기
for i in range(len(stock)):
    ax.plot(x[i],time,priceArr[i], label=stock[i])
ax.legend()

plt.show()

종목수가 적어지니 보기가 좋습니다. 3D 화면을 돌려가며 볼 수 도 있습니다.

이상입니다.

반응형