2

I have a dataset that I would like to plot in 3D. Here is a working demo that I would like to adapt:

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

L = 2
n = 5
x = np.linspace(-L, L, n)
y = x.copy()
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X**2 + Y**2))

print("X",X)
print("Y",Y)
print("Z",Z)
print("X Y", (X,Y))

 
fig = plt.figure('3D surface')
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(X, Y, Z)
ax.set_xticks([-2, -1, 0, 1, 2])
ax.set_yticks([-2, -1, 0, 1, 2])
ax.set_zticks([0, 0.5, 1])
fig.tight_layout()

plt.show()

Which will produce a simple(ish) 3d Graph

enter image description here

One thing I dont understand is how Z = np.exp(-(X**2 + Y**2)) comes up with the array of arrays.

Anyway my data is a dictionary of coordinates of (X,Y) to each value that I want to plot. So it should do assignments like this Z[0][0] = data[(30,7)], Z[0][1] = data[(30,8)] and so on. I also have _x, _y, _z as columns. However I'm having trouble understanding how to map Z from the data set. I been playing for hours with no luck. Even running this with zero as data, it does not like the shape. How do I construct Z from this data set so that it renders correctly?

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

data = {(30, 7): 2.899760589371981, (30, 8): 4.3702838372222175, (30, 9): 257.85906533277785, (30, 10): 156.9642451913889, (30, 11): 117.79734351666666, (30, 12): 87.12845625999996, (30, 13): 94.1963482875, (30, 14): 144.57304811222224, (30, 15): 223.74991824888886, (29, 7): 2.9388598647343014, (29, 8): 183.23979641944442, (29, 9): 183.87488728833333, (29, 10): 119.85781460916668, (29, 11): 133.86661589138888, (29, 12): 109.66159447583333, (29, 13): 3.6515377230555557, (29, 14): 176.69359495694445, (29, 15): 218.97532622376457, (28, 7): 2.99624667961165, (28, 8): 152.36525726868572, (28, 9): 254.6567875744445, (28, 10): 310.34455074499994, (28, 11): 3.6265693675, (28, 12): 295.7473858616667, (28, 13): 354.81396648555545, (28, 14): 330.7759454947221, (28, 15): 515.8284059156024, (27, 7): 3.4832570676328496, (27, 8): 494.6530009130556, (27, 9): 558.9684737969444, (27, 10): 628.1385504569445, (27, 11): 429.3385649711112, (27, 12): 305.40794006611105, (27, 13): 398.37097107749986, (27, 14): 444.77040126472224, (27, 15): 595.9394107845642, (26, 7): 0.0, (26, 8): 0.0, (26, 9): 0.0, (26, 10): 0.0, (26, 11): 0.0, (26, 12): 0.0, (26, 13): 0.0, (26, 14): 0.0, (26, 15): 0.0, (23, 7): 2.7060749759615375, (23, 8): 533.8678920588889, (23, 9): 482.0098852449999, (23, 10): 284.4878292747223, (23, 11): 231.53837660861112, (23, 12): 205.2212722930555, (23, 13): 299.9973697577778, (23, 14): 325.5393605852778, (23, 15): 382.63983945363685, (22, 7): 2.83702641826923, (22, 8): 524.1154506774999, (22, 9): 346.5053747252778, (22, 10): 222.7439437819444, (22, 11): 251.81164356472226, (22, 12): 232.7076795425, (22, 13): 288.4576297033334, (22, 14): 362.3498162430556, (22, 15): 520.0129735083241, (21, 7): 2.7541651057692302, (21, 8): 211.71934589441514, (21, 9): 348.59216153305556, (21, 10): 330.0827526966666, (21, 11): 260.69524474055555, (21, 12): 320.93003513888885, (21, 13): 369.6799363852778, (21, 14): 3.6481402877777773, (21, 15): 1.8889219255968905, (20, 7): 2.7879265990338156, (20, 8): 497.38878044777783, (20, 9): 578.3888874361112, (20, 10): 519.4063311825, (20, 11): 379.19423817277783, (20, 12): 355.4565675847222, (20, 13): 315.1411549133333, (20, 14): 534.9071456774999, (20, 15): 497.936075809101, (19, 7): 2.944537333333333, (19, 8): 644.4201197541665, (19, 9): 527.9697446508333, (19, 10): 410.7373982661112, (19, 11): 3.7668233774999997, (19, 12): 302.8033477325001, (19, 13): 112.06049545249999, (19, 14): 174.2037114966666, (19, 15): 387.2604299555802, (16, 7): 2.8616058750000004, (16, 8): 538.8488919238888, (16, 9): 376.52284052694444, (16, 10): 300.7281810838889, (16, 11): 3.7158952178382885, (16, 12): 294.77077434194445, (16, 13): 556.5988753430554, (16, 14): 1228.526131274722, (16, 15): 2.231257877290394, (15, 7): 3.01720390821256, (15, 8): 979.4515585080555, (15, 9): 1564.1824778733335, (15, 10): 1018.206215281111, (15, 11): 541.9170581094446, (15, 12): 336.1475581652777, (15, 13): 764.1392879230556, (15, 14): 4.015594756111109, (15, 15): 509.6690150694059, (14, 7): 2.8746716811594197, (14, 8): 818.7880467329813, (14, 9): 3.8322007208333337, (14, 10): 731.1910409155555, (14, 11): 596.6873250883333, (14, 12): 412.8375621772222, (14, 13): 520.7571591841667, (14, 14): 591.1471487788889, (14, 15): 475.0035797801222, (13, 7): 2.9789540289855068, (13, 8): 639.7969894552778, (13, 9): 637.3779882011111, (13, 10): 506.29437398361114, (13, 11): 353.42218859972223, (13, 12): 305.01100706444447, (13, 13): 340.25735466222227, (13, 14): 3.8758763275000008, (13, 15): 543.8317377257081, (12, 7): 2.906306302884616, (12, 8): 542.9521286569444, (12, 9): 463.0875075130556, (12, 10): 379.6890530136111, (12, 11): 286.1033081977778, (12, 12): 178.39918646277772, (12, 13): 170.33147364083334, (12, 14): 365.98617212138885, (12, 15): 405.7444252476402, (9, 7): 2.928884572115384, (9, 8): 720.7984582758332, (9, 9): 3.8483128874999992, (9, 10): 341.41119732944446, (9, 11): 270.2110689561111, (9, 12): 247.2861200113889, (9, 13): 3.6537818458333327, (9, 14): 306.4674261755556, (9, 15): 2.074388856746252, (8, 7): 2.8890238550724634, (8, 8): 528.4556908091666, (8, 9): 547.9114031425, (8, 10): 500.7944513597222, (8, 11): 3.8512908269444446, (8, 12): 218.3805275261111, (8, 13): 333.57671157, (8, 14): 569.8214435466666, (8, 15): 192.89880216601884, (7, 7): 2.858327285024154, (7, 8): 4.12684743635353, (7, 9): 443.1686869602776, (7, 10): 240.09031229000004, (7, 11): 371.5734720022222, (7, 12): 218.1925328358334, (7, 13): 368.90455026333336, (7, 14): 361.331266850278, (7, 15): 514.2903071515823, (6, 7): 2.8794815652173913, (6, 8): 607.3809963869444, (6, 9): 431.1556074402779, (6, 10): 356.52103546333336, (6, 11): 446.5897162197221, (6, 12): 496.7547147022222, (6, 13): 806.7499224338891, (6, 14): 3.336047919399667, (6, 15): 1.7095653892282068, (5, 7): 2.923072471153846, (5, 8): 637.6159190302777, (5, 9): 419.02678446083337, (5, 10): 448.8138195866668, (5, 11): 419.91707975833333, (5, 12): 428.1129128058334, (5, 13): 413.6354027394445, (5, 14): 548.7387238566666, (5, 15): 469.7728208978345, (2, 7): 2.8789869371980683, (2, 8): 437.0934774280554, (2, 9): 343.60157044583343, (2, 10): 351.74249603000004, (2, 11): 203.51295713194446, (2, 12): 251.80848501055553, (2, 13): 321.7246431113889, (2, 14): 230.65422133611108, (2, 15): 573.934631541921}

