Protraktor

Реальность, замеры и графики

Особенности интерпретации графиков как представлений реальных сигналов и характеристик.

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

Дело в том, что целью многих инженерных систем является предоставление точных данных о состоянии какого-нибудь объекта автоматизации — будь то оборудование или окружающая среда. Мы не будем уходить в причины и рассматривать комплексные случаи, а сфокусируемся на очень простых одномерных численных характеристиках — ведь если уже в них отражается проблема карты и местности, то что уж говорить о более сложных ситуациях.

Средний уровень воды в Волге у Самары за 20 лет наблюдений. Что это нам говорит?

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

Путь искажения реальности

Что же здесь может быть интересного? Начнём немного издалека.

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

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

В принципе, мало отличий от записи значений карандашом в табличку

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

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

Вторая, более практически частая проблема, это хранение снятых замеров — чем больший период исторических данных мы хотим хранить и чем выше необходимая частота замеров, тем больший объем диска нам нужен. Например, хранить какие-нибудь погодные данные (температура, давление, влажность, скорость и направление ветра и т.п.) даже для одной метеостанции за год с хорошей точностью для построения прогнозов или сравнения с текущей погодой — это уже довольно большой объем. А если мы хотим это хранить по всей стране или планете — вопрос становится очень серьезным. То же можно сказать о состоянии фондовых рынков, показателях оборудования атомной электростанции или содержимом бортовых самописцев самолётов и судов для последующего анализа топливной эффективности или расследования инцидентов.

И, наконец, перемещаясь ближе к людям и пользовательским интерфейсам, при изображении динамики изменения величины посредством графика на экране, мы ограничены количеством пикселей. Например, если мы хотим показать динамику расхода топлива за год на экране Full HD, то на один пиксель ширины у нас будет приходиться 4.5 часа — и если не предпринимать каких-то осмысленных действий, что мы хотим показывать в этом пикселе — суммарный (накопленный за 4.5 часа) расход, средний или максимальный — мы можем потерять довольно важную информацию, которая промотивирует пользователя увеличить участок с какой-то аномалией и расследовать его подробнее.

Что мы получаем?

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

Было → Стало

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

Самый честный график. Показываем только что есть, дальше думайте сами. Но хороший ли?

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

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

Ситуация пропуска данных

Выглядит как будто тут всё в порядке

Периодически происходят неисправности с датчиками или каналами связи или, банально, если сама регистрирующая система отключена. Тогда в замерах происходят пропуски. Но ведь поскольку сами по себе замеры «содержат» пропуски других, более точных (высокочастотных) замеров — то подобные аномальные пропуски можно и не заметить. В итоге, если не проработать эту ситуацию специально, пользователь может не заметить, что в данный момент данные не поступали. А ведь это само по себе является важными сведениями и может быть поводом предпринять какие-то действия — например, пойти проверять техчасть и менять неисправные сенсоры.

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

А ведь есть пропуски в замерах
Точно есть — мимо не пройдешь

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

Ситуация низкой плотности

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

Ломаный характер линейной интерполяции сразу показывает, что данных не очень много

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

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

Ситуация высокой плотности

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

Потеряли на общей картине аномалию, которая могла бы представлять интерес.

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

Как поступать — зависит от задач.

Как получить и быстрый, и информативный график (если знаем, что нужно пользователю)

Мы можем показывать вместо 100 замеров среднее арифметическое для них (это тоже может тоже занять какое-то время, но вполне можно делать этот расчёт заранее, уже на этапе записи данных). Но это не поможет увидеть нам экстремумы, хотя хорошо работает, если значения сильно зашумлены — как в случае с амперметром или при замере силы ветра (он очень сильно скачет).

Если нам важно видеть максимумы — мы можем показывать максимальное значение за 100 замеров. Тогда, например, если мы, например, изучаем данные датчиков движения охранной системы, мы увидим характерные пики в те редкие периоды, когда происходила регистрация движения.

Уровень Волги рядом с Самарой с минимумами, максимумами и средним за 20 лет наблюдений

Если же мы хотим видеть и максимумы, и минимумы — то мы можем заменить тонкую линию на линию разной толщины, соответствующую максимуму и минимуму за 100 замеров. А сверху еще и рисовать точкой среднее значение. Если вы ещё помните график среднего уровня воды в Волге, то он изначально ещё и содержит максимумы и минимумы на каждый день года по результатам 20 лет измерений.

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

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

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

Академические опции

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

Только ли про графики речь?

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

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

Слева — замеры, справа — реконструкция изобат (линии равной глубины). Карта справа выглядит более подробной и точной, чем она есть на самом деле.

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

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

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