-1

I am new to Python. I have been trying to plot a data file that contains 3 columns and 1024 data points. While running the code the following error arises:

    Traceback (most recent call last):
  File "plot-data.py", line 27, in <module>
    linewidth=0, antialiased=False)
  File "/home/ritajit/.local/lib/python2.7/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 1624, in plot_surface
    X, Y, Z = np.broadcast_arrays(X, Y, Z)
  File "/home/ritajit/.local/lib/python2.7/site-packages/numpy/lib/stride_tricks.py", line 249, in broadcast_arrays
    shape = _broadcast_shape(*args)
  File "/home/ritajit/.local/lib/python2.7/site-packages/numpy            /lib/stride_tricks.py", line 184, in _broadcast_shape
b = np.broadcast(*args[:32])
ValueError: shape mismatch: objects cannot be broadcast to a single shape

My code looks like this

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.mlab import griddata
import matplotlib.cm as cm    
from pylab import rcParams
rcParams['figure.figsize'] = 9, 9


## 3D surface_plot
fig = plt.figure()
axes = fig.add_subplot(111, projection='3d') #gca = get current axis

data = np.loadtxt('2D-data.txt')
x = data[:,0]
y = data[:,1]
z = data[:,2]

xi = np.unique(x)
yi = np.unique(y)

xv, yv = np.meshgrid(x,y)
Z = griddata(x, y, z, xi, yi, interp='linear')

# surface_plot with color grading and color bar
p = axes.plot_surface(xv,yv,Z, rstride=4, cstride=4, cmap=cm.RdBu, 
    linewidth=0, antialiased=False)
fig.colorbar(p, shrink=0.5)

axes.set_xlabel('$x$',fontsize=15)
axes.set_ylabel('$y$',fontsize=15)
axes.set_zlabel('$z$',fontsize=15)
plt.tight_layout()
fig.savefig("surface.pdf")
plt.show()

I am unable to work this through.
What wrong am I doing?
Is there any other way to plot 3d datafile?

A few lines from my data file:

1 2 1.30884
2 2 1.30925
3 2 1.30974
4 2 1.30841
5 2 1.30864
6 2 1.30795

The 1st,2nd,3rd columns are x,y,z respectively

Galilean
  • 246
  • 4
  • 15

1 Answers1

1

Three main issues here:

  • You need to meshgrid the unique values, not the original ones

    xi = np.unique(x)
    yi = np.unique(y)
    xv, yv = np.meshgrid(xi,yi)
    
  • You need to interpolate on the gridded values

    griddata(x, y, z, xv, yv)
    
  • You need to plot Z, not z

    p = axes.plot_surface(xv,yv,Z)
    

In total it looks like you could achieve pretty much the same by reshaping the data columns (but the small data excerpt is not enough to judge on this).

Last, matplotlib.mlab.griddata will be deprecated in the next version. As an alternative consider scipy.interpolate.griddata. Also have a look at the Contour plot of irregularly spaced data example.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • thanks for the response. I've straighten up all errors in the code now it shows this, **ValueError: Argument Z must be 2-dimensional** can't figure it out. – Galilean Jun 13 '18 at 11:03
  • 2
    That's the usual problem of answering questions which do not provide a [mcve]. You are assuming that people can solve your problem by just looking at the code. I updated the answer for now. – ImportanceOfBeingErnest Jun 13 '18 at 11:27