Tableau — это инструмент аналитики, и вряд ли кто-то серьезно ассоциирует его с созданием видео. В этой статье я расскажу о том, как при помощи Tableau создавать кадры для видео и соединять кадры в один видеофайл при помощи других инструментов.

1. Что Tableau умеет делать нативно?

У Tableau есть опция pages, которая позволяет создавать анимацию на основании данных. Суть этой опции в том, что последовательно отображается только часть данных за каждый кадр, также можно показывать историю предыдущих кадров с затуханием и без.

В качестве примеров можно посмотреть на пару визуализаций: a ploygonal dog и How has the world changed since 1962?, автор Marc Reid.

Для проигрывания видео нужно нажать кнопку ‘play’ на визуализациях. В вебе скорость проигрывания не регулируется, нельзя смотреть анимацию на высокой скорости, поскольку каждый кадр генерируется своим запросом на сервер, и это занимает время. В Tableau Desktop для Pages можно выбирать только 3 скорости.

Кроме того, для корректной работы опции Pages нужна определенная структура данных, и Pages анимируют визуализацию только по одному полю. При большом количестве данных и точек на визуализации будут заметны «тормоза», то есть, Tableau не сможет в реальном времени быстро обрабатывать все Pages.

Tableau не может нативно автоматически создавать анимацию при помощи параметров — для этого нужно вручную изменять значение нужного параметра.

2. Видео, которое можно создавать из кадров, сгенерированных Tableau

Указанные выше ограничения не позволяют Tableau создавать видео любого фреймрейта и разрешения. Можно, конечно, использовать видеозахват экрана и записать видео, а потом ускорить его в каком-то редакторе видео, но оно получается рваным — кадры дергаются из-за времени отрисовки каждого кадра. Такое видео не будет качественным.

Для равномерного видеопотока с одинаковой скоростью кадров в секунду можно в Tableau нарисовать каждый кадр, сохранить как PNG, и потом объединить все кадры в анимированный GIF или видеофайл.

Пример такого анимированного файла показан внизу — он показывает динамику роста округов в США по годам. По сути, за несколько секунд можно увидеть историю возникновения государства США, здесь отражаются грандиозные события, например, покупка Луизианы в 1803 году. Идею для этой визуализации предложил Егор Ларин, за что ему огромное спасибо.

Полноэкранная версия этого GIFa здесь, и сам виз

Следующий GIF — это результат склеивания кадров. В датасете этого виза — только 2 значения (сами портреты рисуются математическими функциями), поэтому, Pages работать не будут. Отрисовка каждого кадра этого виза занимает примерно 20 секунд в Tableau из-за сложности функций.

Сам виз в Tableau

Такие анимированные GIF или видеофайлы могут содержать до 2000 кадров (в идеале — можно любое кол-во кадров сделать при желании). Для GIFа вверху на каждый портрет приходится от 120 до 500 кадров — номера кадров указаны в правом верхнем углу.

Проблема здесь заключается в том, чтобы отрисовать и сохранить эти кадры. В Tableau есть функция экспорта в PNG, но надо повторить этот экспорт 2000 раз, а вручную на это нет смысла тратить время.

Формально процесс генерации картинки прост — надо создать первый кадр, сохранить его, увеличить параметр на одно значение, сохранить следующий кадр, и так до последнего кадра. Алгоритм достаточно простой и подразумевает клики мышью в определенных местах экрана плюс набор на клавиатуре порядковых номеров кадров.
Вместо нас это могут сделать роботы!

3. Программные роботы

Рутинные процессы можно и нужно автоматизировать. Мне не нравится делать вручную операции на ПК, которые могут выполняться скриптами.

Аббревиатура RPA (Robotic Process Automation) сейчас в IT встречается достаточно часто. Суть автоматизации рутинных процессов — управление одними приложениями посредством других приложений (программных роботов), которые взаимодействуют с интерфейсом, выполняя действия аналогичные действиям пользователя. Или, если проще, роботы делают за вас рутинную работу на ПК.

Существуют коммерческие решения типа Blue Prism или UIPath, но они нам не подойдут — мы хотим бесплатный аналог. Когда я искал бесплатный продукт, Артем Прытков из русскоязычного сообщества Tableau порекомендовал AutoHotkey, за что Артему большое спасибо.

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

