10
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

matplotlibを使用した3次元グラフ描画ができなかった件(解決)

Posted at

記事を書いたきっかけ

下の2つの書籍で機械学習を勉強していたところ、両方で紹介されていたコードをそのまま書いても3次元グラフの描画ができませんでした。

(少し古いことを除けば、書籍としては滅茶苦茶おすすめです!)

[Python]グラフが描画されない
from mpl_toolkits.mplot3d import Axes3D

xx = "sepal width (cm)"
yy = "sepal length (cm)"
zz = "petal length (cm)"

fig = plt.figure(figsize=(5, 5))
ax = Axes3D(fig)

ax.scatter(df0[xx], df0[yy], df0[zz], color="b")
ax.scatter(df1[xx], df1[yy], df1[zz], color="r")
ax.scatter(df2[xx], df2[yy], df2[zz], color="g")

ax.set_xlabel(xx)
ax.set_ylabel(yy)
ax.set_zlabel(zz)

plt.show()
出力
<Figure size 500x500 with 0 Axes>

本来であれば3d散布図が描画されるはずですが、正常に出力されません
with 0 Axesということで、空の図が作成されているようです

描画されなかった原因

Matplotlib公式ドキュメント

Axes3D automatically adding itself to Figure is deprecated
New Axes3D objects previously added themselves to figures when they were created, unlike all other Axes classes, which lead to them being added twice if fig.add_subplot(111, projection='3d') was called.

This behavior is now deprecated and will warn. The new keyword argument auto_add_to_figure controls the behavior and can be used to suppress the warning. The default value will change to False in Matplotlib 3.5, and any non-False value will be an error in Matplotlib 3.6.

In the future, Axes3D will need to be explicitly added to the figure

一言で言うと
Axes3Dオブジェクトが自動的にFigureオブジェクトに追加される動作は非推奨」
とのこと。

Axes3DとFigureインスタンス化部分抜粋
fig = plt.figure(figsize=(5, 5))
ax = Axes3D(fig)

上記部分にて、Axes3DオブジェクトとFigureオブジェクトは作成していますが、Matplotlibのバージョン3.4からは、Axes3Dオブジェクトを生成しても自動的にはFigureオブジェクトには追加されなくなったようです。

解決方法

公式ドキュメントに書かれている通り、明示的に書けば描画されました。

# add to Figure
fig.add_axes(ax)
正常にグラフが描画される
from mpl_toolkits.mplot3d import Axes3D

xx = "sepal width (cm)"
yy = "sepal length (cm)"
zz = "petal length (cm)"

fig = plt.figure(figsize=(5, 5))
ax = Axes3D(fig)
#ここを追加↓
fig.add_axes(ax)

ax.scatter(df0[xx], df0[yy], df0[zz], color="b")
ax.scatter(df1[xx], df1[yy], df1[zz], color="r")
ax.scatter(df2[xx], df2[yy], df2[zz], color="g")

ax.set_xlabel(xx)
ax.set_ylabel(yy)
ax.set_zlabel(zz)

plt.show()

出力
image.png

他にも方法があるらしい

一般的にmatplotlibを使用して3Dグラフを作成するときは、Axes3Dメソッドではなく、Figureクラスで定義されているadd_subplotメソッドの方がよくつかわれているようです。

こちらも正常にグラフが描画される
from mpl_toolkits.mplot3d import Axes3D

xx = "sepal width (cm)"
yy = "sepal length (cm)"
zz = "petal length (cm)"

fig = plt.figure(figsize=(5, 5))
#ここ↓
ax = fig.add_subplot(111, projection="3d")

ax.scatter(df0[xx], df0[yy], df0[zz], color="b")
ax.scatter(df1[xx], df1[yy], df1[zz], color="r")
ax.scatter(df2[xx], df2[yy], df2[zz], color="g")

ax.set_xlabel(xx)
ax.set_ylabel(yy)
ax.set_zlabel(zz)

plt.show()

Axes3Dメソッド(with明示的追加)とadd_subplotメソッドどちらでも同様に描画できるみたいです。

10
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?