Внимание: 3D модели в Tableau — не лучший вариант использования в визуализациях бизнеса и для аналитики , но вы можете использовать их в нетривиальных визуализациях или просто для фана. Создавая такие модели можно расширить свои знания и владение Tableau.
На Tableau public есть визуализации, использующие технику 3D. Ссылки на них приведены ниже в тексте.
1. Что мы знаем о 3D в Tableau
Я далеко не первый пользователь, визуализирующий 3D модели в Tableau. Noah Salvaterra придумал первый способ и сделал 3D Tesla. Bora Beran упростил этот способ и описал его в блоге Going 3D with Tableau. Allan Walker применил шейдеры — Guassian filters, slope, smoothstep functions. Anya A’Hearn с Philip Riggs сделали STL to TDE/Hyper конвертор в Alteryx, это описано в The 3D Full Monty.
Спасибо Allan Walker, который поделился этой историей. Если вы еще не читали блоги по 3D, перейдите по ссылкам выше и потратьте несколько минут для ознакомление с техникой 3D.
Мировое сообщество Tableau чрезвычайно крутое, я нашел там много материала для вдохновения и создания своих 3D моделей в Tableau. Существует множество инструментов для работы с 3D, например Blender (бесплатный), Meshlab (бесплатный), SketchUp (платный). Эти инструменты позволяют создавать сами модели и экспортировать их в формат ASCII STL (stereolithography). Процесс создания и экспорта в формат стереолитографии описан в статье Anya A’Hearn. Каждая строка файла STL описывает вершину полигона, и этот формат работает только с треугольниками (многоугольник или полигон с 3мя вершинами). В этой статье есть ссылка на Alteryx flow, который преобразует формат STL в формат TDE (Tableau Data Extract). У меня, как и у многих других, нет лицензии Alteryx, поэтому я написал скрипт парсинга STL на Python.
На самом деле, даже можно не использовать Alteryx или Python для вытаскивания данных из .STL file — это можно сделать в MS Excel.
Формат .STL содержит данные о координатах вершин (X,Y,Z) каждого треугольника. .STL — это текстовый формат, и вам хватит блокнота (Notepad) для просмотра и редактирования таких файлов (Я использую Notepad++).
Давайте посмотрим на фрагмент файла .STL:
facet normal 0.000000 0.000000 1.000000 outer loop vertex 1.000000 1.000000 1.000000 vertex -1.000000 1.000000 1.000000 vertex -1.000000 -1.000000 1.000000 endloop endfacet
Нам нужно оставить только строки с префиксом “vertex”, затем пронумеровать строки. Чтобы это сделать, пойдем по шагам:
1. Откройте файл .STL в Excel, выберите пробел (‘space’) как разделитель.

После этой операции будет следующее:

2. Отфильтруйте данные по слову “vertex” в столбце A, удалив другие строки. Вместо фильтрации можно отсортировать столбец A по названиям и удалить все строки не “vertex”.
3. Добавьте новый столбец перед A, назвав его ‘Vertice_id’ и пронумеруйте строки (1,2,3,4, и т.д.). Это будет идентификатор вершины.
4. Добавьте еще один столбец ‘Polygon_id’ с вычислением: =CEILING.MATH(A2/3). Это будет идентификатором вершины.
Переименуйте столбцы C,D,E в X,Y,Z и удалите остальные столбцы. После жтого вы получите следующее:

Сохраните файл как .xlsx или .csv и подключите его к Tableau.
Используйте поля X,Y и Z fields для превью в проекциях, так вы можете понять, удачно ли экспортировалась ваша модель или нет.

Можно заметить, что полигоны на картинке сверху отсортированы в возрастающем порядке по оси Y (глубина модели), это объясняется алгоритмом художника (painter’s algorithm). Алгоритм художника сортирует все полигоны модели по их глубине, и они рисуются в порядке от дальнего к ближнему. Можно больше узнать об алгоритме.
Для вращения модели нам надо создать 3 параметра: XY-Angle, XZ-Angle, YZ-Angle (для вращения по 3м осям) и 3 вычисления: x_rotated, y_rotated and z_rotated. Я использовал вычислении из воркбука Anya’s workbook . Формулы рассчитывают проекции на плоскости координат. Сейчас можно новыми вычислениями заменить X, Y и Z на листе. Теперь, при изменении параметров, модель будет поворачиваться. Можно добавить цвет. Вариантов добавления цвета множество, включая раскраску по Polygon_id или по вычислениям на основе X,Y или Z. Например, модель снизу раскрашена по среднему X для каждого полигона.