Внимание: следующие действия примеры скриптов работают под Windows. На Mac я не пользуюсь этой программой.

Скачать эту программу можно на официальном сайте autohotkey.com, там же есть форум с примерами скриптов. Программа ставится без проблем. Скрипты пишутся в текстовых файлах (я использую Notepad++ для этого). Присваивая расширение .ahk этим текстовым файлам, вы привязываете их выполнение к AutoHotKey, поэтому скрипты можно запускать просто кликнув по этим файлам.

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

4. Скрипты на AutoHotkey

Давайте напишем первый скрипт и запустим его чтобы понять как работает AutoHotkey. Скрипт будет делать только одну операцию — клик правой кнопкой мыши через 1 секунду. Запускается по клавише F8, выход из скрипта — Esc.

SetTimer Click, 1000 ; Установка задержки клика на 1000 мс

F8::Toggle := !Toggle ; Ждем F8 для старта скрипта 

Click: ; Запуск бесконечного цикла клика правой кнопкой
    If (!Toggle)
        Return
    Click

return

Esc::ExitApp  ; Выход из скрипта по клавише Esc

В Tableau такой скрипт может пригодиться для автоклика с заданной частотой на контрол параметра. В компьютерных играх это работает как автоматический огонь Autofire, То есть, это простой кликер.

Вставив строку Send a после строки Click, мы скажем скрипту посылать символ «a» после каждого клика. Это по сути эмуляция нажатий клавиш на клавиатуре.

Следующий скрипт Get Cursor Position, который нам пригодится. Это скрипт захвата позиции курсора

SetTimer Click, 10000 ; Начальная задержка 10 секунд

F8::Toggle := !Toggle ; Ждем F8 для старта скрипта 

Click:
    If (!Toggle)
        Return
    MouseGetPos, xpos, ypos ; Возвращает позицию курсора
	MsgBox, The cursor is at X%xpos% Y%ypos%. ; Message box с координатами
return

Esc::ExitApp  ; Выход из скрипта по клавише Esc

После старта скрипта по клавише F8 через 10 секунд захватится позиция курсора и всплывет Message Box c координатами X и Y:

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

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

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

SetKeyDelay, 800 ; Задержка эмуляции клавиш на клавиатуре
SetTimer Click, 1000 ; Задержка клика на 1 секунду

F8::Toggle := !Toggle ; Ждем F8

Click:
    If (!Toggle)
        Return
		
	Loop, 1056 ; Цикл, где 1056 - желаемое количество кадров
	{	
	Click, 1850, 702 ; Клик на стрелке параметра с координатами 1850, 702
	sleep, 2000 ; Ждем 2 секунды для отрисовки кадра Tableau
	Click, 193, 43 ; Клик на верхней панели по вкладке Dashboard c координатами 193, 43
	sleep, 1000 ; Ждем 1 секунду
	Click, 239, 221 ; Клик на выпадающей вкладке Export Image
	sleep, 1000 ; Ждем 1 секунду
	var = A_Index ; начинаем последовательность с 1,2.. и т.д.
	Send %A_Index% ; нажимаем цифры с 1,2.. и т.д, нумеруя кадры
	Send {Enter} ; Нажимаем Enter
	sleep, 1000 ; Ждем 1 секунду
	}
	MsgBox, Done!. ; Окно 'Done!' после сохранения всех кадров
	
Esc::ExitApp  ; Выход из скрипта по клавише Esc

Этот скрипт работает следующим образом:

1. Ждет F8 для старта
2. После нажатия F8 кликает на стрелку увеличения параметра.
3. Пауза 1 секунда
4. Кликает на выпадающей вкладке Dashboard
5. Пауза 1 секунда
6. Клик на Export Image
7. Пауза 1 секунда
8. Ввод номера кадра + Enter
9. Пауза 1 секунда
10. Цикл повторяется
11. После сохранения всех кадров показывается окно Done!

Перед запуском скрипта нужно сохранить первый кадр в папку — вручную экспортировать начальное состояние как 0.png или 0.jpg в папку. Таким образом вы определите папку, куда будут сохраняться все кадры.

