user3224130
user3224130

Reputation: 61

creating surface data for axes3d

Okay, apologies for this question but I'm pulling my hair out here.

I have a data structure loaded in python in the form:

[(1,0,#),(1,1,#),(1,2,#),(1,3,#),(2,0,#),(2,1,#) ... (26,3,#)]

with # being a different number each time that I wish to represent on the z-axis. You can see that x and y are always integers.

Plotting a scatter graph is simple:

x,y,z = zip(*data)
fig = plt.figure()
ax = fig.gca(projection = '3d')
surface = ax.scatter(x, y, z)
plt.show()

But when it comes to surfaces, I can see two methods:

1) Call ax.plot_trisurf(), which should work with 1D arrays similar to ax.scatter() and apparently works here, but for me gives me an error:

"AttributeError: Axes3D subplot object has not attribute 'plot_trisurf'"

This error also appears if I use the example source code at: http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#tri-surface-plots, suggesting it's something wrong with my installation - my Matplotlib version is 1.1.1rc,. This error does not appear if, for example, ax.plot_surface() is called, nor ax.scatter().

2) Use meshgrid() or griddata() in combination with ax.plot_surface() - in either case, after two days' of pouring over the documentation and examples, I still don't understand how to correctly use these in my case, particularly when it comes to generating the values for Z.

Any help would be much appreciated.

Upvotes: 5

Views: 7167

Answers (2)

Alvaro Fuentes
Alvaro Fuentes

Reputation: 17455

Here is an example of how could you extract your z-values from data

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


data = [(j,i,i**2 + j) for j in range(1,27) for i in range(4)]
print data

fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(0, 4, 1)
Y = np.arange(1, 27, 1)
X, Y = np.meshgrid(X, Y)
print X.shape
print Y.shape

Z = np.array([z for _,_,z in data]).reshape(26,4)

surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
        linewidth=0, antialiased=True)

fig.colorbar(surf, shrink=0.5, aspect=5)

plt.xlabel('X')
plt.ylabel('Y')

plt.show()

Upvotes: 2

danodonovan
danodonovan

Reputation: 20343

To address your first question (1) I believe you need to import Axes3D from the mplot3d library, even if you're not directly calling it. Maybe try adding

from mpl_toolkits.mplot3d import Axes3D

before your main code (this line triggered a memory while reading the tutorial).

As for (2), X, Y and Z need to be matrix (2d array) type objects. This can get confusing, but you may consider an example:

# two arrays - one for each axis
x = np.arange(-5, 5, 0.25)
y = np.arange(-5, 5, 0.25)

# create a mesh / matrix like object from the arrays
X, Y = np.meshgrid(x, y)
# create Z values - also in a mesh like shape
Z = np.sin(np.sqrt(X**2 + Y**2))

# plot!
surface = ax.plot_surface(X, Y, Z)

Upvotes: 4

Related Questions