ㅇ
기본적으로 데이터 가공을 끝낸 상태입니다.
위의 포스팅에서 가공하는 것을 진행했습니다.
그렇다면 이제 가공된 데이터를 이용해서 이미지에 색을 입혀보겠습니다.
사용할 이미지입니다.
파일을 업로드하려고 했는데... 티스토리에서 파일 업로드 방법을 모르겠네요...
.
서울 지도 이미지는 구글에서 찾으면 나옵니다.
찾은지 좀 오래된 이미지라서 어디있는지 가물가물하네요..ㅎ
이런 지도에 대한 이미지를 Atom이라는 프로그램을 이용해서 확인해보면!
숫자값과 id값으로 구분되어서 xml형식으로 구성되어 있는 걸 확인!
이제 위의 그림에 색을 입히는 작업을 진행할 예정입니다.
결론부터 말하자면!
색을 입혀서 이런 디자인으로 변신완료!
화재와 유사한 붉은 계열로 입혔습니다.
이제 코드를 봐볼까요?
import pandas as pd
import numpy as np
rea = pd.read_excel('소방장비현황_서울특별시.xlsx')
우선 DataFrame과 함수를 이용할 수 있도록 pandas와 numpy를 임폴트 해줍니다.
추가적으로 저번 포스팅에서 완성시킨 엑셀파일을 rea 파일에서 불러옵니다.
불러오면 이런 테이블을 확인할 수 있습니다.
import csv
from bs4 import BeautifulSoup
svg = open('서울특별시.svg','r').read()
CSV 파일을 사용할 수 있도록 임폴트해주고
BeautifulSoup를 임폴트를 하면서 bs4로 사용하겠다고 선언합니다..
여기서 BeautifulSoup란 HTML 및 XML 문서 를 구문 분석하기위한 Python 패키지입니다
마지막으로 위에 서울특별시 지도인 svg파일을 호출하면 끝!
출력해보면 그림이 아닌 이렇게 숫자로 결과가 나오는걸 확인할 수 있습니다.
결과값이 아직 정리가 안된 것처럼 보일 수 있으나 xml 형식이라는 점!
soup = BeautifulSoup(svg)
beautifulSoup를 이용해서 svg문서를 구문을 분석해봅시다!
이제 조금 xml 문서같죠?
자세히 보다보면 <path> 테그를 볼 수 있습니다.
이 테그에 있는 값들을 이용하기 위해서
paths = soup.findAll('path')
path에 대한 값들 모두 찾아서 paths라는 변수에 넣어줍니다.
이렇게 path에 대한 값들만 가져온 것을 확인할 수 있습니다.
이제 값들에서 추출할 수 있는 값들을 찾아보겠습니다.
위의 그림처럼 자세히 보면 id값들을 확인할 수 있습니다.
해당 id값들에 대해서 어떤 값들이 있는지 확인해보죠!
trans_list=[]
for i in paths:
trans_list.append(i['id'])
trans_list
반복문을 돌려서 해당 id가 있는지 확인하고 id에 대한 값들을 trans_list에 담아서 출력해줍니다.
이처럼 id에 대한 값들을 확인할 수 있습니다.
이 값들을 이제 전에 만들었던 엑셀에 id와 유사한지 확인하면 되겠죠?
rea = rea.sort_values(by='소방장비',ascending=True)
rea = rea.set_index('소방장비')
rea = rea.reset_index()
rea = rea.drop([0,15,19,28])
rea = rea.set_index('소방장비')
rea = rea.reset_index()
확인하기 위해서 우선적으로 DataFrame을 id와 일치하도록 가공해줍니다.
참고로 가공하는 건 자신이 가지고 있는 Data에 따라서 달라질 수 있다는 점!
위처럼 테이블을 정리해준 후!
rea.loc[0, ['소방장비']] = 'Gangnam-gu'
rea.loc[1, ['소방장비']] = 'Gangdong-gu'
rea.loc[2, ['소방장비']] = 'Gangbuk-gu'
rea.loc[3, ['소방장비']] = 'Gangseo-gu'
rea.loc[4, ['소방장비']] = 'Gwanak-gu'
rea.loc[5, ['소방장비']] = 'Gwangjin-gu'
rea.loc[6, ['소방장비']] = 'Guro-gu'
rea.loc[7, ['소방장비']] = 'Geumcheon-gu'
rea.loc[8, ['소방장비']] = 'Nowon-gu'
rea.loc[9, ['소방장비']] = 'Dobong-gu'
rea.loc[10, ['소방장비']] = 'Dongdaemun-gu'
rea.loc[11, ['소방장비']] = 'Dongjak-gu'
rea.loc[12, ['소방장비']] = 'Mapo-gu'
rea.loc[13, ['소방장비']] = 'Seodaemun-gu'
rea.loc[14, ['소방장비']] = 'Seocho-gu'
rea.loc[15, ['소방장비']] = 'Seongdong-gu'
rea.loc[16, ['소방장비']] = 'Seongbuk-gu'
rea.loc[17, ['소방장비']] = 'Songpa-gu'
rea.loc[18, ['소방장비']] = 'Yangcheon-gu'
rea.loc[19, ['소방장비']] = 'Yeongdeungpo-gu_1_'
rea.loc[20, ['소방장비']] = 'Yongsan-gu'
rea.loc[21, ['소방장비']] = 'Eunpyeong-gu'
rea.loc[22, ['소방장비']] = 'Jongno-gu'
rea.loc[23, ['소방장비']] = 'Jungnang-gu'
rea.loc[24, ['소방장비']] = 'Jung-gu'
rea = rea.rename(columns={'소방장비':'COUNTY','합계':'NUMBER'})
ID값에 일치하도록 변경해줍니다.
마지막으로 컬럼까지 변경해주면 끝!
이 작업을 하기 위해서는 일단 테이블에 있는 index값과 id값을 하나씩 확인해봤다...
즉 노가다....
노가다 작업을 끝내고 이런 테이블을 확인할 수 있다.
이제 이 테이블에 색을 입혀주면 끝!
색을 입혀줄 때 크기별로 다르게 입혀주려고 노력했지만 값이 대부분 20이라서 변화가 크게 없다는 아쉬움...
그래도 마저 진행해보면!
rea = rea.sort_values(by='COUNTY',ascending=True)
rea = rea.set_index('COUNTY')
rea.to_csv('서울특별시_값변경_svg.csv', encoding='ms949')
일단 이렇게 열심히 만든 테이블을 CSV로 저장해주고
reader = csv.reader(open('서울특별시_값변경_svg.csv','r'))
다시 호출해준다.
이제는 SVG에 있는 이미지 별로 색을 입혀주는 작업을 진행할껀데 단순하고 쉽습니다.
방법은 해당 reader의 값을 정리해서 크기별로 색을 부여해주면 끝!
counter={}
counts_only=[]
min_value = 100;
max_value = 0;
past_header = False
for row in reader:
try:
colorId = row[0]
count = float(row[1].strip())
counter[colorId] = count
counts_only.append(count)
except:
pass
반복문을 이용해서 reader라는 csv파일에 데이터를 counts_only라는 배열에 하나씩 넣어줍니다.
데이터를 넣을 때 소수형태로 넣어주는 건 포인트!
colors=['#F6EEEE','#FFD3D3','#FF7F7F', '#FF5E5E','#FF3F3F','#FF0000']
path_style = 'font-size:12px;fill-rule:nonzero;stroke:#FFFFFF;stroke-opacity:1;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;
stroke-linecap:butt;marker-start:none;stroke-linejoin:bevel;fill:'
데이터 정리가 완료되면 이제 6개의 색을 선택해주고
path_style이라는 값에는 SVG에서 표현하는 그림의 크기와 같이 디자인적인 요소를 수정해줍니다.
for p in paths:
if p['id']:
try:
count=counter[p['id']]
except:
continue
if count> 70:
color_class=5
elif count > 60:
color_class=4
elif count > 50:
color_class=3
elif count > 40:
color_class=2
elif count > 30:
color_class=1
elif count > 20:
color_class=0
color = colors[color_class]
p['style'] = path_style+color
file=open('서울특별시_소방장비_시각화.svg','w')
for i in soup:
file.write('%s\n' %soup)
file.close()
마지막으로 반복문을 이용해서 크기별로 색을 구분해줍니다.
반복문이 끝나면 해당 값을 SVG파일로 저장하면 끝!
저장까지 완료되구 이렇게 파일로 저장된 걸 확인할 수 있습니다.
파일을 확인해보면 처음에 보여준 핑크한 지도를 확인할 수 있습니다.
이번 포스팅에서는 데이터를 정형화하고 SVG를 이용해서 이미지에 색을 입히는 작업을 했습니다.
다음에는 더 흥미로은 포스팅으로 찾아오겠습니다!
'Programing > Python' 카테고리의 다른 글
파이썬 웹 개발을 위한 기초 공부하기 3탄 - django 기본 틀 잡기 및 DB 설계 초본 제작 (0) | 2021.12.08 |
---|---|
파이썬 웹 개발을 위한 기초 공부하기 2탄 - Flask 기본 툴 잡기 [세무민의 코딩일기] (1) | 2021.12.02 |
파이썬 웹 개발을 위한 기초 공부하기 1탄 - Flask 설치 및 오류 해결 [세무민의 코딩일기] (0) | 2021.11.28 |
세무민의 코딩일기 : 화재와 소방공무원 및 장비의 관계 분석(오랜만에 데이터 분석하기) (13) | 2021.07.17 |
세무민의 SVG 도전! [1] : 쓸수 없는 공공데이터를 의미 있게 변환하기! (0) | 2020.11.25 |