MATLABによる散布図と9つの図

※こちらは，会社の技術ブログとのクロスポスト記事です．元の記事は[こちら](https://www.timedia.co.jp/tech/20220524-tech)
※記事の一部内容は，[MATLAB EXPO 2023 JAPAN](https://www.matlabexpo.com/jp/2023.html)にてポスター発表しました．[（ポスター）](https://www.matlabexpo.com/content/dam/mathworks/mathworks-dot-com/images/events/matlabexpo/jp/2023/visualization-of-point-cloud-data-with-matlab-takagi.pdf)


この記事では，散布図とそこから連想される9つの図を紹介します．
画像生成プログラムは，[こちら](https://github.com/tomtkg/Utility-Functions/tree/main/Geometry)で公開しています．（一部改変，整理済）
皆さんの知識として，あるいは思考を豊かにする一助として，お役に立てれば幸いです．

プログラム言語は，MATLABです．以下のプログラムで図の作成をしています．
```Matlab
  rng('default');
  for i = 1 : 3
    x = rand(20,1); y = rand(20,1);
    // ---図の描画処理---
  end
```
2次元平面上にランダムに分布する点群を利用して図を作成します．
図を3パターン作成し，掲載します．
図毎に，描画するMATLABプログラムと結果の図を掲載します．

# 0. 散布図
```Matlab
  scatter(x,y,'r','filled');
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/scatter1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/scatter2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/scatter3.svg)|
|:-:|:-:|:-:|

点群から考えられる，最も基本的な図です．赤点がデータ点を表します．
以降の図でも，これらの点は必ず描画します．

# 1. 完全グラフ
```Matlab
  G = graph(ones(20),'omitselfloops');
  plot(G,'XData',x,'YData',y,'NodeLabel',{});
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graph1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graph2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graph3.svg)|
|:-:|:-:|:-:|

全ての点を線で結んだ図です．

# 2. 有向グラフ
```Matlab
  [~,C] = pdist2([x,y],[x,y],'euclidean','Smallest',2);
  G = digraph(C(1,:),C(2,:));
  plot(G,'XData',x,'YData',y,'NodeLabel',{});
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graphA1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graphA2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graphA3.svg)|
|:-:|:-:|:-:|
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graphB1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graphB2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/graphB3.svg)|

上は各点の最近傍点，下は各点の第二近傍点までを表す図です．
派生形として，無向グラフ，距離の重み付きグラフが考えられます．
この記事では，ユークリッド空間，ユークリッド距離のみ考えます．

# 3. 最短ハミルトン閉路
プログラムは，[MathWorks社のページ](https://jp.mathworks.com/help/optim/ug/traveling-salesman-problem-based.html)を参考にしました．
点の数が少ない場合は[Dynamic Programming](https://jp.mathworks.com/matlabcentral/fileexchange/31454-dynamic-programming-solution-to-the-tsp)の利用をお勧めします．
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/7e9a7a0919d1d45ec2ec260b13385158384e399d/Data/geometry/tsp1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/7e9a7a0919d1d45ec2ec260b13385158384e399d/Data/geometry/tsp2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/7e9a7a0919d1d45ec2ec260b13385158384e399d/Data/geometry/tsp3.svg)|
|:-:|:-:|:-:|

巡回セールスマン問題の解です．NP困難であり，点の数が多くなると厳密解の獲得が困難です．

# 4. クラスタリング
```Matlab
  [X,Y] = meshgrid(0:0.01:1);
  [~,C] = kmeans([x,y],5,'MaxIter',1000);
  idx = kmeans([X(:),Y(:)],5,'MaxIter',0,'Start',C);
  gscatter(X(:),Y(:),idx);
  scatter(C(:,1),C(:,2),'k');
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/54ec7477659c00f5a996dd8e3a39dff5866503ea/Data/geometry/kmeans1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/54ec7477659c00f5a996dd8e3a39dff5866503ea/Data/geometry/kmeans2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/54ec7477659c00f5a996dd8e3a39dff5866503ea/Data/geometry/kmeans3.svg)|
|:-:|:-:|:-:|

クラスタリングの代表として，k-meansを利用して空間を5つに分割した結果を載せています．
派生形として，分割数を変更した図，距離の閾値で分割した図が考えられます．

# 5. ボロノイ図
```Matlab
  voronoi(x,y);
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/voronoi1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/voronoi2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/voronoi3.svg)|
|:-:|:-:|:-:|

ボロノイ図です．点の数だけ空間を分割します．

# 6. ドロネー図
```Matlab
  triplot(delaunayTriangulation(x,y));
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/triplot1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/triplot2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/triplot3.svg)|
|:-:|:-:|:-:|

ドロネー図です．ドロネー三角形分割図など，表記ゆれがあります．

# 7. 凸包
```Matlab
  k = convhull(x,y);
  plot(x(k),y(k));
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/convhull1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/convhull2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/convhull3.svg)|
|:-:|:-:|:-:|

凸包です．輪ゴムで締めた形と言われたりします．

# 8. 点群境界
```Matlab
  k = boundary(x,y);
  plot(x(k),y(k));
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundary1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundary2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundary3.svg)|
|:-:|:-:|:-:|

縮小係数というパラメータが存在します．
既定値は0.5で，その値を0.3，0.8にすると以下の結果が得られます．
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundaryA1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundaryA2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundaryA3.svg)|
|:-:|:-:|:-:|
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundaryB1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundaryB2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/boundaryB3.svg)|

縮小係数を大きくするほど，境界内部の領域が小さくなります．

# 9. アルファシェイプ
```Matlab
  plot(alphaShape(x,y));
```
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShape1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShape2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShape3.svg)|
|:-:|:-:|:-:|

アルファ半径というパラメータが存在します．
既定値は，すべての点を囲むアルファ形状を生成する最小値です．
その値を0.5倍，1.5倍にすると以下の結果が得られます．
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShapeA1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShapeA2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShapeA3.svg)|
|:-:|:-:|:-:|
|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShapeB1.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShapeB2.svg)|![](https://raw.githubusercontent.com/tomtkg/Utility-Functions/cc7607cbc73472582a6d0933c7a14c33d6a91806/Data/geometry/alphaShapeB3.svg)|

アルファシェイプ，アルファ形状，$\alpha$-shapeなど，表記ゆれがあります．

# 終わりに
この記事では，散布図とそこから連想される9つの図を紹介しました．
9つの図は，グラフネットワークの図，クラスタリングの図，計算幾何学の図など細かく分けられることが多いです．
分野を横断する形で，これらの図をまとめて紹介することは価値があると思い，記事を執筆しました．
皆さんにとって価値ある記事になることを願っています．

最後に，アルファシェイプに関する日本語の参考文献を1つ紹介します．
9つの図の中でアルファシェイプが最も知名度が低く，日本語の資料が少ないので参考になると思います．
図3-5は，アルファシェイプが関係する図です．図19と付録は，アルファシェイプのことだけ書いてあります．

* 高木智章, 髙玉圭樹, 佐藤寛之, “推定パレートフロントに基づいて重みベクトル群を配置する多目的進化アルゴリズム”, 進化計算学会論文誌, 12巻, 2号, pp. 45-60, 2021. [（リンク）](https://doi.org/10.11394/tjpnsec.12.45)