Всё, 3D модель готова.
NOTE: Как я отмечал выше, я не сделал ничего нового — просто работал с методом, описанным Anya’s A’Hearn. Единственное отличие что мы использовали Excel для подготовки данных вместо Alteryx.
Я использовал ту же технику в моей визуализации «Полигональные города» ( ‘Polygonal Cities’), посмотреть ее можно, кликнув на картинку:

Можно экспериментировать с другими типами меток,(marks) включая bars, lines, circles и т.д. чтобы строить псевдо 3D модели в Tableau. Для следующего вида я использовал бары (bars):

Вы можете не верить, что это бар-чарт, но это он!

2. Изучаем другие 3D форматы
Визуализации выше основаны на моделях .STL models. Особенность моделей STL в том, что они не включают информацию о цветах и группах полигонов и работают только с треугольниками (т.е. каждый полигон имеет 3 вершины). Но существуют другие 3D форматы: .OBJ, .DAE, .FBX, .KMZ и др. Многие из них работают с полигонами, имеющими больше 3х вершин и содержашими информацию о группах и текстурах полигонов. Дальше я буду рассказывать про старый добрый формат .OBJ format (вы можете познакомиться с другими форматами сами). Причины, по которым я выбрал формат .OBJ:
- Это открытый формат
- Это текстовый формат, который можно открыть в блокноте (Я пользуюсь Notepad++ на PC и Atom на Mac)
- Этот формат проще для понимания и конвертирования в .CSV (по моему мнению).
- Множество моделей формата .OBJ доступны бесплатно в интернете (free3d.com например)
Для сравнения моделей и нахождения преимуществ OBJ файлов, сравним одну и ту же 3D модель в .STL и .OBJ форматах, отрисованную в Tableau (смотрите картинку внизу).

Поскольку .STL работает только с треугольниками, 3D модели в Tableau в этом формате будут содержать больше полигонов, чем 3D модели в формате .OBJ. Следовательно, .OBJ модель содержит меньше меток Tableau и выглядит эстетичнее. Очевидно, из-за меньшего количества меток, Tableau будет рендерить быстрее .OBJ модель (Сравните время рендеринга на картинке сверху. Время рендеринга замерялось штатной функцией performance recording в Tableau). Но есть и недостаток у формата .OBJ: в случае сложных полигонов в формате .OBJ могут возникать расхождения при рендеринге при перекрытиях полигонов или прохождении одного полигона через другой (cyclic overlap or piercing polygons).
3. Формат .OBJ
Давайте немного поговорим о файлах формата OBJ. (Если хотите узнать больше, см. описание формата).
Ниже показан фрагмент файла .OBJ:

Дальше будем использовать терминологию формата. Каждый Mesh в файле .OBJ содержит полигоны (Faces). Каждый полигон содержит набор вершин. Meshes и Groups можно объединять в Groups. Для лучшего понимания представим 3D модель Лего:


usemtl Color_006 в фрагменте кода — это material name (название материала), который представляет текстуру в 3D модели. Tableau не работает с текстурами, но можно использовать эти данные для цвета полигонов.
Таким образом, формат .OBJ выглядит как матрешка с несколькими уровнями геометрических объектов. Формат еще содержит информацию о краях полигонов, нормалях, освещении. Эти данные для Tableau нам не пригодятся, поэтому будем их отбрасывать.
Note: Полная спецификация .OBJ приведена здесь
Много моделей есть на 3D Warehouse, их можно скачать в формате SketchUp (.SKP). SketchUP Pro для десктопа может экспортировать .SKP файла в .OBJ формат. Обращаю внимание, что SketchUP Pro не бесплатное ПО, но можно его попробовать (30 дней триального периода).

