Contour/imshow plot for irregular X Y Z data

前端 未结 4 1759
感动是毒
感动是毒 2020-12-13 14:36

I have data in X, Y, Z format where all are 1D arrays, and Z is the amplitude of the measurement at coordinate (X,Y). I\'d like to show this data as a contour or \'imshow\'

相关标签:
4条回答
  • Well if you are prepared to deviate from Python into its competitor, R, I have just submitted a package to CRAN (should be available tomorrow or the next day), which conducts contouring on non-regular grids -- the following can be achieved in a few lines of code:

    library(contoureR)
    set.seed(1)
    x = runif(100)
    y = runif(100)
    z = sin(x) + cos(y)
    df = getContourLines(x,y,z,binwidth=0.0005)
    ggplot(data=df,aes(x,y,group=Group)) + 
      geom_polygon(aes(fill=z)) + 
      scale_fill_gradient(low="blue",high="red") + 
      theme_bw()
    

    Which produces the following:

    If you want a more regular grid, and can afford a bit of extra computation time:

    x = seq(0,1,by=0.005)
    y = seq(0,1,by=0.005)
    d = expand.grid(x=x,y=y)
    d$z = with(d,sin(x) + cos(y))
    df = getContourLines(d,binwidth=0.0005)
    ggplot(data=df,aes(x,y,group=Group)) + 
      geom_polygon(aes(fill=z)) + 
      scale_fill_gradient(low="blue",high="red") + 
      theme_bw()
    

    The fuzzy edges in the above, I know how to resolve and should be fixed for the next version of the software....

    0 讨论(0)
  • 2020-12-13 14:39

    Does plt.tricontourf(x,y,z) satisfy your requirements?

    It will plot filled contours for irregularly spaced data (non-rectilinear grid).

    You might also want to look into plt.tripcolor().

    import numpy as np
    import matplotlib.pyplot as plt
    x = np.random.rand(100)
    y = np.random.rand(100)
    z = np.sin(x)+np.cos(y)
    f, ax = plt.subplots(1,2, sharex=True, sharey=True)
    ax[0].tripcolor(x,y,z)
    ax[1].tricontourf(x,y,z, 20) # choose 20 contour levels, just to show how good its interpolation is
    ax[1].plot(x,y, 'ko ')
    ax[0].plot(x,y, 'ko ')
    plt.savefig('test.png')
    

    tripcolor and tricontourf example

    0 讨论(0)
  • 2020-12-13 14:42

    (Source code @ the end...)

    Here's a little bit of eye candy that I produced playing around with this a bit. It explores the fact that a linear transformation of a meshgrid is still a meshgrid. I.e. on the left of all of my plots, I'm working with X and Y coordinates for a 2-d (input) function. On the right, I want to work with (AVG(X, Y), Y-X) coordinates for the same function.

    I played around with making meshgrids in native coordinates and transforming them into meshgrids for the other coordinates. Works fine if the transform is linear.

    For the bottom two graphs, I worked with random sampling to address your question directly.

    Here are the images with setlims=False: enter image description here

    And the same with setlims=True: enter image description here

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    def f(x, y):
        return y**2 - x**2
    lim = 2
    xlims = [-lim , lim]
    ylims = [-lim, lim]
    
    setlims = False
    
    pde = 1
    numpts = 50
    numconts = 20
    
    xs_even = np.linspace(*xlims, num=numpts)
    ys_even = np.linspace(*ylims, num=numpts)
    
    xs_rand = np.random.uniform(*xlims, size=numpts**2)
    ys_rand = np.random.uniform(*ylims, size=numpts**2)
    
    XS_even, YS_even = np.meshgrid(xs_even, ys_even)
    
    levels = np.linspace(np.min(f(XS_even, YS_even)), np.max(f(XS_even, YS_even)), num=numconts)
    
    cmap = sns.blend_palette([sns.xkcd_rgb['cerulean'], sns.xkcd_rgb['purple']], as_cmap=True)
    
    fig, axes = plt.subplots(3, 2, figsize=(10, 15))
    
    ax = axes[0, 0]
    H = XS_even
    V = YS_even
    Z = f(XS_even, YS_even)
    ax.contour(H, V, Z, levels, cmap=cmap)
    ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
    if setlims:
        ax.set_xlim([-lim/2., lim/2.])
        ax.set_ylim([-lim/2., lim/2.])
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_title('Points on grid, contour')
    
    ax = axes[1, 0]
    H = H.flatten()
    V = V.flatten()
    Z = Z.flatten()
    ax.tricontour(H, V, Z, levels, cmap=cmap)
    ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
    if setlims:
        ax.set_xlim([-lim/2., lim/2.])
        ax.set_ylim([-lim/2., lim/2.])
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_title('Points on grid, tricontour')
    
    ax = axes[0, 1]
    H = (XS_even + YS_even) / 2.
    V = YS_even - XS_even
    Z = f(XS_even, YS_even)
    ax.contour(H, V, Z, levels, cmap=cmap)
    ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
    if setlims:
        ax.set_xlim([-lim/2., lim/2.])
        ax.set_ylim([-lim, lim])
    ax.set_xlabel('AVG')
    ax.set_ylabel('DIFF')
    ax.set_title('Points on transformed grid, contour')
    
    ax = axes[1, 1]
    H = H.flatten()
    V = V.flatten()
    Z = Z.flatten()
    ax.tricontour(H, V, Z, levels, cmap=cmap)
    ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
    if setlims:
        ax.set_xlim([-lim/2., lim/2.])
        ax.set_ylim([-lim, lim])
    ax.set_xlabel('AVG')
    ax.set_ylabel('DIFF')
    ax.set_title('Points on transformed grid, tricontour')
    
    ax=axes[2, 0]
    H = xs_rand
    V = ys_rand
    Z = f(xs_rand, ys_rand)
    ax.tricontour(H, V, Z, levels, cmap=cmap)
    ax.plot(H[::pde], V[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
    if setlims:
        ax.set_xlim([-lim/2., lim/2.])
        ax.set_ylim([-lim/2., lim/2.])
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_title('Points random, tricontour')
    
    ax=axes[2, 1]
    H = (xs_rand + ys_rand) / 2.
    V = ys_rand - xs_rand
    Z = f(xs_rand, ys_rand)
    ax.tricontour(H, V, Z, levels, cmap=cmap)
    ax.plot(H[::pde], V[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
    if setlims:
        ax.set_xlim([-lim/2., lim/2.])
        ax.set_ylim([-lim, lim])
    ax.set_xlabel('AVG')
    ax.set_ylabel('DIFF')
    ax.set_title('Points random transformed, tricontour')
    
    fig.tight_layout()
    
    0 讨论(0)
  • 2020-12-13 14:58
    xx, yy = np.meshgrid(x, y)
    
    plt.contour(xx, yy, z)
    

    Doesn't matter if they are irregularly spaced, contour and 3d plots require a meshgrid.

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