Quels algorithmes existe-t-il pour choisir les couleurs des lignes de tracé sur les graphiques?


19

Je suis intéressé par les algorithmes ou les règles que je peux implémenter par programme pour générer des couleurs RVB ou HSV pour les tracés afin de les garder visuellement distincts des voisins.

Je sais que dans la cartographie professionnelle, il existe des algorithmes ou des règles qui garantissent qu'il n'y a pas deux pays adjacents sur une carte de la même couleur. Je peux également penser à Microsoft Office Excel comme choisissant de bonnes teintes / nuances pour les lignes de tracé (rouge, puis bleu, puis violet / orange).

Voici un exemple de ce dont je parle - j'ai besoin de générer des couleurs pour 12 lignes sur un fond noir. Ici, j'ai codé en dur les couleurs à l'aide de codes couleur RVB sécurisés sur le Web. Le problème survient lorsque ces lignes se chevauchent - il est difficile de dire si l'on regarde le violet, le violet légèrement plus foncé ou le violet. Je recherche un meilleur algorithme pour produire des couleurs pour des intrigues comme celles-ci.

Exemple de couleur de plusieurs lignes de tracé

Voici un exemple utilisant la bibliothèque de traçage Flot pour jQuery, il a une belle succession de couleurs pour les graphiques: entrez la description de l'image ici



Il semble qu'ils aient juste choisi les couleurs de base. Et vous n'avez que cinq lignes dans ce graphique tandis que votre autre exemple en a douze. Si vous laissez Flot avoir plus de graphiques, vous rencontrerez très probablement des problèmes similaires. Il n'y a que beaucoup de couleurs différentes et à partir de là, vous devez répéter les nuances et ne pouvez qu'essayer d'avoir une certaine "distance" entre elles.
thorsten müller