Есть другие сайты где можно бесплатно скачивать сразу файлы моделей OBJ.
В SketchUP Pro можно удалить ненужные полигоны. Я рекомендую центрировать модели с центром в начале координат (0,0,0). Теперь можно экспортировать модель в .OBJ файл. Мы получили файл .OBJ , теперь надо конвертировать его в данные, понятные Tableau.
4. Как взять данные из .OBJ файла и загрузить из в Tableau
Формат .OBJ хранит данные последовательно, то есть, он не содержит номера вершин и полигонов. Поэтому надо пронумеровать каждый объект как мы делали для STL файла. Как и для файла STL, I использовал скрипт на питоне, но можно это сделать и в Excel. Цель — создать 4 файла:
— v.csv (vertices) для вершин
— f.csv (faces) для полигонов
— g.csv (meshes/groups) для групп
— color.csv (colors) для цветов
Если вам не нужны цвета и группы для модели в Tableau, можно сделать только v.csv and f.csv.
Faces
Текстовый файл для полигонов (faces) выглядит примерно так, где столбцы разделены пробелами:
1 f 1/1/1 2/2/1 3/3/1 4/4/1 2 f 2/3/2 1/4/2 5/5/2 6/6/2 3 f 1/7/3 4/3/3 7/6/3 5/8/3 4 f 3/3/4 8/6/4 7/8/4 4/7/4 5 f 8/6/5 3/3/5 2/4/5 6/5/5 6 f 7/7/6 8/3/6 6/2/6 5/9/6 7 f 9/4/1 10/3/1 4/2/1 3/1/1
Можно открыть файл .OBJ в Excel и сделать там следующие преобразования:
- Удалить строки без ‘f’ в первом столбце
- Удалить столбец с ‘f’
- Добавить столбец с нумерацией строк
- Добавить имена столбцов
После преобразований имеем следующее:

Заметьте, что столбцы нумеруем до максимального номера вершины в полигоне: 1,2,3… и до максимума.
Vertices (Вершины)
Откроем файл .OBJ в Excel и сделаем подобные преобразования как для полигонов. Результат будет следующим:

Загрузка данных Tableau
1. Подключим файл f.csv (или f.xlsx)
2. Сделаем Pivot полей с 1 по 14 (в нашем случае):

3. Сделаем inner join c v.txt (или v.xlsx) файлом используя в качестве join clause вычисление слева и Vertice_id справа:
INT(SPLIT([Pivot Field Values],’/’,1)) and Vertice_id

Поздравляю! Сейчас есть все данные для построения полигональной модели:
- Создайте те же вычисления и параметры для поворотов, что и для .STL
- Создайте на листе визуализацию как показано внизу, используя ‘Pivot Field Names’ как Path. ‘Pivot Field Names’ здесь номер вершины полигона.

Мы получили монохромную полигональную 3D модель. Дальше отсортируем полигоны по глубине по алгоритму художника как было описано в части для .STL.
Color and groups (Цвета и группы)
Для сопоставления цветов с полигонами воспользуемся новыми аналитическими функциями Tableau Prep. В примере ниже используется Tableau Prep 2020.1.
Воспользуемся функциями RANK and RANK_DENSE. В отличие от таких же функций в Tableau Desktop, эти функции не являются табличными и имеют другой синтаксис. Функции в Tableau Prep возвращают ранги значений любого столбца.
Мой flow делает следующее:
1. Оставляет только строки с префиксами ‘usemtl’ (colour) и ‘f’ (faces)
2. Вычисляет ранги: { ALONG [Row Number Field] ASC : RANK() }
Цвета
Мы будем использовать данные о текстурах для определения цветов. Строки, описывающие текстуры, начинаются с ‘usemtl’ в .OBJ файле. Все полигоны после строки ‘usemtl’ имеют тот же самый цвет, поэтому нужно взять все полигоны после ‘usemtl’ и присвоить им тот же цвет. Это сложнее, чем операции с вершинами и полигонами, но это тоже можно сделать в Excel. Воспользуемся новыми функциями Tableau Prep.
1. Подключите Prep к .OBJ файлу (как txt).
2. Отфильтруйте все строки не содержащие ‘f’ или ‘usemtl’ в первом столюце.
3. Добавьте вычисление: { ALONG [Row Number Column] ASC : RANK() } (Как на картинке внизу). ‘ASC’ определяет возрастающий порядок. Это вычисление создает новую нумерацию строк, возвращая ранг столбца исходной нумерации строк.

