Насколько интересны ваши посты?

Это приложение Streamlit позволяет вам загружать данные о ваших взаимодействиях, показах и публикациях для анализа ваших публикаций!

Обзор

Эта статья познакомит вас с кодом, который запускает это приложение Streamlit!

Я расскажу о следующем:

  • создание многостраничного приложения Streamlit
  • создание различных элементов диаграммы и виджетов
  • загрузка пользовательских данных
  • создание вертикальной полосы для отслеживания положения курсора
  • создание интерактивных подсказок
  • включение перехода по точкам данных для открытия гиперссылок (в данном случае, сообщений LinkedIn)
  • создание диаграмм Altair
  • создание составных диаграмм с использованием функций layer() и vconcat()
  • создание интерактивных таблиц AgGrid

В конце этой статьи я включил видео YouTube, в котором представлен пошаговый обзор интерфейса панели управления.

Я также включил ссылку на мой репозиторий GitHub.

Надеюсь, вам понравится, и пожалуйста, оставьте свои комментарии!

Код

Я познакомлю вас с кодом этого приложения Streamlit, которое было запрограммировано на Python с использованием IDE Visual Studio Code.

Импорт библиотек

Во-первых, мы собираемся импортировать необходимые библиотеки, в том числе:

  • os для навигации по файлам
  • openpyxl для чтения файлов
  • streamlit для создания приложения!
  • pandas и numpy, потому что мы их любим
  • AgGrid для красивых таблиц
  • datetime для обработки даты и времени
  • altair для красивых участков

Требования.txt

Обязательно создайте файл requirements.txt, чтобы Streamlit мог получить к нему доступ из вашего репозитория. Я включил файл для своего приложения ниже.

Многостраничное приложение

Я на секунду перейду к концу кода, чтобы предоставить контекст для следующей части, где я начну определять функции страницы.

Для своего приложения я хотел создать несколько страниц, чтобы интерфейс не был слишком перегружен информацией. Я хотел, чтобы у самой приборной панели была своя страница.

Итак, чтобы сделать это, я определил несколько страниц, включая main_page, page2 и page3, которые соответствуют целевой странице, информационной панели и направлениям данных. В приведенном ниже коде используется функция selectbox() для создания раскрывающегося списка со страницами навигации на боковой панели.

Главная страница

Вот целевая страница моего приложения LinkedIn Engagement Dashboard.

В этом коде я определяю главную страницу или целевую страницу приложения.

Я начинаю с определения заголовка страницы, предоставления относительного пути к изображению логотипа LinkedIn в репозитории и использования функции image().

Затем я предоставляю информацию на боковой панели с помощью функции sidebar.markdown().

В теле страницы я определяю подзаголовки с помощью функции subheader().

Я добавляю другое изображение на страницу так же, как добавлял изображение логотипа LinkedIn, за исключением того, что на этот раз я не определяю ширину. Это позволяет изображению занимать всю ширину экрана.

Панель инструментов (запуск приложения)

Чтобы начать говорить о приборной панели, я на самом деле пропущу код ниже, поскольку возникает исключение из-за того, что данные не загружаются при запуске приложения.

Код сначала «пытается» прочитать файл Excel, но он еще не существует, поскольку пользователь не загрузил свой файл.

Это исключение приводит к представлению ниже, где экран предлагает пользователю «Пожалуйста, загрузите свои данные :)». См. код обработки исключений ниже.

Панель инструментов

Хорошо, следующий раздел кода ниже — это «верхняя часть» функции page2(), которая определяет страницу панели инструментов.

Как и на предыдущей странице, я определяю заголовок страницы с логотипом LinkedIn.

Я использую функцию file_uploader() для загрузки файла Excel (.xlsx) заданий и показов на боковой панели страницы. Имя файла будет иметь вид {Год}_{Ваше имя}.xlsx.

Обратите внимание, что я требую, чтобы тип файла был файлом .xlsx. Именно так данные о взаимодействиях и показах загружаются из LinkedIn, и это следует сравнивать с файлом Shares.csv, который вы получаете из архива данных LinkedIn.

Функция page3(), о которой я расскажу далее, охватывает страницу Data Directions. На этой странице приведены сведения о том, как загрузить данные о взаимодействиях и показах из LinkedIn, а также запросить архив данных из LinkedIn для получения файла Shares.csv.

С .xlsx file_uploader() я предоставляю всплывающую подсказку с описанием данных, которые нужно загрузить, а также с тем, как получить данные.

Я также определяю переменную file1_details для хранения различных сведений о файле на случай, если они понадобятся.

Код для page2() продолжает попытку прочитать файл Excel как pandas DataFrame, df. Если это удается, я затем преобразую переменную Date в тип date, а не datetime, поскольку она была загружена. Это делает участки намного чище позже.

Если чтение файла завершается ошибкой, DataFrame df определяется как пустой.

Продолжая работу со страницей2() — как и в дальнейшем, я пишу аналогичный код для загрузки в файл Shares.csv как файл2.

