Когда 3D обманывает: псевдо-3D как зло

Третья ось на плоском экране почти всегда отнимает точность, а не добавляет.

Псевдо-3D — изображение трёхмерного графика на плоском экране/бумаге. Перспектива, окклюзия (закрытие дальних объектов ближними) и невозможность точно считать глубину делают такие графики менее точными, чем плоские.

Почему 3D обычно хуже

Экран и бумага двумерны. Чтобы показать три координаты, 3D-график проецирует их на плоскость — и при этой проекции возникают три беды. Перспектива: дальние объекты кажутся меньше, поэтому одинаковые значения выглядят по-разному в зависимости от глубины. Окклюзия: передние столбцы/точки закрывают задние — часть данных просто не видна. Неоднозначность глубины: глаз не может точно сказать, где вдоль третьей оси находится точка, без опорных линий. В итоге считать значения с 3D почти невозможно — остаётся лишь «общее впечатление объёма».

3D-столбцы — классический антипример

Трёхмерная столбчатая диаграмма — почти всегда ошибка. Третье измерение здесь не несёт данных (категории можно разложить на плоскости), зато добавляет окклюзию и перспективное искажение высот. То же значение выглядит выше спереди и ниже сзади. Замена — плоские сгруппированные столбцы, фасетки или heatmap.

3D-столбцы (плохо):          плоская замена (хорошо):
     __                       A1 A2 B1 B2
    /_/|  __                  ## #  ## #
   |  |/_/|   <- задний       ## ## ## ##
   |  |  |/|      закрыт      ## ## ## ###
   перспектива врёт           всё видно, сравнимо
   о высотах

Проверим искажение перспективой

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

def perspective_height(value, depth, focal=10.0):
    # чем дальше (больше depth), тем сильнее сжатие
    scale = focal / (focal + depth)
    return round(value * scale, 2)

val = 100  # одинаковое истинное значение
for depth in (0, 3, 6, 9):
    print(f"значение {val}, глубина {depth} -> видимая высота {perspective_height(val, depth)}")
print("одно значение выглядит по-разному из-за перспективы — 3D врёт")

Вывод:

значение 100, глубина 0 -> видимая высота 100.0
значение 100, глубина 3 -> видимая высота 76.92
значение 100, глубина 6 -> видимая высота 62.5
значение 100, глубина 9 -> видимая высота 52.63
одно значение выглядит по-разному из-за перспективы — 3D врёт

Одно и то же значение 100 на глубине 9 выглядит как 53 — почти вдвое ниже. Никакой подписи это не исправит: глаз сравнивает видимые высоты.

Когда 3D оправдан

3D полезен в редких случаях, когда данные по сути трёхмерны и важна форма поверхности: молекулярные структуры, поверхности отклика, рельеф, изоповерхности в томографии. Но даже тогда лучше дать интерактивность (вращение) или показать поверхность через 2D-контуры/срезы, где значения читаются точно. Статичная 3D-картинка в статье почти всегда проигрывает паре грамотных 2D-проекций.

Как работает под капотом

Зрительная система реконструирует глубину по косвенным признакам (перспектива, окклюзия, тени), но эта реконструкция неточна и легко обманывается. Для измерения (а не узнавания формы) нам нужны опорные шкалы, а в 3D-проекции их роль размывается. Поэтому почти любую задачу «сравнить значения» 3D решает хуже, чем 2D, где значение — это просто позиция на подписанной оси.

Когнитивная цена третьего измерения

Корень проблемы 3D в том, что мозг тратит силы на реконструкцию глубины — и эта реконструкция ненадёжна. Чтобы понять, где точка вдоль третьей оси, зрение опирается на косвенные подсказки: перспективу, перекрытие, тени, известный размер объектов. Все они легко обманываются и в принципе не дают той точности, что прямое считывание позиции на подписанной оси. Получается парадокс: добавив измерение «чтобы показать больше», мы делаем считывание каждой координаты менее точным. Информации формально больше, а понимания — меньше.

Есть и честное применение 3D — когда трёхмерна сама природа данных и важна форма: белковые структуры, поверхности отклика в оптимизации, изоповерхности томографии, рельеф местности. Но даже тогда статичная картинка проигрывает: лучший вариант — интерактивное вращение, которое даёт мозгу параллакс движения (сильнейшую подсказку о глубине), либо набор 2D-проекций и срезов, где значения читаются точно. Правило простое: 3D оправдан для узнавания формы, но почти никогда для измерения значений.

Частые ошибки

  • 3D-столбцы и 3D-pie — третье измерение без данных, только искажение.
  • 3D-scatter в статике — глубину не считать, точки перекрываются; лучше пары 2D-проекций.
  • Декоративный «объём» ради эффектности — чистый chartjunk.
  • Поверхность без контуров/срезов — точные значения недоступны; добавьте 2D-проекции.

Итог

  • Псевдо-3D искажает перспективой, прячет окклюзией, мешает считать глубину.
  • 3D-столбцы и 3D-pie — почти всегда ошибка.
  • 3D оправдан лишь для по-настоящему трёхмерной формы и лучше с вращением.
  • Для сравнения значений 2D почти всегда точнее.
Проверьте себя
1. Почему 3D-столбчатая диаграмма обычно хуже плоской?
AОна ярче
BПерспектива искажает высоты, а окклюзия прячет задние столбцы — третье измерение не несёт данных
CОна не печатается
DОна требует больше цветов
2. Что такое окклюзия в 3D-графике?
AЯркость цвета
BЗакрытие дальних объектов ближними, из-за чего часть данных не видна
CТип палитры
DСглаживание линий
3. Когда применение 3D действительно оправдано?
AДля любой столбчатой диаграммы
BКогда данные по сути трёхмерны (форма поверхности, молекула) и желательна интерактивность
CЧтобы график выглядел солиднее
DДля круговых диаграмм