Search code examples
pythonpython-3.xmatplotlibnested-listshistogram2d

Create 2d histogram from a list of lists


I'm attempting to create a 2d histogram from two data arrays, one with a list with y value ranges (rdata) and other which is a nested list where the outer list gives the intensity at a specific time and the inner list givs the intensity at a specific time in one of the height ranges.

I'm attempting to create a 2d histogram with the range values on the y axis and the intensity values on the x axis. I've looked at the numpy.histogram2d documentation and tried to reconstruct this histogram from a template file I created with a simmpler array.

Attached is the code:

import numpy as np
import file_reader as fr
import matplotlib.pyplot as plt

time = []
rdata = []
intensity = []

fr.file_reader(time, rdata, intensity)
print('TIME DATA:', time)
print('RANGE DATA:', rdata)
print('INTENSITY DATA:', intensity)

range_bins = np.linspace(rdata[0],rdata[1],len(rdata))
intensity_bins = np.linspace(-70,30,len(intensity))
rdata = [rdata]

for i in range((len(time)-1)):
    rdata.append(rdata)

print(rdata)


H, intensity_bins, rdata_bins = np.histogram2d(intensity,rdata,bins=(intensity_bins,range_bins))

X,Y = np.meshgrid(intensity_bins,range_bins)
plt.xlim(intensity_bins[-1])
plt.ylim(range_bins[-1])
plt.pcolormesh(X,Y,H, cmap='Reds')
plt.draw()

file_reader is a file I created to read data from a .txt and for simplicities sake I will include the data outputs from that, which construct the arrays I'm trying to plot:

TIME DATA: [16.23638916015625, 16.23916625976562, 16.24194526672363, 16.24472236633301, 16.24749946594238, 16.25027847290039, 16.25305557250977]
RANGE DATA: [155.89599609375, 187.0751953125, 218.25439453125, 249.43359375, 280.61279296875, 311.7919921875]
INTENSITY DATA: [[nan, nan, nan, nan, nan, nan], [nan, nan, -59.63091278076172, -49.99733352661133, nan, nan], [nan, 4.0, -3.2, -20.0, -20.0, -20.0], [1.1, nan, nan, nan, nan, nan], [nan, nan, -59.63091278076172, -49.99733352661133, nan, nan], [nan, 4.0, -3.2, -20.0, -20.0, -20.0], [5.32, -29.48, -50.0, -32.2, -1.111, -51.3]]

The for i in range(len(time)-1) function was me testing to see if copying the range data list so it was the same length and also contained a nested set of lists would help for data input into the histogram, but when I run the code there is no output and it seems to get stuck as I have to ctrl+c to stop the code running. Sat here for ten minutes and it didn't produce any output or finish running, which is ludicrous as these are small data arrays.

Any help would be much appreciated.


Solution

  • numpy.histogram2D requires X and Y to be 1D arrays of the x and y coordinates of each point. From the data outputs you've given, it looks like your intensity array is 2D. Also, when you are running through your rdata append loop, you are appending the intermediate value (which is 2D). I've changed your code by using the ravel function to make intensity a 1D array and using repeat to create the rdata array:

    import numpy as np
    import matplotlib.pyplot as plt
    
    time =[16.23638916015625, 16.23916625976562, 16.24194526672363,
        16.24472236633301, 16.24749946594238, 16.25027847290039, 16.25305557250977]
    rdata=[155.89599609375, 187.0751953125, 218.25439453125, 249.43359375,
        280.61279296875, 311.7919921875]
    intensity= [[np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN], 
        [np.NaN, np.NaN, -59.63091278076172, -49.99733352661133, np.NaN, np.NaN], 
        [np.NaN, 4.0, -3.2, -20.0, -20.0, -20.0], [1.1, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN], 
        [np.NaN, np.NaN, -59.63091278076172, -49.99733352661133, np.NaN, np.NaN],
        [np.NaN, 4.0, -3.2, -20.0, -20.0, -20.0], [5.32, -29.48, -50.0, -32.2, -1.111, -51.3]]
    
    
    range_bins = np.linspace(rdata[0],rdata[-1],len(rdata))
    intensity_bins = np.linspace(-70,30,len(intensity))
    
    intensity = np.array(intensity).ravel()
    
    rdata = np.repeat(rdata,len(time))
    
    H, intensity_bins, range_bins = np.histogram2d(intensity,rdata,
        bins=(intensity_bins,range_bins))
    
    plt.imshow(H, interpolation='nearest', origin='low',
        extent=[intensity_bins[0], intensity_bins[-1],range_bins[0], range_bins[-1]])
    

    Output