Обратите внимание, что на этот раз файл должен быть в формате .csv.

Аналогично тому, как мы обрабатывали файл1, мы попытаемся прочитать файл2 как кадр данных pandas с именем df2.

Если это чтение завершится ошибкой, df2 будет определен как пустой DataFrame.

Загрузка данных

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

Однако взгляните на всплывающую подсказку. Обратите внимание, что в поле Сообщение отображается «Недоступно. Требуются данные». Это связано с тем, что пользователь еще не загрузил файл Shares.csv.

Если пользователь решит загрузить свой файл Shares.csv, он просто сделает это так же, как и с файлом .xlsx, но в нижнем виджете загрузки файлов.

После загрузки файла Shares.csv во всплывающей подсказке отобразится предварительный просмотр публикации, как показано ниже.

Подготовка данных

Здесь я пытаюсь определить новые столбцы в кадре данных df2, который содержит данные об общих ресурсах (см. объяснение исключений далее).

  • определите новый столбец DateTime, который изначально был датой
  • переопределить столбец Date, чтобы он содержал только дату типа, а не тип datetime
  • определить новый столбец времени, чтобы он содержал только компонент времени столбца DateTime
  • переименуйте столбец ShareCommentary в Post для ясности (этот столбец является содержимым предварительного просмотра публикации, отображаемым во всплывающей подсказке)

Затем я перезаписываю df путем слияния (слияния слева) DataFrame df, который содержит данные о взаимодействиях и показах, с df2 (общие данные).

Я заполняю значения nan в столбцах Post и ShareLink (url). Если в определенный день публикации нет, значение в столбце «Публикация» становится «Нет публикации в этот день». и если в столбце ShareLink нет значения, я заменяю nan страницей канала LinkedIn (вы попадете на страницу канала LinkedIn, если вы нажмете на день, когда вы не публиковали сообщения).

Если эта попытка манипулирования данными не удалась (из-за того, что df2 пуст, потому что пользователь еще не загрузил свои данные об общих ресурсах), столбец «Сообщение» будет заполнен «Недоступно. Требуются данные». и все значения ShareLink будут страницей LinkedIn Feed.

Настройка сюжета

Я предоставил пользователю возможность настроить ширину и высоту графика, если он хочет просмотреть данные в большем масштабе.

Это доступно на боковой панели с помощью функции slider().

Фильтр диапазона дат

Здесь я определяю фильтр диапазона дат, чтобы пользователь мог выбрать окно времени.

Я установил диапазон по умолчанию от минимальной даты до максимальной даты в столбце «Дата». Я снова использую функцию slider(), чтобы предоставить пользователю средства фильтрации своих данных и настройки окна времени.

Затем DataFrame df переопределяется на основе любых изменений ползунка.

Здесь я также определяю столбец «Процент» df, который представляет собой взаимодействие, деленное на количество показов за любой день.

Создание интерактивных диаграмм

Я определяю новый источник DataFrame как эквивалентный DataFrame df.

Затем я создаю выделение, которое выбирает ближайшую точку на основе значения x местоположения мыши.

Я создаю базовую диаграмму с осью X, определенной столбцом «Дата», и указываю формат даты.

Затем я определяю строки 1 и 2 как строки для вовлечений и показов.

А вот и драма

Эта следующая часть была причиной большей части моей головной боли в этом приключении. Графики, которые я создал на этой панели инструментов, не похожи ни на какие примеры, которые я мог найти в Интернете. У меня было две линейные диаграммы на одном подграфике, каждая из которых получала собственную ось Y, и этот подграфик затем накладывался поверх другого графика.

Проблема, с которой я сталкивался в течение длительного времени, заключалась в том, что моя основная метка оси Y и галочки для «Взаимодействия» также отображались на вторичной оси Y. Итак, у меня было множество пюреобразных галочек, наложенных друг на друга, и две метки по оси Y, «Взаимодействия» и «Показы», ​​сдвинутые вместе.

Я неоднократно пытался исправить это, но так и не смог понять. Отсюда скриншот моих вкладок ниже. Это не уникальный опыт в любом приключении по кодированию (не говоря уже об изучении нового инструмента, такого как Streamlit), но это было болезненно. Мне пришлось уйти от этой проблемы, а затем продолжать возвращаться к ней в попытках ее исправить. Я много раз терпел неудачу.

К счастью, есть счастливый конец! В конце концов я столкнулся с ответом, когда искал другую проблему! О разрешении я расскажу ниже.

Подробнее о графике

Итак, как я понял, как исправить вторичную ось Y? Ну, так как у меня есть две сложенные диаграммы, я подумал, что должен был применить функцию resolve_scale() к комбинации диаграмм. Altair и Streamlit разборчивы в том, что и где можно настроить. Итак, я подумал, что поступаю правильно, помещая это на комбинацию, а не на отдельный график.

Получается, что resolve_scale() с условием y = «независимая» нужно было разместить прямо на строках. Чтобы сделать это, я использовал функцию layer() для наложения линий line1 и line2, а затем я использовал resolve_scale() для строк. Ву! Это сработало!

