Welche Algorithmen gibt es, um Farben für Plotlinien in Diagrammen auszuwählen?

19

Mich interessiert, welche Algorithmen oder Regeln ich programmgesteuert implementieren kann, um RGB- oder HSV-Farben für Plotlinien zu generieren , damit sie sich optisch von den Nachbarn unterscheiden.

Ich weiß, dass es im professionellen Kartenbau Algorithmen oder Regeln gibt, die sicherstellen, dass keine zwei benachbarten Länder auf einer Karte dieselbe Farbe haben. Ich kann mir auch vorstellen, dass Microsoft Office Excel gute Farbtöne für Plotlinien auswählt (rot, dann blau, dann lila / orange).

Hier ist ein Beispiel dafür, wovon ich spreche: Ich muss Farben für 12 Linien auf einem schwarzen Hintergrund erzeugen. Die Farben hier habe ich von Hand mit web-sicheren RGB-Farbcodes fest codiert. Das Problem entsteht, wenn sich diese Linien überlappen - es ist schwer zu erkennen, ob man lila, etwas dunkler lila oder violett betrachtet. Ich suche nach einem besseren Algorithmus, um Farben für Plotlinien wie diese zu erzeugen.

Beispiel für die Farbe mehrerer Plotlinien

Hier ist ein Beispiel für die Verwendung der Flot-Plot-Bibliothek für jQuery, die eine schöne Folge von Farben für Diagramme enthält: Bildbeschreibung hier eingeben

Alex Stone
quelle
Es scheint, dass sie nur die Grundfarben gewählt haben. Und Sie haben nur fünf Zeilen in diesem Diagramm, während Ihr anderes Beispiel zwölf Zeilen enthält. Wenn Sie Flot mehr Graphen zur Verfügung stellen würden, würden Sie höchstwahrscheinlich auf ähnliche Probleme stoßen. Es gibt nur so viele verschiedene Farben und von dort aus muss man die Schattierungen wiederholen und kann nur versuchen, einen gewissen "Abstand" zwischen ihnen zu haben.
thorsten müller
1
Obwohl es hier ein sehr interessantes (und gutes) Problem gibt, würde ich aus praktischer Sicht strikt empfehlen, die Farbpalette für ein Thema (Graustufen, hoher Kontrast, Pastell, Farbenblind usw.) mit einem zu identifizieren angemessene maximale Anzahl (bevor es unlesbar wird) - 32 oder 128 oder so Farben (abhängig von der Anwendung) und verwenden Sie diesen Array-Index, anstatt zu versuchen, eine nächste Farbe zu berechnen.

Antworten:

15

Ich empfehle die Verwendung des HSV- oder HSL-Farbraums, nicht des RGB-Farbraums, da HSV und HSL besser strukturiert sind, um Farben zu erzeugen, die für den Menschen anders aussehen. Sie werden mehr Arbeit in RGB haben (obwohl Konvertierungen hin und her existieren, sollten Sie sie brauchen).

So sieht HSV / HSL aus: Bildbeschreibung hier eingeben

Bei Verwendung des HSV- oder HSL-Farbraums kann (sehr grob) davon ausgegangen werden, dass der Unterschied zwischen den H- (Farbton-) Komponenten zweier Farben eine gute Annäherung an den Wahrnehmungsabstand zwischen den Farben darstellt - dh je größer die Änderung des Farbtons ist, desto größer ist der Unterschied Anders sehen die Farben für den Menschen aus. Sie können auch versuchen, mit S (Sättigung) und L / V (Helligkeit / Wert) zu spielen, um ein paar sehr unterschiedliche Farben zu erzielen, aber sie sehen bei der gleichen Wertänderung nicht so unterschiedlich aus wie beim Variieren des Farbtons.

Abhängig von der Anzahl der verschiedenen Farben, die Sie benötigen, können Sie den Farbtonraum in diese Anzahl verschiedener Farben aufteilen. Wenn Sie zum Beispiel einen Farbtonbereich von 256 Werten haben und 16 verschiedene Farben benötigen, kann Ihre erste Farbe (0, 128, 128), Ihre zweite (16, 128, 128) usw. sein. Ich habe hier etwas willkürlich ausgewählte S / L-Werte ausgewählt, da diese normalerweise hell und gesättigt genug sind, um die Farbunterschiede deutlich zu erkennen. Dieses System ist einfach und setzt voraus, dass Sie nichts über die Farbanpassung in Ihrem Diagramm / Ihrer Karte wissen müssen.

