Какие существуют алгоритмы выбора цветов для линий графика на графиках?

19

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

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

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

Пример цветовых линий с несколькими участками

Вот пример использования библиотеки построения графиков Flot для jQuery, она имеет хорошую последовательность цветов для графиков: введите описание изображения здесь

Алекс Стоун
источник
2
два важных вопроса здесь: programmers.stackexchange.com/questions/44929/… и stackoverflow.com/questions/470690/…
Фредерик Дьюирдт,
Кажется, они просто выбрали базовые цвета. И у вас есть только пять строк в этом графике, в то время как ваш другой пример имеет двенадцать. Если вы позволите Flot иметь больше графиков, вы, скорее всего, столкнетесь с подобными проблемами. Есть только так много разных цветов, и оттуда вы должны повторять оттенки и можете только пытаться иметь некоторое «расстояние» между ними.
Торстен Мюллер
1
Хотя здесь есть очень интересная (и хорошая) проблема, со стороны практической реализации я бы настоятельно рекомендовал рассмотреть возможность определения набора цветов для темы (оттенки серого, высокая контрастность, пастель, дальтоник и т. Д.) С разумное максимальное количество (до того, как оно станет нечитаемым) - 32 или 128 или около того цветов (в зависимости от приложения) и используйте этот индекс массива, вместо того, чтобы пытаться вычислить следующий цвет.

Ответы:

15

Я рекомендую использовать цветовые пространства HSV или HSL, а не цветовое пространство RGB, потому что HSV и HSL лучше структурированы для создания цветов, которые отличаются от людей. У вас будет больше работы в RGB (хотя конверсии туда и обратно существуют, если они вам понадобятся).

Вот как выглядит HSV / HSL: введите описание изображения здесь

При использовании цветового пространства HSV или HSL вы можете предположить (очень приблизительно), что разница между компонентами H (оттенка) двух цветов является хорошим приближением к воспринимаемому расстоянию между цветами - т.е. чем больше изменение оттенка, тем больше разные цвета будут смотреться на людей. Вы также можете попробовать поиграть с S (насыщенность) и L / V (яркость / значение), чтобы получить еще несколько очень разных цветов, но они не будут выглядеть такими же разными при одинаковом изменении значения, как при изменении оттенка.

В зависимости от количества нужных вам разных цветов, вы можете разделить пространство оттенков на это количество разных цветов. Если, например, у вас есть диапазон оттенков 256 значений и вам требуется 16 различных цветов, то ваш первый цвет может быть (0, 128, 128), ваш второй (16, 128, 128) и так далее. Я несколько произвольно выбрал средние значения S / L здесь, так как они обычно будут достаточно легкими и насыщенными, чтобы ясно видеть цветовые различия. Эта система проста и предполагает, что вам не нужно ничего знать о смежности цветов на графике / карте.

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

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

Итак, наконец, в самой сложной ситуации ваш график достаточно сложен, чтобы у вас не было достаточно цветового пространства, чтобы гарантировать, что вы не получите в результате отдельные элементы с цветами, которые слишком похожи, используя вышеуказанную систему. В этом случае вам нужно построить граф смежности элементов вашего графа визуализации. Смежность здесь - нечеткое понятие - вы должны будете определить его правильно для вашей реальной ситуации. Например, во втором примере у данных от 12 июля есть дроссельная точка, где каждый цвет смежен с любым другим. Одним из подходов, который может помочь вам, если вы можете построить граф смежности, является проблема раскраски графов - есть библиотеки, которые могут вам помочь - например, boost :: graph в C ++ .

Йорис Тиммерманс
источник
Независимо от того, есть пересечение или нет, вы не хотите, чтобы одни и те же цвета представляли разные вещи на одном графике (если это то, что вы подразумеваете), слишком много места для путаницы, и вы не сможете понять, какой именно так что раскраска графа не связана. Если вы не заметили, каждая линия имеет только один цвет и состоит из последовательности связанных точек.
Dukeling
@Dukeling - вы неправильно поняли мою точку зрения. В какой-то момент, независимо от того, насколько тщательно вы выберете, если вам нужно много разных цветов, вы начнете иметь цвета, которые выглядят одинаково (например, пурпурные на первом изображении в вопросе). В этот момент наивная, но простая реализация, как я предложил, может сблизить эти цвета, что затруднит понимание происходящего. Тогда вы можете использовать раскраску графика, чтобы убедиться, что вы используете отдаленные цвета для «близких» линий на графике.
Йорис Тиммерманс
@Dukeling - я отредактировал свой ответ, включив в него ваше замечание о том, почему повторное использование одного и того же цвета может быть плохим.
Йорис Тиммерманс
1

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

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

Угол между последовательными цветочками в некоторых цветах - это золотой угол.

(Изображение из Википедии )

Римский рейнер
источник
0

Я немного поэкспериментировал и обнаружил, что даже с HSL / HSV нелегко получить достойный алгоритм для хороших, спокойных, успокаивающих (все довольно субъективных, но ...), но контрастных цветов. Некоторые части призрака визуально похожи - особенно зелено-синий участок. Поэтому мне пришлось добавить немного вариации легкости.

Вот что я закончил:

введите описание изображения здесь

$.plot($('#application_pie'), data_application_pie, {
    series: { pie: { show: true,  innerRadius: 0.55, offset: { top: 0, left: -120 } } },
    colors: $.map( data_application_pie, function (item, index) {
        return jQuery.Color({
            hue: (index*0.95*360/data_application_pie.length),
            saturation: 0.95,
            //lightness: (index%2/-4)+0.55, alpha: 1
            lightness: ((index%4 == 3 ? 1:0)/-4)+0.55, alpha: 1
        }).toHexString();
    })
});
Ондра Жижка
источник