Затем я определяю селекторы на основе ближайшего, который был определен выше. Это говорит нам значение x курсора.

Я определяю точки 1 и точки 2 (а также точки 3 позже), чтобы включить всплывающие подсказки с подробным описанием даты, участия, показов, процента и публикации. Примеры и изображения этих всплывающих подсказок были предоставлены ранее. Вот пример, показывающий предварительный просмотр поста о Джеймсе Бонде, который я сделал.

Эти точки становятся видимыми только при наведении на них курсора. При нажатии на любую точку поле href сообщает приложению, что нужно направить пользователя на ссылку ShareLink, которая является URL-адресом сообщения LinkedIn, связанным с данной точкой данных.

Ниже приведен пример сообщения LinkedIn после перехода пользователя по ссылке.

Вот пример поста LinkedIn после перехода пользователя в определенный день на диаграмме.

Вертикальная полоса прокрутки и процентный график

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

Затем я определяю нижнюю диаграмму аналогично тому, как была определена верхняя диаграмма. Я определяю диаграмму base2 с осью x, определенной столбцом Date.

Я определяю строку3 как процентную линию и точки3 таким же образом, как я определил точки1 и точки2 выше.

Привязка элементов диаграммы

Я связываю элементы диаграммы для верхней и нижней диаграмм с помощью функции layer(). Помните, как я сделал это раньше, когда строки 1 и 2 стали строками?

Я комбинирую линии, селекторы, точки1, точки2 и правило, чтобы получить верхнюю диаграмму и определить динамические свойства на основе выбора пользователем ширины и высоты графика.

Я делаю то же самое для нижней диаграммы, комбинируя линию 3, точки 3 и правило, чтобы стать ниже.

Финальная диаграмма

Чтобы завершить все это бантиком, я использовал функцию altair_chart() для построения окончательного графика.

В рамках этого я использовал функцию vconcat() для вертикальной конкатенации, чтобы сложить верхнюю и нижнюю диаграммы.

Помните, как я говорил, что альтаир и стримлит придирчивы к тому, что и где вы настраиваете? Именно в этот момент я могу настроить точки и оси с помощью функций configure_points() и configure_axis() соответственно.

Сводные статистические данные

У меня была возможность показать сводную статистику по взаимодействиям и показам за период, определенный пользователем, или среднее значение за дни, когда были данные.

Я взял сводную статистику за период, выбранный пользователем, так как это имело для меня наибольший смысл.

Вот код для создания таблицы сводной статистики.

Я определяю средние значения, итоги и изменения для взаимодействий и показов за период, определенный пользователем, и выполняю здесь некоторое форматирование.

Я создаю таблицу сводной статистики, используя AgGrid для более красивой таблицы.

Таблица отфильтрованных данных

Затем я создал таблицу отфильтрованных данных, которая предоставляет пользователю данные за выбранный им период времени.

Я определяю новый DataFrame output_df, так как мне нужно было выполнить дальнейшие изменения форматирования, и я не хотел менять df DataFrame.

Затем я снова создаю таблицу отфильтрованных данных, используя AgGrid.

Исключение (нет данных)
Вот обработка исключения для события, когда данные еще не загружены, которое обсуждалось ранее, но для полноты изложения появляется в этом месте кода.

Направления данных

Сделал это через код для страницы панели инструментов! И наконец, страница Data Directions, которая предоставляет пользователю инструкции о том, где загрузить необходимые данные для этого приложения.

Точно так же, как и на предыдущих страницах, я определяю заголовок с логотипом LinkedIn.

Затем я использую subheader() и markdown() для ввода инструкций!

Собираем все вместе

Не прекращайте следовать за вами прямо сейчас! Это самая важная часть.

Здесь я беру все созданные выше функции страницы, включая main_page(), page2() и page3(), и создаю навигацию по страницам с помощью selectbox().

И вуаля! У вас есть панель инструментов LinkedIn Engagements.

Посмотрите мое видео на YouTube, а также мой репозиторий на GitHub по ссылкам ниже.

Пошаговое руководство по интерфейсу панели инструментов

Вот видео на YouTube, где я рассказываю вам об интерфейсе LinkedIn Engagement Dashboard!

Репозиторий GitHub

Репозиторий GitHub для этого кода можно найти по ссылке ниже.



Краткое содержание

Я создал приложение LinkedIn Engagements Dashboard с помощью Streamlit, которое позволяет пользователям загружать данные о своих взаимодействиях, впечатлениях и публикациях для анализа их участия в публикациях!

Загляните на мою панель LinkedIn Engagements Dashboard и дайте мне знать, что вы думаете!

До скорого…

Нравится этот контент? Следуйте за мной на Medium, чтобы увидеть будущие публикации! Стань участником Medium, чтобы читать неограниченное количество статей. Поверьте, это того стоит!

Не стесняйтесь обращаться ко мне с любыми вопросами о жизни специалиста по работе с данными в LinkedIn или Twitter!