QGIS – How to Animate Time Series with Points in Polygon Using CSV

csvqgis

This was probably asked before but I am not very good with the terminology so cannot seem to find what I am looking for.

I have a large set of data that has the parameters; date, longitude, and latitude. I downloaded a shapefile with the cities of the country the coordinates belong to. For each date, I want to count points in polygon and color the map for each date, and make an animation of it. I have tried using time manager on one CSV that contains all the data, however, I cannot seem to turn the points into polygons when I use it. The only option I can think of is to use count points in polygon for each individual layer (one for each date) but there are hundreds of layers.

Is there any simpler way to do this?

Best Answer

Writing your steps one by one:

  • Load a points layer for a single date
  • Load a polygon layer
  • Run "Count Points in Polygons" from Processing > Toolbox
  • Add a date to the newly created layer

Next:

  • Collect all the created layers and concatenate them into a single layer
  • Set the temporal properties to use the appropriate datetime column
  • Animate

Your problem is: running "Count Points in Polygons" for every date will take forever, and is extremely tedious! The typical solution to this is writing a (Python) script, which will do the repeated step for you.

This can be done with PyQGIS, but it's a bit of a hassle.

It's much easier to do this with e.g. geopandas:

import geopandas as gpd
import pandas as pd
import glob

# Collect all the filenames of the csv's
csv_paths = glob.glob("*.csv")
# Load them as DataFrames
dfs = [pd.read_csv(path) for path in csv_paths]
# Concatenate them into a single big dataframe
df = pd.concat(dfs)
# Turn the dataframe into a GeoDataFrame
gdf = gpd.GeoDataFrame(
    df["date"], geometry=gpd.points_from_xy(x=df["lon"], y=df["lat"])
)
# Read the polygons
polygons = gpd.read_file("polygons.shp")
# Do a spatial join: find out for every point in which polygon it's located
joined = gpd.sjoin(gdf, polygons, op="within")
# Now count how many points there are per polygon
counts = joined.groupby(["date", "index_right"]).count().reset_index("date")
counts = counts.rename(columns={"geometry": "count"})
# Attach the counts back to the polygons
out = polygons.join(counts)
# Write to an output file
out.to_file("counts-over-time.shp")
# This file can be loaded into QGIS and used to animate
Related Question