yuliianikolaenko 21 июня 2021

🐍 Создание интерактивных панелей с Streamlit и Python

В небольшом туториале мы расскажем, как за 12 простых шагов подготовить среду и создать интерактивную панель для визуализации данных.
🐍 Создание интерактивных панелей с Streamlit и Python
Панель мониторинга (dashboards) – это графический пользовательский интерфейс для интерактивного отображения информации, а также визуализации ключевых показателей и тенденций данных. Разработка таких панелей является довольно утомительной задачей.

Создать интерактивные панели можно с использованием библиотек вроде Plotly и Bokeh. Мы расскажем о Streamlit – еще одной простой библиотеке Python с открытым исходным кодом, которая стремительно набирает популярность в области машинного обучения и Data Science. Она позволяет публиковать веб-приложения в открытом доступе, а также включает встроенный веб-сервер с возможностью развертывания в контейнере docker. В этом обзоре вы найдете подробную инструкцию о том, как самостоятельно разработать и опубликовать интерактивную панель для визуализации данных.

Подготовка

Подготовка среды

Начнем с установки Streamlit и запуска команды hello. Откройте терминал и запустите приведенные ниже команды:

        $ pip install streamlit
$ streamlit hello
    

Если приложение работает, вы увидите следующий результат:

🐍 Создание интерактивных панелей с Streamlit и Python

Когда вы запустите приложение, в браузере автоматически откроется сервер localhost:

🐍 Создание интерактивных панелей с Streamlit и Python
Tip💡
Чтобы выйти из запущенного приложения, используйте Ctrl+с.

Установка библиотек

Импортируем необходимые библиотеки для построения графиков и отображения информации.

        import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
from urllib.request import urlopen
import json
    

Streamlit позволяет отображать текст по-разному:

  • st.title() – для установки заголовка;
  • st.text() – для записи описания для конкретного графика;
  • st.markdown() – для отображения текста в виде markdown;
  • st.latex() – для отображения математических выражений на панели мониторинга;
  • st.write() – помогает отображать все возможные детали, например, график, фрейм данных, функции, модель и т. д.;
  • st.sidebar() – для отображения данных на боковой панели;
  • st.dataframe() – для отображения фрейма данных;
  • st.map() – для отображения карты в одной строке кода и т. д.

Пример приложения

Подготовим данные

Чтобы приложение работало более эффективно, уменьшим размер данных, оставив только необходимые переменные:

        # Оставляем только необходимые переменные
df = df[['iso_code','location','total_cases_per_million','total_deaths_per_million','people_vaccinated_per_hundred','date']]
df = df[df.location != 'World']
df["date"] = pd.to_datetime(df["date"])
# Сохраним данные в формате csv для создания приложения
df.to_csv('data.csv', index = False)
    

Настройка заголовка и боковой панели для мониторинга

        # Настройка заголовка и текста 
st.title("COVID 19 IN THE WORLD DASHBOARD")
st.write("""This dashboard will present the spread of COVID-19 in the world by visualizing the timeline of the total cases and deaths. As well as the total number of vaccinated people.""")

# Настройка боковой панели
st.sidebar.title("About")
st.sidebar.info(
    """
    This app is Open Source dashboard.
    """
)
st.sidebar.info("Feel free to collaborate and comment on the work. The github link can be found "
                "[here](https://github.com/yuliianikolaenko/COVID_dashboard_proglib).")


    
Tip💡
Добавьте изображение с помощью st.image().

Загружаем данные

На примере данных о COVID-19 Центра системных наук и инженерии (CSSE) Университета Джона Хопкинса, мы создадим визуализацию для интерактивной панели Streamlit.

        # Загружаем новые оптимизированные данные
DATA = ('data.csv')
DATE_COLUMN = 'date'
@st.cache # для оптимизации работы приложения

# Создадим функцию для загрузки данных
def load_data():
    df = pd.read_csv(DATA, parse_dates=[DATE_COLUMN])
    return df   

# Применим функцию 
df = load_data() 

# Загружаем координаты стран для карты
 with open('countries.geo.json') as json_file:
    json_locations = json.load(json_file)

    

Визуализация

        # Создадим функции для визуализации количества случаев заражения, смертей и вакцинированных людей.
def draw_map_cases():
    fig = px.choropleth_mapbox(df, geojson=json_locations, locations='iso_code', color='total_cases_per_million',
                               color_continuous_scale="Reds",
                               mapbox_style="carto-positron",
                               title = "COVID 19 cases per million",
                               zoom=1,
                               opacity=0.5,
                               )
    fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
    return fig

