13

So I'm trying to create a figure that presents a 3d plot from data points, along with the plots 3 projections in 3 other subplots. I can add the subplots for the projections with no problems, but when I try to place the 3 dimensional plot into the figure things backfire.

here's my code:

def plotAll(data):
    fig = plt.figure()
    plot_3d = fig.add_subplot(221)
    ax = Axes3D(plot_3d)  
    for i,traj in enumerate(data.values()):
        ax.plot3D([traj[0][-1]],[traj[1][-1]],[traj[2][-1]],".",color=[0.91,0.39,0.046])    
    #plot_12v13 = fig.add_subplot(222)
    #plot_projections(data,0,1)
    #plot_13v14 = fig.add_subplot(223)
    #plot_projections(data,1,2)
    #plot_12v14 = fig.add_subplot(224)
    #plot_projections(data,0,2)
    #plt.plot()

which throws back: 'AxesSubplot' object has no attribute 'transFigure'

I'm using matplotlib 0.99.3, any help would be greatly appreciated, thanks!

Serenity
  • 35,289
  • 20
  • 120
  • 115
Dane Allen
  • 131
  • 1
  • 1
  • 5

3 Answers3

20

I was searching for a way to create my 3D-plots with the nice fig, axes = plt.subplots(...) shortcut, but since I just browsed Matplotlib's mplot3d tutorial, I want to share a quote from the top of this site.

New in version 1.0.0: This approach is the preferred method of creating a 3D axes.

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

Note

Prior to version 1.0.0, the method of creating a 3D axes was different. For those using older versions of matplotlib, change ax = fig.add_subplot(111, projection='3d') to ax = Axes3D(fig).

So if you have to use the <1.0.0 version of Matplotlib, this should be taken into account.

Community
  • 1
  • 1
Xidus
  • 421
  • 1
  • 5
  • 7
  • 7
    It should be emphasized that the line "from mpl_toolkits.mplot3d import Axes3D" is necessary, even though you never directly use Axes3D. Without that import, add_subplot(111, projection='3d') will fail, saying that the projection '3d' is not recognized. Using "import mpl_toolkits.mplot3d" instead also works. – SuperElectric Feb 01 '15 at 23:27
  • 1
    The method in the tutorial is to use `fig.gca(projection="3d")` (instead of `add_subplot`) which doesn't appear to work. But your method does. Maybe it's just that I'm using an out-of-date version, but they should probably update the examples! – Luciano Mar 07 '16 at 11:13
  • 1
    I think the `from mpl_toolkits.mplot3d import Axes3D` is not needed anymore. – Andreas K. May 04 '21 at 11:42
17

If you would like to use plt.subplots instead of plt.subplot (see the difference here), then you can do something like this one:

import matplotlib.pyplot as plt
from matplotlib import cm # for a scatter plot
from mpl_toolkits.mplot3d import Axes3D

fig, ax = plt.subplots(1,2,figsize=(10,10),subplot_kw=dict(projection='3d'))

sc1 = ax[0].scatter(x,y,z, c = true, cmap=cm.jet)
ax[0].set_title('True solution')

sc2 = ax[1].scatter(x,y,z c = y_pred, cmap=cm.jet)
ax[1].set_title('Predicted Solution')

Well, I don't know how to set individual axes as 3D using plt.subplots. It would be helpful if someone could comment down.

Prakhar Sharma
  • 543
  • 9
  • 19
4

The preferred way of creating an 3D axis is giving the projection keyword:

def plotAll(data):
    fig = plt.figure()
    ax = fig.add_subplot(221, projection='3d')
    for i,traj in enumerate(data.values()):
        ax.plot3D([traj[0][-1]],[traj[1][-1]],[traj[2][-1]],".",color=[0.91,0.39,0.046])    
    plot_12v13 = fig.add_subplot(222)
    plot_projections(data,0,1)
    plot_13v14 = fig.add_subplot(223)
    plot_projections(data,1,2)
    plot_12v14 = fig.add_subplot(224)
    plot_projections(data,0,2)
    plt.plot()

Unfortunately, you didn't supply a working example with suitable data, so I couldn't test the code. Also, I would recommend updating to a newer version of matplotlib.

David Zwicker
  • 23,581
  • 6
  • 62
  • 77