質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Q&A

解決済

3回答

4450閲覧

Python 3次元グラフの作り方

raspypy

総合スコア247

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

0グッド

0クリップ

投稿2020/03/07 06:52

編集2020/03/17 07:33

##やろうとしていること

センサデバイスから取得したデータを3次元グラフ化したいと考えています。

##作りたいグラフのイメージ
x,yは、ともに0~7で固定
z軸の値としてセンサから取得するデータを表示したいと考えています。

##センサからのデータ
センサはアレイ型センサです。

##プログラムコード
このコードで、2次元のグラフ表示はできていますが、3次元にする方法が分かりません。
教えていただけると助かります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

3D グラフは plot_surface() で作成できます。
補完機能は matplotlib にはないので、例えば、scipy.interpolate で行ってください。

以下、もとのグラフと2次元スプライン補間したグラフです。

python

1import matplotlib.pyplot as plt 2import numpy as np 3from mpl_toolkits.mplot3d import Axes3D 4from scipy import interpolate 5 6data = np.array( 7 [ 8 [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], 9 [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], 10 [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], 11 [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], 12 [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], 13 [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], 14 [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], 15 [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], 16 ] 17) 18 19rows, cols = data.shape 20X, Y = np.indices(data.shape) 21 22xs = np.linspace(0, cols, 30) 23ys = np.linspace(0, rows, 30) 24X2, Y2 = np.meshgrid(xs, ys, indexing="ij") 25 26# 2次元スプライン補間を行なう。 27tck = interpolate.bisplrep(X, Y, data, s=0) 28data2 = interpolate.bisplev(xs, ys, tck) 29 30# 描画する。 31fig = plt.figure(figsize=(12, 6)) 32ax1 = fig.add_subplot(121, projection="3d") 33ax2 = fig.add_subplot(122, projection="3d") 34ax1.plot_surface(X, Y, data, cmap="magma", edgecolor="gray") 35surf = ax2.plot_surface(X2, Y2, data2, cmap="magma", edgecolor="gray") 36fig.colorbar(surf) 37 38for ax in [ax1, ax2]: 39 ax.set_zticks((10, 20, 30)) 40 ax.view_init(30, -10) 41 42plt.show()

イメージ説明

追記

python

1import numpy as np 2import matplotlib.pyplot as plt 3from mpl_toolkits.mplot3d import Axes3D 4 5 6data = np.array( 7 [ 8 [20.75, 21.25, 22.25, 22.5, 21.25, 21.25, 22.75, 23.25], 9 [20.5, 21.0, 22.25, 22.25, 23.25, 23.25, 24.0, 24.75], 10 [20.0, 21.25, 21.75, 22.0, 22.5, 23.75, 25.5, 25.25], 11 [20.0, 19.75, 20.75, 22.5, 24.25, 24.75, 25.25, 26.0], 12 [20.25, 22.25, 23.25, 24.25, 24.0, 24.5, 25.5, 25.75], 13 [21.0, 20.75, 21.0, 20.75, 21.5, 24.75, 26.0, 23.5], 14 [21.0, 20.0, 20.25, 22.5, 24.0, 24.75, 22.25, 23.75], 15 [21.25, 18.5, 20.5, 22.5, 21.0, 20.5, 20.25, 21.75], 16 ] 17) 18 19# 点を表示する (x, y) 座標を作成 20X, Y = np.indices(data.shape) 21 22# 描画する。 23fig = plt.figure(figsize=(7, 7)) 24ax = fig.add_subplot(111, projection="3d") 25ax.set_zticks((10, 20, 30)) 26ax.view_init(30, -45) 27points = ax.scatter( 28 X.flat, Y.flat, data.flat, c=data.flat, cmap="jet", edgecolor="gray", s=50 29) 30 31# カラーバー追加 (xmin, ymin, w, h) でカラーバーを表示する位置を指定 32cax = fig.add_axes((0.9, 0.3, 0.02, 0.4)) 33fig.colorbar(points, cax=cax) 34 35plt.show()

イメージ説明

追記

私も試してみましたが、上下にグレーの線がでてしまいます。