Внизу показан процесс работы скрипта после его старта

Паузы в 1 секунду между операциями выбраны такими, чтобы Tableau успело отрисовать кадр и сохранить картинку. В действительности эти задержки можно уменьшить, они зависят от сложности визуализации и мощности вашего ПК. Если задержку на отрисовку оставим 1 секунду, задержку нажатия клавиш уменьшим до 0.2 секунд а остальные задержки уменьшим до 0.5 секунд, то весь процесс значительно ускорится:

Процесс можно еще ускорить так, что вы даже не увидите открытия окон и сохранения кадров. Надо помнить, что при малых задержках может получиться, что процессы Tableau не успеют за кликами, и ничего не получится. Поэтому лучше выбирать задержки с запасом, давая Tableau немного подумать.

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

Можно экспортировать кадры как .png и .jpg. Формат JPEG сжимает файлы, на них образуются артефакта сжатия, это скажется на качестве итогового видео. Лучше использовать формат .png, если нужно получить качественное видео.

Внимание: размер одного файла .png может быть больше 2МБ, и 1000 кадров будет занимать больше 2GB, поэтому проверяйте свободное место на диске перед запуском скрипта.

Еще нужно помнить, что Tableau сохраняет предыдущие шаги в оперативной памяти, и в сложных визуализациях каждый следующий кадр или шаг в Tableau отжирает часть оперативки. Чем больше таких шагов будет сделано, тем меньше свободной памяти будет оставаться, и в один какой-то момент память закончится, и Tableau перестанет работать (будет ошибка ‘Out of Memory’). То есть, Tableau не может хранить в памяти бесконечное число шагов — их количество ограничено ресурсами компьютера. Про это тоже нужно помнить.

5. Склеивание кадров в видеоряд

Итак, последний скрипт сгенерировал вам кадры, которые теперь нужно конвертировать в GIF или видеоформат. Если кадров немного, можно использовать онлайн конвертеры, например EZGIF. Онлайн конвертеры ограничивают размер файлов и количество кадров. Для EZGIF максимальный объем файлов — 100МБ, мне такого количества в какой-то момент оказалось недостаточно, поэтому я пользуюсь утилитами для конвертации.

Утилита, в которой дальше будем склеивать кадры, называется ScreenToGif, ее можно скачать на официальном сайте.

Запустив ScreenToGif, нажмите ‘открыть файл’ и загрузите все кадры сразу:

Можно изменить длительность каждого кадра или всех кадров сразу:

Можно изменить размеры кадров или отрезать лишнее:

Программа достаточно понятна, поэтому сделайте все операции над кадрами и сохраните проект как GIF или .MP4.

Все! Ваше видео готово.

При экспорте визуализации в .png и .jpg остаются значения параметров и фильтров в тех местах, где они находятся на визуализациях. Если они не нужны, можно в Tableau убрать их в контейнер справа на дашборде, а в ScreenToGif отрезать эту область.

Еще ScreenToGif хранит все изображения во временной папке. На моем компьютере это C:\Users\Alex\AppData\Local\Temp\ScreenToGif\Recording
Но можно менять этот путь и время хранения в настройках программы. По умолчанию время хранения — 7 дней, и, если вы часто пользуйтесь этой программой, то эта папка будет много весить, поэтому лучше очищать ее чаще.

Преимущества этого подхода перед Pages в том, что структура данных может быть любой, и если в визуализации настроить параметры, фильтры и хайлайты так, чтобы их комбинацией получить любой желаемый кадр, то можно менять значения нескольких контролов, после чего сохранять кадры. Например, на GIF внизу для каждого кадра меняется два параметра: угол поворота и высота здания.

Сам виз

Заключение

В статье были рассмотрены процессы создания простых программных роботов, которые помогают выполнять рутинные операции в пользовательских интерфейсах. Такие роботы работают с любыми интерфейсами, не только с Tableau. Применительно к Tableau и бизнес-задачам такие роботы могут переключать визуализации во время презентаций на больших экранах. Можно сделать робота, который полностью создаст любую визуализацию по последовательности операций за несколько секунд, интересно, это противоречит правилам IronViz?

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