Skip to content

Commit

Permalink
enh: split active events per vehicle type
Browse files Browse the repository at this point in the history
  • Loading branch information
munterfi committed Oct 8, 2024
1 parent 4c98242 commit 5f994f7
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 40 deletions.
11 changes: 7 additions & 4 deletions rssched/app/pages/02_Fleet.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

from rssched.app.utils.io import get_uploaded_data
from rssched.app.utils.transform import get_vehicle_types
from rssched.visualization.active_events import plot_active_events_over_time
from rssched.visualization.fleet_efficiency import plot_fleet_efficiency
from rssched.visualization.active_events import plot_active_events_per_vehicle_type
from rssched.visualization.fleet_efficiency import (
plot_fleet_efficiency_per_vehicle_type,
)
from rssched.visualization.vehicle_type_gantt import plot_gantt_per_vehicle_type
from rssched.visualization.vehicle_utilization import plot_utilization_per_vehicle_type

Expand All @@ -26,12 +28,13 @@
st.plotly_chart(plots[selected_vehicle_type])

with tabs[1]:
st.plotly_chart(plot_active_events_over_time(response, instance_name))
plots = plot_active_events_per_vehicle_type(response, instance_name)
st.plotly_chart(plots[selected_vehicle_type])

with tabs[2]:
plots = plot_utilization_per_vehicle_type(response, instance_name)
st.plotly_chart(plots[selected_vehicle_type])

with tabs[3]:
plots = plot_fleet_efficiency(response, instance_name)
plots = plot_fleet_efficiency_per_vehicle_type(response, instance_name)
st.plotly_chart(plots[selected_vehicle_type])
72 changes: 42 additions & 30 deletions rssched/visualization/active_events.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

from rssched.model.response import Response
from rssched.visualization.colors import EVENT_TYPES


def plot_active_events_over_time(response: Response, instance_name: str):
def plot_active_events_per_vehicle_type(
response: Response, instance_name: str
) -> dict[str, go.Figure]:
events = []
for fleet in response.schedule.fleet:
for vehicle in fleet.vehicles:
Expand All @@ -15,6 +18,7 @@ def plot_active_events_over_time(response: Response, instance_name: str):
"Start": segment.departure,
"End": segment.arrival,
"Type": "ServiceTrip",
"Vehicle Type": fleet.vehicle_type,
}
)
for slot in vehicle.maintenance_slots:
Expand All @@ -23,6 +27,7 @@ def plot_active_events_over_time(response: Response, instance_name: str):
"Start": slot.start,
"End": slot.end,
"Type": "MaintenanceSlot",
"Vehicle Type": fleet.vehicle_type,
}
)
for trip in vehicle.dead_head_trips:
Expand All @@ -31,39 +36,46 @@ def plot_active_events_over_time(response: Response, instance_name: str):
"Start": trip.departure,
"End": trip.arrival,
"Type": "DeadHeadTrip",
"Vehicle Type": fleet.vehicle_type,
}
)

df = pd.DataFrame(events)
min_time = df["Start"].min().floor("15min")
max_time = df["End"].max().ceil("15min")
time_range = pd.date_range(min_time, max_time, freq="15min")
df_count = pd.DataFrame(
0,
index=time_range,
columns=["ServiceTrip", "MaintenanceSlot", "DeadHeadTrip"],
)
figures = {}

for interval in time_range:
for _, event in df.iterrows():
if event["Start"] <= interval < event["End"]:
df_count.at[interval, event["Type"]] += 1
for vehicle_type, group in df.groupby("Vehicle Type"):
min_time = group["Start"].min().floor("15min")
max_time = group["End"].max().ceil("15min")
time_range = pd.date_range(min_time, max_time, freq="15min")
df_count = pd.DataFrame(
0,
index=time_range,
columns=["ServiceTrip", "MaintenanceSlot", "DeadHeadTrip"],
)

df_count.reset_index(inplace=True)
df_count.rename(columns={"index": "Time"}, inplace=True)
df_melted = df_count.melt(
id_vars=["Time"], var_name="Event Type", value_name="Active Count"
)
for interval in time_range:
for _, event in group.iterrows():
if event["Start"] <= interval < event["End"]:
df_count.at[interval, event["Type"]] += 1

fig = px.line(
df_melted,
x="Time",
y="Active Count",
color="Event Type",
title=f"Active Events Over Time (instance: {instance_name})",
color_discrete_map=EVENT_TYPES,
)
fig.update_layout(hovermode="x", hoverdistance=50)
fig.update_xaxes(title_text="Time", tickformat="%Y-%m-%d %H:%M")
fig.update_yaxes(title_text="Number of Active Events")
return fig
df_count.reset_index(inplace=True)
df_count.rename(columns={"index": "Time"}, inplace=True)
df_melted = df_count.melt(
id_vars=["Time"], var_name="Event Type", value_name="Active Count"
)

fig = px.line(
df_melted,
x="Time",
y="Active Count",
color="Event Type",
title=f"Active Events '{vehicle_type}' (instance: {instance_name})",
color_discrete_map=EVENT_TYPES,
)
fig.update_layout(hovermode="x", hoverdistance=50)
fig.update_xaxes(title_text="Time", tickformat="%Y-%m-%d %H:%M")
fig.update_yaxes(title_text="Number of Active Events")

figures[vehicle_type] = fig

return figures
2 changes: 1 addition & 1 deletion rssched/visualization/fleet_efficiency.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def summarize_vehicle_activities(response):
return df_activities


def plot_fleet_efficiency(
def plot_fleet_efficiency_per_vehicle_type(
response: Response, instance_name: str
) -> dict[str, go.Figure]:
df = summarize_vehicle_activities(response)
Expand Down
16 changes: 11 additions & 5 deletions rssched/visualization/plot.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
from rssched.model.response import Response
from rssched.visualization.active_events import plot_active_events_over_time
from rssched.visualization.fleet_efficiency import plot_fleet_efficiency
from rssched.visualization.active_events import plot_active_events_per_vehicle_type
from rssched.visualization.fleet_efficiency import (
plot_fleet_efficiency_per_vehicle_type,
)
from rssched.visualization.vehicle_type_gantt import plot_gantt_per_vehicle_type
from rssched.visualization.vehicle_utilization import plot_utilization_per_vehicle_type


def generate_plots(response: Response, instance_name: str):
figures = list(plot_gantt_per_vehicle_type(response, instance_name).values())
figures.append(plot_active_events_over_time(response, instance_name))
figures.append(
figures.extend(
list(plot_active_events_per_vehicle_type(response, instance_name).values())
)
figures.extend(
list(plot_utilization_per_vehicle_type(response, instance_name).values())
)
figures.extend(list(plot_fleet_efficiency(response, instance_name).values()))
figures.extend(
list(plot_fleet_efficiency_per_vehicle_type(response, instance_name).values())
)
return figures

0 comments on commit 5f994f7

Please sign in to comment.