Коронавирус типа 2019-nCoV, после вспышки заболевания в китайском городе Ухань, стремительно распространяется по миру. На момент написания оригинальной статьи (30 января 2020 года) сообщалось о более чем 9000 заражённых и о 213 умерших, на сегодня (10 февраля 2020 года) сообщается уже о 40570 зараженных, 910 человек умерло. Случаи заражения коронавирусом выявлены во Франции, в Австралии, в России, в Японии, в Сингапуре, в Малайзии, в Германии, в Италии, в Шри-Ланке, в Камбодже, в Непале и во многих других странах. Никто не знает о том, когда вирус будет остановлен. Пока же число подтверждённых случаев коронавируса лишь растёт.
Автор статьи, перевод которой мы сегодня публикуем, хочет рассказать о том, как, с использованием Python, создать простое приложение для отслеживания распространения коронавируса. После завершения работы над этим приложением в распоряжении читателя окажется HTML-страница, которая выводит карту распространения вируса и ползунок, который позволяет выбирать дату, по состоянию на которую данные выводятся на карту.
Интерактивная карта распространения коронавируса типа 2019-nCoV
Здесь будут использованы такие технологии, как Python 3.7, Pandas, Plotly 4.1.0 и Jupyter Notebook.
import plotly.offline as go_offline
import plotly.graph_objects as go
import pandas as pd
read_csv
. Но прежде чем загружать данные из таблицы, воспользовавшись ссылкой на неё, нам нужно поработать с этой ссылкой. Сейчас она выглядит так:https://docs.google.com/spreadsheets/d/18X1VM1671d99V_yd-cnUI1j8oSG2ZgfU_q1HfOizErA/edit#gid=0
https://docs.google.com/spreadsheets/d/18X1VM1671d99V_yd-cnUI1j8oSG2ZgfU_q1HfOizErA/export?format=csv&id
url
, записывая в неё ссылку на данные, читаем данные с использованием метода read_csv
и записываем в пустые ячейки, содержащие NaN
, значения 0
.url='https://docs.google.com/spreadsheets/d/18X1VM1671d99V_yd-cnUI1j8oSG2ZgfU_q1HfOizErA/export?format=csv&id'
data=pd.read_csv(url)
data=data.fillna(0)
data.head()
. Это приведёт к выводу первых 5 строк таблицы.country
, location_id
, location
, latitude
и longitude
. Другие столбцы представляют собой пары, имена которых построены по следующей схеме: confirmedcase_dd-mm-yyyy
и deaths_dd-mm-yyyy
. Общее число столбцов в таблице на момент написания этого материала было 47. Это означает, что в моём распоряжении были данные за 21 день ((47-5)/2=21). Если начальной датой сбора данных было 10.01.2020, то конечной датой было 30.01.2020.#Инициализация некоторых переменных
fig=go.Figure()
col_name=data.columns
n_col=len(data.columns)
date_list=[]
init=4
n_range=int((n_col-5)/2)
#Цикл, в котором производится разбор данных и подготовка их к визуализации
for i in range(n_range):
col_case=init+1
col_dead=col_case+1
init=col_case+1
df_split=data[['latitude','longitude','country','location',col_name[col_case],col_name[col_dead]]]
df=df_split[(df_split[col_name[col_case]]!=0)]
lat=df['latitude']
lon=df['longitude']
case=df[df.columns[-2]].astype(int)
deaths=df[df.columns[-1]].astype(int)
df['text']=df['country']+'<br>'+df['location']+'<br>'+'confirmed cases: '+ case.astype(str)+'<br>'+'deaths: '+deaths.astype(str)
date_label=deaths.name[7:17]
date_list.append(date_label)
#Настройка графика Scattergeo
fig.add_trace(go.Scattergeo(
name='',
lon=lon,
lat=lat,
visible=False,
hovertemplate=df['text'],
text=df['text'],
mode='markers',
marker=dict(size=15,opacity=0.6,color='Red', symbol='circle'),
))
fig.add_trace
. На момент написания материала данные, на основе которых будут строиться изображения, представлены 21 объектом. Проверить это можно, воспользовавшись командой fig.data
.#Код слайдера
steps = []
for i in range(len(fig.data)):
step = dict(
method="restyle",
args=["visible", [False] * len(fig.data)],
label=date_list[i],
)
step["args"][1][i] = True # Переключить i-й набор данных в состояние "visible"
steps.append(step)
sliders = [dict(
active=0,
currentvalue={"prefix": "Date: "},
pad={"t": 1},
steps=steps
)]
steps
, используемый при перемещении бегунка слайдера. При перемещении слайдера выполняется визуализация соответствующего набора данных и скрытие того, что было выведено до этого. Вторая часть кода — это включение сконструированного ранее списка steps
в объект слайдера. Когда слайдер перемещается — осуществляется выбор соответствующего элемента из steps
.#Делаем видимым первый набор данных
fig.data[0].visible=True
#Выводим карту и сохраняем её в формате HTML
fig.update_layout(sliders=sliders,title='Coronavirus Spreading Map'+'<br>geodose.com',height=600)
fig.show()
go_offline.plot(fig,filename='F:/html/map_ncov.html',validate=True, auto_open=False)
fig.show
, после чего сохраняем её в HTML с помощью метода go_offline.plot
.import plotly.offline as go_offline
import plotly.graph_objects as go
import pandas as pd
#Чтение данных
url='https://docs.google.com/spreadsheets/d/18X1VM1671d99V_yd-cnUI1j8oSG2ZgfU_q1HfOizErA/export?format=csv&id'
data=pd.read_csv(url)
data=data.fillna(0)
#Инициализация некоторых переменных
fig=go.Figure()
col_name=data.columns
n_col=len(data.columns)
date_list=[]
init=4
n_range=int((n_col-5)/2)
#Цикл, в котором производится разбор данных и подготовка их к визуализации
for i in range(n_range):
col_case=init+1
col_dead=col_case+1
init=col_case+1
df_split=data[['latitude','longitude','country','location',col_name[col_case],col_name[col_dead]]]
df=df_split[(df_split[col_name[col_case]]!=0)]
lat=df['latitude']
lon=df['longitude']
case=df[df.columns[-2]].astype(int)
deaths=df[df.columns[-1]].astype(int)
df['text']=df['country']+'<br>'+df['location']+'<br>'+'confirmed cases: '+ case.astype(str)+'<br>'+'deaths: '+deaths.astype(str)
date_label=deaths.name[7:17]
date_list.append(date_label)
#Настройка графика Scattergeo
fig.add_trace(go.Scattergeo(
name='',
lon=lon,
lat=lat,
visible=False,
hovertemplate=df['text'],
text=df['text'],
mode='markers',
marker=dict(size=15,opacity=0.6,color='Red', symbol='circle'),
))
#Код слайдера
steps = []
for i in range(len(fig.data)):
step = dict(
method="restyle",
args=["visible", [False] * len(fig.data)],
label=date_list[i],
)
step["args"][1][i] = True # Переключить i-й набор данных в состояние "visible"
steps.append(step)
sliders = [dict(
active=0,
currentvalue={"prefix": "Date: "},
pad={"t": 1},
steps=steps
)]
#Делаем видимым первый набор данных
fig.data[0].visible=True
#Выводим карту и сохраняем её в формате HTML
fig.update_layout(sliders=sliders,title='Coronavirus Spreading Map'+'<br>geodose.com',height=600)
fig.show()
go_offline.plot(fig,filename='F:/html/map_ncov_slider.html',validate=True, auto_open=False)
К сожалению, не доступен сервер mySQL