Note

Interactive online version: Binder badge

Visualization of trajectories#

If we work with trajectory data, we often want to visualize them from a so called birds eye view. The following example demonstrates how to achieve this with tasi using the DLR Urban Traffic Dataset.

Load trajectories#

At first, let’s load trajectories from the DLR dataset.

[1]:
from tasi.dlr.dataset import DLRUTDatasetManager, DLRUTVersion
from tasi.dlr import DLRTrajectoryDataset

dataset = DLRUTDatasetManager(DLRUTVersion.latest)
# select a trajectory file from the middle of the dataset to include data from all object classes
ut = DLRTrajectoryDataset.from_csv(dataset.trajectory()[48])
ut
[1]:
center velocity acceleration yaw dimension classifications interpolated
easting northing easting northing magnitude easting northing magnitude length width height pedestrian bicycle motorbike car van truck
timestamp id
2023-09-24 12:00:00.016482+00:00 1695556712692966 604755.977 5792823.363 0.004 0.019 0.020 0.003 0.009 0.010 -73.593 2.407 1.334 1.625 0.000 0.025 0.150 0.824 0.000 0.000 False
1695556715491157 604795.259 5792804.167 -3.971 -1.074 4.113 -1.093 -0.575 1.235 -164.869 3.463 2.045 1.556 0.005 0.000 0.109 0.883 0.000 0.003 False
1695556722944961 604753.090 5792830.880 -0.000 -0.008 0.008 -0.000 0.001 0.001 -69.165 2.135 1.124 1.682 0.000 0.000 0.334 0.579 0.000 0.087 False
1695556743992329 604751.898 5792835.737 -0.012 0.010 0.016 -0.005 0.006 0.007 -68.221 2.508 1.565 1.990 0.000 0.000 0.060 0.590 0.000 0.344 False
1695556773745982 604793.176 5792766.007 0.014 -0.022 0.026 0.013 0.016 0.021 110.513 2.739 1.101 1.366 0.011 0.002 0.176 0.811 0.000 0.000 False
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2023-09-24 12:14:59.966482+00:00 1695557695944822 604725.113 5792777.272 10.926 1.419 11.018 -0.626 -0.085 0.632 7.340 2.909 1.466 1.450 0.000 0.008 0.056 0.925 0.000 0.011 True
1695557698396270 604798.425 5792719.248 -4.345 13.181 13.879 0.127 -0.301 0.327 108.258 3.275 1.686 1.472 0.006 0.000 0.003 0.989 0.000 0.001 False
1695557698694887 604810.204 5792821.677 -4.130 -1.184 4.296 0.149 0.061 0.161 -163.998 0.909 0.497 1.656 0.000 1.000 0.000 0.000 0.000 0.000 False
1695557699646115 604685.307 5792776.662 11.289 0.410 11.297 -0.706 0.068 0.709 2.078 3.301 1.654 1.637 0.000 0.000 0.000 0.996 0.004 0.000 False
1695557700093347 604652.341 5792771.867 12.743 -0.639 12.759 -1.155 -0.274 1.187 -2.968 3.873 1.524 1.306 0.000 0.000 0.308 0.692 0.000 0.000 True

299053 rows × 19 columns

Plot trajectories#

We now utilize the TrajectoryPlotter to visualize the trajectories of the traffic participants that we’ve loaded.

[2]:
from tasi.plotting import TrajectoryPlotter
import matplotlib.pyplot as plt

f, ax = plt.subplots()

plotter = TrajectoryPlotter()
plotter.plot(ut, ax=ax)
../../_images/user_guide_data_visualization_trajectory_3_0.png

Change trajectory color#

Note that the trajectories are colorized with the default color which we can change so any arbitrary color, such as lightgray.

[3]:
f, ax = plt.subplots()
plotter.plot(ut, ax=ax, color="lightgray")
../../_images/user_guide_data_visualization_trajectory_5_0.png

Change color of a specific trajectory#

You can also define the color of a specific trajectory.

