public static Image FrameSliceOf3DSpectrogram_ConstantFreq(Image bmp1, Image titleBar, TimeSpan xInterval, int herzValue, FileInfo sunriseSetData, int nyquistFreq) { SunAndMoon.AddSunRiseSetLinesToImage((Bitmap)bmp1, sunriseSetData, 0, 365, 1); // assume full year and 1px/day var g = Graphics.FromImage(bmp1); var pen = new Pen(Color.White); var stringFont = new Font("Arial", 12); var str = $"Freq = {herzValue} Hz"; g.DrawString(str, stringFont, Brushes.Wheat, new PointF(10, 7)); var xAxisPixelDuration = TimeSpan.FromSeconds(60); var startOffset = TimeSpan.Zero; double secondsDuration = xAxisPixelDuration.TotalSeconds * bmp1.Width; var fullDuration = TimeSpan.FromSeconds(secondsDuration); // init frequency scale int herzInterval = 1000; int frameSize = bmp1.Height; var freqScale = new DSP.FrequencyScale(nyquistFreq, frameSize, herzInterval); SpectrogramTools.DrawGridLinesOnImage((Bitmap)bmp1, startOffset, fullDuration, xInterval, freqScale); int trackHeight = 20; var xAxisTicInterval = TimeSpan.FromMinutes(60); // assume 60 pixels per hour var timeScale24Hour = ImageTrack.DrawTimeTrack(fullDuration, startOffset, xAxisTicInterval, bmp1.Width, trackHeight, "hours"); var imageList = new List <Image> { titleBar, timeScale24Hour, bmp1, timeScale24Hour }; var compositeBmp = ImageTools.CombineImagesVertically(imageList.ToArray()); if (compositeBmp == null) { throw new ArgumentNullException(nameof(compositeBmp)); } trackHeight = compositeBmp.Height; Bitmap timeScale12Months = ImageTrack.DrawYearScaleVertical(40, trackHeight); Bitmap freqScaleImage = DrawFreqScale_vertical(40, trackHeight, herzValue, nyquistFreq); imageList = new List <Image> { timeScale12Months, compositeBmp, freqScaleImage }; compositeBmp = ImageTools.CombineImagesInLine(imageList.ToArray()); return(compositeBmp); }