how to generate heat maps given the points

2020-05-29 02:02发布

I want to generate a heat map in windows form. I have a set of points as the input. How to go about doing this in the simplest way? Thanks.

标签: c# .net
8条回答
Emotional °昔
2楼-- · 2020-05-29 02:14

Here is a simple method that will generate a color based on the relative position of a value between min and max. Values closer to min will be greener, while values closer to max will be redder.
To use this method, generate your list of values and calculate the min and max values. If you are building a grid you can handle the RowDataBound event or something similar and call the HeatMap method from there. Get a reference to the cell and set the background color to the color returned by the HeatMap method.

public Color HeatMap(decimal value, decimal min, decimal max)
{
   decimal val = (value - min) / (max-min);
   return new Color
   {
       A = 255,
       R = Convert.ToByte(255 * val),
       G = Convert.ToByte(255 * (1-val)),
       B = 0
   };
}
查看更多
Viruses.
3楼-- · 2020-05-29 02:14

Building on the answers already here, this method allows you to specify the Colors you wish to use as the max and min colours.

private Color HeatMapColor(double value, double min, double max)
{
    Color firstColour = Color.RoyalBlue;
    Color secondColour = Color.LightSkyBlue;

    // Example: Take the RGB
    //135-206-250 // Light Sky Blue
    // 65-105-225 // Royal Blue
    // 70-101-25 // Delta

    int rOffset = Math.Max(firstColour.R, secondColour.R);
    int gOffset = Math.Max(firstColour.G, secondColour.G);
    int bOffset = Math.Max(firstColour.B, secondColour.B);

    int deltaR = Math.Abs(firstColour.R - secondColour.R);
    int deltaG = Math.Abs(firstColour.G - secondColour.G);
    int deltaB = Math.Abs(firstColour.B - secondColour.B);

    double val = (value - min) / (max - min);
    int r = rOffset - Convert.ToByte(deltaR * (1 - val));
    int g = gOffset - Convert.ToByte(deltaG * (1 - val));
    int b = bOffset - Convert.ToByte(deltaB * (1 - val));        

    return Color.FromArgb(255, r, g, b);
}

The results look like this for a test DataGrid with some sample data.

enter image description here

查看更多
再贱就再见
4楼-- · 2020-05-29 02:15

This worked well for me.

public Color HeatMap(float value, float max)
    {
        int r, g, b;
        float val = value / max; // Assuming that range starts from 0
        if (val > 1)
            val = 1;
        if (val > 0.5f)
        {
            val = (val - 0.5f) * 2;
            r = Convert.ToByte(255 * val);
            g = Convert.ToByte(255 * (1 - val));
            b = 0;
        }
        else
        {
            val = val * 2;
            r = 0;
            g = Convert.ToByte(255 * val);
            b = Convert.ToByte(255 * (1 - val));
        }
        return Color.FromArgb(255, r, g, b);
    }
查看更多
一夜七次
5楼-- · 2020-05-29 02:21

If you want red to green via yellow, you could also use HSL to get your heatmap. The numbers in that instance would be 0 - 60, where 0 = red and 60 = green (see figure 11 on this link).

To implement, you need to use System.Runtime.InteropServices and add the following:

[DllImport("shlwapi.dll")]
public static extern int ColorHLSToRGB(int H, int L, int S);

In the method, val is a long value and m_iMax is the largest number in the collection, you could change it as required:

if (val == 0)
    return ColorTranslator.ToHtml(Color.FromArgb(255, 255, 255)); // white
else
{
  // 0 = red, 60 = green
  int col = 60 - (int)(60 * val / m_iMax);

  return ColorTranslator.ToHtml(ColorTranslator.FromWin32(ColorHLSToRGB(col, 120, 240)));
}

The following is the result of the code above in a HTML table:

Heatmap

查看更多
狗以群分
6楼-- · 2020-05-29 02:31

The C# version of "Curtis White"'s answer:

public Color HeatMap(decimal value, decimal min, decimal max)
        {
            decimal val = (value - min) / (max - min);
            int A, B, R, G;
            A = 255;
            R = Convert.ToByte(255 * val);
            B = Convert.ToByte(255 * (1 - val));
            G = 0;
            return Color.FromArgb(A, R, G, B);
        }
查看更多
再贱就再见
7楼-- · 2020-05-29 02:34

Divide the surface up into a grid of cells, and count the points inside each cell.

Given the count of points, calculate a color for each cell

查看更多
登录 后发表回答