こちらで確認しましたが、グレーの線が出る現象は再現しません。
当方のバージョンは 3.1.3 です。

python

1import matplotlib 2print(matplotlib.__version__) # 3.1.3

python

1import numpy as np 2import matplotlib.pyplot as plt 3from mpl_toolkits.mplot3d import Axes3D 4 5 6sensordata = np.array( 7 [ 8 [20.75, 21.25, 22.25, 22.5, 21.25, 21.25, 22.75, 23.25], 9 [20.5, 21.0, 22.25, 22.25, 23.25, 23.25, 24.0, 24.75], 10 [20.0, 21.25, 21.75, 22.0, 22.5, 23.75, 25.5, 25.25], 11 [20.0, 19.75, 20.75, 22.5, 24.25, 24.75, 25.25, 26.0], 12 [20.25, 22.25, 23.25, 24.25, 24.0, 24.5, 25.5, 25.75], 13 [21.0, 20.75, 21.0, 20.75, 21.5, 24.75, 26.0, 23.5], 14 [21.0, 20.0, 20.25, 22.5, 24.0, 24.75, 22.25, 23.75], 15 [21.25, 18.5, 20.5, 22.5, 21.0, 20.5, 20.25, 21.75], 16 ] 17) 18 19# 点を表示する (x, y) 座標を作成 20X, Y = np.indices(sensordata.shape) 21 22# 描画する。 23fig = plt.figure(figsize=(7, 7)) 24axes = fig.add_subplot(111, projection="3d") 25points = axes.scatter( 26 X.flat, 27 Y.flat, 28 sensordata.flat, 29 c=sensordata.flat, 30 cmap="jet", 31 edgecolor="gray", 32 s=50, 33) 34 35# カラーバー追加 (xmin, ymin, w, h) でカラーバーを表示する位置を指定 36cbar_ax = fig.add_axes((0.9, 0.3, 0.02, 0.4)) 37cbar = fig.colorbar(points, cax=cbar_ax) 38cbar.set_label("Temp") 39 40# 軸ラベル設定 41axes.set_xlabel("X") 42axes.set_ylabel("Y") 43 44# 軸目盛設定 45axes.set_xticks(np.arange(0, 9, 1)) 46axes.set_yticks(np.arange(0, 9, 1)) 47axes.set_zticks((10, 20, 30)) 48 49# Title表示 50axes.set_title("Temp", fontsize=16) 51 52# 余白調整 53plt.subplots_adjust(right=0.85) 54plt.subplots_adjust(wspace=0.15) 55 56# 視点 57axes.view_init(30, -45)

イメージ説明

追記

python

1import numpy as np 2import matplotlib.pyplot as plt 3from mpl_toolkits.mplot3d import Axes3D 4 5 6sensordata = np.array( 7 [ 8 [20.75, 21.25, 22.25, 22.5, 21.25, 21.25, 22.75, 23.25], 9 [20.5, 21.0, 22.25, 22.25, 23.25, 23.25, 24.0, 24.75], 10 [20.0, 21.25, 21.75, 22.0, 22.5, 23.75, 25.5, 25.25], 11 [20.0, 19.75, 20.75, 22.5, 24.25, 24.75, 25.25, 26.0], 12 [20.25, 22.25, 23.25, 24.25, 24.0, 24.5, 25.5, 25.75], 13 [21.0, 20.75, 21.0, 20.75, 21.5, 24.75, 26.0, 23.5], 14 [21.0, 20.0, 20.25, 22.5, 24.0, 24.75, 22.25, 23.75], 15 [21.25, 18.5, 20.5, 22.5, 21.0, 20.5, 20.25, 21.75], 16 ] 17) 18 19# 点を表示する (x, y) 座標を作成 20X, Y = np.indices(sensordata.shape) 21 22# 描画する。 23fig = plt.figure(figsize=(7, 7)) 24axes = fig.add_subplot(111, projection="3d") 25points = axes.scatter( 26 X.flat, 27 Y.flat, 28 sensordata.flat, 29 c=sensordata.flat, 30 cmap="jet", 31 edgecolor="gray", 32 s=50, 33) 34axes.plot_surface(X, Y, sensordata, cmap="jet", alpha=0.4) 35 36# カラーバー追加 (xmin, ymin, w, h) でカラーバーを表示する位置を指定 37cbar_ax = fig.add_axes((0.9, 0.3, 0.02, 0.4)) 38cbar = fig.colorbar(points, cax=cbar_ax) 39cbar.set_label("Temp") 40 41# 軸ラベル設定 42axes.set_xlabel("X") 43axes.set_ylabel("Y") 44 45# 軸目盛設定 46axes.set_xticks(np.arange(0, 9, 1)) 47axes.set_yticks(np.arange(0, 9, 1)) 48axes.set_zticks((10, 20, 30)) 49 50# Title表示 51axes.set_title("Temp", fontsize=16) 52 53# 余白調整 54plt.subplots_adjust(right=0.85) 55plt.subplots_adjust(wspace=0.15) 56 57# 視点 58axes.view_init(30, -45)

