Уменьшение данных графика без потери формы графика

У меня есть набор данных со 100 000 точками данных, которые мне нужно построить на графике. Полученный граф будет иметь ширину около 500 пикселей, поэтому для каждого пикселя будет около 200 данных, что кажется совершенно ненужным.

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

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

Кто-нибудь знает о методе, который бы соответствовал моим потребностям здесь? Язык, который я использую, - это PHP, граф создается GD, и данные поступают из MySQL, поэтому оптимизация для некоторых из них приветствуется.


Данные находятся в таком формате:

Datetime               Value
2005-01-30 00:00:00    35.30
2005-01-30 01:00:00    35.65
2005-01-30 02:00:00    36.15
2005-01-30 03:00:00    35.95
...

И получившийся график выглядит следующим образом:

alt text http://www.ulmanen.fi/stuff/graph-sample.png

Ответ 1

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

EDIT: посмотрев на график, кажется, что вам нужен как минимум, так и максимум за определенный интервал, потому что темно-синяя область - это значения между этими двумя, правильно? Возможно, вы можете взять 100 значений и составить график из минимального, максимального и среднего, так что каждая точка в графе будет сделана с 6 вместо 200 значений или что-то в этом роде.

Ответ 2

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

Чтобы уменьшить количество отображаемых точек, не влияя на форму графика, мы используем Ramer-Douglas-Peucker algoritm. Различие формы между несжатым графиком и одним с этим алгоритмом незаметно.

Ответ 3

Один подход к вашей проблеме - прореживание max-min; Я предлагаю вам Google для определения и алгоритма, с которыми мне не нужно сдавать, или я бы поделился с вами.

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

Ответ 4

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

Ответ 5

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

Ответ 6

Я не знаю, как выглядит ваш код/​​источник данных, но возможно ли сделать вывод в вашем заявлении select mysql, чтобы уменьшить количество точек данных, возвращаемых в ваше приложение?