def draw_map_deaths():
    fig = px.choropleth_mapbox(df, geojson=json_locations, locations='iso_code', color='total_deaths_per_million',
                               color_continuous_scale="Greys",
                               mapbox_style="carto-positron",
                               title = "Deaths from COVID 19 per million",
                               zoom=1,
                               opacity=0.5,
                               )
    fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
    return fig

def draw_map_vaccine():
    fig = px.choropleth_mapbox(df, geojson=json_locations, locations='iso_code', color='people_vaccinated_per_hundred',
                               color_continuous_scale="BuGn",
                               mapbox_style="carto-positron",
                               title = "Vaccinations from COVID 19 per hundred",
                               zoom=1,
                               opacity=0.5,
                               )
    fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
    return fig
    
Tip💡
Измените цветовую палитру карты с помощью аругумента color_continuous_scale. Подробнее: https://plotly.com/python/builtin-colorscales/.

Добавьте интерактивность с помощью виджетов:

  • st.sidebar.checkbox() - для отображения/скрытия данных;
  • st.sidebar.selectbox() – для выбора для отображения параметров.
Tip💡
Используйте флажки, чтобы выбрать данные для визуализации в разных категориях. В поле выбора отобразите raw data, а также кнопку выбора между количеством зараженных, смертельных или восстановленных случаев.

Далее мы также можем выбрать случаи в соответствии с требуемым параметрами. Метод st_write используется для визуализации набора данных.

        show_data = st.sidebar.checkbox('Show raw data')
if show_data == True:
    st.subheader('Raw data')
    st.markdown(
        "#### Data on COVID-19 (coronavirus) by Our World in Data could be found [here](https://github.com/owid/covid-19-data/tree/master/public/data).")
    st.write(df)

    
🐍 Создание интерактивных панелей с Streamlit и Python
        # Создадим поле выбора для даты
show_timerange = st.sidebar.checkbox("Show date range")
if show_timerange == True:
    # Вычислим даты для создания временного слайдера
    min_ts = min(df[DATE_COLUMN]).to_pydatetime()
    max_ts = max(df[DATE_COLUMN]).to_pydatetime()
    day_date = pd.to_datetime(st.sidebar.slider("Date to chose", min_value=min_ts, max_value=max_ts, value=max_ts))
    st.write(f"Data for {day_date.date()}")
    df = df[(df['date'] == day_date)]

# Создадим поле выбора для визуализации общего количества случаев, смертей или вакцинаций
select_event = st.sidebar.selectbox('Show map', ('cases per million', 'deaths per million', 'vaccinated per hundred'))
if select_event == 'cases per million':
    st.plotly_chart(draw_map_cases(), use_container_width=True)

if select_event == 'deaths per million':
    st.plotly_chart(draw_map_deaths(), use_container_width=True)

if select_event == 'vaccinated per hundred':
    st.plotly_chart(draw_map_vaccine(), use_container_width=True)

    

Для построения графика мы используем метод библиотеки plotly.express, в формате который поддерживает Streamlit – st.plotly_chart().

🐍 Создание интерактивных панелей с Streamlit и Python
Tip💡
Чтобы просмотреть фрейм данных в табличном представлении, воспользуйтесь st.dataframe() и st.table().

Соединяем все вместе

Вот и все, теперь мы можем опубликовать свое творение. Полный скрипт для интерактивного приложения выглядит так:

        # Настройка заголовка и текста 
st.title("COVID 19 IN THE WORLD DASHBOARD")
st.write("""This dashboard will present the spread of COVID-19 in the world by visualizing the timeline of the total cases and deaths. As well as the total number of vaccinated people.""")

# Настройка боковой панели
st.sidebar.title("About")
st.sidebar.info(
    """
    This app is Open Source dashboard.
    """
)
st.sidebar.info("Feel free to collaborate and comment on the work. The github link can be found "
                "[here](https://github.com/yuliianikolaenko/COVID_dashboard_proglib).")
# Загружаем новые оптимизированные данные
DATA = ('data.csv')
DATE_COLUMN = 'date'
@st.cache # для оптимизации работы приложения

# Создадим функцию для загрузки данных
def load_data():
    df = pd.read_csv(DATA, parse_dates=[DATE_COLUMN])
    return df   

# Применим функцию 
df = load_data()  


# Создадим функции для визуализации количества случаев заражения, смертей и вакцинированных людей.
def draw_map_cases():
    fig = px.choropleth(df, locations="iso_code",
                         color="total_cases",
                         hover_name="location",
                         title="Total COVID 19 cases in the world",
                         color_continuous_scale=px.colors.sequential.Redor)
    return fig

def draw_map_deaths():
    fig = px.choropleth(df, locations="iso_code",
                         color="total_deaths",
                         hover_name="location",
                         title="Total deaths from COVID 19 in the world",
                         color_continuous_scale=px.colors.sequential.Greys)
    return fig

