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

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

ただいまの
回答率

90.51%

  • Python

    11683questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • NumPy

    638questions

    NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

  • Matplotlib

    452questions

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

Pythonのmatplotlibを使って三次元散布図をシンプルに描写したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,002

ShikaTech

score 432

前提・実現したいこと

Python初心者です。
1人3属性からなる1000件ほどのデータを、3次元の散布図として描写したいです。
属性一つ一つがそのままX,Y,Zに対応するイメージです。
さらにZ軸の高低により色付けも行ない、グラデーション状のカラーマップも描写したいです。

例)

  • X軸=属性1=年齢/20~89の範囲
  • Y軸=属性2=週に何度運動をするか/0~7の範囲
  • Z軸=属性3=体重/30~150の範囲

これ↑で描写を行なって体重が軽ければ寒色・重ければ暖色のグラデーションを付ける。
体重が重い人が多く位置するデータから属性の傾向を見極めたいというのが最終的にやりたいことです。

試したこと

まずmatplotlibで3Dグラフを描画するを参考に描写ロジックを書きました。
が、Z軸に相当するデータをどのように作ればよいかが分かりません。
X軸Y軸は元データがあるため、生データの配列を直接指定し、サンプルコードの通りmeshgridと通して生成しています。
Z軸にも生の配列をどうにかしてセットしたいところですが、meshgridを通したX,Yに対してどのように与えるべきかが分からず。。

次にSciPy+matplotlibで3D散布図を作成(Python)を参考に別のアプローチで書いてみました。
X,Y,Zに相当するCSVを手動で作成し、それを元データとして読み込み、単純な描写としては概ね意図通りの表示ができました。
ただこれにカラーマップを追加する方法が分からず、色も手動で指定していたためグラデーションにできていません。
※例えば元データZのパーセンタイル10で分割してグラデーションした10色を宣言して一つ一つ色を変えて…等やればできるのだと思いますが、もっとシンプルかつ簡単にできないものか?と思っています。

cmap=plt.cm.bwrこんな感じで書けないのかなー?っていう。

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure(figsize=(10, 5))
ax = fig.add_subplot(111, projection='3d')
p = ax.scatter3D(X, Y, Z, s=3, c=Z, cmap=plt.cm.bwr)
fig.colorbar(p)

補足情報(言語/FW/ツール等のバージョンなど)

Windows 10 64
Python 3.6.1
numpy.version.version 1.13.1
matplotlib.version 2.0.2

最後に

そもそも勘違いしている、意図したことをもっと簡単にできるよ!この情報が足りてない、、等々ありましたらご指摘ください。
メインC#歴10年で、Pythonは今回必要に迫られて初めて触ります。
元データの整形や縦横変換、トリミングなどの元データ編集は自在にできると思っていただいてOKです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

提示コードとだいたい同じですが、以下でいかがでしょうか?

from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d.axes3d import Axes3D

x = np.array([20,40,50,80]) # 年齢
y = np.array([0,1,3,7])     # 運動
z = np.array([30,50,70,120])# 体重

fig = plt.figure()
ax = Axes3D(fig)
p = ax.scatter(x, y, z, c=z, cmap='hot') # zにカラーマップを利用
fig.colorbar(p)
plt.show()


イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/24 15:42

    ありがとうございました。
    ものすごく単純な話で、meshgridを抜いてそのまま配列を使ってやればよかったんですね。。
    思いつきませんでした。

    キャンセル

同じタグがついた質問を見る

  • Python

    11683questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • NumPy

    638questions

    NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

  • Matplotlib

    452questions

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