Строим «график счастья» на Python
Примеры Python python графика, python построение графиков, python построить график
Зима – это очень красивое время года. Однако многие из нас замечают, что в эту пору уходить на работу приходится, когда еще темно, а приходить домой, когда уже темно. Поэтому, в этой статье мы попытаемся визуализировать данные о восходе-заходе солнца и соотнести их с привычным для большинства людей режимом дня (работа и бодрствование). Работу мы будем выполнять на Python (pandas + matplotib). Посмотрим, что получится.
Итак, сначала мы должны подготовить данные, которые будем визуализировать. В интернете есть уже готовые наборы, а при желании можно собрать и свой. По сути, нам нужны таблицы, в которых собраны сведения о дате, восходе и заходе солнца, продолжительности светового дня, зените. Также нужны данные о астрономических, навигационных и гражданских сумерках.
Чтобы было удобнее создадим папку для проекта /sumerki, в которой папку /input, а также скрипт sumerki.py. А в папке input нам нужно разместить файлики sumerki_1.txt и sumerki_2.txt, а в них скопировать данные из наших таблиц. Первые строки будут иметь такой вид:
1 января 09:00:39 12:33:54 16:07:09 07:06:29 +1:16
08:14:08 07:25:39 06:40:27 18:27:20 17:42:09 16:53:40
Нам хватит и данных из сторонних источников, теперь остается определить рабочее время и время бодрствования. Возьмем следующие промежутки: 07:00:00-20:00:00 – бодрствование, 09:00:00-18:00:00 – работа.
Структура понятна. Теперь нужно поработать с кодом Python.
Для начала следует сделать все необходимое импорты и выполнить некоторые настройки.
import os
import datetime
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib import rc
# Создадим небольшую служебную функцию для преобразования строкового времени с число
def stn(dstr):
return mdates.datestr2num(dstr.tolist())
# Простой рецепт для решения проблемы отображения кириллицы в matplotlib
font = {'family': 'Verdana', 'weight': 'normal'}
rc('font', **font)
DIR = os.path.dirname('__File__')
Данные нужно сформировать в pandas (в результате будем иметь 2 датафрейма, которыми и будем пользоваться – S,W):
# Считаем данные из текстовых файлов и сохраним их в датафрейм с заранее известными столбцами
s1 = open(os.path.join(DIR, 'input', 'sumerki_1.txt'), 'r').read().split('\n')
s2 = open(os.path.join(DIR, 'input', 'sumerki_2.txt'), 'r').read().split('\n')
oday = datetime.datetime.strptime('01.01.2016', '%d.%m.%Y')
dates = [oday + datetime.timedelta(days=dt) for dt in range(len(s1))]
# От себя мы добавим столбцы с временем начала и окончания дня (0, 24)
s = [[dates[i[0]]] + s1[i[0]].split('\t') + s2[i[0]].split('\t') + ['00:00:01', '23:59:59'] for i in enumerate(s1)]
columns = ['datetime', 'date', 'voshod', 'zenit', 'zahod', 'dolgota', 'cng',
'sum1_from', 'sum2_from', 'sum3_from', 'sum3_to', 'sum2_to', 'sum1_to',
'0', '24']
S = pd.DataFrame(s, columns=columns)
# Сформироуем датафрейм, содержащий данные о дне и начале/конце рабочего дня (бодрствования)
w = [[dt, '07:00:00', '09:00:00', '18:00:00', '20:00:00'] for dt in dates]
columns = ['datetime', 'life_from', 'work_from', 'work_to', 'life_to']
W = pd.DataFrame(w, columns=columns)
Остается лишь отразить все это в виде графика. Чтобы было удобнее желтым цветом отобразим световой день, а оранжевым сумерки, темное время будет отмечено голубоватым со звездами.
# Ну а теперь построим график
fig, ax = plt.subplots()
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
plt.gca().xaxis.set_major_locator(mdates.MonthLocator())
plt.gcf().autofmt_xdate()
# Отобразим нужные данные на графике
l1, = ax.plot(S['datetime'], stn(S['voshod']), 'r-', label='восход')
l2, = ax.plot(S['datetime'], stn(S['zahod']), 'b-', label='заход')
l3, = ax.plot(S['datetime'], stn(S['sum1_from']), 'g-', label='сумерки (от)')
l4, = ax.plot(S['datetime'], stn(S['sum1_to']), 'm-', label='сумерки (до)')
l5, = ax.plot(W['datetime'], stn(W['work_from']), 'k-', label='рабочее время')
l6, = ax.plot(S['datetime'], stn(W['work_to']), 'k-', label='рабочее время')
l7, = ax.plot(S['datetime'], stn(W['life_from']), 'k-', label='время бодрствования')
l8, = ax.plot(S['datetime'], stn(W['life_to']), 'k-', label='время бодрствования')
# Заполним пространство между
# Восход-заход
plt.fill_between(S['datetime'].tolist(), stn(S['voshod']), stn(S['zahod']), alpha=0.4, color='yellow', hatch='.')
# Cумерки
plt.fill_between(S['datetime'].tolist(), stn(S['sum1_from']), stn(S['voshod']), alpha=0.4, color='orange', hatch='.')
plt.fill_between(S['datetime'].tolist(), stn(S['zahod']), stn(S['sum1_to']), alpha=0.4, color='orange', hatch='.')
# Ночь
plt.fill_between(S['datetime'].tolist(), stn(S['0']), stn(S['sum1_from']), alpha=0.4, color='blue', hatch='*')
plt.fill_between(S['datetime'].tolist(), stn(S['sum1_to']), stn(S['24']), alpha=0.4, color='blue', hatch='*')
# Рабочее время и время бодрствования
plt.fill_between(W['datetime'].tolist(), stn(W['work_from']), stn(W['work_to']), alpha=0.1, color='blue', hatch='/')
plt.fill_between(W['datetime'].tolist(), stn(W['life_from']), stn(W['life_to']), alpha=0.1, color='blue', hatch='/')
# Форматирование, заголовок и легенда
ax.yaxis_date()
ax.xaxis_date()
ax.set_xlabel("Дата")
ax.set_ylabel("Время")
plt.title('График зависимости рабочего времени (времени бодрствования) от светового дня.')
plt.legend(handles=[l1, l2, l3, l4, l6, l8], loc=1, fontsize=11)
fig.autofmt_xdate()
# Ну и покажем график уже наконец
plt.show()
В результате имеем наш график. Таким образом можно сделать графики для различных городов, и на основе этого определить, какой город будет наиболее приемлемым в плане восхода-захода солнца лично для вас.