前提・実現したいこと
混合ガウスモデル(GMM)を使って三次元座標のデータに等高線を引きたいです。
二次元座標のデータの等高線の引き方はわかるのですが、三次元になるとエラーが出てしまいます。
エラーの内容もわかるのですがどのように変更したらいいのかわかりません。(恐らく変数CCが三次元配列なのが原因だと思います。)
また、等高線なしのプロットはできています。
初めての質問なので拙い部分が多いと思いますが、どうかよろしくお願いします。
発生している問題・エラーメッセージ
Traceback (most recent call last): File "C:/Users/PycharmProjects/Project/Project.py", line 49, in <module> CS = plt.contour(X_contour,Y_contour,CC,norm=LogNorm(vmin=-CC.min(), vmax=CC.max()),levels=np.logspace(0, 3, 10), cmap="jet") File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\pyplot.py", line 2489, in contour **kwargs) File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\__init__.py", line 1565, in inner return func(ax, *map(sanitize_sequence, args), **kwargs) File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\axes\_axes.py", line 6326, in contour contours = mcontour.QuadContourSet(self, *args, **kwargs) File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\contour.py", line 822, in __init__ kwargs = self._process_args(*args, **kwargs) File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\contour.py", line 1419, in _process_args x, y, z = self._contour_args(args, kwargs) File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\contour.py", line 1477, in _contour_args x, y, z = self._check_xyz(args[:3], kwargs) File "C:\Users\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\contour.py", line 1508, in _check_xyz raise TypeError(f"Input z must be 2D, not {z.ndim}D") TypeError: Input z must be 2D, not 3D
該当のソースコード
Python
1# 1:ライブラリのインポート---------------------------------------------------------- 2import numpy as np # numpyという行列などを扱うライブラリを利用 3import pandas as pd # pandasというデータ分析ライブラリを利用 4import matplotlib.pyplot as plt # プロット用のライブラリを利用 5from sklearn import cluster, preprocessing, mixture # 機械学習用のライブラリを利用 6from mpl_toolkits.mplot3d import Axes3D 7from matplotlib.colors import LogNorm 8import xlrd 9 10# 2:データセットを読み込む---------------------------------------------------------- 11wb = xlrd.open_workbook('C:\Desktop\Data.xlsx') 12sheet = wb.sheet_by_name('sheetExample1') 13n_components=4 14def get_list_2d_all(sheet): 15 return [sheet.row_values(row) for row in range(sheet.nrows)] 16data = get_list_2d_all(sheet) 17data_all = pd.DataFrame(data) 18 19# 3:データの整形------------------------------------------------------------------ 20Fix = pd.DataFrame(data_all) # numpyからpandasへのデータフレームの変換 21Hand = Fix[[1, 2, 3, 4]] 22Hand.columns = [u'frame', u'x_coordinate', u'y_coordinate', u'z_coordinate'] # カラム名をつける(カラム:列. データの項目) 23Coordinate = Hand[["x_coordinate", "y_coordinate", "z_coordinate"]] 24x = Coordinate.iloc[:, 0] # 全ての行の0列目を取得 25nx = x.astype(np.float64) # データ型dtypeの変換 26y = Coordinate.iloc[:, 1] # 全ての行の1列目を取得 27ny = y.astype(np.float64) # データ型dtypeの変換 28z = Coordinate.iloc[:, 2] # 全ての行の2列目を取得 29nz = z.astype(np.float64) # データ型dtypeの変換 30 31# 4:GMMを実施--------------------------------------------------------------------- 32gmm = mixture.GaussianMixture(n_components, covariance_type='tied') # クラスター数を設定し、covariance(共分散)行列を各ガウス分布で異なるものを設定。種類はfull,diag,tied,sphericalがある。 33z_gmm = gmm.fit(Coordinate) # クラスタ化の対象となるデータ配列を指定してクラスタ化を実行させる 34z_gmm = z_gmm.predict(Coordinate) # ある値に対して、それがどの分布が占める割合が高いかをpredictメソッドで計算 35 36# 5: 等高線----------------------------------------------------------------- 37x_contour = np.linspace(-0.3, 0.3) 38y_contour = np.linspace(-0.1, 0.1) 39z_contour = np.linspace(0.5, 1.1) 40X_contour, Y_contour, Z_contour = np.meshgrid(x_contour,y_contour,z_contour) 41XX = np.array([X_contour.ravel(), Y_contour.ravel(), Z_contour.ravel()]).T 42CC = -gmm.score_samples(XX) 43CC = CC.reshape(X_contour.shape) 44 45# 6: 結果をプロット----------------------------------------------------------------- 46fig = plt.figure() 47ax = fig.add_subplot(111, projection='3d') 48CS = ax.contour(X_contour,Y_contour,CC,norm=LogNorm(vmin=-CC.min(), vmax=CC.max()),levels=np.logspace(0, 3, 10), cmap="jet") 49ax.set_xlabel("x") 50ax.set_ylabel("y") 51ax.set_zlabel("z") 52ax.scatter(nx, ny, nz, s=10, c=z_gmm) 53plt.show()
補足情報(FW/ツールのバージョンなど)
ExcelにはB列にフレーム数、C列にx座標、D列にy座標、E列にz座標が入っています。
回答1件
あなたの回答
tips
プレビュー