1
Bien qu'il y ait un problème très intéressant (et bon) ici, du point de vue de la mise en œuvre pratique, je suggérerais vivement de chercher à identifier le jeu de couleurs pour un thème (niveaux de gris, contraste élevé, pastels, daltonien, etc.) avec un nombre maximum raisonnable (avant qu'il ne devienne illisible) - 32 ou 128 couleurs environ (selon l'application) et utilisez cet index de tableau plutôt que d'essayer de calculer une couleur suivante.

Réponses:


15

Je recommande d'utiliser les espaces colorimétriques HSV ou HSL, pas l'espace colorimétrique RVB, car HSV et HSL sont mieux structurés pour générer des couleurs qui semblent différentes de celles des humains. Vous aurez plus de travail en RVB (même si des conversions d'avant en arrière existent, si vous en avez besoin).

Voici à quoi ressemble HSV / HSL: entrez la description de l'image ici

Lorsque vous utilisez l'espace colorimétrique HSV ou HSL, vous pouvez supposer (très grossièrement) que la différence entre les composantes H (teinte) de deux couleurs est une bonne approximation de la distance de perception entre les couleurs - c'est-à-dire que plus le changement de teinte est important, plus différentes couleurs ressembleront aux humains. Vous pouvez essayer de jouer avec S (saturation) et L / V (luminosité / valeur) ainsi que quelques couleurs très différentes, mais elles ne seront pas aussi différentes pour le même changement de valeur que la variation de la teinte.

Selon le nombre de couleurs distinctes dont vous avez besoin, vous pouvez diviser l'espace de teinte en ce nombre de couleurs différentes. Si, par exemple, vous avez une plage de teintes de 256 valeurs et que vous avez besoin de 16 couleurs distinctes, votre première couleur peut être (0, 128, 128), votre seconde (16, 128, 128) et ainsi de suite. J'ai choisi un peu arbitrairement des valeurs S / L au milieu ici car cela sera généralement assez léger et saturé pour voir clairement les différences de couleur. Ce système est simple et suppose que vous ne devez rien savoir sur la contiguïté des couleurs dans votre graphique / carte.

Si vous ne savez pas à l'avance combien de couleurs distinctes vous avez besoin mais que vous connaissez la limite supérieure, et que la division de la gamme de teintes en couleurs avec cette limite supérieure à l'esprit comme ci-dessus vous donne toujours de bonnes couleurs perceptuellement différentes, vous pouvez utiliser le même système avec la limite supérieure.

Si vous (pourriez) avoir besoin de très nombreuses couleurs distinctes, vous pouvez toujours vous en sortir en utilisant des couleurs très similaires ou même identiques, tant qu'elles n'apparaissent pas à proximité des autres éléments du graphique qui ont la couleur similaire. Cela nécessite de connaître votre situation d'adjacence dans le graphique que vous restituez et peut ne pas toujours être simple, et même alors, ce n'est peut-être pas une bonne idée, comme le souligne Dukeling dans les commentaires: il peut être déroutant pour les téléspectateurs que la même couleur soit utilisée. deux fois dans le graphique pour deux concepts différents.

Donc, finalement, dans la situation la plus complexe, votre graphique est suffisamment complexe pour que vous n'ayez pas assez d'espace colorimétrique pour vous assurer de ne pas vous retrouver avec des éléments distincts avec des couleurs trop similaires en utilisant le système ci-dessus. Dans ce cas, vous devez créer un graphe d'adjacence des éléments de votre graphe de visualisation. L'adjacence est ici un concept flou - vous devrez le définir correctement pour votre situation réelle. Par exemple, dans votre deuxième exemple, les données du 12 juillet ont un point d'étranglement où chaque couleur est adjacente à toutes les autres. Une approche qui peut vous aider si vous pouvez créer le graphe d'adjacence est le problème de coloration du graphe - il existe des bibliothèques qui peuvent vous aider - par exemple boost :: graph en C ++ .


Qu'il y ait ou non intersection, vous ne voulez pas que les mêmes couleurs représentent différentes choses sur un seul graphique (si c'est ce que vous impliquez), il y a trop de place à la confusion et vous ne pourrez peut-être pas déterminer laquelle est laquelle. , la coloration des graphiques n'est donc pas liée. Au cas où vous ne l'auriez pas remarqué, chaque ligne n'a qu'une seule couleur et se compose d'une séquence de points connectés.
Dukeling

@Dukeling - vous comprenez mal mon point. À un moment donné, peu importe le soin que vous choisissez, si vous avez besoin de nombreuses couleurs différentes, vous commencerez à avoir des couleurs similaires (par exemple, les violets dans la première image de la question). À ce stade, une mise en œuvre naïve mais simple comme je l'ai suggéré peut rapprocher ces couleurs, ce qui rend difficile de voir ce qui se passe. C'est à ce moment que vous pouvez utiliser la coloration du graphique pour vous assurer que vous utilisez des couleurs éloignées pour les lignes "proches" du graphique.
Joris Timmermans

@Dukeling - J'ai modifié ma réponse pour inclure votre remarque sur les raisons pour lesquelles la réutilisation de la même couleur peut être mauvaise.
Joris Timmermans

1

Dans le cas où vous ne savez pas à l'avance combien de couleurs distinctes vous aurez besoin d'un autre algorithme intéressant, c'est l'algorithme du nombre d' or .

Commencez simplement par votre couleur préférée, puis contournez la roue chromatique par étapes de l' angle doré (137,5 °). Avec cet angle, vous vous assurerez qu'après chaque convolution autour de la roue chromatique, vos nouvelles couleurs se situent entre les couleurs que vous avez déjà créées.

L'angle entre les fleurons successifs de certaines fleurs est l'angle doré.

(Image de wikipedia )


0

J'ai un peu expérimenté et j'ai découvert que même avec HSL / HSV, il n'est pas assez facile d'obtenir un algorithme décent pour des couleurs agréables, tranquilles, apaisantes (toutes assez subjectives, mais ...), mais contrastées. Certaines parties du spectre sont visuellement similaires - esp. la section vert-bleu. J'ai donc dû ajouter une variation de légèreté.

Voici ce que j'ai fini avec:

entrez la description de l'image ici

$.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();
    })
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.