3

I have the following code that produces a surface plot, but it does not do what I would expect.

xx, yy = np.meshgrid(dealer_sums, player_sums)
    def getter(dealer_sum, player_sum):
        state = (dealer_sum, player_sum)
        return self.get_value(state)
    z = np.vectorize(getter)
    zz = z(xx,yy)

    fig = plt.figure()
    ax  = fig.add_subplot(111, projection='3d')
    ax.plot_wireframe(xx,yy, zz)

FYI, the shapes of xx, yy, and zz are all equal and 2D.

From looking at other posts about this (surface plots in matplotlib; Simplest way to plot 3d surface given 3d points) it looks like a common problem is that the x and y coordinates are irregular, but if I have understood correctly, I think mine are already regularised through the call to np.meshgrid?

I have provided a scatter plot below to show what the data looks like without surfaces: enter image description here

and this is what the call to plot_wireframe looks like:
enter image description here I have drawn over a few of the lines that I did not expect. My question is, is it possible to get rid of those lines and create a surface that looks like this? enter image description here

Thanks for your help.

EDIT: Here is a scatter plot of the XY grid, showing that it is regular: enter image description here

1 Answers1

1

Make sure dealer_sums and player_sums are sorted before calling meshgrid, otherwise, the points connected in the wireframe will also be out of order:

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d

def z(xx, yy):
    return -xx + (yy-18)**2

dealer_sums = [1, 5, 9]
player_sums = [14, 17, 21, 14]

fig = plt.figure()
ax = fig.add_subplot(1, 2, 1, projection='3d')
ax2 = fig.add_subplot(1, 2, 2, projection='3d')

xx, yy = np.meshgrid(dealer_sums, player_sums)
zz = z(xx, yy)
ax.plot_wireframe(xx, yy, zz)

xx2, yy2 = np.meshgrid(np.unique(dealer_sums), np.unique(player_sums))
zz2 = z(xx2, yy2)

ax2.plot_wireframe(xx2, yy2, zz2)
plt.show()

enter image description here

On the left, the dealer_sums and player_sums were unsorted. On the right, they were sorted.


np.unique returns the unique values in sorted order. Above, it is really the sorting which is most important, but there is no point in making the grid with duplicate coordinates, so uniqueness is an added benefit.


Note that meshgrid does not necessarily return a regular grid. If dealer_sums and/or player_sums is irregular, than so will xx and/or yy be.

In [218]: xx, yy = np.meshgrid([0,2,1], [0, .5, 10])

In [219]: xx
Out[219]: 
array([[0, 2, 1],
       [0, 2, 1],
       [0, 2, 1]])

In [220]: yy
Out[220]: 
array([[  0. ,   0. ,   0. ],
       [  0.5,   0.5,   0.5],
       [ 10. ,  10. ,  10. ]])
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677