教你用MSChart控制元件繪製正態分佈圖形
阿新 • • 發佈:2019-01-07
一年多的“潛伏”也算是深資“特務”了,長時間看別人的部落格,自己卻沒有寫點東東,對不起那些園中勞碌的人。今天終於可以“洗牌”了做正常勞苦大眾。那也得感謝是專案交付期,有了“空擋”可以寫點什麼,讓大家拍磚。
今天主講是的繪製正態分佈圖形所用的質量指標公式的,不注重講MSChart圖形控制元件的用法,MSChart圖形控制元件博園中有很多例項。正態分佈圖形所用的質量指標如下: USL(下規格線簡稱:下限)、USL(上限)、SIGMA(西格瑪)、XBAR(平均值)、SAMPLE DATA(樣本資料)、Zoom Multiple(縮放倍數)、Most Precision(最大精度)。
- Most Precision:最大精度,即小數點後面的位數長度。
1 /// <summary> 2 /// 獲取資料序列的最大精度 (即小數點後面的位數長度) 3 /// </summary> 4 /// <param name="sampleData">樣本資料</param> 5 /// <returns></returns> 6 public static int GetMostPrecision(List<decimal> sampleData) 7 {
- Zoom Multiple:縮放倍數,為了增加圖形邊沿線的平滑度。
View Code
1 /// <summary> 2 /// 縮放倍數 3 /// </summary> 4 /// <param name="mostPrecision"></param> 5 /// <returns></returns> 6 private static decimal ZoomMultiple(ref int mostPrecision) 7 { 8 decimal zoomMultiple = (decimal)Math.Pow(10, mostPrecision - 1); 9 10 if (mostPrecision <= 2) //保證精度大於二的資料序列圖形的平滑 11 { 12 mostPrecision = 4; 13 zoomMultiple = 100; 14 } 15 16 return zoomMultiple; 17 }
- SAMPLE DATA:樣本資料是概率運算裡的一個概念。隨機抽取的部分用於計算出效能優良的數量。
- XBAR:這個大家好理解,也很好計算。即是所有樣本資料之和的平均值。
View Code
1 double xbar = Math.Round(sampleData.Average(), mostPrecision);
- SIGMA:是一個希臘字母σ的中文譯音,在統計學中,代表標準偏差,用來對過程變異進行測量。
View Code
1 /// <summary> 2 /// 計算Sigma 3 /// </summary> 4 /// <param name="sampleData">樣本資料</param> 5 /// <param name="xbar">平均值</param> 6 /// <returns></returns> 7 public static double CalculateSigma(List<decimal> sampleData, double xbar) 8 { 9 double sigma = 0; 10 int sampleCount = sampleData.Count; 11 double powSum = 0; 12 13 if (sampleData == null || sampleCount <= 2 14 ) //樣本個數大於2計算才有意思 15 { 16 return sigma; 17 } 18 19 foreach (double value in sampleData) 20 { 21 powSum += Math.Pow(value - xbar, 2); //樣本值減去均值2的次冪相加。 22 } 23 24 sigma = Math.Sqrt(powSum / (sampleCount - 1)); 25 26 return sigma; 27 }
- USL和LSL一般是抽樣人員事先設定好的,也可以用公式得到:
View Code
1 double usl = xbar + 3 * sigma;//均值加3sigma 2 double lsl = xbar - 3 * sigma;//均值減3sigma
首先清除圖表Series集合上的資料點:
1 chart.Series[serieIndex].Points.Clear();
X軸正、負界限以及正態公式係數:
1 int positiveLimit = (int)((xbar + 6 * sigma) * zoomMultiple); //X軸的正界限 2 int minusLimit = (int)((xbar - 6 * sigma) * zoomMultiple); //X軸的負界限 3 double coefficient = Math.Round(1 / Math.Sqrt(2 * Math.PI) / sigma, mostPrecision); //係數;如果計算需要精確,就不要四捨五入;建議:為了提高運算效率要四捨五入。
根據公式生成正態圖形所需要的資料點:
1 List<double> xValues = new List<double>(); 2 List<double> yValues = new List<double>(); 3 4 for (int x = minusLimit; x <= positiveLimit; x++) 5 { 6 //x軸縮小zoomMultiple倍x每隔1/zoomMultiple變化曲線變平滑 7 double xValue = x / zoomMultiple; 8 double yValue = coefficient * Math.Exp(Math.Pow((xValue - xbar), 2) / (-2 * Math.Pow(sigma, 2))); 9 xValue = Math.Round(xValue, mostPrecision); 10 yValue = Math.Round(yValue, mostPrecision); 11 if (yValue > 0.0001)//可設為yValue > 0 12 { 13 xValues.Add(xValue); 14 yValues.Add(yValue); 15 } 16 } 17 18 //為MSChart繫結資料值 19 chart.Series[serieIndex].Points.DataBindXY(xValues, yValues);
為了確保圖形顯示完全,調整X和Y軸的最大值和最小值刻度:
1 if (yValues.Count > 0) 2 { 3 yAxisMax = 0; 4 return; 5 6 } 7 //將Y軸最大值放大倍作為 8 double yMax = Math.Round(yValues.Max() * 1.1, args.MostPrecision); 9 double xMin = xValues.Min(); 10 double xMax = xValues.Max(); 11 double yMin = yValues.Min(); 12 yAxisMax = yValues.Max(); 13 14 if (xMin > lsl) 15 { 16 xMin = lsl; 17 } 18 if (xMax < usl) 19 { 20 xMax = usl; 21 } 22 //設定軸值x軸加減極大極小值的1/zoomMultiple倍是為了圖形能全部繪製出來 23 chart.ChartAreas[0].AxisX.Minimum = (double)Math.Round(xMin - xMin * 1 / zoomMultiple, mostPrecision); 24 chart.ChartAreas[0].AxisX.Maximum = (double)Math.Round(xMax + xMax * 1 / zoomMultiple, mostPrecision); 25 chart.ChartAreas[0].AxisY.Minimum = (double)Math.Round(yMin, mostPrecision); 26 chart.ChartAreas[0].AxisY.Maximum = (double)Math.Round(yMax, mostPrecision);
分別新增XBAR、USL、LSL閾值限函式如下:
View Code1 /// <summary> 2 /// 新增閾值線 3 /// </summary> 4 /// <param name="chartArea">圖形Area</param> 5 /// <param name="lineName">線上顯示的名子</param> 6 /// <param name="lineOffset">線在圖上的位置</param> 7 /// <param name="lineWidth">線寬</param> 8 /// <param name="lineColor">線的顏色</param> 9 public void AddStripLine(ChartArea chartArea, string lineName, double lineOffset, double lineWidth, Color lineColor) 10 { 11 StripLine stripLine = new StripLine 12 { 13 BackColor = lineColor, 14 StripWidth = lineWidth, 15 BackHatchStyle = ChartHatchStyle.DarkVertical, 16 Text = lineName, 17 TextAlignment = StringAlignment.Far, 18 TextLineAlignment = StringAlignment.Center, 19 IntervalOffset = lineOffset 20 }; 21 22 chartArea.AxisY.StripLines.Add(stripLine); 23 }
最後是根據樣本值重置X軸的最大和最小刻度
View Code1 /// <summary> 2 /// 根據sampleData的最大和最小值重設X軸的最大和最小刻度 3 /// </summary> 4 /// <param name="queueValue"></param> 5 public static void ResetAxisBySampleData(List<decimal> sampleData, Chart chart) 6 { 7 if (sampleData == null || sampleData.Count <= 0) 8 { 9 SwapValue(chart); 10 return; 11 } 12 13 double max = (double) sampleData.Max(); 14 double min = (double) sampleData.Min(); 15 double xMax = chart.ChartAreas[0].AxisX.Maximum; 16 double xMin = chart.ChartAreas[0].AxisX.Minimum; 17 18 if (xMin > xMax) 19 { 20 chart.ChartAreas[0].AxisX.Minimum = min; 21 chart.ChartAreas[0].AxisX.Maximum = max; 22 } 23 }
以上是正態分佈圖所用到的指標和函式,正態直方圖所用到的指標和函式下次再講,時間倉促,寫的不細。如有不明的請發郵件,我們一起探討。Mail:[email protected] 如要轉發,請註明出處!