Saturday, 4 June 2022

Animate grid count with GeoPandas

I'm trying to incorporate the following code into an animation. The data below is a workable example. I'm working with has both date and time as the timestamp.

I'm currently plotting count as a heat map. I'm hoping to use the timestamp column to display the variation of this count over time.

gdf_area = gpd.read_file('https://raw.githubusercontent.com/openpolis/geojson-italy/master/geojson/limits_IT_municipalities.geojson')#.loc[:, ["geometry"]]

BOXES = 50
a, b, c, d = gdf_area.total_bounds

gdf_grid = gpd.GeoDataFrame(
    geometry=[
        shapely.geometry.box(minx, miny, maxx, maxy)
        for minx, maxx in zip(np.linspace(a, c, BOXES), np.linspace(a, c, BOXES)[1:])
        for miny, maxy in zip(np.linspace(b, d, BOXES), np.linspace(b, d, BOXES)[1:])
    ],
    crs="epsg:4326",
)

gdf_grid.insert(0, 'timestamp', range(0, 0 + len(gdf_grid)))

# total area for the grid
xmin, ymin, xmax, ymax = gdf_grid.total_bounds

# how many cells across and down
n_cells = 30
cell_size = (xmax-xmin)/n_cells

# create the cells in a loop
grid_cells = []
for x0 in np.arange(xmin, xmax+cell_size, cell_size ):
        for y0 in np.arange(ymin, ymax+cell_size, cell_size):
            # bounds
            x1 = x0-cell_size
            y1 = y0+cell_size
            grid_cells.append(shapely.geometry.box(x0, y0, x1, y1))
        
cell = gpd.GeoDataFrame(grid_cells, columns = ['geometry'], crs = 'EPSG:4326')

merged = gpd.sjoin(gdf_grid, cell, how='left', predicate='within')

# make a simple count variable that we can sum
merged['gridCount'] = 1

# Compute stats per grid cell -- aggregate fires to grid cells with dissolve
dissolve = merged.dissolve(by = 'index_right', aggfunc = 'count')

# put this into cell
cell.loc[dissolve.index, 'gridCount'] = dissolve['gridCount'].values

fig = plt.figure()

im = cell.plot(column = 'gridCount', 
               figsize = (12, 8), 
               cmap = 'viridis_r', 
               #vmax = 1000,
               alpha = 0.5,
               edgecolor = 'grey')


def init():
    im.set_data(np.zeros((x1, y1)))

def animate(i):
    xi = i // y1
    yi = i % y1
    cell[xi, yi] = 1
    im.set_data(cell)
    return im

anim = animation.FuncAnimation(fig, animate, init_func = init, frames = 10,
                           interval = 50)

Output:

   im.set_data(np.zeros((x1, y1)))
AttributeError: 'AxesSubplot' object has no attribute 'set_data'


from Animate grid count with GeoPandas

No comments:

Post a Comment