2012-10-13 10 views
24

Angenommen, die Werte werden von 0 auf 1 normiert. Wie lautet der Algorithmus, um eine Farbe zu erhalten, um eine solche Heatmap zu erstellen?Was ist der Algorithmus zum Erstellen von Farben für eine Heatmap?

1 ist rot, .5 ist grün, 0 ist dunkelblau.

Arbeiten in RMagick/ImageMagick.

heatmap

+0

Kasse dies: - http://stackoverflow.com/questions/2343681/algorithm-for-heat-map –

Antwort

13

Ich fand dies überraschend einfach mit HSL zu tun.

In Ruby:

def heatmap_color_for value # [0,1] 
    h = (1 - value) * 100 
    s = 100 
    l = value * 50 
    "hsl(#{h.round(2)}%,#{s.round(2)}%,#{l.round(2)}%)" 
end 

Diese Methode liefert HSL-Werte als Zeichenkette zwischen 0% und 100%. Es kann mit RMagick oder ImageMagick verwendet werden.

Referenz: ImageMagick HSL documentation.

+0

h ist kein Prozent, sondern ein Grad von 0 - 360 auf dem Farbrad. – pixelearth

4

Ein allgemeiner Ansatz ist es, Farben zu interpolieren. Sie entschieden, dass

0: 0 0 255 (or any blue) 
0.5: 0 255 0 (or any green) 
1: 255 0 0 (or any red) 

Sie einfach eine lineare Interpolation der RGB tun. Zwischen 2 Referenzwerte (zB t zwischen 0 und 0,5), wobei die interpolierten Farb C ist wie

C = (1 - t) * c0 + t * c1 

Sie diese Formel auf jeder RGB-Farbkomponente anwenden müssen. Einige andere Hinweise über Farbe lineare Interpolation: How to interpolate a color sequence?

---- ----- bearbeiten ich den Header meiner Antwort entfernt, als ich erkannte ich die Frage falsch verstanden (siehe Kommentar). Ich lasse eine Kopie für konsistentes Lesen und Informationen, nur für den Fall. Eine erste Möglichkeit besteht darin, eine Referenz-Heatmap mit jeder Software zu erstellen, die: ein Bild 256X1pixel mit Pixelwerten von 0 bis 255 erstellt und die gewünschte Heatmap mit ImageMagick anwendet: dann kann man die RGB-Rückseite lesen und eine Map erstellen (Wert: RGB)

+0

hat ImageMagick eine Heatmap? –

+0

Keine Ahnung. Wie auch immer, es ist nicht mein Ziel für den ersten Ansatz, ich meinte: Erstellen Sie eine Datei mit Werten von 0-255, wenden Sie dann eine Heatmap mit Ihren Lieblingswerkzeugen an und verwenden Sie die erstellte Heatmap als Referenz. –

+0

Ah, mir ist klar geworden, dass ich deinen letzten Satz missverstanden habe. Ich habe dir gesagt, dass die Heatmap-Farbtransformation in Image Magick funktioniert und du es selbst in einem Code machen möchtest. Ich bearbeite meine Antwort. –

10

Die lineare Interpolation der RGB-Komponenten funktioniert in der Praxis ziemlich gut, und die von Bruno geteilte Verbindung erwähnt, dass Sie Ihre Interpolation in HSL, die helfen kann, machen.

Sie können Ihre drei Grundfarben auch mit besser ausgewählten Zwischenprodukten kombinieren. Check out http://colorbrewer2.org/ für einige gute Farbverläufe. Dann brechen Sie Ihre Schritte weiter auf:

0 red 
0.25 yellow 
0.5 green 
0.75 cyan 
1 blue 
+2

Dieser Farbbrauer ist großartig! – Offirmo

17

hier ein JavaScript-Code-Snippet ist CSS HSL-Farbcode aus [0, 1] Wert

function heatMapColorforValue(value){ 
    var h = (1.0 - value) * 240 
    return "hsl(" + h + ", 100%, 50%)"; 
} 

Dieser Algorithmus basiert auf den 5 color heatmap,

In diesem Algorithmus zu erzeugen, entsprechend die Farben mit Werte sind

0 : blue (hsl(240, 100%, 50%)) 
0.25 : cyan (hsl(180, 100%, 50%)) 
0.5 : green (hsl(120, 100%, 50%)) 
0.75 : yellow (hsl(60, 100%, 50%)) 
1 : red (hsl(0, 100%, 50%)) 

So einfach!

+0

Schöne Lösung, und dieser Code konvertieren HSL zu RGB https://github.com/optimisme/javascript-temperatureMap/blob/master/temperatureMap.js#L57 –

0

Hier ist eine einfache 5 Farbe Heatmap in Python (in pyqt, aber leicht zu verallgemeinern)

def genColorMap(self): 
    points = [(255,0,0), (255,255,0), (0,255,0), (0,255,255), (0,0,255)] 
    cm = {} 
    for i in range(0, 256): 
     p0 = int(numpy.floor((i/256.0)/len(points))) 
     p1 = int(numpy.ceil((i/256.0)/len(points))) 
     rgb = map(lambda x: x[0]*max(0,(i-p0)) + x[1]*max(0,(i-p1)), zip(points[p0], points[p1])) 
     cm[i] = QtGui.qRgb(rgb[0], rgb[1], rgb[2]) 
    return cm 
+2

Anständige Antwort, aber versuchen, den Code zu erklären, damit das OP es eher verstehen kann dann benutze es, ohne es zu fassen! – ShellFish

0

ich hier eine Implementierung Swift 4 verlassen basierend auf this blog post für jede Menge Farben! Perfekte Erklärung ist da! Hoffe es hilft und spart etwas Zeit für jemanden!

import Foundation 
import UIKit 

struct ColorPoint { 
    let color: UIColor 
    let value: CGFloat 
} 

class HeatMapColor { 
    var colorPoints: [ColorPoint] 

    init(colorPoints: [ColorPoint]) { 
     self.colorPoints = colorPoints 
    } 

    func colorAt(value: CGFloat) -> UIColor { 
     if(colorPoints.isEmpty) { return UIColor.black } 

     let colorsPointsToUse = colorPoints.sorted { (colorPointA, colorPointB) -> Bool in 
      return colorPointA.value <= colorPointB.value 
     } 

     for (index, colorPoint) in colorsPointsToUse.enumerated() where value < colorPoint.value { 
      let previousColorPoint = colorsPointsToUse[max(0, index - 1)] 
      let valueDiff = previousColorPoint.value - colorPoint.value 
      let fraction = valueDiff == 0 ? 0 : (value - colorPoint.value)/valueDiff 

      guard 
       let prevComp = previousColorPoint.color.cgColor.components, 
       let currComp = colorPoint.color.cgColor.components else { continue } 

      let red = (prevComp[0] - currComp[0]) * fraction + currComp[0] 
      let green = (prevComp[1] - currComp[1]) * fraction + currComp[1] 
      let blue = (prevComp[2] - currComp[2]) * fraction + currComp[2] 

      return UIColor(red: red, green: green, blue: blue, alpha: 1.0) 
     } 

     return colorsPointsToUse.last!.color 
    } 
}