def draw_map_vaccine():
    fig = px.choropleth(df, locations="iso_code",
                         color="total_vaccinations",
                         hover_name="location",
                         title="Total vaccinated from COVID 19 in the world",
                         color_continuous_scale=px.colors.sequential.Greens)
    return fig

show_data = st.sidebar.checkbox('Show raw data')
if show_data == True:
    st.subheader('Raw data')
    st.markdown(
        "#### Data on COVID-19 (coronavirus) by Our World in Data could be found [here](https://github.com/owid/covid-19-data/tree/master/public/data).")
    st.write(df)

# Вычислим даты для создания временного слайдера
min_ts = min(df[DATE_COLUMN]).to_pydatetime()
max_ts = max(df[DATE_COLUMN]).to_pydatetime()

# Создадим поле выбора для даты
show_timerange = st.sidebar.checkbox("Show date range")
if show_timerange:
    min_selection, max_selection = st.sidebar.slider("Timeline", min_value=min_ts, max_value=max_ts, value=[min_ts, max_ts])
    df = df[(df[DATE_COLUMN] >= min_selection) & (df[DATE_COLUMN] <= max_selection)]

# Создадим поле выбора для визуализации общего количества случаев, смертей или вакцинаций
select_event = st.sidebar.selectbox('Show map', ('total_cases', 'total_deaths', 'total_vaccinations'))
if select_event == 'total_cases':
    st.plotly_chart(draw_map_cases(), use_container_width=True)

if select_event == 'total_deaths':
    st.plotly_chart(draw_map_deaths(), use_container_width=True)

if select_event == 'total_vaccinations':
    st.plotly_chart(draw_map_vaccine(), use_container_width=True)
    

Публикация приложения

Создайте запрос

Теперь, когда вы создали свое приложение, вы можете поделиться им. Используйте Streamlit sharing, чтобы приложение с открытым кодом совершенно бесплатно. Оно будет развертываться непосредственно из вашего репозитория GitHub.

Совместное использование Streamlit – идеальное решение, если ваше приложение размещено в общедоступном репозитории GitHub, и вы хотите, чтобы любой человек в мире мог получить к нему доступ. Если это не так, присмотритесь к Streamlit для команд, чтобы получить дополнительную информацию о безопасном частном доступе к приложениям.

Если вы хотите разместить приложение с помощью другого хостинг-провайдера, это не станет проблемой.

Чтобы начать работу, сначала запросите приглашение по адресу streamlit.io/sharing. Как только вы получите электронное письмо, можно будет приступить к развертыванию. Для этого придется выполнить несколько шагов.

🐍 Создание интерактивных панелей с Streamlit и Python

Поместите свое приложение на GitHub

Поместите ваше приложение Streamlit в публичное репозиторий GitHub. Добавьте файл requirements.txt для управления любыми внешними зависимостями. Streamlit просматривает имя файла ваших требований, чтобы определить, какой менеджер зависимостей Python использовать:

🐍 Создание интерактивных панелей с Streamlit и Python

Войдите в систему

Зайдите на share.streamlit.io, нажмите на кнопку кнопка для входа в систему с помощью GitHub (используйте адрес электронной почты, связанный с вашей учетной записью).

Разверните приложение

Нажмите кнопку «Новое приложение»‎, затем введите имя вашего репозитория, ветвь и путь к файлу и нажмите кнопку «Развернуть»‎.

Разработанное в данном туториале приложение живет по адресу:

Когда вы сделаете git push, приложение будет обновлено. Если оно имеет много зависимостей, может потребоваться некоторое время для первого развертывания, но не касающиеся зависимостей изменения выполняются немедленно. Streamlit быстро определяет изменение зависимостей и в этом случае автоматически выполняет полное повторное развертывание приложения, что может занять немного больше времени.

Ваше приложение теперь живет по фиксированному URL в открытом доступе для имеющих ссылку. Достаточно нажать кнопку меню в правом верхнем углу и выбрать «Поделиться этим приложением».
Tip💡
Ознакомьтесь с документацией Streamlit подробнее: https://docs.streamlit.io/en/stable/deploy_streamlit_app.html#python-dependencies.

Заключение

Streamlit является одной из самых быстрорастущих и популярных платформ для создания интерактивных панелей визуализации данных машинного обучения и Data Science. Опробуйте ее с различными наборами данных, а для вдохновения загляните в Streamlit блог, где собраны примеры использования и полезные советы.

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Продуктовый аналитик
Екатеринбург, по итогам собеседования
Продуктовый аналитик в поддержку
по итогам собеседования
DevOps
Санкт-Петербург, от 150000 RUB до 400000 RUB

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