diff --git a/notebooks/fundamental_diagram.ipynb b/notebooks/fundamental_diagram.ipynb index 9f1e03c4..33b7813a 100644 --- a/notebooks/fundamental_diagram.ipynb +++ b/notebooks/fundamental_diagram.ipynb @@ -245,6 +245,15 @@ " nts[name] = nt" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(nts)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -260,11 +269,18 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", + "from pedpy import plot_nt\n", + "\n", + "prop_cycle = plt.rcParams[\"axes.prop_cycle\"]\n", + "colors = prop_cycle.by_key()[\"color\"]\n", + "\n", "fig = plt.figure(figsize=(7, 7))\n", "ax1 = fig.add_subplot(111)\n", + "ii = 0\n", "\n", "for name, nt in nts.items():\n", - " ax1.plot(nt.time, nt.cumulative_pedestrians, label=name)\n", + " plot_nt(axes=ax1, nt=nt, label=name, color=colors[ii])\n", + " ii += 1\n", "\n", "ax1.legend()\n", "ax1.set_xlabel(\"time / s\")\n", @@ -498,12 +514,11 @@ "metadata": {}, "outputs": [], "source": [ + "from pedpy import PEDPY_BLUE, PEDPY_RED, plot_density, plot_speed\n", + "\n", "fig, ax = plt.subplots(nrows=len(trajectories.values()), ncols=2, figsize=(20, 60))\n", "row = 0\n", "\n", - "ax[row, 1].set_title(\"Velocity\", size=\"xx-large\")\n", - "ax[row, 0].set_title(\"Density\", size=\"xx-large\")\n", - "\n", "for name, trajectory in trajectories.items():\n", " ax[row, 0].annotate(\n", " name,\n", @@ -517,27 +532,23 @@ " rotation=90,\n", " )\n", "\n", - " ax[row, 0].plot(\n", - " classic_densities[name][FRAME_COL],\n", - " classic_densities[name][DENSITY_COL],\n", - " alpha=1,\n", - " )\n", + " plot_density(axes=ax[row, 0], density=classic_densities[name], color=PEDPY_BLUE)\n", " ax[row, 0].set_xlim(left=0)\n", " ax[row, 0].set_ylim(bottom=0, top=4)\n", - " ax[row, 0].set_xlabel(\"frame\")\n", - " ax[row, 0].set_ylabel(\"rho / 1/m^2\")\n", " ax[row, 0].grid()\n", "\n", - " ax[row, 1].plot(mean_area_speeds[name].frame, mean_area_speeds[name].speed, alpha=1)\n", + " plot_speed(axes=ax[row, 1], speed=mean_area_speeds[name], color=PEDPY_RED)\n", " ax[row, 1].set_xlim(\n", " left=0,\n", " )\n", " ax[row, 1].set_ylim(bottom=0, top=3)\n", - " ax[row, 1].set_xlabel(\"frame\")\n", - " ax[row, 1].set_ylabel(\"v / m/s\")\n", " ax[row, 1].grid()\n", "\n", - " row += 1" + " row += 1\n", + "ax[0, 1].set_title(\"Speed\", size=\"xx-large\")\n", + "ax[0, 0].set_title(\"Density\", size=\"xx-large\")\n", + "\n", + "plt.show()" ] }, { @@ -717,12 +728,11 @@ "metadata": {}, "outputs": [], "source": [ + "from pedpy import PEDPY_BLUE, PEDPY_ORANGE, plot_density, plot_speed\n", + "\n", "fig, ax = plt.subplots(nrows=len(trajectories.values()), ncols=2, figsize=(20, 60))\n", "row = 0\n", "\n", - "ax[row, 1].set_title(\"Speed\", size=\"xx-large\")\n", - "ax[row, 0].set_title(\"Density\", size=\"xx-large\")\n", - "\n", "for name, trajectory in trajectories.items():\n", " ax[row, 0].annotate(\n", " name,\n", @@ -736,46 +746,25 @@ " rotation=90,\n", " )\n", "\n", - " ax[row, 0].plot(\n", - " voronoi_densities[name][FRAME_COL],\n", - " voronoi_densities[name][DENSITY_COL],\n", - " alpha=1,\n", - " label=\"without cut-off\",\n", - " )\n", - " ax[row, 0].plot(\n", - " voronoi_densities_cutoff[name][FRAME_COL],\n", - " voronoi_densities_cutoff[name][DENSITY_COL],\n", - " alpha=1,\n", - " label=\"with cut-off\",\n", - " )\n", + " plot_density(axes=ax[row, 0], density=voronoi_densities[name], label=\"without cut-off\", color=PEDPY_BLUE)\n", + " plot_density(axes=ax[row, 0], density=voronoi_densities_cutoff[name], label=\"with cut-off\", color=PEDPY_ORANGE)\n", " ax[row, 0].set_xlim(left=0)\n", " ax[row, 0].set_ylim(bottom=0, top=4)\n", - " ax[row, 0].set_xlabel(\"frame\")\n", - " ax[row, 0].set_ylabel(\"rho / 1/m^2\")\n", " ax[row, 0].grid()\n", " ax[row, 0].legend()\n", "\n", - " ax[row, 1].plot(\n", - " voronoi_speeds[name][FRAME_COL],\n", - " voronoi_speeds[name][SPEED_COL],\n", - " alpha=1,\n", - " label=\"without cut-off\",\n", - " )\n", - " ax[row, 1].plot(\n", - " voronoi_speeds_cutoff[name][FRAME_COL],\n", - " voronoi_speeds_cutoff[name][SPEED_COL],\n", - " alpha=1,\n", - " label=\"with cut-off\",\n", - " )\n", + " plot_speed(axes=ax[row, 1], speed=voronoi_speeds[name], label=\"without cut-off\", color=PEDPY_BLUE)\n", + " plot_speed(axes=ax[row, 1], speed=voronoi_speeds_cutoff[name], label=\"with cut-off\", color=PEDPY_ORANGE)\n", " ax[row, 1].set_xlim(\n", " left=0,\n", " )\n", " ax[row, 1].set_ylim(bottom=0, top=3)\n", - " ax[row, 1].set_xlabel(\"frame\")\n", - " ax[row, 1].set_ylabel(\"v / m/s\")\n", " ax[row, 1].grid()\n", " ax[row, 1].legend()\n", " row += 1\n", + "\n", + "ax[0, 1].set_title(\"Speed\", size=\"xx-large\")\n", + "ax[0, 0].set_title(\"Density\", size=\"xx-large\")\n", "plt.show()" ] }, @@ -1003,7 +992,6 @@ "# Start plotting\n", "fig = plt.figure(layout=\"constrained\")\n", "ax1 = fig.add_subplot(131, aspect=\"equal\")\n", - "ax1.set_title(\"Color by density\")\n", "plot_voronoi_cells(\n", " voronoi_data=combined_data,\n", " walkable_area=walkable_area,\n", @@ -1014,10 +1002,10 @@ " ped_size=5,\n", " voronoi_outside_ma_alpha=0.4,\n", " axes=ax1,\n", + " title=\"Color by density\",\n", ")\n", "\n", "ax2 = fig.add_subplot(132, aspect=\"equal\")\n", - "ax2.set_title(\"Color by speed\")\n", "plot_voronoi_cells(\n", " voronoi_data=combined_data,\n", " walkable_area=walkable_area,\n", @@ -1028,10 +1016,10 @@ " ped_size=5,\n", " voronoi_outside_ma_alpha=0.4,\n", " axes=ax2,\n", + " title=\"Color by speed\",\n", ")\n", "\n", "ax3 = fig.add_subplot(133, aspect=\"equal\")\n", - "ax3.set_title(\"Color by id\")\n", "plot_voronoi_cells(\n", " voronoi_data=combined_data,\n", " walkable_area=walkable_area,\n", @@ -1042,6 +1030,8 @@ " ped_size=5,\n", " voronoi_outside_ma_alpha=0.4,\n", " axes=ax3,\n", + " show_colorbar=False,\n", + " title=\"Color by id\",\n", ")\n", "plt.show()" ] diff --git a/notebooks/user_guide.ipynb b/notebooks/user_guide.ipynb index 2fcb4717..4bb611c4 100644 --- a/notebooks/user_guide.ipynb +++ b/notebooks/user_guide.ipynb @@ -985,6 +985,34 @@ "plt.show()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Note:\n", + "\n", + "For all functions that plot time series, it is also possible to plot the time in Seconds on the x-axis instead of the frame. You can choose this option with the keyword argument x_axis. Then, also a framerate needs to be defined as in the following example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "from pedpy import plot_density\n", + "\n", + "plot_density(\n", + " density=classic_density,\n", + " title=\"Classic density\",\n", + " x_axis=\"time\",\n", + " framerate=traj.frame_rate,\n", + ")\n", + "plt.show()" + ] + }, { "cell_type": "markdown", "metadata": { @@ -1020,6 +1048,13 @@ "The computation of the individual polygons can be done from the {class}`trajectory data` and {class}`walkable area ` with:" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, @@ -1292,42 +1327,29 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "jupyter": { - "outputs_hidden": false - }, - "tags": [ - "hide-input" - ] - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", - "from pedpy import PEDPY_BLUE, PEDPY_GREY, PEDPY_ORANGE\n", + "from pedpy import PEDPY_BLUE, PEDPY_GREY, PEDPY_ORANGE, plot_density\n", "\n", "fig = plt.figure()\n", - "plt.title(\"Comparison of different density methods\")\n", - "plt.plot(\n", - " classic_density.frame,\n", - " classic_density.density,\n", + "plot_density(\n", + " density=classic_density,\n", " label=\"classic\",\n", " color=PEDPY_BLUE,\n", ")\n", - "plt.plot(\n", - " density_voronoi.frame,\n", - " density_voronoi.density,\n", + "plot_density(\n", + " density=density_voronoi,\n", " label=\"voronoi\",\n", " color=PEDPY_ORANGE,\n", ")\n", - "plt.plot(\n", - " density_voronoi_cutoff.frame,\n", - " density_voronoi_cutoff.density,\n", + "plot_density(\n", + " density=density_voronoi_cutoff,\n", " label=\"voronoi with cutoff\",\n", " color=PEDPY_GREY,\n", ")\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"$\\\\rho$ / 1/$m^2$\")\n", "plt.grid()\n", "plt.legend()\n", "plt.show()" @@ -1335,11 +1357,7 @@ }, { "cell_type": "markdown", - "metadata": { - "jupyter": { - "outputs_hidden": false - } - }, + "metadata": {}, "source": [ "(passing_density)=\n", " #### Passing density (individual)\n", @@ -1544,7 +1562,9 @@ "metadata": {}, "outputs": [], "source": [ - "plot_density(density=line_density, title=\"density at measurement line\")\n", + "from pedpy import plot_density_at_line\n", + "\n", + "plot_density_at_line(density_at_line=line_density, title=\"Density at measurement line\")\n", "plt.show()" ] }, @@ -1641,21 +1661,20 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "from pedpy import PEDPY_GREEN\n", + "from pedpy import PEDPY_GREEN, plot_speed\n", "\n", "ped_id = 25\n", "\n", "plt.figure()\n", - "plt.title(f\"Speed time-series of a pedestrian {ped_id} (border excluded)\")\n", + "title = \"Speed time-series of a pedestrian {} (border excluded)\".format(ped_id)\n", "single_individual_speed = individual_speed_exclude[individual_speed_exclude.id == ped_id]\n", - "plt.plot(\n", - " single_individual_speed.frame,\n", - " single_individual_speed.speed,\n", + "\n", + "plot_speed(\n", + " speed=single_individual_speed,\n", " color=PEDPY_GREEN,\n", + " title=title,\n", ")\n", "\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"v / m/s\")\n", "plt.show()" ] }, @@ -1720,19 +1739,13 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "from pedpy import PEDPY_RED\n", + "from pedpy import PEDPY_RED, plot_speed\n", "\n", "plt.figure()\n", - "plt.title(f\"Speed time-series of an pedestrian {ped_id} (adaptive)\")\n", + "title = f\"Speed time-series of an pedestrian {ped_id} (adaptive)\"\n", "single_individual_speed = individual_speed_adaptive[individual_speed_adaptive.id == ped_id]\n", - "plt.plot(\n", - " single_individual_speed.frame,\n", - " single_individual_speed.speed,\n", - " color=PEDPY_RED,\n", - ")\n", + "plot_speed(speed=single_individual_speed, color=PEDPY_RED, title=title)\n", "\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"v / m/s\")\n", "plt.show()" ] }, @@ -1801,19 +1814,17 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "from pedpy import PEDPY_GREY\n", + "from pedpy import PEDPY_GREY, plot_speed\n", "\n", "plt.figure()\n", - "plt.title(f\"Speed time-series of an pedestrian {ped_id} (single sided)\")\n", + "title = f\"Speed time-series of an pedestrian {ped_id} (single sided)\"\n", "single_individual_speed = individual_speed_single_sided[individual_speed_single_sided.id == ped_id]\n", - "plt.plot(\n", - " single_individual_speed.frame,\n", - " single_individual_speed.speed,\n", + "plot_speed(\n", + " speed=single_individual_speed,\n", " color=PEDPY_GREY,\n", + " title=title,\n", ")\n", "\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"v / m/s\")\n", "plt.show()" ] }, @@ -1833,14 +1844,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "jupyter": { - "outputs_hidden": false - }, - "tags": [ - "hide-input" - ] - }, + "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", @@ -1854,71 +1858,67 @@ "speed_adaptive = individual_speed_adaptive[individual_speed_adaptive.id == ped_id]\n", "speed_single_sided = individual_speed_single_sided[individual_speed_single_sided.id == ped_id]\n", "\n", - "ax[0].plot(\n", - " speed_single_sided.frame,\n", - " speed_single_sided.speed,\n", + "plot_speed(\n", + " axes=ax[0],\n", + " speed=speed_single_sided,\n", " color=PEDPY_GREY,\n", - " linewidth=3,\n", + " line_width=3,\n", " label=\"single sided\",\n", ")\n", - "ax[0].plot(\n", - " speed_adaptive.frame,\n", - " speed_adaptive.speed,\n", + "plot_speed(\n", + " axes=ax[0],\n", + " speed=speed_adaptive,\n", " color=PEDPY_RED,\n", - " linewidth=3,\n", + " line_width=3,\n", " label=\"adaptive\",\n", ")\n", - "ax[0].plot(\n", - " speed_exclude.frame,\n", - " speed_exclude.speed,\n", + "plot_speed(\n", + " axes=ax[0],\n", + " speed=speed_exclude,\n", " color=PEDPY_GREEN,\n", - " linewidth=3,\n", + " line_width=3,\n", " label=\"excluded\",\n", ")\n", - "ax[0].set_xlabel(\"frame\")\n", - "ax[0].set_ylabel(\"v / m/s\")\n", "ax[0].legend()\n", "\n", - "ax[1].plot(\n", - " speed_single_sided.frame[speed_single_sided.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", - " speed_single_sided.speed[speed_single_sided.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", + "plot_speed(\n", + " axes=ax[1],\n", + " speed=speed_single_sided[speed_single_sided.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", " color=PEDPY_GREY,\n", - " linewidth=3,\n", + " line_width=3,\n", ")\n", - "ax[1].plot(\n", - " speed_adaptive.frame[speed_adaptive.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", - " speed_adaptive.speed[speed_adaptive.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", + "plot_speed(\n", + " axes=ax[1],\n", + " speed=speed_adaptive[speed_adaptive.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", " color=PEDPY_RED,\n", - " linewidth=3,\n", + " line_width=3,\n", ")\n", - "ax[1].plot(\n", - " speed_exclude.frame[speed_exclude.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", - " speed_exclude.speed[speed_exclude.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", + "plot_speed(\n", + " axes=ax[1],\n", + " speed=speed_exclude[speed_exclude.frame < speed_single_sided.frame.min() + 3 * frame_step],\n", " color=PEDPY_GREEN,\n", - " linewidth=3,\n", + " line_width=3,\n", ")\n", - "ax[1].set_xlabel(\"frame\")\n", "\n", - "ax[2].plot(\n", - " speed_single_sided.frame[speed_single_sided.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", - " speed_single_sided.speed[speed_single_sided.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", + "plot_speed(\n", + " axes=ax[2],\n", + " speed=speed_single_sided[speed_single_sided.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", " color=PEDPY_GREY,\n", - " linewidth=3,\n", + " line_width=3,\n", ")\n", - "ax[2].plot(\n", - " speed_adaptive.frame[speed_adaptive.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", - " speed_adaptive.speed[speed_adaptive.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", + "plot_speed(\n", + " axes=ax[2],\n", + " speed=speed_adaptive[speed_adaptive.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", " color=PEDPY_RED,\n", - " linewidth=3,\n", + " line_width=3,\n", ")\n", - "ax[2].plot(\n", - " speed_exclude.frame[speed_exclude.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", - " speed_exclude.speed[speed_exclude.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", + "plot_speed(\n", + " axes=ax[2],\n", + " speed=speed_exclude[speed_exclude.frame > speed_single_sided.frame.max() - 3 * frame_step],\n", " color=PEDPY_GREEN,\n", - " linewidth=3,\n", + " line_width=3,\n", ")\n", "\n", - "ax[2].set_xlabel(\"frame\")\n", "plt.show()" ] }, @@ -1979,7 +1979,7 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "from pedpy import PEDPY_BLUE, PEDPY_GREEN, PEDPY_GREY, PEDPY_RED\n", + "from pedpy import PEDPY_BLUE, PEDPY_GREEN, PEDPY_GREY, PEDPY_RED, plot_speed\n", "\n", "colors = [PEDPY_BLUE, PEDPY_GREY, PEDPY_RED, PEDPY_GREEN]\n", "ped_ids = [10, 20, 17, 70]\n", @@ -1988,14 +1988,13 @@ "plt.title(\"Velocity time-series of an excerpt of the pedestrians in a specific direction\")\n", "for color, ped_id in zip(colors, ped_ids, strict=False):\n", " single_individual_speed = individual_speed_direction[individual_speed_direction.id == ped_id]\n", - " plt.plot(\n", - " single_individual_speed.frame,\n", - " single_individual_speed.speed,\n", + " plot_speed(\n", + " speed=single_individual_speed,\n", " color=color,\n", + " label=\"Ped ID {}\".format(ped_id),\n", " )\n", "\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"v / m/s\")\n", + "plt.legend()\n", "plt.show()" ] }, @@ -2065,7 +2064,7 @@ "from pedpy import PEDPY_BLUE, plot_speed\n", "\n", "plot_speed(\n", - " speed=mean_speed.speed,\n", + " speed=mean_speed,\n", " title=\"Mean speed in front of the bottleneck\",\n", " color=PEDPY_BLUE,\n", ")\n", @@ -2114,7 +2113,7 @@ "from pedpy import PEDPY_RED, plot_speed\n", "\n", "plot_speed(\n", - " speed=mean_speed_direction.speed,\n", + " speed=mean_speed_direction,\n", " title=\"Mean speed in specific direction in front of the bottleneck\",\n", " color=PEDPY_RED,\n", ")\n", @@ -2195,7 +2194,7 @@ "from pedpy import PEDPY_ORANGE, plot_speed\n", "\n", "plot_speed(\n", - " speed=voronoi_speed.speed,\n", + " speed=voronoi_speed,\n", " title=\"Voronoi speed in front of the bottleneck\",\n", " color=PEDPY_ORANGE,\n", ")\n", @@ -2245,7 +2244,7 @@ "from pedpy import PEDPY_GREY, plot_speed\n", "\n", "plot_speed(\n", - " speed=voronoi_speed.speed,\n", + " speed=voronoi_speed,\n", " title=\"Voronoi velocity in specific direction in front of the bottleneck\",\n", " color=PEDPY_GREY,\n", ")\n", @@ -2277,36 +2276,30 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "from pedpy import PEDPY_BLUE, PEDPY_GREY, PEDPY_ORANGE, PEDPY_RED\n", + "from pedpy import PEDPY_BLUE, PEDPY_GREY, PEDPY_ORANGE, PEDPY_RED, plot_speed\n", "\n", "plt.figure(figsize=(8, 6))\n", - "plt.title(\"Comparison of different speed methods\")\n", - "plt.plot(\n", - " voronoi_speed.frame,\n", - " voronoi_speed.speed,\n", + "plot_speed(\n", + " speed=voronoi_speed,\n", " label=\"Voronoi\",\n", " color=PEDPY_ORANGE,\n", ")\n", - "plt.plot(\n", - " voronoi_speed_direction.frame,\n", - " voronoi_speed_direction.speed,\n", + "plot_speed(\n", + " speed=voronoi_speed_direction,\n", " label=\"Voronoi direction\",\n", " color=PEDPY_GREY,\n", ")\n", - "plt.plot(\n", - " mean_speed.frame,\n", - " mean_speed.speed,\n", + "plot_speed(\n", + " speed=mean_speed,\n", " label=\"classic\",\n", " color=PEDPY_BLUE,\n", ")\n", - "plt.plot(\n", - " mean_speed_direction.frame,\n", - " mean_speed_direction.speed,\n", + "plot_speed(\n", + " speed=mean_speed_direction,\n", " label=\"classic direction\",\n", " color=PEDPY_RED,\n", ")\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"v / m/s\")\n", + "plt.title(\"Comparison of different speed methods\")\n", "plt.legend()\n", "plt.grid()\n", "plt.show()" @@ -2362,10 +2355,12 @@ }, "outputs": [], "source": [ - "from pedpy import plot_speed\n", - "from pedpy.column_identifier import SPEED_COL\n", + "from pedpy import plot_speed_at_line\n", "\n", - "plot_speed(speed=line_speed[SPEED_COL])\n", + "plot_speed_at_line(\n", + " speed_at_line=line_speed,\n", + " title=\"Speed at measurement line\",\n", + ")\n", "plt.show()" ] }, @@ -2503,9 +2498,9 @@ } }, "source": [ - "#### Flow at bottleneck\n", + "#### Flow at measurement line\n", "\n", - "From the N-t data we then can compute the flow at the bottleneck.\n", + "From the N-t data we then can compute the flow measured at a measurement line (inside the bottleneck).\n", "\n", "For the computation of the flow we look at frame intervals $\\Delta frame$ in which the flow is computed.\n", "The first intervals starts, when the first person crossed the {class}`measurement line `.\n", @@ -2588,9 +2583,9 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "from pedpy import plot_flow\n", + "from pedpy import plot_crossing_speed_flow\n", "\n", - "plot_flow(\n", + "plot_crossing_speed_flow(\n", " flow=flow,\n", " title=\"Crossing velocities at the corresponding flow at bottleneck\",\n", ")\n", @@ -2708,21 +2703,19 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "from pedpy import PEDPY_GREEN\n", + "from pedpy import PEDPY_GREEN, plot_acceleration\n", "\n", "ped_id = 50\n", "\n", "plt.figure()\n", - "plt.title(f\"Acceleration time-series of a pedestrian {ped_id} (border excluded)\")\n", + "title = f\"Acceleration time-series of a pedestrian {ped_id} (border excluded)\"\n", "single_individual_acceleration = individual_acceleration_exclude[individual_acceleration_exclude.id == ped_id]\n", - "plt.plot(\n", - " single_individual_acceleration.frame,\n", - " single_individual_acceleration.acceleration,\n", + "plot_acceleration(\n", + " acceleration=single_individual_acceleration,\n", " color=PEDPY_GREEN,\n", + " title=title,\n", ")\n", "\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"a / $m/s^2$\")\n", "plt.show()" ] }, @@ -2780,14 +2773,13 @@ "plt.title(\"Acceleration time-series of an excerpt of the pedestrians in a specific direction\")\n", "for color, ped_id in zip(colors, ped_ids, strict=False):\n", " single_individual_acceleration = individual_acceleration_direction[individual_acceleration_direction.id == ped_id]\n", - " plt.plot(\n", - " single_individual_acceleration.frame,\n", - " single_individual_acceleration.acceleration,\n", + " label = \"Ped ID \".format(ped_id)\n", + " plot_acceleration(\n", + " acceleration=single_individual_acceleration,\n", " color=color,\n", + " label=label,\n", " )\n", - "\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"a / $m/s^2$\")\n", + "plt.legend()\n", "plt.show()" ] }, @@ -2877,7 +2869,7 @@ "from pedpy import PEDPY_BLUE, plot_acceleration\n", "\n", "plot_acceleration(\n", - " acceleration=mean_acceleration.acceleration,\n", + " acceleration=mean_acceleration,\n", " title=\"Mean acceleration in front of the bottleneck\",\n", " color=PEDPY_BLUE,\n", ")\n", @@ -2919,7 +2911,7 @@ "from pedpy import PEDPY_RED, plot_acceleration\n", "\n", "plot_acceleration(\n", - " acceleration=mean_acceleration_direction.acceleration,\n", + " acceleration=mean_acceleration_direction,\n", " title=\"Mean acceleration in specific direction in front of the bottleneck\",\n", " color=PEDPY_RED,\n", ")\n", @@ -3016,7 +3008,7 @@ "from pedpy import PEDPY_ORANGE, plot_acceleration\n", "\n", "plot_acceleration(\n", - " acceleration=voronoi_acceleration.acceleration,\n", + " acceleration=voronoi_acceleration,\n", " title=\"Voronoi acceleration in front of the bottleneck\",\n", " color=PEDPY_ORANGE,\n", ")\n", @@ -3059,7 +3051,7 @@ "from pedpy import PEDPY_GREY, plot_acceleration\n", "\n", "plot_acceleration(\n", - " acceleration=voronoi_acceleration.acceleration,\n", + " acceleration=voronoi_acceleration,\n", " title=\"Voronoi acceleration in specific direction in front of the bottleneck\",\n", " color=PEDPY_GREY,\n", ")\n", @@ -3091,32 +3083,26 @@ "\n", "plt.figure(figsize=(8, 6))\n", "plt.title(\"Comparison of different acceleration methods\")\n", - "plt.plot(\n", - " voronoi_acceleration.frame,\n", - " voronoi_acceleration.acceleration,\n", + "plot_acceleration(\n", + " acceleration=voronoi_acceleration,\n", " label=\"Voronoi\",\n", " color=PEDPY_ORANGE,\n", ")\n", - "plt.plot(\n", - " voronoi_acceleration_direction.frame,\n", - " voronoi_acceleration_direction.acceleration,\n", + "plot_acceleration(\n", + " acceleration=voronoi_acceleration_direction,\n", " label=\"Voronoi direction\",\n", " color=PEDPY_GREY,\n", ")\n", - "plt.plot(\n", - " mean_acceleration.frame,\n", - " mean_acceleration.acceleration,\n", + "plot_acceleration(\n", + " acceleration=mean_acceleration,\n", " label=\"classic\",\n", " color=PEDPY_BLUE,\n", ")\n", - "plt.plot(\n", - " mean_acceleration_direction.frame,\n", - " mean_acceleration_direction.acceleration,\n", + "plot_acceleration(\n", + " acceleration=mean_acceleration_direction,\n", " label=\"classic direction\",\n", " color=PEDPY_RED,\n", ")\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"a / $m/s^2$\")\n", "plt.legend()\n", "plt.grid()\n", "plt.show()" @@ -3172,12 +3158,12 @@ }, "outputs": [], "source": [ - "from pedpy.column_identifier import FLOW_COL\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from pedpy import plot_flow_at_line\n", "\n", - "plt.plot(line_flow[FRAME_COL], line_flow[FLOW_COL])\n", - "plt.title(\"flow on line\")\n", - "plt.xlabel(\"frame\")\n", - "plt.ylabel(\"$J$\")\n", + "fig = plt.figure()\n", + "plot_flow_at_line(flow_at_line=line_flow, title=\"Flow at line\")\n", "plt.show()" ] }, diff --git a/pedpy/__init__.py b/pedpy/__init__.py index cba5c3d8..bcf484ea 100644 --- a/pedpy/__init__.py +++ b/pedpy/__init__.py @@ -132,10 +132,10 @@ PEDPY_PETROL, PEDPY_RED, plot_acceleration, + plot_crossing_speed_flow, plot_density, plot_density_at_line, plot_density_distribution, - plot_flow, plot_flow_at_line, plot_measurement_setup, plot_neighborhood, @@ -219,7 +219,7 @@ "plot_density", "plot_density_at_line", "plot_density_distribution", - "plot_flow", + "plot_crossing_speed_flow", "plot_flow_at_line", "plot_measurement_setup", "plot_neighborhood", diff --git a/pedpy/plotting/plotting.py b/pedpy/plotting/plotting.py index c254739c..1b0ff3e1 100644 --- a/pedpy/plotting/plotting.py +++ b/pedpy/plotting/plotting.py @@ -19,6 +19,7 @@ from numpy.typing import NDArray from pedpy.column_identifier import ( + ACC_COL, CUMULATED_COL, DENSITY_COL, DENSITY_SP1_COL, @@ -65,11 +66,9 @@ def _plot_polygon( polygon: shapely.Polygon, polygon_color: Any, polygon_alpha: float = 1, - line_color: Any = PEDPY_GREY, - line_width: float = 1, - hole_color: Any = "lightgrey", hole_alpha: float = 1, zorder: float = 1000, + **kwargs: Any, ) -> matplotlib.axes.Axes: """Plot the shapely polygon (including holes). @@ -79,13 +78,19 @@ def _plot_polygon( created polygon_color (Any): background color of the polygon polygon_alpha (float): alpha of the background for the polygon - line_color (Any): color of the borders - line_width (float): line width of the borders - hole_color (Any): background color of holes hole_alpha (float): alpha of background color for holes zorder (float): Specifies the drawing order of the polygon, lower values are drawn first + kwargs: Additional parameters to change the plot appearance, see + below for list of usable keywords + + Keyword Args: + line_color (optional, Any): color of the borders + line_width (optional, float): line width of the borders + hole_color (optional, Any): background color of holes + + Returns: matplotlib.axes.Axes instance where the polygon is plotted @@ -93,6 +98,10 @@ def _plot_polygon( # Plot the boundary of the polygon/holes separately to get the same color # as the outside as alpha modifies all colors + line_color = kwargs.pop("line_color", PEDPY_GREY) + line_width = kwargs.pop("line_width", 1) + hole_color = kwargs.pop("hole_color", "lightgrey") + # Plot the exterior of the polygon exterior_coords = list(polygon.exterior.coords) @@ -152,12 +161,13 @@ def _plot_series( # pylint: disable=too-many-arguments x: pd.Series, y: pd.Series, color: str, + line_width: float, x_label: str, y_label: str, **kwargs: Any, ) -> matplotlib.axes.Axes: axes.set_title(title) - axes.plot(x, y, color=color, **kwargs) + axes.plot(x, y, color=color, linewidth=line_width, **kwargs) axes.set_xlabel(x_label) axes.set_ylabel(y_label) return axes @@ -207,6 +217,12 @@ def plot_speed_at_line( label_species1 (optional): tag of species 1 in the legend label_species2 (optional): tag of species 2 in the legend label_total (optional): tag of total speed in the legend + line_width (optional): line width of the density timeseries + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis + x_axis (optional): chose whether the 'frame' (default) or 'time' is plotted on the x-axis + framerate (optional): give the framerate, when x-axis=='time' + Returns: matplotlib.axes.Axes instance where the speeds are plotted @@ -217,18 +233,35 @@ def plot_speed_at_line( color_sp1 = kwargs.get("color_species1", PEDPY_BLUE) color_sp2 = kwargs.get("color_species2", PEDPY_ORANGE) color_total = kwargs.get("color_total", PEDPY_GREEN) - title = kwargs.get("title", "Speed at Line") - x_label = kwargs.get("x_label", "Frame") + title = kwargs.get("title", "") + x_axis = kwargs.get("x_axis", "frame") y_label = kwargs.get("y_label", "v / m/s") - label_sp1 = kwargs.get("lable_species1", "species 1") - label_sp2 = kwargs.get("lable_species2", "species 2") - label_total = kwargs.get("lable_total", "total") - line_width = kwargs.get("line_width", 0.5) + label_sp1 = kwargs.get("label_species1", "species 1") + label_sp2 = kwargs.get("label_species2", "species 2") + label_total = kwargs.get("label_total", "total") + line_width = kwargs.get("line_width", 1.5) + + if x_axis == "time": + x_label = kwargs.pop("x_label", "time / $s$") + if TIME_COL in speed_at_line.columns: + x = speed_at_line[TIME_COL] + else: + framerate = kwargs.pop("framerate", 1) + if framerate == 1: + title = "Attention: no framerate was available to calculate time from frame!" + x = speed_at_line[FRAME_COL] + x_label = "frame" + else: + x = speed_at_line[FRAME_COL] / framerate + + else: + x_label = kwargs.pop("x_label", "frame") + x = speed_at_line[FRAME_COL] return _plot_multiple_series( axes=axes, title=title, - x=speed_at_line[FRAME_COL], + x=x, y_s=[ speed_at_line[SPEED_SP1_COL], speed_at_line[SPEED_SP2_COL], @@ -266,6 +299,11 @@ def plot_density_at_line( label_species1 (optional): tag of species 1 in the legend label_species2 (optional): tag of species 2 in the legend label_total (optional): tag of total speed in the legend + line_width (optional): line width of the density timeseries + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis + x_axis (optional): chose whether the 'frame' (default) or 'time' is plotted on the x-axis + framerate (optional): give the framerate, when x-axis=='time' Returns: matplotlib.axes.Axes instance where the densities are plotted @@ -276,18 +314,35 @@ def plot_density_at_line( color_sp1 = kwargs.get("color_species1", PEDPY_BLUE) color_sp2 = kwargs.get("color_species2", PEDPY_ORANGE) color_total = kwargs.get("color_total", PEDPY_GREEN) - title = kwargs.get("title", "Density at Line") - x_label = kwargs.get("x_label", "Frame") + title = kwargs.get("title", "") + x_axis = kwargs.pop("x_axis", "frame") y_label = kwargs.get("y_label", "$\\rho$ / 1/$m^2$") - label_sp1 = kwargs.get("lable_species1", "species 1") - label_sp2 = kwargs.get("lable_species2", "species 2") - label_total = kwargs.get("lable_total", "total") - line_width = kwargs.get("line_width", 0.5) + label_sp1 = kwargs.get("label_species1", "species 1") + label_sp2 = kwargs.get("label_species2", "species 2") + label_total = kwargs.get("label_total", "total") + line_width = kwargs.get("line_width", 1.5) + + if x_axis == "time": + x_label = kwargs.pop("x_label", "time / $s$") + if TIME_COL in density_at_line.columns: + x = density_at_line[TIME_COL] + else: + framerate = kwargs.pop("framerate", 1) + if framerate == 1: + title = "Attention: no framerate was available to calculate time from frame!" + x = density_at_line[FRAME_COL] + x_label = "frame" + else: + x = density_at_line[FRAME_COL] / framerate + + else: + x_label = kwargs.pop("x_label", "frame") + x = density_at_line[FRAME_COL] return _plot_multiple_series( axes=axes, title=title, - x=density_at_line[FRAME_COL], + x=x, y_s=[ density_at_line[DENSITY_SP1_COL], density_at_line[DENSITY_SP2_COL], @@ -325,6 +380,11 @@ def plot_flow_at_line( label_species1 (optional): tag of species 1 in the legend label_species2 (optional): tag of species 2 in the legend label_total (optional): tag of total speed in the legend + line_width (optional): line width of the density timeseries + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis + x_axis (optional): chose whether the 'frame' (default) or 'time' is plotted on the x-axis + framerate (optional): give the framerate, when x-axis=='time' Returns: matplotlib.axes.Axes instance where the profiles are plotted @@ -335,18 +395,35 @@ def plot_flow_at_line( color_sp1 = kwargs.get("color_species1", PEDPY_BLUE) color_sp2 = kwargs.get("color_species2", PEDPY_ORANGE) color_total = kwargs.get("color_total", PEDPY_GREEN) - title = kwargs.get("title", "Flow at Line") - x_label = kwargs.get("x_label", "Frame") + title = kwargs.get("title", "") + x_axis = kwargs.pop("x_axis", "frame") y_label = kwargs.get("y_label", "J / 1/s") label_sp1 = kwargs.get("lable_species1", "species 1") label_sp2 = kwargs.get("lable_species2", "species 2") label_total = kwargs.get("lable_total", "total") - line_width = kwargs.get("line_width", 0.5) + line_width = kwargs.get("line_width", 1.5) + + if x_axis == "time": + x_label = kwargs.pop("x_label", "time / $s$") + if TIME_COL in flow_at_line.columns: + x = flow_at_line[TIME_COL] + else: + framerate = kwargs.pop("framerate", 1) + if framerate == 1: + title = "Attention: no framerate was available to calculate time from frame!" + x = flow_at_line[FRAME_COL] + x_label = "frame" + else: + x = flow_at_line[FRAME_COL] / framerate + + else: + x_label = kwargs.pop("x_label", "frame") + x = flow_at_line[FRAME_COL] return _plot_multiple_series( axes=axes, title=title, - x=flow_at_line[FRAME_COL], + x=x, y_s=[ flow_at_line[FLOW_SP1_COL], flow_at_line[FLOW_SP2_COL], @@ -366,7 +443,7 @@ def plot_nt( axes: Optional[matplotlib.axes.Axes] = None, **kwargs: Any, ) -> matplotlib.axes.Axes: - """Plot the number of pedestrians over time. + """Plot the number of pedestrians crossing a line over time. Args: nt (pd.DataFrame): cumulative number of pedestrians over time @@ -378,6 +455,7 @@ def plot_nt( Keyword Args: color (optional): color of the plot title (optional): title of the plot + line_width (optional): line width of the N-t diagram x_label (optional): label on the x-axis y_label (optional): label on the y-axis @@ -388,18 +466,17 @@ def plot_nt( axes = plt.gca() color = kwargs.pop("color", PEDPY_BLUE) - title = kwargs.pop("title", "N-t") + title = kwargs.pop("title", "") + line_width = kwargs.pop("line_width", 1.5) x_label = kwargs.pop("x_label", "t / s") - y_label = kwargs.pop( - "y_label", - r"\# pedestrians" if plt.rcParams["text.usetex"] else "# pedestrians", - ) + y_label = kwargs.pop("y_label", "cumulative pedestrians") return _plot_series( axes=axes, title=title, x=nt[TIME_COL], y=nt[CUMULATED_COL], color=color, + line_width=line_width, x_label=x_label, y_label=y_label, **kwargs, @@ -424,6 +501,9 @@ def plot_density( Keyword Args: color (optional): color of the plot title (optional): title of the plot + x_axis (optional): chose whether the 'frame' (default) or 'time' is plotted on the x-axis + framerate (optional): give the framerate, when x-axis=='time' + line_width (optional): line width of the density timeseries x_label (optional): label on the x-axis y_label (optional): label on the y-axis @@ -434,16 +514,35 @@ def plot_density( axes = plt.gca() color = kwargs.pop("color", PEDPY_BLUE) - title = kwargs.pop("title", "density over time") - x_label = kwargs.pop("x_label", "frame") + line_width = kwargs.pop("line_width", 1.5) + title = kwargs.pop("title", "") + x_axis = kwargs.pop("x_axis", "frame") y_label = kwargs.pop("y_label", "$\\rho$ / 1/$m^2$") + if x_axis == "time": + x_label = kwargs.pop("x_label", "time / $s$") + if TIME_COL in density.columns: + x = density[TIME_COL] + else: + framerate = kwargs.pop("framerate", 1) + if framerate == 1: + title = "Attention: no framerate was available to calculate time from frame!" + x = density[FRAME_COL] + x_label = "frame" + else: + x = density[FRAME_COL] / framerate + + else: + x_label = kwargs.pop("x_label", "frame") + x = density[FRAME_COL] + return _plot_series( axes=axes, title=title, - x=density.index, + x=x, y=density[DENSITY_COL], color=color, + line_width=line_width, x_label=x_label, y_label=y_label, **kwargs, @@ -452,7 +551,7 @@ def plot_density( def plot_speed( *, - speed: pd.Series, + speed: pd.DataFrame, axes: Optional[matplotlib.axes.Axes] = None, **kwargs: Any, ) -> matplotlib.axes.Axes: @@ -467,7 +566,10 @@ def plot_speed( Keyword Args: color (optional): color of the plot + line_width (optional): line width of the speed timeseries title (optional): title of the plot + x_axis (optional): chose whether the 'frame' (default) or 'time' is plotted on the x-axis + framerate (optional): give the framerate, when x-axis=='time' x_label (optional): label on the x-axis y_label (optional): label on the y-axis @@ -478,16 +580,35 @@ def plot_speed( axes = plt.gca() color = kwargs.pop("color", PEDPY_BLUE) - title = kwargs.pop("title", "speed over time") - x_label = kwargs.pop("x_label", "frame") + line_width = kwargs.pop("line_width", 1.5) + title = kwargs.pop("title", "") + x_axis = kwargs.pop("x_axis", "frame") y_label = kwargs.pop("y_label", "v / m/s") + if x_axis == "time": + x_label = kwargs.pop("x_label", "time / $s$") + if TIME_COL in speed.columns: + x = speed[TIME_COL] + else: + framerate = kwargs.pop("framerate", 1) + if framerate == 1: + title = "Attention: no framerate was available to calculate time from frame!" + x = speed[FRAME_COL] + x_label = "frame" + else: + x = speed[FRAME_COL] / framerate + + else: + x_label = kwargs.pop("x_label", "frame") + x = speed[FRAME_COL] + return _plot_series( axes=axes, title=title, - x=speed.index, - y=speed, + x=x, + y=speed[SPEED_COL], color=color, + line_width=line_width, x_label=x_label, y_label=y_label, **kwargs, @@ -593,13 +714,13 @@ def plot_density_distribution( return _plot_violin_xy(data=density.density, axes=axes, **kwargs) -def plot_flow( +def plot_crossing_speed_flow( *, flow: pd.DataFrame, axes: Optional[matplotlib.axes.Axes] = None, **kwargs: Any, ) -> matplotlib.axes.Axes: - """Plot the flow. + """Plot the relationship of mean speed and flow while crossing a measurement line. Args: flow(pd.DataFrame): flow for some given crossing_frames and nt @@ -613,6 +734,8 @@ def plot_flow( title (optional): title of the plot x_label (optional): label on the x-axis y_label (optional): label on the y-axis + marker (optional): Markerstyle + marker_size (optional): Size of the markers Returns: matplotlib.axes.Axes instance where the flow is plotted @@ -621,11 +744,13 @@ def plot_flow( axes = plt.gca() color = kwargs.pop("color", PEDPY_BLUE) - title = kwargs.pop("title", "flow") + title = kwargs.pop("title", "") x_label = kwargs.pop("x_label", "J / 1/s") y_label = kwargs.pop("y_label", "v / m/s") + marker = kwargs.get("marker", "o") + marker_size = kwargs.get("marker_size", 16) axes.set_title(title) - axes.scatter(flow[FLOW_COL], flow[MEAN_SPEED_COL], color=color, **kwargs) + axes.scatter(flow[FLOW_COL], flow[MEAN_SPEED_COL], color=color, s=marker_size, marker=marker, **kwargs) axes.set_xlabel(x_label) axes.set_ylabel(y_label) return axes @@ -633,7 +758,7 @@ def plot_flow( def plot_acceleration( *, - acceleration: pd.Series, + acceleration: pd.DataFrame, axes: Optional[matplotlib.axes.Axes] = None, **kwargs: Any, ) -> matplotlib.axes.Axes: @@ -648,7 +773,10 @@ def plot_acceleration( Keyword Args: color (optional): color of the plot + line_width (optional): line width of the acceleration time series title (optional): title of the plot + x_axis (optional): chose whether the 'frame' (default) or 'time' is plotted on the x-axis + framerate (optional): give the framerate, when x-axis=='time' x_label (optional): label on the x-axis y_label (optional): label on the y-axis @@ -659,16 +787,35 @@ def plot_acceleration( axes = plt.gca() color = kwargs.pop("color", PEDPY_BLUE) - title = kwargs.pop("title", "acceleration over time") - x_label = kwargs.pop("x_label", "frame") + line_width = kwargs.pop("line_width", 1.5) + title = kwargs.pop("title", "") + x_axis = kwargs.pop("x_axis", "frame") y_label = kwargs.pop("y_label", "a / $m/s^2$") + if x_axis == "time": + x_label = kwargs.pop("x_label", "time / $s$") + if TIME_COL in acceleration.columns: + x = acceleration[TIME_COL] + else: + framerate = kwargs.pop("framerate", 1) + if framerate == 1: + title = "Attention: no framerate was available to calculate time from frame!" + x = acceleration[FRAME_COL] + x_label = "frame" + else: + x = acceleration[FRAME_COL] / framerate + + else: + x_label = kwargs.pop("x_label", "frame") + x = acceleration[FRAME_COL] + return _plot_series( axes=axes, title=title, - x=acceleration.index, - y=acceleration, + x=x, + y=acceleration[ACC_COL], color=color, + line_width=line_width, x_label=x_label, y_label=y_label, **kwargs, @@ -714,10 +861,14 @@ def plot_neighborhood( default_color (optional): color of default pedestrians, which are not neighbors of the base pedestrian default_alpha (optional): alpha of the default pedestrians - line_color (optional): color of the borders - line_width (optional): line width of the borders + border_line_color (optional): color of the borders + border_line_width (optional): line width of the borders hole_color (optional): background color of holes hole_alpha (optional): alpha of background color for holes + title (optional): title of the plot + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis + Returns: matplotlib.axes.Axes: instances where the neighborhood is plotted @@ -778,10 +929,13 @@ def _plot_neighborhood( default_color (optional): color of default pedestrians, which are not neighbors of the base pedestrian default_alpha (optional): alpha of the default pedestrians - line_color (optional): color of the borders - line_width (optional): line width of the borders + border_line_color (optional): color of the borders + border_line_width (optional): line width of the borders hole_color (optional): background color of holes hole_alpha (optional): alpha of background color for holes + title (optional): title of the plot + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis Returns: matplotlib.axes.Axes: instances where the neighborhood is plotted @@ -794,6 +948,9 @@ def _plot_neighborhood( default_color = to_rgb(kwargs.pop("default_color", PEDPY_GREY)) default_alpha = kwargs.pop("default_alpha", 0.2) + x_label = kwargs.pop("x_label", r"x / m") + y_label = kwargs.pop("y_label", r"y / m") + # Filter voronoi_data for polygons in the same frame voronoi_neighbors = voronoi_data[voronoi_data[FRAME_COL] == frame] @@ -815,7 +972,6 @@ def _plot_neighborhood( # Set up the plot if axes is None: axes = plt.gca() - axes.set_title(f"Neighbors of pedestrian {pedestrian_id}") # Plot the walkable area if walkable_area is not None: @@ -850,6 +1006,11 @@ def _plot_neighborhood( # Set aspect ratio axes.set_aspect("equal") + title = kwargs.pop("title", "Neighbors of pedestrian {}".format(pedestrian_id)) + axes.set_title(title) + axes.set_xlabel(x_label) + axes.set_ylabel(y_label) + return axes @@ -868,7 +1029,7 @@ def plot_time_distance( # noqa: PLR0915 Args: time_distance (pd.DataFrame): DataFrame containing information on time and distance to some target - speed (pd.DataFrame): DataFrame containing speed calculation. + speed (pd.DataFrame, optional): DataFrame containing speed calculation. axes (matplotlib.axes.Axes): Axes to plot on, if None new will be created kwargs: Additional parameters to change the plot appearance, see @@ -876,7 +1037,11 @@ def plot_time_distance( # noqa: PLR0915 Keyword Args: marker_color (optional): color of the markers on the plot + marker_size (optional): size of the markers + marker (optional): type of the markers line_color (optional): color of the lines on the plot + line_width (optional): width of the line sof the plot + line_alpha (optional): alpha value of the plotted lines title (optional): title of the plot x_label (optional): label on the x-axis y_label (optional): label on the y-axis @@ -893,7 +1058,7 @@ def _setup_plot(axes: matplotlib.axes.Axes, **kwargs: Any) -> None: **kwargs: Keyword arguments containing 'title', 'x_label' and 'y_label'. """ - title = kwargs.get("title", "Distance Plot") + title = kwargs.get("title", "") x_label = kwargs.get("x_label", "Distance / m") y_label = kwargs.get("y_label", "Time / s") @@ -905,6 +1070,8 @@ def _scatter_min_data( axes: matplotlib.axes.Axes, ped_data: pd.DataFrame, color: str, + marker_size: float, + marker: str, ) -> None: """Adds a scatter plot marker at the start of a pedestrian's line. @@ -912,20 +1079,24 @@ def _scatter_min_data( axes: The matplotlib axes to plot on. ped_data: DataFrame containing pedestrian data. color: Color of the scatter plot marker. + marker_size: Size of the markers. + marker: Type of marker. """ min_data = ped_data.loc[ped_data.groupby(ID_COL)[FRAME_COL].idxmin()] axes.scatter( min_data.distance, min_data.time, color=color, - s=5, - marker="o", + s=marker_size, + marker=marker, ) def _scatter_min_data_with_color( axes: matplotlib.axes.Axes, ped_data: pd.DataFrame, norm: Normalize, + marker_size: float, + marker: str, ) -> None: """Adds a scatter plot marker at the start of a pedestrian's line. @@ -936,6 +1107,8 @@ def _scatter_min_data_with_color( cmap: The colormap to use for coloring the line based on speed. frame_rate: Frame rate used to adjust time values. color: Color of the scatter plot marker. + marker_size: Size of the markers. + marker: Type of marker. """ min_data = ped_data.loc[ped_data.groupby(ID_COL)[FRAME_COL].idxmin()] axes.scatter( @@ -944,14 +1117,16 @@ def _scatter_min_data_with_color( c=min_data.speed, cmap="jet", norm=norm, - s=5, - marker="o", + s=marker_size, + marker=marker, ) def _plot_line( axes: matplotlib.axes.Axes, ped_data: pd.DataFrame, color: str, + line_width: float, + line_alpha: float, ) -> None: """Plots a line for a single pedestrian's data. @@ -960,19 +1135,23 @@ def _plot_line( ped_data: DataFrame containing a single pedestrian's distance and time data. color: Color of the line. + line_width: Width of the line. + line_alpha: Alpha of the lines. """ axes.plot( ped_data.distance, ped_data.time, color=color, - alpha=0.7, - lw=0.25, + alpha=line_alpha, + lw=line_width, ) def _plot_colored_line( axes: matplotlib.axes.Axes, ped_data: pd.DataFrame, norm: Normalize, + line_width: float, + line_alpha: float, ) -> None: """Plots a line for a single pedestrian's data. @@ -985,6 +1164,8 @@ def _plot_colored_line( data. norm: Normalization for the colormap based on speed. cmap: The colormap to use for coloring the line based on speed. + line_width: Width of the lines. + line_alpha: Alpha of the lines. """ points = ped_data[["distance", "time"]].to_numpy() speed_id = ped_data.speed.to_numpy() @@ -995,9 +1176,9 @@ def _plot_colored_line( ] for i in range(len(points) - 1) ] - line_collection = LineCollection(segments, cmap="jet", alpha=0.7, norm=norm) + line_collection = LineCollection(segments, cmap="jet", alpha=line_alpha, norm=norm) line_collection.set_array(speed_id) - line_collection.set_linewidth(0.5) + line_collection.set_linewidth(line_width) axes.add_collection(line_collection) def _add_colorbar(axes: matplotlib.axes.Axes, norm: Normalize) -> None: @@ -1031,6 +1212,7 @@ def _plot_with_speed_colors( axes: matplotlib.axes.Axes, time_distance: pd.DataFrame, speed: pd.DataFrame, + **kwargs: Any, ) -> None: """Plots pedestrian data with lines colored according to speed. @@ -1039,14 +1221,19 @@ def _plot_with_speed_colors( time_distance: DataFrame containing the pedestrian data. speed: DataFrame containing speed calculations. frame_rate: Frame rate used to adjust time values. + **kwargs: Additional customization options (line_width, line_alpha, marker_size, marker). """ + line_width = kwargs.pop("line_width", 0.5) + line_alpha = kwargs.pop("line_alpha", 0.7) + marker_size = kwargs.pop("marker_size", 5) + marker = kwargs.pop("marker", "o") time_distance = time_distance.merge(speed, on=[ID_COL, FRAME_COL]) norm = Normalize(vmin=time_distance.speed.min(), vmax=time_distance.speed.max()) for _, ped_data in time_distance.groupby(ID_COL): - _plot_colored_line(axes, ped_data, norm) + _plot_colored_line(axes, ped_data, norm, line_width, line_alpha) - _scatter_min_data_with_color(axes, time_distance, norm) + _scatter_min_data_with_color(axes, time_distance, norm, marker_size, marker) _add_colorbar(axes, norm) def _plot_without_colors( @@ -1060,19 +1247,23 @@ def _plot_without_colors( axes: The matplotlib axes to plot on. time_distance: DataFrame containing the pedestrian data. frame_rate: Frame rate used to adjust time values. - **kwargs: Additional customization options (line_color, marker_color). + **kwargs: Additional customization options (line_color, line_width, marker_color, marker_size, marker). """ line_color = kwargs.pop("line_color", PEDPY_GREY) + line_width = kwargs.pop("line_width", 0.5) + line_alpha = kwargs.pop("line_alpha", 0.7) marker_color = kwargs.pop("marker_color", PEDPY_GREY) + marker_size = kwargs.pop("marker_size", 5) + marker = kwargs.pop("marker", "o") for _, ped_data in time_distance.groupby(ID_COL): - _plot_line(axes, ped_data, line_color) + _plot_line(axes, ped_data, line_color, line_width, line_alpha) - _scatter_min_data(axes, time_distance, marker_color) + _scatter_min_data(axes, time_distance, marker_color, marker_size, marker) axes = axes or plt.gca() _setup_plot(axes, **kwargs) if speed is not None: - _plot_with_speed_colors(axes, time_distance, speed) + _plot_with_speed_colors(axes, time_distance, speed, **kwargs) else: _plot_without_colors(axes, time_distance, **kwargs) @@ -1104,6 +1295,8 @@ def plot_profiles( Keyword Args: title (optional): title of the plot + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis walkable_color (optional): color of the walkable area in the plot hole_color (optional): background color of holes hole_alpha (optional): alpha of background color for holes @@ -1173,10 +1366,14 @@ def plot_walkable_area( below for list of usable keywords Keyword Args: - line_color (optional): color of the borders - line_width (optional): line width of the borders + border_line_color (optional): color of the lines of the borders + border_line_width (optional): line width of the borders hole_color (optional): background color of holes hole_alpha (optional): alpha of background color for holes + title (optional): title of the plot + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis + Returns: matplotlib.axes.Axes instance where the walkable area is plotted @@ -1184,24 +1381,29 @@ def plot_walkable_area( if axes is None: axes = plt.gca() - line_color = kwargs.pop("line_color", PEDPY_GREY) - line_width = kwargs.pop("line_width", 1.0) + border_line_color = kwargs.pop("border_line_color", PEDPY_GREY) + border_line_width = kwargs.pop("border_line_width", 1.0) hole_color = kwargs.pop("hole_color", "lightgrey") hole_alpha = kwargs.pop("hole_alpha", 1.0) + title = kwargs.pop("title", "") + x_label = kwargs.pop("x_label", r"x / m") + y_label = kwargs.pop("y_label", r"y / m") + axes = _plot_polygon( polygon=walkable_area.polygon, polygon_color="none", - line_color=line_color, - line_width=line_width, + line_color=border_line_color, + line_width=border_line_width, hole_color=hole_color, hole_alpha=hole_alpha, axes=axes, ) - axes.set_xlabel(r"x/m") - axes.set_ylabel(r"y/m") + axes.set_title(title) + axes.set_xlabel(x_label) + axes.set_ylabel(y_label) axes.autoscale_view() @@ -1232,10 +1434,14 @@ def plot_trajectories( traj_start_marker (optional): marker to indicate the start of the trajectory traj_end_marker (optional): marker to indicate the end of the trajectory - line_color (optional): color of the borders - line_width (optional): line width of the borders + border_line_color (optional): color of the borders + border_line_width (optional): line width of the borders hole_color (optional): background color of holes hole_alpha (optional): alpha of background color for holes + title (optional): title of the plot + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis + Returns: matplotlib.axes.Axes instance where the trajectories are plotted @@ -1247,6 +1453,10 @@ def plot_trajectories( traj_start_marker = kwargs.pop("traj_start_marker", "") traj_end_marker = kwargs.pop("traj_end_marker", "") + title = kwargs.pop("title", "") + x_label = kwargs.pop("x_label", r"x / m") + y_label = kwargs.pop("y_label", r"y / m") + if axes is None: axes = plt.gca() @@ -1274,8 +1484,9 @@ def plot_trajectories( marker=traj_end_marker, ) - axes.set_xlabel(r"x/m") - axes.set_ylabel(r"y/m") + axes.set_title(title) + axes.set_xlabel(x_label) + axes.set_ylabel(y_label) return axes @@ -1317,10 +1528,13 @@ def plot_measurement_setup( trajectory traj_end_marker (optional): marker to indicate the end of the trajectory - line_color (optional): color of the borders - line_width (optional): line width of the borders - hole_color (optional): background color of holes - hole_alpha (optional): alpha of background color for holes + border_line_color (optional): color of the lines of the borders + border_line_width (optional): line width of the lines of the borders + hole_color (optional): background color of holes/geometries + hole_alpha (optional): alpha of background color for holes/geometries + title (optional): title of the plot + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis Returns: matplotlib.axes.Axes instance where the measurement setup is plotted @@ -1333,6 +1547,10 @@ def plot_measurement_setup( ml_color = kwargs.pop("ml_color", PEDPY_BLUE) ml_width = kwargs.pop("ml_width", 1.0) + title = kwargs.pop("title", "") + x_label = kwargs.pop("x_label", r"x / m") + y_label = kwargs.pop("y_label", r"y / m") + if axes is None: axes = plt.gca() @@ -1357,8 +1575,9 @@ def plot_measurement_setup( for measurement_line in measurement_lines: axes.plot(*measurement_line.xy, color=ml_color, linewidth=ml_width) - axes.set_xlabel(r"x / m") - axes.set_ylabel(r"y / m") + axes.set_title(title) + axes.set_xlabel(x_label) + axes.set_ylabel(y_label) return axes @@ -1390,22 +1609,29 @@ def plot_voronoi_cells( # noqa: PLR0912,PLR0915 below for list of usable keywords Keyword Args: + title (optional): title of the plot + x_label (optional): label on the x-axis + y_label (optional): label on the y-axis ped_color (optional): color used to display current ped positions + ped_size (optional): size of the marker of the current ped positions voronoi_border_color (optional): border color of Voronoi cells + voronoi_border_width (optional): border width of the Voronoi cells voronoi_inside_ma_alpha (optional): alpha of part of Voronoi cell inside the measurement area, data needs to contain column "intersection"! voronoi_outside_ma_alpha (optional): alpha of part of Voronoi cell outside the measurement area - color_by_column (str, optional): Optioanlly provide a column name to + color_by_column (str, optional): Optionally provide a column name to specify the data to color the cell. Only supports Integer and Float data types. E.g. color_by_column `DENSITY_COL` vmin (optional): vmin of colormap, only used when color_mode != "id" vmax (optional): vmax of colormap, only used when color_mode != "id" + cmap (optional): colormap used for show_colorbar (optional): colorbar is displayed, only used when color_mode != "id" cb_location (optional): location of the colorbar, only used when color_mode != "id" + cb_label (optional): label of colorbar ma_line_color (optional): color of the measurement areas borders ma_line_width (optional): line width of the measurement areas borders ma_color (optional): fill color of the measurement areas @@ -1416,13 +1642,18 @@ def plot_voronoi_cells( # noqa: PLR0912,PLR0915 line_width (optional): line width of the borders hole_color (optional): background color of holes hole_alpha (optional): alpha of background color for holes - cmap (optional): colormap used for + Returns: matplotlib.axes.Axes instance where the Voronoi cells are plotted """ + title = kwargs.pop("title", "") + x_label = kwargs.pop("x_label", r"x / m") + y_label = kwargs.pop("y_label", r"y / m") + ped_color = kwargs.pop("ped_color", PEDPY_BLUE) ped_size = kwargs.pop("ped_size", 5) voronoi_border_color = kwargs.pop("voronoi_border_color", PEDPY_BLUE) + voronoi_border_width = kwargs.pop("voronoi_border_width", 1) voronoi_inside_ma_alpha = kwargs.pop("voronoi_inside_ma_alpha", 1) voronoi_outside_ma_alpha = kwargs.pop("voronoi_outside_ma_alpha", 1) @@ -1430,6 +1661,7 @@ def plot_voronoi_cells( # noqa: PLR0912,PLR0915 vmax = kwargs.pop("vmax", None) cb_location = kwargs.pop("cb_location", "right") show_colorbar = kwargs.pop("show_colorbar", True) + cb_label = kwargs.pop("cb_label", None) color_by_column = kwargs.pop("color_by_column", None) voronoi_colormap = plt.get_cmap(kwargs.pop("cmap", "YlGn")) @@ -1485,6 +1717,7 @@ def inverse(values): axes=axes, polygon=poly, line_color=voronoi_border_color, + line_width=voronoi_border_width, polygon_color=color, polygon_alpha=voronoi_outside_ma_alpha, zorder=1, @@ -1505,15 +1738,20 @@ def inverse(values): if traj_data: axes.scatter(row[X_COL], row[Y_COL], color=ped_color, s=ped_size) - if show_colorbar and color_by_column and typ == "float64": - if color_by_column == DENSITY_COL: - label = "$\\rho$ / $\\frac{1}{m^2}$" - elif color_by_column == SPEED_COL: - label = r"v / $\frac{m}{s}$" - elif color_by_column == ID_COL: - label = "Id" - else: - label = "" + if show_colorbar: + if color_by_column and typ == "float64": + if color_by_column == DENSITY_COL: + label = "$\\rho$ / $\\frac{1}{m^2}$" + elif color_by_column == SPEED_COL: + label = r"v / $\frac{m}{s}$" + elif color_by_column == ID_COL: + label = "Id" + else: + label = " " + + if cb_label is not None: + label = cb_label + plt.colorbar( scalar_mappable, ax=axes, @@ -1524,6 +1762,7 @@ def inverse(values): if walkable_area is not None: plot_walkable_area(axes=axes, walkable_area=walkable_area, **kwargs) - axes.set_xlabel(r"x / m") - axes.set_ylabel(r"y / m") + axes.set_title(title) + axes.set_xlabel(x_label) + axes.set_ylabel(y_label) return axes