IT/파이썬 - Bokeh

Bokeh 파이썬 반응형 시각화 라이브러리 사용 (pandas, csv) 작업물(막대그래프)

게발인생 2021. 8. 22. 16:28

bokeh_page05_4-1.py
0.00MB
pandas_test_data4.csv
0.01MB

import pandas as pd
import numpy as np
import operator
from bokeh.io import output_file, show
from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource, LabelSet
from bokeh.plotting import figure
from bokeh.palettes import Spectral6
from bokeh.transform import factor_cmap

TOOLS = "pan,wheel_zoom,save,reset"  # tools="pan,wheel_zoom,save,reset" # 툴 옵션
TOOLTIPS = [("툴팁", "@tooltip"), ("sample", "@sample")]

def create_chart(chart_year_list, chart_year_data_list):

    multiplot = list()

    for year in chart_year_list:
        # 2번째 인덱스 기준으로 내림차순 정렬
        chart_data = dict(sorted(chart_year_data_list[year].items(), key=operator.itemgetter(1), reverse=True))
        x_label = list(chart_data.keys()) # dict의 key를 x축 레이블로 설정
        air_data = list(chart_data.values())
        title = year

        # 그래프 색깔 부여 및 x레이블 개수 체크
        top_label = list()
        color = list()
        for i in range(len(x_label)):
            if x_label[i] == 'jeonbuk':
                color.append('#F9A7B0')
                top_label.append(i + 1)
            else:
                color.append('skyblue')
                top_label.append(i + 1)

        source = ColumnDataSource(data=dict(under_label=x_label, height=air_data, top_label=top_label, color=color))

        p = figure(x_range=x_label, plot_height=250, tools=TOOLS,
                   tooltips=TOOLTIPS)  # title="2016 타이틀" # toolbar_location=None # 툴 위치&툴 표시 여부

        # 그래프 타이틀 설정
        p.title.text = title
        p.title.text_font_size = "25px"
        p.title.align = 'center'

        # 그래프 그리기
        p.vbar(x='under_label', top='height', width=0.9, source=source,
               line_color='white', fill_color='color')

        # 막대 그래프 상단 텍스트 설정
        top_data_labels = LabelSet(x="under_label", y="height", text="height", y_offset=-18,
                                   text_font_size="14px", text_color="#555555",
                                   source=source, text_align='center')
        p.add_layout(top_data_labels)

        # 막대 그래프 최상단 텍스트 설정 y=높이
        top_labels = LabelSet(x="under_label", y=60, text="top_label", y_offset=8,
                              text_font_size="15px", text_color="#555555",
                              source=source, text_align='center')
        p.add_layout(top_labels)

        # x축 그리드 라인 제거
        p.xgrid.grid_line_color = None
        # p.ygrid.grid_line_color = None

        # y축 시작, 종료 범위 설정
        p.y_range.start = 0
        p.y_range.end = 70

        multiplot.append(p)

    return multiplot


# under_label = ['Apples', 'jeonbuk', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
# data = [5, 3, 4, 2, 4, 6]

# pandas로 엑셀 csv 데이터 읽기
df = pd.read_csv("./pandas_test_data4.csv")
# time 칼럼 기준으로 오름차순 정렬(시간순으로 오름차순 정렬)
df = df.sort_values(by=['time', 'location'])


# 지역 리스트 뽑기
location_list = list(set(df.loc[:, "location"]))
location_list.sort()

# 연도 리스트 뽑기
year_list = set(df.loc[:, "time"].str[0:4])
year_list = sorted(year_list)

# 데이터 1차 가공(평균 구하기, dictionary 생성)
year_data_list = dict()
for year in year_list:
    avg_data_list = dict()
    for location in location_list:
        temp = list()
        temp = df.loc[(df['location'] == location) & (df['time'].str[0:4] == year), "data"]
        temp = list(filter(None, temp))
        temp = np.mean(temp)
        temp = (np.floor(temp * 10) / 10)
        avg_data_list[str(location)] = temp
    year_data_list[str(year)] = avg_data_list

# 차트 그리기
mp = list()
mp = create_chart(year_list, year_data_list)

multi_plot = gridplot([[mp[0], mp[1]], [mp[2], mp[3]], [mp[4], mp[5]]], merge_tools=True)
# merge_tools=True #True=한개로 표시, False=툴 개별로 표시

# html 이름
output_file("bokeh_page05_4-1.html")

# 차트 html로 출력
show(multi_plot)

 

연도별 자료를 막대그래프 보여주고, 특정 지역을 강조하는 효과를 넣었다. 그리고 데이터 가공을 하면서 오름차순 정렬을 하여 수치가 높은 지역이 왼쪽으로 가도록 하였다.