【问题标题】:how to generate heat maps given the points给定点如何生成热图
【发布时间】:2018-02-23 16:28:07
【问题描述】:

我想以 Windows 形式生成热图。我有一组点作为输入。如何以最简单的方式做到这一点? 谢谢。

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    这是一个简单的方法,它将根据最小值和最大值之间的值的相对位置生成颜色。接近最小值的值会更绿,而接近最大值的值会更红。
    要使用此方法,请生成值列表并计算最小值和最大值。如果您正在构建一个网格,您可以处理 RowDataBound 事件或类似事件并从那里调用 HeatMap 方法。获取单元格的引用并将背景颜色设置为 HeatMap 方法返回的颜色。

    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
       };
    }
    

    【讨论】:

    • Curtis,你的修复解决了什么问题?我发布的代码有意稀疏,但它运行(在 WPF 中)。
    • 您的代码未在 Windows 窗体应用程序中构建。 ARGB 字段仅准备就绪。 Color 是一个 Struct,ARGB 只有 get 方法。
    【解决方案2】:

    基于此处已有的答案,此方法允许您指定您希望用作最大和最小颜色的Colors

    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);
    }
    

    带有一些样本数据的测试DataGrid 的结果如下所示。

    【讨论】:

    • 如果我使用以下颜色 Color firstColour = Color.Blue;颜色 secondColor = Color.Yellow;我只是得到灰色阴影
    【解决方案3】:

    这是对 Sam 代码的修复。

      public Color HeatMapColor(decimal value, decimal min, decimal max)
        {
            decimal val = (value - min) / (max - min);
            int r = Convert.ToByte(255 * val);
            int g = Convert.ToByte(255 * (1 - val));
            int b = 0;
    
            return Color.FromArgb(255,r,g,b);                                    
        }
    

    【讨论】:

    • 这和Sam's answer到底有什么不同?
    • 在 Windows 窗体中,Sam 的代码无法运行。 ARGB 字段仅准备就绪。
    【解决方案4】:

    将表面划分为单元格,并计算每个单元格内的点数。

    给定点数,计算每个单元格的颜色

    【讨论】:

      【解决方案5】:

      从红色到黄色到绿色的解决方案

      static Color CreateHeatColor(int value, decimal max)
          {
              if (max == 0) max = 1M;
              decimal pct = value/max;
               Color color = new Color();
      
              color.A = 255;
      
              if (pct < 0.34M)
              {
                  color.R = (byte) (128 + (127 * Math.Min(3 * pct, 1M)));
                  color.G = 0;
                  color.B = 0;
              }
              else if (pct < 0.67M)
              {
                  color.R = 255;
                  color.G = (byte) (255 * Math.Min(3 * (pct - 0.333333M), 1M));
                  color.B = 0;
              }
              else
              {
                  color.R = (byte)(255 * Math.Min(3 * (1M - pct), 1M));
                  color.G = 255;
                  color.B = 0;
              }
      
              return color;
          }
      

      【讨论】:

        【解决方案6】:

        “Curtis White”答案的 C# 版本:

        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】:

          这对我来说效果很好。

          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);
              }
          

          【讨论】:

            【解决方案8】:

            如果您希望通过黄色从红色变为绿色,您还可以使用 HSL 来获取热图。该实例中的数字为 0 - 60,其中 0 = 红色,60 = 绿色 (see figure 11 on this link)。

            要实现,需要使用 System.Runtime.InteropServices 并添加以下内容:

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

            该方法中val是一个long值,m_iMax是集合中最大的数,你可以根据需要改变它:

            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)));
            }
            

            以下是HTML表格中上述代码的结果:

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-10-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多