_x = np.array([k[0] for k in data.keys()])
_y = np.array([k[1] for k in data.keys()])
_z = np.array([v for v in data.values()])

X,Y = np.meshgrid(_x,_y)

sizeY = max(_y) - min(_y)
sizeX = max(_x) - min(_x)

print('data size', len(data), "sizeX", sizeX, "sizeY", sizeY, " * ", sizeX * sizeY)
print('X',X)
print('Y',Y)

Z = np.zeros(sizeX * sizeY)
Z.shape = (sizeX, sizeY)
print('Z', Z)


fig = plt.figure('3D surface')
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(X, Y, Z)
plt.show()
Peter Moore
  • 1,632
  • 1
  • 17
  • 31
  • `Z = np.exp(-(X**2 + Y**2))` is an example of [numpy's broadcasting](https://numpy.org/doc/stable/user/basics.broadcasting.html). – JohanC Jul 29 '20 at 21:54

1 Answers1

2

np.mesh_grid(x, y) makes a 2D grid of two 1D arrays. In your case, the data are already organized as a grid, so meshgrid isn't needed nor wanted.

The only missing piece is to let plot_wireframe know that the data is 2D, and what the exact count is in each direction. In this case, there are 21x9 grid points. Therefore, setting the shape of each array to that dimension provides enough information:

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

data = {(30, 7): 2.899760589371981, (30, 8): 4.3702838372222175, (30, 9): 257.85906533277785, (30, 10): 156.9642451913889, (30, 11): 117.79734351666666, (30, 12): 87.12845625999996, (30, 13): 94.1963482875, (30, 14): 144.57304811222224, (30, 15): 223.74991824888886, (29, 7): 2.9388598647343014, (29, 8): 183.23979641944442, (29, 9): 183.87488728833333, (29, 10): 119.85781460916668, (29, 11): 133.86661589138888, (29, 12): 109.66159447583333, (29, 13): 3.6515377230555557, (29, 14): 176.69359495694445, (29, 15): 218.97532622376457, (28, 7): 2.99624667961165, (28, 8): 152.36525726868572, (28, 9): 254.6567875744445, (28, 10): 310.34455074499994, (28, 11): 3.6265693675, (28, 12): 295.7473858616667, (28, 13): 354.81396648555545, (28, 14): 330.7759454947221, (28, 15): 515.8284059156024, (27, 7): 3.4832570676328496, (27, 8): 494.6530009130556, (27, 9): 558.9684737969444, (27, 10): 628.1385504569445, (27, 11): 429.3385649711112, (27, 12): 305.40794006611105, (27, 13): 398.37097107749986, (27, 14): 444.77040126472224, (27, 15): 595.9394107845642, (26, 7): 0.0, (26, 8): 0.0, (26, 9): 0.0, (26, 10): 0.0, (26, 11): 0.0, (26, 12): 0.0, (26, 13): 0.0, (26, 14): 0.0, (26, 15): 0.0, (23, 7): 2.7060749759615375, (23, 8): 533.8678920588889, (23, 9): 482.0098852449999, (23, 10): 284.4878292747223, (23, 11): 231.53837660861112, (23, 12): 205.2212722930555, (23, 13): 299.9973697577778, (23, 14): 325.5393605852778, (23, 15): 382.63983945363685, (22, 7): 2.83702641826923, (22, 8): 524.1154506774999, (22, 9): 346.5053747252778, (22, 10): 222.7439437819444, (22, 11): 251.81164356472226, (22, 12): 232.7076795425, (22, 13): 288.4576297033334, (22, 14): 362.3498162430556, (22, 15): 520.0129735083241, (21, 7): 2.7541651057692302, (21, 8): 211.71934589441514, (21, 9): 348.59216153305556, (21, 10): 330.0827526966666, (21, 11): 260.69524474055555, (21, 12): 320.93003513888885, (21, 13): 369.6799363852778, (21, 14): 3.6481402877777773, (21, 15): 1.8889219255968905, (20, 7): 2.7879265990338156, (20, 8): 497.38878044777783, (20, 9): 578.3888874361112, (20, 10): 519.4063311825, (20, 11): 379.19423817277783, (20, 12): 355.4565675847222, (20, 13): 315.1411549133333, (20, 14): 534.9071456774999, (20, 15): 497.936075809101, (19, 7): 2.944537333333333, (19, 8): 644.4201197541665, (19, 9): 527.9697446508333, (19, 10): 410.7373982661112, (19, 11): 3.7668233774999997, (19, 12): 302.8033477325001, (19, 13): 112.06049545249999, (19, 14): 174.2037114966666, (19, 15): 387.2604299555802, (16, 7): 2.8616058750000004, (16, 8): 538.8488919238888, (16, 9): 376.52284052694444, (16, 10): 300.7281810838889, (16, 11): 3.7158952178382885, (16, 12): 294.77077434194445, (16, 13): 556.5988753430554, (16, 14): 1228.526131274722, (16, 15): 2.231257877290394, (15, 7): 3.01720390821256, (15, 8): 979.4515585080555, (15, 9): 1564.1824778733335, (15, 10): 1018.206215281111, (15, 11): 541.9170581094446, (15, 12): 336.1475581652777, (15, 13): 764.1392879230556, (15, 14): 4.015594756111109, (15, 15): 509.6690150694059, (14, 7): 2.8746716811594197, (14, 8): 818.7880467329813, (14, 9): 3.8322007208333337, (14, 10): 731.1910409155555, (14, 11): 596.6873250883333, (14, 12): 412.8375621772222, (14, 13): 520.7571591841667, (14, 14): 591.1471487788889, (14, 15): 475.0035797801222, (13, 7): 2.9789540289855068, (13, 8): 639.7969894552778, (13, 9): 637.3779882011111, (13, 10): 506.29437398361114, (13, 11): 353.42218859972223, (13, 12): 305.01100706444447, (13, 13): 340.25735466222227, (13, 14): 3.8758763275000008, (13, 15): 543.8317377257081, (12, 7): 2.906306302884616, (12, 8): 542.9521286569444, (12, 9): 463.0875075130556, (12, 10): 379.6890530136111, (12, 11): 286.1033081977778, (12, 12): 178.39918646277772, (12, 13): 170.33147364083334, (12, 14): 365.98617212138885, (12, 15): 405.7444252476402, (9, 7): 2.928884572115384, (9, 8): 720.7984582758332, (9, 9): 3.8483128874999992, (9, 10): 341.41119732944446, (9, 11): 270.2110689561111, (9, 12): 247.2861200113889, (9, 13): 3.6537818458333327, (9, 14): 306.4674261755556, (9, 15): 2.074388856746252, (8, 7): 2.8890238550724634, (8, 8): 528.4556908091666, (8, 9): 547.9114031425, (8, 10): 500.7944513597222, (8, 11): 3.8512908269444446, (8, 12): 218.3805275261111, (8, 13): 333.57671157, (8, 14): 569.8214435466666, (8, 15): 192.89880216601884, (7, 7): 2.858327285024154, (7, 8): 4.12684743635353, (7, 9): 443.1686869602776, (7, 10): 240.09031229000004, (7, 11): 371.5734720022222, (7, 12): 218.1925328358334, (7, 13): 368.90455026333336, (7, 14): 361.331266850278, (7, 15): 514.2903071515823, (6, 7): 2.8794815652173913, (6, 8): 607.3809963869444, (6, 9): 431.1556074402779, (6, 10): 356.52103546333336, (6, 11): 446.5897162197221, (6, 12): 496.7547147022222, (6, 13): 806.7499224338891, (6, 14): 3.336047919399667, (6, 15): 1.7095653892282068, (5, 7): 2.923072471153846, (5, 8): 637.6159190302777, (5, 9): 419.02678446083337, (5, 10): 448.8138195866668, (5, 11): 419.91707975833333, (5, 12): 428.1129128058334, (5, 13): 413.6354027394445, (5, 14): 548.7387238566666, (5, 15): 469.7728208978345, (2, 7): 2.8789869371980683, (2, 8): 437.0934774280554, (2, 9): 343.60157044583343, (2, 10): 351.74249603000004, (2, 11): 203.51295713194446, (2, 12): 251.80848501055553, (2, 13): 321.7246431113889, (2, 14): 230.65422133611108, (2, 15): 573.934631541921}

_x = np.array([k[0] for k in data.keys()])
_y = np.array([k[1] for k in data.keys()])
_z = np.array([v for v in data.values()])
# plt.scatter(_x, _y, c=_z, cmap='magma')

_x.shape = (21, 9)
_y.shape = (21, 9)
_z.shape = (21, 9)

fig = plt.figure('3D surface')
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(_x, _y, _z)
plt.show()

3d surface

Creating a scatter plot with the original 1D arrays already gives an idea how the data look like:

plt.scatter(_x, _y, c=_z, cmap='magma')
plt.colorbar()

scattter plot

Smooth surface Plot with Pyplot shows a way to create a smooth surface plot:

from scipy import interpolate
# ...

fig = plt.figure('3D surface')
ax = fig.add_subplot(111, projection='3d')

xnew, ynew = np.mgrid[1:30:80j, 7:15:80j]
tck = interpolate.bisplrep(_x, _y, _z)
znew = interpolate.bisplev(xnew[:,0], ynew[0,:], tck)
ax.plot_surface(xnew, ynew, znew, cmap='inferno')
plt.show()

smooth surface

JohanC
  • 71,591
  • 8
  • 33
  • 66