4

The question is to read 10,000 coordinate points from a file and create a colored grid based on the density of each block on the grid. The range of x-axis is [-73.59, -73.55] and the y-axis is [45.49,45.530]. My code will plot a grid with many different colors, now I need a feature to only color the grid that has a specific density n, for example, The n = 100, only the grid with 100 points or higher will be colored to yellow, and other grids will be black.

I just added a link to my shapefile https://drive.google.com/open?id=1H-8FhfonnPrYW9y7RQZDtiNLxVEiC6R8

import numpy as np
import matplotlib.pyplot as plt
import shapefile

grid_size = 0.002
x1 = np.arange(-73.59,-73.55,grid_size)
y1 = np.arange(45.49,45.530,grid_size)
shape = shapefile.Reader("Shape/crime_dt.shp",encoding='ISO-8859-1')
shapeRecords = shape.shapeRecords()

x_coordinates=[]
y_coordinates=[]

# read all points in .shp file, and store them in 2 lists.
for k in range(len(shapeRecords)):
    x = float(shapeRecords[k].shape.__geo_interface__["coordinates"][0])
    y = float(shapeRecords[k].shape.__geo_interface__["coordinates"][1])
    x_coordinates.append(x)
    y_coordinates.append(y)

plt.hist2d(x_coordinates,y_coordinates,bins=[x1,y1])
plt.show()
2
  • Since we don't have your shapefile, you probably want to make a toy example that is reproduceable minimal reproducible example Commented May 11, 2020 at 18:37
  • @anishtain4 I just added a link to my shapefile, the data is open-sourced so no problem. Commented May 11, 2020 at 18:43

1 Answer 1

1

You can create a colormap with just two colors, and set vmin and vmax to be symmetrical around your desired pivot value.

Optionally you put the value of each bin inside the cells, while the pivot value decides the text color.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

grid_size = 0.002
x1 = np.arange(-73.59, -73.55, grid_size)
y1 = np.arange(45.49, 45.530, grid_size)

# read coordinates from file and put them into two lists, similar to this
x_coordinates = np.random.uniform(x1.min(), x1.max(), size=40000)
y_coordinates = np.random.uniform(y1.min(), y1.max(), size=40000)
pivot_value = 100
# create a colormap with two colors, vmin and vmax are chosen so that their center is the pivot value
cmap = ListedColormap(['indigo', 'gold'])
# create a 2d histogram with xs and ys as bin boundaries
binvalues, _, _, _ = plt.hist2d(x_coordinates, y_coordinates, bins=[x1, y1], cmap=cmap, vmin=0, vmax=2*pivot_value)
binvalues = binvalues.astype(np.int)
for i in range(len(x1) - 1):
    for j in range(len(y1) - 1):
        plt.text((x1[i] + x1[i + 1]) / 2, (y1[j] + y1[j + 1]) / 2, binvalues[i, j],
                 color='white' if binvalues[i, j] < pivot_value else 'black',
                 ha='center', va='center', size=8)
plt.show()

example plot

PS: If the bin values are very important, you can add them all as ticks. Then, their positions can also be used to draw gridlines as a division between the cells.

plt.yticks(y1)
plt.xticks(x1, rotation=90)
plt.grid(True, ls='-', lw=1, color='black')

To obtain contours based on these data, you could plt.contourf with the generated matrix. (You might want to use np.histogram2d to directly create the matrix.)

plt.contourf((x1[1:]+x1[:-1])/2, (y1[1:]+y1[:-1])/2, binvalues.T, levels=[0,100,1000], cmap=cmap)

contour plot

Sign up to request clarification or add additional context in comments.

5 Comments

nvm, It worked, I didn't remove plt.hist2d(x_coordinates,y_coordinates,bins=[x1,y1]) from my code.
This is very helpful, I appreciate it! actually I don't need to show the number in each grid so I removed the last loop part. I am just trying to understand how the vmax = 2*pivot_value worked
Yes, feel free to make any changes, the code is just an example. It can also help to debug, as depending on the pivot value everything might have just one color. When working with a colormap, the value of vmin is assigned to the lowest color, and vmax to the highest. When there are just two colors, the central value ( (vmin+vmax)/2) is the pivot value where a cell changes its color. (Values higher than vmax also get that highest color.)
now I understand why you assign 2*pivot to vmax, it will make all numbers higher than the pivot one color, a very detailed explanation! btw will the pivot number included or excluded?
In this case it is yellow. But as these are floating point operations, in some circumstances the pivot value may tilt the other way. You might set vmax=2*pivot_value - 0.001 to make sure the pivot is always included in the high part.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.