1

I have a dataset of longitudes/latitudes as follows:

id,spp,lon,lat
1a,sp1,1,9
1b,sp1,3,11
1c,sp1,6,12
2a,sp2,1,9
2b,sp2,1,10
2c,sp2,3,10
2d,sp2,4,11
2e,sp2,5,12
2f,sp2,6,12
3a,sp3,4,13
3b,sp3,5,11
3c,sp3,8,8
4a,sp4,4,12
4b,sp4,6,11
4c,sp4,7,8
5a,sp5,8,8
5b,sp5,7,6
5c,sp5,8,2
6a,sp6,8,8
6b,sp6,7,5
6c,sp6,8,3

From such data, I want to generate a grid like this:

0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 0 0 0 0 0 
0 0 0 0 0 0 1 1 2 0 0 0 0 
0 0 0 0 0 1 1 1 1 0 0 0 0 
0 0 0 1 0 1 0 0 0 0 0 0 0 
0 0 0 2 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 3 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0

which gives the number of data records in each cell of the grid, using variable "spp" as a categorical (grouping) factor.

From this grid, I then want to create a heat map, superimposed on a geographical map, so that I end up with something like the figure below.

enter image description here

I can see how to plot a heatmap on a Matplotlib/Basemap, but I could not figure out how to generate the grid from the point data. Also, it is important that I am able to choose the grid size, so that several different resolutions can be evaluated.

Is there any way of doing this using Numpy meshgrid (or alternatively Scipy griddata)?

2
  • Do you mean you need one grip per spp category? – YoLecomte Oct 4 '17 at 14:11
  • Given a grid if a certain cell size (say, one-degree), I want to count the number of "spp" which appears in each cell of the grid. – maurobio Oct 4 '17 at 14:14
2

I can imagine a solution with csv and numpy the code snippet just below do the job (creating an array with counting group of file):

import csv
import numpy

csvfile = open ('path/to/your/csv.csv', 'r')
reader = csv.reader(csvfile, delimiter=',')
headers = reader.next()

#calculate the size of the grid
x_size = []
y_size =  []

#calculate the size of the array base on the max_value possible(maybe not necessary if you want a normalized size)
for row in reader:
    x_size.append(int(row[2]))
    y_size.append(int(row[3]))

#create an array of the right size with zero
my_array = numpy.zeros((max(x_size)+1,max(y_size)+1), numpy.int16)

#create lists to loop through the array
val_I = range(0, max(x_size)+1, 1)
val_J= range(0, max(y_size)+1, 1)

#loop in the array
reader = csv.reader(csvfile, delimiter=',')            
for i in val_I:
    for j in val_J:
        csvfile.seek(0)
        headers = reader.next()
        count = 0
        group = []
        for row in reader:
            if int(row[2]) == i and int(row[3]) == j: #add the value if coordinate match
                if row[1] not in group: #avoid counting to time the same group
                    group.append(row[1])
                    count += 1
        my_array[i,j] = count #add the value to array 
# you got your array
print my_array

And you got the array you need in the my_array variable (See comment on the code for explanation on the method)

For example, with the data you provide in your question, here is what I obtain (first row an column is (0,0)):

[[0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 2 1 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 1 1 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 1 1 1]
 [0 0 0 0 0 0 0 0 0 0 0 1 1 0]
 [0 0 0 0 0 0 0 0 0 0 0 1 2 0]
 [0 0 0 0 0 1 1 0 1 0 0 0 0 0]
 [0 0 1 1 0 0 0 0 3 0 0 0 0 0]]

I'm sure this is not the most efficient way to do this but it works well for me. Please give more information about what is your aim if you need more specific answer.

3
  • Thank you very much for your kind reply. I appreciate your effort in offering a solution, but it seems to be a problem with it because the counts do not correspond to those I provided in my question. But this is not a complaint! I feel very glad you provided some code which I can then study and, if so required, improve. I will dig into it. Also, I have edited the question to provide you with more information, as requested. Again, thank you very much!!! – maurobio Oct 4 '17 at 21:24
  • You were right, I edited my answer (I didn't take the last line of the array). But i checked ans values seems to be good! – YoLecomte Oct 5 '17 at 6:18
  • @maurobio Glad to help! Good luck for your next steps – YoLecomte Oct 5 '17 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.