0

I would like to use matplotlib to create a scattered 3d plot with a projected surface that looks like this demo but using a CSV file that I created from excel that has the X Y Z data in 3 columns of numbers.

Here is the demo code ...

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm

fig = plt.figure()

ax = fig.gca(projection='3d')

X, Y, Z = axes3d.get_test_data(0.05)

ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3)
cset = ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm)

ax.set_xlabel('X')
ax.set_xlim(-40, 40)
ax.set_ylabel('Y')
ax.set_ylim(-40, 40)
ax.set_zlabel('Z')
ax.set_zlim(-100, 100)

plt.show()
matt12
  • 11
  • 1
  • What is your question? – Alex Mar 09 '15 at 21:11
  • I would like to use the above demo but reading the data from a csv file. How do I do that? My data is currently in columns in excel exported as a csv file but could rearrange if there was a simpler alternative. – matt12 Mar 09 '15 at 22:12

1 Answers1

1

You can just use a csv.reader to load the data, then map them to float. Then you need to put them into shape for numpy.

import csv
from itertools import groupby

data = []
with open('my.csv') as my_csv:
    csv_reader = csv.reader(my_csv)
    for line in csv_reader:
        data.append(map(float, line))
data.sort()
X, Z = [], []
for x, g in groupby(data, key=lambda line: line[0]):
    X.append(x)
    Y = []
    new_Z = []
    for y, gg in groupby(g, key=lambda line: line[1]):
        Y.append(y)
        new_Z.append(list(gg)[-1][2])
    Z.append(new_Z)
X, Y = np.meshgrid(X, Y) # transform into 2D index numpy arrays 
Z = np.array(Z) # transform into 2D values numpy array

edit: forgot to reshape values; updated code.

Francis Colas
  • 3,459
  • 2
  • 26
  • 31
  • Should I delete this line .. "X, Y, Z = axes3d.get_test_data(0.05)" and replace with your code? When I tried that the error message was "TypeError: Input z must be a 2D array." – matt12 Mar 09 '15 at 21:23
  • Oh, indeed, sorry; should be better. – Francis Colas Mar 09 '15 at 22:03
  • Thanks :) That is more complicated than I was expecting! Will test later today. What is the simplest method to use a dataset of approx 2,000 to 10,000 values? What would be the best format to simplify the code? I can rearrange with a pivot table in Excel, etc. – matt12 Mar 09 '15 at 22:10
  • "NameError: name 'np' is not defined" so I added "import numpy as np". Then the next error was "TypeError: Shape of x does not match that of z: found (1,545) instead of (545,1)." – matt12 Mar 10 '15 at 14:27