4. Удалите ненужные столбцы, оставив только 3 столбца (Rank, #, Alias)

5. Добавьте два столбца ‘Face Num Rank’ и ‘Color’ как показано ниже.

6. Создайте вычисляемое полк ‘Face Id Raw’
{ ALONG [Face Num Rank] ASC : RANK_DENSE() }

Вычисление ‘Face Id Raw’ возвращает ‘Face_id’+1. Здесь не используется RANK(), поскольку RANK() присваивает 1 всем пустым ‘null’ значениям и возвращает 275 в нашем случае следующему значению, поэтому будем использовать RANK_DENSE.
Сравните оба вычисления:
RANK() RANK_DENSE()

7. Создайте вычисляемое поле ‘Face_id’
[Face Num Raw]-1
8. Оставьте только 3 поля: Face_Id, Rank, Color

9. Экспортируйте данные в .csv
10. Откройте .csv в Excel. Отсортируйте столбец ‘Rank’ в восходящем порядке:

11. Заполните пустые ячейки в столбце ‘Color’. Для этого выберите этот столбец, нажав ‘fn+f5’ в Windows, выберите ‘Blanks’ в диалоговом окне и нажмите ‘Ok’. После выбора всех пустых ячеек в столбце, наберите ‘=C2’ в окне функций и нажмите ‘Ctrl+Enter’

12. Вы получите такой набор данных:

Сохраните его и загрузите данные в ваш проект в Tableau
13. Сделайте Inner Join

Добавьте поле ‘Color’ field в color card Tableau:

Добавление групп
Данные для групп можно подготовить аналогично данным по цветам, только нужно работать со строками с ‘g’ и ‘f’ вместо ‘usemtl’ and ‘f’.
Объединяя предыдущие дата сеты с данными Groups в Tableau, получим поле ‘Group’ .

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

Это видео показывает процесс сборки дома из лего по шагам:
Про то как делать такие видео я писал в статье «Создание видео при помощи Tableau и программных роботов».
Кроме этого можно посмотреть модели анимированные каркасные .OBJ модели вертолета и корабля в Tableau: A Helicopter and A Ship , нарисованные линиями.
5. Порядок рендеринга полигонов
Нам нужно задать в Tableau как рисовать полигоны, чтобы ближние полигоны рисовались последними (это называется Z-Order). Для этого надо создать вычисление. Самый простой подход — взять вычисление z_rotation, описанное в модели .STL. Но вращение может вызвать ситуацию перекрытия полигонов. Смотрите пример ниже. На примере z_axis сортировки видно, что деревянные балки храма нарисованы перед крышей, хотя должны быть за ней.
‘Z_axis’ polygon sorting

Custom calculation for polygon sorting

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

[Color] =‘_1’ – это цвет крыши. Также есть другие группы и полигоны, для которых искусственно меняется порядок, приближая и удаляя их, тем самым минимизируя проблему перекрытия.
Мне не удалось найти универсальный метод сортировки, поэтому я использую подход, описанный выше. Когда вы используете 3D модели в Tableau, вы можете столкнуться с подобной проблемой.
Визуализация «Архитектурное наследие Японии»:
Заключение
3D модели в Tableau — очень необычный способ использования инструмента, но они могут быть хорошим способом исследования возможностей инструмента и получения глубоких знаний о платформе. Я не сомневаюсь, что сообщество будет находить новые подходы к визуализации 3D моделей, и надеюсь, этот блог вдохновит участников Tableau community к созданию 3D визуализаций. Например, можно создать баскетбольную площадку с трехмерными траекториями полета мяча — это тоже возможно в Tableau!