[4]:
f, ax = plt.subplots()
plotter.plot(ut, ax=ax, color="black", trajectory_kwargs={
    ut.ids[-20]: {
        "color": "red"
    }
})
../../_images/user_guide_data_visualization_trajectory_7_0.png

Change trajectory opacity#

or even change the opacity of each trajectory to quickly get an overview of the traffic density. Let’s change the opacity to 20% via the alpha argument.

[5]:
f, ax = plt.subplots()
plotter.plot(ut, ax=ax, alpha=0.2)
../../_images/user_guide_data_visualization_trajectory_9_0.png

The plot already indicates the various traffic volumes on the different routes at the intersection.

Plot DLR UT trajectories on orthophoto#

We can also combine the TrajectoryPlotter with the BoundingboxPlotter to visualize trajectories on an orthophoto.

[6]:
import numpy as np
from tasi.plotting import BoundingboxPlotter, LowerSaxonyOrthophotoTile

f, ax = plt.subplots()

# plot the orthophoto first
bbox_plotter = BoundingboxPlotter(ut.roi, LowerSaxonyOrthophotoTile())
bbox_plotter.plot(ax)

# and the trajectories on top
tj_plotter = TrajectoryPlotter()
tj_plotter.plot(ut, ax=ax)

# hide the axis
_ = ax.axis("off")
[2025-04-25 12:46:54 | tiles.py:fetch:184] > INFO:  Requesting https://opendata.lgln.niedersachsen.de/doorman/noauth/dop_wms?bbox=604649,5792683,604883,5792859&service=WMS&crs=EPSG%3A25832&format=image%2Fpng&request=GetMap&layers=ni_dop20&styles=&version=1.3.0&width=512&height=385
../../_images/user_guide_data_visualization_trajectory_12_1.png

Note that it may become hard to see the trajectories on the background. To increase the contrast, we can adapt the opacity of the ortophoto via the alpha argument. Let’s set is to 0.5 (50%) to highlight the trajectories.

[7]:
f, ax = plt.subplots()

bbox_plotter.plot(ax, alpha=0.5)
tj_plotter.plot(ut, ax=ax, alpha=0.25)

_ = ax.axis("off")
../../_images/user_guide_data_visualization_trajectory_14_0.png

Plot DLR HT trajectories on orthophoto#

We can also use the TrajectoryPlotter with the BoundingboxPlotter to visualize trajectories of the DLR HT dataset on an orthophoto. Let’s load and plot the trajectories from the DLR HT dataset. This time, let’s use the DLRTrajectoryPlotter to color the trajectories in default DLR-colors.

[8]:
from tasi.dlr.dataset import DLRHTDatasetManager, DLRHTVersion
from tasi.dlr.plotting import DLRTrajectoryPlotter

# load dataset
dataset = DLRHTDatasetManager(DLRHTVersion.latest)
path = dataset.load()
# use 3 as it contains objects from all object classes
ht = DLRTrajectoryDataset.from_csv(dataset.trajectory()[3])

f, ax = plt.subplots()

# plot the orthophoto first
bbox_plotter = BoundingboxPlotter(ht.roi, LowerSaxonyOrthophotoTile())
bbox_plotter.plot(ax)

# and the trajectories on top
tj_plotter = DLRTrajectoryPlotter()
tj_plotter.plot(ht, ax=ax)

# hide the axis
_ = ax.axis("off")
[2025-04-25 12:46:59 | dataset.py:load:112] > INFO:  Checking if dataset already downloaded /tmp/DLR-Highway-Traffic-dataset_v1-1-0
[2025-04-25 12:46:59 | dataset.py:load:138] > INFO:  Dataset already available at /tmp/DLR-Highway-Traffic-dataset_v1-1-0
[2025-04-25 12:47:00 | tiles.py:fetch:184] > INFO:  Requesting https://opendata.lgln.niedersachsen.de/doorman/noauth/dop_wms?bbox=614174,5791044,617606,5796205&service=WMS&crs=EPSG%3A25832&format=image%2Fpng&request=GetMap&layers=ni_dop20&styles=&version=1.3.0&width=512&height=769
../../_images/user_guide_data_visualization_trajectory_16_1.png