イメージ説明

投稿2020/03/09 05:44

編集2020/03/10 07:30
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raspypy

2020/03/09 06:57

回答ありがとうございます。 scipyをインストールする際、エラーがでてしまいました。(質問にエラーメッセージをアップさせていただきました) 私の環境python2.7では使えないのでしょうか?
tiitoi

2020/03/09 07:05 編集

そのエラーはなったことはないのですが、調べたら、Lapack という数値計算ソフトがインストールされていないのが原因のようです。 OS によって違うので、「OS名 lapack インストール」で調べて出てきたコマンドで Lapack をインストールしてから、再度 pip install scipy を試してみてください。 https://qiita.com/kubor/items/5a86d757e45568a7218d それはそうとして、Python 2はサポートが終了しているので、特殊な事情がなければ Python 3に移行したほうがいいと思います。 各種ライブラリも Python2 のサポートを打ち切る方向なので、動かないもしくは今後動かなくなるということが起こりえます。
raspypy

2020/03/10 04:32

昨日から何回もscipyをインストールしているのですが、pipコマンドの途中で落ちてしまう(ラズパイにSSH接続していますが、ラズパイ側がフリーズしてします)ため、インストールができない状況です。 scipy以外の方法もありますでしょうか。
tiitoi

2020/03/10 05:14

少し調べてみましたが、1変数の補完なら実装は容易なので、GitHub を探すとサンプルコードが見つかりますが、2変数の補完は scipy 以外実装が見つかりませんでした。(探しきれていないだけでどこかにある可能性はありますが) となると、scipy はオープンソースなので、それを移植してくるか、補完方法のアルゴリズムを勉強して自前で実装するかとなります。 どちらもそれなりに手間がかかりそうです。
raspypy

2020/03/10 05:59

調べていただきありがとうございます。 scipyは今回はあきらめたいと思います。 補間無し(生データ)で3次元グラフを作成していますが、次の2つ解決したいことがあります。 1. データを線(面)ではなく、点で表示させたい 2. カラーバーをグラフの大きさに合わせたい(ことらは合わせているつもちなのですが、合いません) ※質問に最新のコードと、結果画像を添付させていただきます。
tiitoi

2020/03/10 06:30

追記しましたが、このような意図であっていますか?
raspypy

2020/03/10 06:50

ありがとうございます。 私も試してみましたが、上下にグレーの線がでてしまいます。 コードとグラフを最新の情報に更新させていただきます。 度々申し訳ありませんが、確認していただけると助かります。
tiitoi

2020/03/10 06:58

質問のコードを試しましたが、グレーの線が出る現象が確認できません。 試したコードを追記しました。
raspypy

2020/03/10 07:04

ありがとうございます。 Z軸の設定を axes.set_zticks(np.arange(temp_min, temp_max, 1)) 最小値から最大値まで1ずつふったところ、上下の線が消えました。 別質問も含めて、色々と助けていただきありがとうございました。
raspypy

2020/03/17 07:33 編集

度々申し訳ありません。
tiitoi

2020/03/10 07:32

面と点は同時に表示できるはずです。試したコードを追記しました。(点が見えやすいように alpha=0.5 で面を透過しています)
raspypy

