4

This is the MATLAB version of the 3D plotting code: EDIT: This is the current code:

        plt.figure(2)
        fig_b = Axes3D(fig2)
        xx2 = np.arange(0, L+h_grid*L, h_grid*L)
        yy2 = np.arange(-b, b+h_grid*b, h_grid*b)
        X, Y = np.meshgrid(xx2, yy2)
        W = np.zeros((41,21), float)
        mx = len(xx2)*len(yy2)
        X = np.reshape(X, (1, mx))
        Y = np.reshape(Y, (1, mx))
        W = np.reshape(W, (1, mx))
        for j in range(0, mx):
            W[0][j] = np.sin(np.pi*X[0][j]/L)
        surf = fig_b.plot_surface(X, Y, W, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False) # This is the line number 168
        plt.xlabel('x')
        plt.ylabel('y')

This is the error message I get:

Traceback (most recent call last):
  File "nonhomog.py", line 247, in <module>
    main()
  File "nonhomog.py", line 245, in main
    nonhomog(nu)
  File "nonhomog.py", line 168, in nonhomog
    surf = fig_b.plot_surface(X, Y, W, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=False)
  File "/usr/lib/pymodules/python2.6/mpl_toolkits/mplot3d/axes3d.py", line 618, in plot_surface
    polyc = art3d.Poly3DCollection(polys, *args, **kwargs)
  File "/usr/lib/pymodules/python2.6/mpl_toolkits/mplot3d/art3d.py", line 290, in __init__
    PolyCollection.__init__(self, verts, *args, **kwargs)
  File "/usr/lib/pymodules/python2.6/matplotlib/collections.py", line 668, in __init__
    self.set_verts(verts, closed)
  File "/usr/lib/pymodules/python2.6/mpl_toolkits/mplot3d/art3d.py", line 312, in set_verts
    self.get_vector(verts)
  File "/usr/lib/pymodules/python2.6/mpl_toolkits/mplot3d/art3d.py", line 305, in get_vector
    xs, ys, zs = zip(*points)
ValueError: need more than 0 values to unpack
Serenity
  • 35,289
  • 20
  • 120
  • 115
user569474
  • 451
  • 3
  • 7
  • 14

2 Answers2

4

What's wrong? You are trying to make a non-number negative. In other words: AxesSubplot (whatever that is) doesn't implement the unary - operator.

So, that code can not reasonably be "what you have done", as you don't even define b in that code, yet it exists and is of some custom type called AxesSubplot. If you explain what AxesSubplot is, then that would help. Try including code that actually demonstrates the problem, if possible.

Edit: As DSM points out, you overwrite your b variable. The problem is that you are stuck in "maths mode" and use non-descriptive variable names like "a", "b" and "M". Use longer descriptive names instead.

Instead of:

 a = fig.add_subplot(2,2,i)
 b = fig2.add_subplot(2,2,i)

do:

 x_subplot = fig.add_subplot(2,2,i)
 y_subplot = fig2.add_subplot(2,2,i)

Or something like that (I'm not sure what the variable actually is, so that's just an example).

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
  • @user569474: No it's not. It's an AxesSubplot. The error clearly states this. It is *not* a float. – Lennart Regebro Jan 26 '11 at 08:07
  • @user569474: see line 107 of your pastebin code, b = fig2.add_subplot(2,2,i), which overwrites your b= 0.5 assignment. As pointed out above, error messages aren't always right, but they're usually the best place to start. – DSM Jan 26 '11 at 10:52
  • Thanks. Yes, one flaw was that there were two different things with a same name b. – user569474 Jan 28 '11 at 12:22
4

After setting up the mesh grid for X and Y, you need to come up with a grid for Z values.

The way I currently do this in my code is:

# [ (x1, y1, z1), (x2, y2, z2), ... (xN, yN, zN) ]
all_vals = ...
# (x1, x2, ... xN) , (y1, y2, ... yN) , (z1, z2, ... zN)
all_xvals, all_yvals, all_zvals = zip(*all_vals)
fig = plt.figure()
ax = Axes3D(fig)
X, Y = np.meshgrid(xvals, yvals)
# This is the part you want:
Z1 = np.zeros(X.shape, float)
for (x, y, z) in all_vals:
    x = find_in_sorted_list(x, xvals)
    y = find_in_sorted_list(y, yvals)
    Z1[y,x] = z    
surf = ax.plot_surface(X, Y, Z1, rstride=1, cstride=1, cmap=cm.jet,
        linewidth=0, antialiased=False)
plt.xlabel('Blur standard deviation')  
plt.ylabel('JPEG quality')
ax.w_zaxis.set_major_locator(LinearLocator(10))
ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))    
fig.colorbar(surf, shrink=0.5, aspect=5)    
plt.show()

This gives me a plot that looks like this:

surf

I've saved it as a file, but when you call plt.show(), you get an interactive window where you can change the viewpoint to anything you want.

mpenkov
  • 21,621
  • 10
  • 84
  • 126
  • Thanks! Looks very promising. Can you see my edits to my original question, please? I have added there something. I get this error message: "ValueError: need more than 0 values to unpack" What's wrong with my new code? – user569474 Jan 28 '11 at 11:32
  • The problem may be related to the fact that you're reshaping your grids as 1D arrays (1 row, N columns). They should be 2D arrays. Have a closer look at my code -- look at how Z1 is initialized, and how it is populated with values. – mpenkov Jan 28 '11 at 12:09
  • Thanks! I added these lines: X = np.reshape(X, (41, 21)) Y = np.reshape(Y, (41, 21)) W = np.reshape(W, (41, 21)) after the for loop of my current code and now it works like a dream. – user569474 Jan 28 '11 at 12:20
  • I'm glad to hear that it works for you. I'm not sure if you need to reshape X and Y -- since they were made using meshgrid, they are probably of that shape already. – mpenkov Jan 28 '11 at 12:37
  • I have to access X and Y using only one argument: X(j), Y(j). That is why I think reshaping is necessary. – user569474 Jan 28 '11 at 13:08
  • @misha, I'm having trouble making your sample work. Can you fix it so that runs on just a example data and doesn't depend on that find_in_sorted_list function (yours?). I want to do something similar but I'm having trouble understanding the Z format. – fabiopedrosa Apr 23 '12 at 07:48