使用 ScottPlot 繪製圖表

初始化設定

安裝套件

1
2
3
4
5
// 套件 Microsoft.Data.Analysis 檔案轉 DataFrame 格式
#r "nuget: Microsoft.Data.Analysis, 0.21.1"

// 套件 ScottPlot 產生圖片
#r "nuget:ScottPlot, 5.0.*"

引用套件

1
2
3
4
5
using System.IO;
using Microsoft.Data.Analysis;
using ScottPlot;
using ScottPlot.Plottables;
using ScottPlot.Statistics;

設定 ScottPlot 圖片格式

1
2
3
using Microsoft.DotNet.Interactive.Formatting;
Formatter.Register(typeof(ScottPlot.Plot), (p, w) =>
w.Write(((ScottPlot.Plot)p).GetPngHtml(400, 300)), HtmlFormatter.MimeType);

載入 CSV 資料

可參考這篇 DataFrame 載入 📥 CSV 資料

建立擴充方法

使用此擴充方法取得特定 Column 資料

1
2
3
4
public static double[] GetColumn(this DataFrame df, string column)
{
return Enumerable.Range(0, (int)df.Rows.Count).Select(x => Convert.ToDouble(df[column][x])).ToArray();
}

使用 SignalXY 繪圖

分析各分類分佈狀態

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Plot myPlot = new();

// 計算資料筆數
int[] rowIndex = Enumerable.Range(0, (int)df.Rows.Count).ToArray();

// 載入 Duration 欄
double[] durationsY = df.GetColumn("Duration");

SignalXY sigAll1 = myPlot.Add.SignalXY(rowIndex, durationsY);
sigAll1.LegendText = "Duration";

// 載入 Pulse 欄
double[] pulseY = df.GetColumn("Pulse");

SignalXY sigAll2 = myPlot.Add.SignalXY(rowIndex, pulseY);
sigAll2.LegendText = "Pulse";

// 載入 Maxpulse 欄
double[] maxpulseY = df.GetColumn("Maxpulse");

SignalXY sigAll3 = myPlot.Add.SignalXY(rowIndex, maxpulseY);
sigAll3.LegendText = "Maxpulse";

// 載入 Calories 欄
double[] caloriesY = df.GetColumn("Calories");

SignalXY sigAll4 = myPlot.Add.SignalXY(rowIndex, caloriesY);
sigAll4.LegendText = "Calories";

// 設定 Legend 位置
myPlot.Legend.Alignment = ScottPlot.Alignment.UpperRight;

// 顯示圖表
myPlot

SignalXY

使用 Scatter 繪圖

使用「Duration」作為 x 軸,使用「Calories」作為 y 軸,分析兩者關聯性

1
2
3
4
5
6
7
8
9
10
Plot myPlot = new();

// 載入 Scatter
Scatter scatter = myPlot.Add.Scatter(durationsY, caloriesY);

// 移除線條
scatter.LineWidth = 0;

// 顯示圖表
myPlot

Scatter1

使用「Duration」作為 x 軸,使用「Maxpulse」作為 y 軸,分析兩者關聯性

1
2
3
4
5
6
7
8
9
10
Plot myPlot = new();

// 載入 Scatter
Scatter scatter = myPlot.Add.Scatter(durationsY, maxpulseY);

// 移除線條
scatter.LineWidth = 0;

// 顯示圖表
myPlot

Scatter2

使用 Bars 繪圖

繪製 Duration 資料分佈狀態,分析 Duration 頻率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Plot myPlot = new();

// 載入 Duration 欄
double[] durationsY = df.GetColumn("Duration");

// 直方圖分箱數
int binCount = 10;

// 獲取直方圖數據
ScottPlot.Statistics.Histogram hist = ScottPlot.Statistics.Histogram.WithBinCount(binCount, durationsY);

// 設定 Bars
BarPlot bar = myPlot.Add.Bars(hist.Bins, hist.GetProbability());

// 設定 Y 軸刻度
myPlot.Axes.Left.TickGenerator = new ScottPlot.TickGenerators.NumericFixedInterval(20);

// 設定 Bars 的顏色與寬度
foreach(var bar in bar.Bars)
{
bar.LineColor = ScottPlot.Color.FromColor(System.Drawing.Color.Blue);
bar.LineWidth = 10;
//bar.Size = hist.FirstBinSize * 0.8;
}

// 繪製機率曲線
ProbabilityDensity pd = new(durationsY);
double[] xs = Generate.Range(durationsY.Min(), durationsY.Max(), 1);
double sumBins = hist.Bins.Select(x => pd.GetY(x)).Sum();
double[] ys = pd.GetYs(xs, 1.0 / sumBins);

Scatter curve = myPlot.Add.ScatterLine(xs, ys);
curve.LineWidth = 2;
curve.LineColor = Colors.Black;
curve.LinePattern = LinePattern.DenselyDashed;

myPlot.Axes.Margins(bottom: 0);

// 顯示圖表
myPlot

Histogram

📜 參考資料

  1. scottplot
  2. pandas plotting