2020/03/10 07:36

ありがとうございます。透過についても、とても助かりました。
guest

0

もっとスマートな方法や便利なモジュールがあるとおもいますけど、基本は大体こんな感じです。
値をいろいろ変えて試してみてください。(とりあえずカラーバーが少々長いので調整したいですね)

import numpy as np from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt # 温度データ indata = np.array([[22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75], [22.25, 20.25, 21.75, 24.5, 25.0, 25.0, 25.5, 25.75]]) # 温度データの形状を確認 indata.shape # 2次元グリッド各x0、x1の位置にindataの値をyとして代入 xn = 8 x0 = np.linspace(0, 7, xn) x1 = np.linspace(0, 7, xn) y = np.zeros((len(x0), len(x1))) for i0 in range(xn): for i1 in range(xn): y[i1, i0] = indata[i0, i1] # 3次元グリッドを作成 xx0, xx1 = np.meshgrid(x0, x1) # 作画領域 plt.figure(figsize=(10, 7)) ax = plt.subplot(1, 1, 1, projection='3d') # 3次元グリッドに温度データとカラーマップを与えて曲面を描く surf = ax.plot_surface(xx0, xx1, y, cmap = "autumn_r", edgecolor='gray') # 曲面データを基に、カラーバーを描く plt.colorbar(surf) # Z軸目盛り ax.set_zticks((10, 20, 30)) # タイトル ax.set_title("温度分布") # 視点 ax.view_init(30, -10)

投稿2020/03/07 09:00

編集2020/03/07 14:39
technocore

総合スコア7337

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raspypy

2020/03/07 09:06

早速ありがとうございます。 提示いただいたコードを自分なりに勉強させていただいた上で試させていただきます。
raspypy

2020/03/09 00:43 編集

提示いただいたコードを試してみましたが、エラーがでてしまいます。 エラーの原因を考えているのですが、分からず困っております。 原因にいて教えていただけないでしょうか。 ※質問にコードおよびエラーメッセージを追加させていただきました。
technocore

2020/03/09 00:55

>ValueError: Unknown projection '3d' すみません。私のミスです。 一番最初に私のソースをアップしたとき、 from mpl_toolkits.mplot3d import Axes3D の1行が漏れていたので、後から回答文を修正したのです。 今の回答文は修正済みなので確認してください。
raspypy

2020/03/09 01:09

回答ありがとうございます。 from mpl_toolkits.mplot3d import Axes3Dを追加して試しましたが、まだエラーがでてしまいます。 質問に最新のエラー情報を追加させていただきました。 ご確認いただけると幸いです。
technocore

2020/03/09 01:13

>"matplotlib display text must have all code points < 128 or use " >ValueError: matplotlib display text must have all code points < 128 or use Unicode strings >コード Unicodeのエラーが出ていますね。タイトルは日本語はやめて英語にしてみてください。 ax.set_title("温度分布")
raspypy

2020/03/09 01:23

ありがとうございます。 提示いただいたグラフと同じものが得られました。 度々申し訳ありませんが、何点かお教えいただけると助かります。 ①作成したグラフの上下に影のような線がでてしまいます。  ⇒これは消すことができますでしょうか。(質問に画像を添付いたします。) ②当たり前かもしれませんが、グラフが凸凹になります。  滑らかに表示させたいのですが、何か方法はありますでしょうか。  ⇒素人考えなのですが、8x8のセンサデータを64x64に補間?したりすることは可能なのでしょうか。
technocore

2020/03/09 04:44

>File "/home/pi/.local/lib/python2.7/site-packages/m すみません。気づくのが遅れましたが、python2系をお使いなのですね? 私の環境は Python 3.7.6 matplotlib 3.2.0 です。 python2系はもうサポートも終わりますので、まずは3系に移行することをお勧めします。
guest

0

こんな感じはいかがですか?

イメージ説明

投稿2020/03/07 07:55

編集2020/03/07 08:02
technocore

総合スコア7337

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raspypy

2020/03/07 08:38

回答ありがとうございます。 是非提示していただいたようなグラフを作りたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問