Wenn Sie nicht im Voraus wissen, wie viele verschiedene Farben Sie benötigen, aber die Obergrenze kennen, und wenn Sie den Farbtonbereich wie oben beschrieben unter Berücksichtigung dieser Obergrenze in Farben unterteilen, erhalten Sie immer noch gute, wahrnehmungsmäßig unterschiedliche Farben, mit denen Sie dasselbe System verwenden können die Obergrenze.

Wenn Sie sehr viele unterschiedliche Farben benötigen (könnten), könnten Sie trotzdem sehr ähnliche oder sogar dieselben Farben verwenden, solange diese nicht in der Nähe der anderen Elemente des Diagramms erscheinen, die ähnliche Farben aufweisen. Dies setzt voraus, dass Sie Ihre Adjazenzsituation in der Grafik kennen, die Sie rendern, und dass dies möglicherweise nicht immer einfach ist, und selbst dann ist es möglicherweise keine gute Idee, wie Dukeling in den Kommentaren betont: Für die Betrachter kann es verwirrend sein, dass dieselbe Farbe verwendet wird zweimal in der Grafik für zwei verschiedene Konzepte.

Schließlich ist Ihr Diagramm in der komplexesten Situation so komplex, dass Sie nicht über genügend Farbraum verfügen, um sicherzustellen, dass Sie mit dem obigen System keine eindeutigen Elemente mit zu ähnlichen Farben erhalten. In diesem Fall müssen Sie ein Adjazenzdiagramm aus Elementen Ihres Visualisierungsdiagramms erstellen. Adjacency ist hier ein unscharfes Konzept - Sie müssen es für Ihre tatsächliche Situation richtig definieren. Beispiel: In Ihrem zweiten Beispiel haben die Daten vom 12. Juli eine Drosselstelle, an der jede Farbe neben jeder anderen liegt. Ein Ansatz, der Ihnen beim Aufbau des Adjazenzdiagramms helfen kann, ist das Problem der Diagrammfärbung. Es gibt Bibliotheken, die Ihnen helfen können, z. B. boost :: graph in C ++ .

Joris Timmermans
quelle
Unabhängig davon, ob es eine Schnittmenge gibt oder nicht, möchten Sie nicht, dass dieselben Farben verschiedene Dinge in einem einzelnen Diagramm darstellen (wenn Sie dies implizieren), es besteht zu viel Raum für Verwirrung, und Sie können möglicherweise nicht herausfinden, welches welches ist Daher hat das Färben von Diagrammen keinen Bezug. Falls Sie es nicht bemerkt haben, hat jede Linie nur eine Farbe und besteht aus einer Folge von verbundenen Punkten.
Dukeling
@Dukeling - du verstehst meinen Punkt falsch. Egal wie sorgfältig Sie sich entscheiden, wenn Sie viele verschiedene Farben benötigen, werden Sie zu Farben kommen, die ähnlich aussehen (z. B. die Purpur im ersten Bild der Frage). Zu diesem Zeitpunkt könnte eine naive, aber einfache Implementierung, wie ich sie vorgeschlagen habe, diese Farben nahe beieinander bringen, was es schwierig macht zu sehen, was los ist. In diesem Fall können Sie die Grafikfarbe verwenden, um sicherzustellen, dass Sie entfernte Farben für "nahe" Linien in der Grafik verwenden.
Joris Timmermans
@Dukeling - Ich habe meine Antwort so bearbeitet, dass sie Ihre Bemerkung enthält, warum die Wiederverwendung derselben Farbe möglicherweise schlecht ist.
Joris Timmermans
1

Für den Fall, dass Sie nicht im Voraus wissen, wie viele verschiedene Farben Sie benötigen, ist der Golden-Ratio-Algorithmus ein weiterer interessanter Algorithmus .

Beginnen Sie einfach mit Ihrer Lieblingsfarbe und drehen Sie dann das Farbrad in Schritten des goldenen Winkels (137,5 °). Mit diesem Winkel stellen Sie sicher, dass Ihre neuen Farben nach jeder Faltung um das Farbrad zwischen den Farben liegen, die Sie bereits erstellt haben.

Der Winkel zwischen aufeinanderfolgenden Blüten in einigen Blüten ist der goldene Winkel.

(Bild aus Wikipedia )

Roman Reiner
quelle
0

Ich habe ein bisschen experimentiert und festgestellt, dass es selbst mit HSL / HSV nicht ganz einfach ist, einen anständigen Algorithmus für schöne, störungsfreie, beruhigende (alles sehr subjektive, aber ...) und dennoch kontrastreiche Farben zu finden. Einige Teile des Spektrums sind optisch ähnlich - insb. der grün-blaue Abschnitt. Also musste ich einige Helligkeitsvariationen hinzufügen.

Hier ist, was ich am Ende hatte:

Bildbeschreibung hier eingeben

$.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();
    })
});
Ondra Žižka
quelle