title: Drawing a matrix with a gradient of colors "Spectrogram"
body: <p>After using STFT(Short-time Fourier transform) the output is a matrix that represents a 3d plot as though <code>(A[X, Y] = M)</code> A is the output matrix, X is the time , Y is the frequency, and the third dimension M is the amplitude illustrated by the intensity of the pixel color as in the following pictures:</p>
  
  <p><a href="https://i.stack.imgur.com/YZUVN.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YZUVN.png" alt="###Spectrogram 1"></a></p>
  
  <p><a href="https://i.stack.imgur.com/mtWqb.jpg" rel="nofollow noreferrer">Spectrogram 2</a></p>
  
  <p>How do I draw the output matrix A with a gradient of colors like in the pictures in C#? <br/> Is there a library that contains a spectrogram control for C#?</p>
  
  <hr>
  
  <p><br/>
  <strong>Update:</strong> <br/>
  After some modifications on the given algorithm I could draw the spectrogram, I didn't change the color palette except the first color changed to black but I don't know why it's very faded!</p>
  
  <p>This one represents a sound saying </p>
  
  <blockquote>
    <p>Bye Bye</p>
  </blockquote>
  
  <p><a href="https://i.stack.imgur.com/rCCvr.jpg" rel="nofollow noreferrer">Bye Bye Spectrogram</a></p>
  
  <p>And this one of a <code>pure sine wave</code> so it's almost the same frequency all the time</p>
  
  <p><a href="https://i.stack.imgur.com/Po1Re.jpg" rel="nofollow noreferrer">Pure sine wave Spectrogram</a>
  <br/><br/>
  The output is accepted it represents the frequencies of the input signal as expected, but i think there is a way to make the spectrogram as well illustrated as the ones in the examples, could you please take a look at my code and suggest modifications?</p>
  
  <p><br/>
  This is the event handler:</p>
  
  <pre><code>private void SpectrogramButton_Click(object sender, EventArgs e)
  {
      Complex[][] SpectrogramData = Fourier_Transform.STFT(/*signal:*/ samples,  /*windowSize:*/ 512, /*hopSize:*/ 512);
      SpectrogramBox.Image = Spectrogram.DrawSpectrogram(SpectrogramData, /*Interpolation Factor:*/ 1000, /*Height:*/ 256);
  }
  </code></pre>
  
  <p><br/>
  And this one is the drawing function after my modifications:</p>
  
  <pre><code>public static Bitmap DrawSpectrogram(Complex[][] Data, int InterpolationFactor, int Height)
  {
      // target size:
      Size sz = new Size(Data.GetLength(0), Height);
      Bitmap bmp = new Bitmap(sz.Width, sz.Height);
  
      // the data array:
      //double[,] data = new double[222, 222];
  
      // step sizes:
      float stepX = 1f * sz.Width / Data.GetLength(0);
      float stepY = 1f * sz.Height / Data[0].GetLength(0);
  
      // create a few stop colors:
      List&lt;Color&gt; baseColors = new List&lt;Color&gt;();  // create a color list
      baseColors.Add(Color.Black);
      baseColors.Add(Color.LightSkyBlue);
      baseColors.Add(Color.LightGreen);
      baseColors.Add(Color.Yellow);
      baseColors.Add(Color.Orange);
      baseColors.Add(Color.Red);
  
  
      // and the interpolate a larger number of grdient colors:
      List&lt;Color&gt; colors = interpolateColors(baseColors, InterpolationFactor);
  
      // a few boring test data
      //Random rnd = new Random(1);
      //for (int x = 0; x &lt; data.GetLength(0); x++)
      //    for (int y = 0; y &lt; data.GetLength(1); y++)
      //    {
      //        //data[x, y] = rnd.Next((int)(300 + Math.Sin(x * y / 999) * 200)) +
      //        //                rnd.Next(x + y + 111);
      //        data[x, y] = 0;
      //    }
  
      // now draw the data:
      float Max = Complex.Max(Data);
      using (Graphics G = Graphics.FromImage(bmp))
          for (int x = 0; x &lt; Data.GetLength(0); x++)
              for (int y = 0; y &lt; Data[0].GetLength(0); y++)
              {
                  int Val = (int)Math.Ceiling((Data[x][y].Magnitude / Max) * (InterpolationFactor - 1));
                  using (SolidBrush brush = new SolidBrush(colors[(int)Val]))
                      G.FillRectangle(brush, x * stepX, (Data[0].GetLength(0) - y) * stepY, stepX, stepY);
              }
  
      // and display the result
      return bmp;
  }
  </code></pre>
  
  <p>I don't really understand the <code>log</code> thing that you are talking about in your answers, I'm sorry for my little knowledge.</p>
  
  <hr>
  
  <p><br/>
  <strong>Update:</strong> 
  <br/>
  This is the output after adding taking <code>log10</code> to the magnitudes (negative values neglected):
  <br/></p>
  
  <ol>
  <li><a href="http://soundbible.com/664-Bye-Bye-.html" rel="nofollow noreferrer">This one of "Bye bye" from before:</a></li>
  </ol>
  
  <p><a href="https://i.stack.imgur.com/bGqMD.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bGqMD.jpg" alt="enter image description here"></a></p>
  
  <ol start="2">
  <li><a href="http://soundbible.com/1919-Shotgun-Blast.html" rel="nofollow noreferrer">A Shotgun Blast:</a></li>
  </ol>
  
  <p><a href="https://i.stack.imgur.com/az4uM.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/az4uM.jpg" alt="enter image description here"></a></p>
  
  <ol start="3">
  <li><a href="http://soundbible.com/1619-Music-Box.html" rel="nofollow noreferrer">A Music Box:</a></li>
  </ol>
  
  <p><a href="https://i.stack.imgur.com/dWRwB.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/dWRwB.jpg" alt="enter image description here"></a></p>
  
  <p>I Think this output is acceptable, it is different from the examples I brought in the beginning but I think it's better.</p>