38377


pandasでcsvファイルを読み込んで3Dのサーフェスのグラフを作りたいのですが、x,y,z成分に当たる要素をcsvファイルからどう割り当てればいいかわかりません。

csvファイルは、

[code]

    NAN 10,20,30,40,50,60,70,80,90
    1  ｘ  x  x  x  x  x  x  x  x
    2  ｘ  x  x  x  x  x  x  x  x
    3  ｘ  x  x  x  x  x  x  x  x
    4  ｘ  x  x  x  x  x  x  x  x
    5  ｘ  x  x  x  x  x  x  x  x
    
[/code]

となっていて(ずれてますが6×10の行列の形です)、xのところにz成分の値が入り,  
x軸を一行目の10～90  
ｙ軸を一列目の1～5としたいです。  
よろしくお願いいたします。


CC BY-SA 3.0
2017-10-02T11:43:07.257
38367
2021-09-03T06:03:05.727
2017-10-02T22:52:45.037
19110
25518
question
python pandas csv matplotlib
matplotlibでCSVから3Dサーフェスグラフを作りたい


サンプルプログラム

[code]

    import pandas as pd
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    import numpy as np
    
    # CSVからデータを読み込む
    data = pd.read_csv('./example.csv', delim_whitespace=True, header=0)
    
    # 3Dグラフの初期化
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    
    # データの準備
    Xgrid = data.columns.values.astype(np.float32)
    Ygrid = data.index.values.astype(np.float32)
    X, Y = np.meshgrid(Xgrid, Ygrid)
    Z = data.as_matrix()
    
    # プロット
    surf = ax.plot_surface(X, Y, Z)
    
    # 必要な場合はここでその他の設定をします。
    
    # 表示
    plt.show()
    
[/code]

example.csv

[code]

        10 20 30 40 50 60 70 80 90
    1    1  2  3  4  5  6  7  8  9
    2    2  4  6  8 10 12 14 16 18
    3    3  6  9 12 15 18 21 24 27
    4    4  8 12 16 20 24 28 32 36
    5    5 10 15 20 25 30 35 40 45
    
[/code]

表示結果

[![サンプルのプロット結果です](https://i.stack.imgur.com/uJlSJ.png)](https://i.stack.imgur.com/uJlSJ.png)

実行した環境: Ubuntu 17.04, Python 3.6.0, pandas 0.19.2, matplotlib 2.0.0, numpy
1.13.1

* * *

## 解説

サンプルのプログラムを書いてみました。ポイントは「どうやってCSVを読み込むか」と「どうやって3Dサーフェスプロットするか」です。

pandas で CSV を読み込むには [`read_csv()`](https://pandas.pydata.org/pandas-
docs/stable/generated/pandas.read_csv.html) を使います。CSV
のフォーマットに合わせて適当にオプションを設定する必要があります。

3Dプロットに関しては、matplotlib
の[公式チュートリアル](https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html)が参考になります。具体的には
["Surface
plots"](https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#surface-
plots)
の節にあるサンプルがぴったしです。ソースコードも置いてあるので分かりやすいと思います。上に書いたソースコードはとりあえずデフォルトで表示させているだけですが、サーフェスの色など細かい設定をしたい場合はチュートリアルのソースコードを見ながらコードを追加すると良いでしょう。

細かい部分についても多少書いておきます。今回はCSVのデリミタが半角スペース複数文字のときを考えているので、そうなるように
`delim_whitespace` 引数で設定します。CSVがカンマ区切りであればこれは必要ありません。詳しくは「pandas
スペース区切り」などで検索してください。また、ヘッダー行が先頭のみであることが分かっているので、`header`
引数でついでに設定しています。その後「データの準備」の部分ではX軸・Y軸に相当する部分（グリッド）を作成しています。今回は dataframe
の行・列ラベルをそのまま軸として使用しています。ただし場合によっては型 (dtype) を合わせておかないとエラーが出るため、最後の `astype()`
で念の為 float32 にキャストしています。ここは float32 でなくても構いません。適当です。

## 参考

公式の解説です。

  * [pandas.read_csv](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html) \-- pandas 0.20.3 documentation
  * [mplot3d tutorial](https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html)

また、以下のような解説サイトは「pandas csv」や「matplotlib
3d」などで検索すると簡単に出てくるので、ひとまず検索してみるのもオススメです。

  * [CSVファイルの扱い](https://qiita.com/okadate/items/7b9620a5e64b4e906c42) \-- pandasでよく使う文法まとめ -- Qiita
  * [CSV, TSV を開く](https://qiita.com/koara-local/items/0e56bc1e58b11e4d7a32) \-- pandasの使い方まとめ -- Qiita
  * [matplotlibで3Dプロット](https://qiita.com/kazetof/items/c0204f197d394458022a) \-- Qiita
  * [Matplotlibで3Dグラフを描く](https://qiita.com/Takumi0204/items/28f35d60bef18954aabe) \-- Qiita


CC BY-SA 3.0
2017-10-02T22:51:38.077
38377
2017-10-03T04:17:12.273
2017-10-03T04:17:12.273
19110
19110
38367
answer


### \--- Update (的な) ---

(@nekketsuuu さんの回答のコードが現在では動かなくなったので, 更新)

pandas 0.23.0 以降, `as_matrix()` は非推奨になり使用できなくなりました

参考: <https://pandas.pydata.org/>

[code]

    Latest version: 1.3.2
    Release date: Aug 15, 2021
    
[/code]

Matplotlib 3.4 で `pyplot.gca`および `Figure.gca`でのキーワード引数は非推奨になりました

参考:
<https://matplotlib.org/stable/api/prev_api_changes/api_changes_3.4.0.html#deprecations>

* * *

そのような訳で, 現在では次のようなコードになります

[code]

    import pandas as pd
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    import numpy as np
    
    # CSVからデータを読み込む
    data = pd.read_csv('./example.csv', delim_whitespace=True, header=0)
    
    # 3Dグラフの初期化
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d') # fig.gca(projection='3d') から変更
    
    # データの準備
    Xgrid = data.columns.values.astype(np.float32)
    Ygrid = data.index.values.astype(np.float32)
    X, Y = np.meshgrid(Xgrid, Ygrid)
    Z = data.values # data.as_matrix() から変更
    
    # プロット
    surf = ax.plot_surface(X, Y, Z)
    
    # 必要な場合はここでその他の設定をします。
    
    # 表示
    plt.show()
    
[/code]


CC BY-SA 4.0
2021-09-03T06:03:05.727
82201
2021-09-03T06:03:05.727
43025
38367
answer