Matplotlib contour from xyz data: griddata invalid index

后端 未结 2 752
伪装坚强ぢ
伪装坚强ぢ 2020-12-04 23:14

I\'m trying to do a contour plot using matplotlib of a file with the following format:

x1 y1 z1

x2 y2 z2

etc

I can load it with numpy.loadtxt

相关标签:
2条回答
  • 2020-12-04 23:38

    ok, I finally found the solution to plot it. For those interested, here is the trick: use the griddata from Scipy with the 'nearest' method.

    from scipy.interpolate import griddata
    import numpy as np
    import matplotlib.pyplot as plt
    x=np.linspace(1.,10.,20)
    y=np.linspace(1.,10.,20)
    z=z = np.random.random(20)
    xi=np.linspace(1.,10.,10)
    yi=np.linspace(1.,10.,10)
    
    X,Y= np.meshgrid(xi,yi)
    Z = griddata((x, y), z, (X, Y),method='nearest')
    plt.contourf(X,Y,Z)
    
    0 讨论(0)
  • 2020-12-04 23:52

    Consider:

    x = np.linspace(1., 10., 20)
    y = np.linspace(1., 10., 20)
    z = np.linspace(1., 2., 20)
    

    This means we know the z-values at certain points along the line x=y.

    From there,

    zi = ml.griddata(x,y,z,xi,yi)
    

    is asking mlab.griddata to extrapolate the values of z for all points in a rectangular grid.

    We've given a lot of information about how z varies along this line, but no information about how z varies in the perpendicular direction (away from the x = y line). An error is being raised because mlab.griddata refuses to guess.

    You'll get better results if your initial x, y data are distributed more randomly:

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.mlab as ml
    
    ndata = 10
    ny, nx = 100, 200
    xmin, xmax = 1, 10
    ymin, ymax = 1, 10
    # x = np.linspace(1, 10, ndata)
    # y = np.linspace(1, 10, ndata)
    
    x = np.random.randint(xmin, xmax, ndata)
    y = np.random.randint(ymin, ymax, ndata)
    z = np.random.random(ndata)
    
    xi = np.linspace(xmin, xmax, nx)
    yi = np.linspace(ymin, ymax, ny)
    zi = ml.griddata(x, y, z, xi, yi)
    
    plt.contour(xi, yi, zi, 15, linewidths = 0.5, colors = 'k')
    plt.pcolormesh(xi, yi, zi, cmap = plt.get_cmap('rainbow'))
    
    plt.colorbar() 
    plt.scatter(x, y, marker = 'o', c = 'b', s = 5, zorder = 10)
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)
    plt.show()
    

    enter image description here


    If you want mlab.griddata to extrapolate data along the line x=y to the entire grid in an arbitrary way, you could add two extra boundary points (xmin, ymax, z[0]) and (xmax,ymin,z[-1]):

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.mlab as ml
    
    np.random.seed(8)
    ndata = 10
    ny, nx = 100, 200
    xmin, xmax = 1, 10
    ymin, ymax = 1, 10
    x = np.linspace(1, 10, ndata)
    y = np.linspace(1, 10, ndata)
    z = np.random.random(ndata)
    x = np.r_[x,xmin,xmax]
    y = np.r_[y,ymax,ymin]
    z = np.r_[z,z[0],z[-1]]
    xi = np.linspace(xmin, xmax, nx)
    yi = np.linspace(ymin, ymax, ny)
    
    
    # Requires installation of natgrid
    # http://sourceforge.net/projects/matplotlib/files/matplotlib-toolkits/
    zi = ml.griddata(x, y, z, xi, yi, interp='nn')
    
    # Or, without natgrid:
    # zi = ml.griddata(x, y, z, xi, yi, interp='linear')
    
    plt.contour(xi, yi, zi, 15, linewidths = 0.5, colors = 'k')
    plt.pcolormesh(xi, yi, zi, cmap = plt.get_cmap('rainbow'))
    
    plt.colorbar() 
    plt.scatter(x, y, marker = 'o', c = 'b', s = 10, zorder = 10)
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)
    plt.show()
    

    enter image description here

    0 讨论(0)
提交回复
热议问题