How to correctly generate a 3d histogram using numpy or matplotlib built in functions in python?

后端 未结 4 539
难免孤独
难免孤独 2020-12-19 12:05

This is more of a general question about 3d histogram creation in python.

I have attempted to create a 3d histogram using the X and Y arrays in the following code

相关标签:
4条回答
  • 2020-12-19 12:22

    Have a look at http://matplotlib.sourceforge.net/examples/mplot3d/hist3d_demo.html, this has a working example script.

    I've improved the code at that link to be more of a histogram:

    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    import numpy as np
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    x = [1, 3, 5, 8, 6, 7, 1, 2, 4, 5]
    y = [3, 4, 3, 6, 5, 3, 1, 2, 3, 8]
    
    hist, xedges, yedges = np.histogram2d(x, y, bins=(4,4))
    xpos, ypos = np.meshgrid(xedges[:-1]+xedges[1:], yedges[:-1]+yedges[1:])
    
    xpos = xpos.flatten()/2.
    ypos = ypos.flatten()/2.
    zpos = np.zeros_like (xpos)
    
    dx = xedges [1] - xedges [0]
    dy = yedges [1] - yedges [0]
    dz = hist.flatten()
    
    ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average')
    plt.xlabel ("X")
    plt.ylabel ("Y")
    
    plt.show()
    

    I'm not sure how to do it with Axes3D.hist ().

    0 讨论(0)
  • 2020-12-19 12:32

    In this answer there is a solution for 2D and 3D Histograms of scattered points. The usage is simple:

    points, sub = hist2d_scatter( radius, density, bins=4 )
    
    points, sub = hist3d_scatter( temperature, density, radius, bins=4 )
    

    Where sub is a matplotlib "Subplot" instance (3D or not) and pointscontains the points used for the scatter plot.

    0 讨论(0)
  • 2020-12-19 12:33

    I posted this in a related thread about colored 3d bar plots, but I think it's also relevant here as I couldn't find a complete answer for what I needed in either thread. This code generates a histogram scatterplot for any sort of x-y data. The height represents the frequency of values in that bin. So, for example, if you had many data point where (x,y) = (20,20) it would be high and red. If you had few data points in the bin where (x,y) = (100,100) it would be low and blue.

    Note: result will vary substantially depending on how much data you have and how many bins your choose for you histogram. Adjust accordingly!

    xAmplitudes = #your data here
    yAmplitudes = #your other data here
    
    x = np.array(xAmplitudes)   #turn x,y data into numpy arrays
    y = np.array(yAmplitudes)
    
    fig = plt.figure()          #create a canvas, tell matplotlib it's 3d
    ax = fig.add_subplot(111, projection='3d')
    
    #make histogram stuff - set bins - I choose 20x20 because I have a lot of data
    hist, xedges, yedges = np.histogram2d(x, y, bins=(20,20))
    xpos, ypos = np.meshgrid(xedges[:-1]+xedges[1:], yedges[:-1]+yedges[1:])
    
    xpos = xpos.flatten()/2.
    ypos = ypos.flatten()/2.
    zpos = np.zeros_like (xpos)
    
    dx = xedges [1] - xedges [0]
    dy = yedges [1] - yedges [0]
    dz = hist.flatten()
    
    cmap = cm.get_cmap('jet') # Get desired colormap - you can change this!
    max_height = np.max(dz)   # get range of colorbars so we can normalize
    min_height = np.min(dz)
    # scale each z to [0,1], and get their rgb values
    rgba = [cmap((k-min_height)/max_height) for k in dz] 
    
    ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color=rgba, zsort='average')
    plt.title("X vs. Y Amplitudes for ____ Data")
    plt.xlabel("My X data source")
    plt.ylabel("My Y data source")
    plt.savefig("Your_title_goes_here")
    plt.show()
    

    The results for about 75k data points of mine are below. Note, you can drag and drop to different perspectives and may want to save multiple views for presentations, posterity.

    0 讨论(0)
  • 2020-12-19 12:39

    I've added to @lxop's answer to allow for arbitrary size buckets:

    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    import numpy as np
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    
    x = np.array([0, 2, 5, 10, 2, 3, 5, 2, 8, 10, 11])
    y = np.array([0, 2, 5, 10, 6, 4, 2, 2, 5, 10, 11])
    # This example actually counts the number of unique elements.
    binsOne = sorted(set(x))
    binsTwo = sorted(set(y))
    # Just change binsOne and binsTwo to lists.
    hist, xedges, yedges = np.histogram2d(x, y, bins=[binsOne, binsTwo])
    
    # The start of each bucket.
    xpos, ypos = np.meshgrid(xedges[:-1], yedges[:-1])
    
    xpos = xpos.flatten()
    ypos = ypos.flatten()
    zpos = np.zeros_like(xpos)
    
    # The width of each bucket.
    dx, dy = np.meshgrid(xedges[1:] - xedges[:-1], yedges[1:] - yedges[:-1])
    
    dx = dx.flatten()
    dy = dy.flatten()
    dz = hist.flatten()
    
    ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average')
    
    0 讨论(0)
提交回复
热议问题