File size: 6,245 Bytes
361a989 154c09f 361a989 154c09f 361a989 33509eb 154c09f 33509eb 1ee2ec7 33509eb 154c09f 361a989 154c09f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | from pathlib import Path
import pandas as pd
import geopandas as gpd
import faicons as fa
from shiny import ui
from shared import app_dir
import matplotlib.pyplot as plt
import numpy as np
#app_dir = Path(__file__).parent
#tips = pd.read_csv(app_dir / "tips.csv")
def load_data():
"""
Load zones shapefile and trips data.
Returns:
zones (GeoDataFrame): GeoDataFrame of zones.
trips (DataFrame): DataFrame of trip data.
"""
zones = gpd.read_file(app_dir / "data" / "zone" / "Napa_TBS_2024_Zone_System.shp") # Replace with your shapefile path
zones = zones[zones.is_valid & ~zones.is_empty]
zones = zones[["FPID", "geometry"]] # Keep only essential columns
zones["geometry"] = zones["geometry"].simplify(0.001, preserve_topology=True) # Simplify geometries
#trips = pd.read_csv(app_dir / "data" / "od_table.csv") # Replace with your trip data path
trips = pd.read_parquet(app_dir / "data" / "od_table.parquet") # Replace with your trip data path
return zones, trips
def load_excel_data(SHEET_NAME):
"""
Load data tables from Excel
Returns:
data (DataFrame): DataFrame of data table.
"""
EXCEL_FILE = app_dir / "data" / "trips_data.xlsx" # Update with your file path
data = pd.read_excel(EXCEL_FILE, sheet_name=SHEET_NAME)
return data
def filter_trips(trips, zones, origin_filter, destination_filter):
"""
Filter trips based on selected origin or destination.
Args:
trips (DataFrame): Trip data with origin and destination zones.
zones (GeoDataFrame): GeoDataFrame of zones.
origin_filter (str): Selected origin zone ID.
destination_filter (str): Selected destination zone ID.
Returns:
filtered_origins (GeoDataFrame): Filtered origin zones with trip counts.
filtered_destinations (GeoDataFrame): Filtered destination zones with trip counts.
"""
if origin_filter and destination_filter:
filtered_trips = trips[
(trips["start_zone_id"] == origin_filter) &
(trips["end_zone_id"] == destination_filter)
]
elif origin_filter:
filtered_trips = trips[trips["start_zone_id"] == origin_filter]
elif destination_filter:
filtered_trips = trips[trips["end_zone_id"] == destination_filter]
else:
filtered_trips = trips
# Aggregate trip counts for origins and destinations
filtered_origins = zones.merge(
#filtered_trips.groupby("start_zone_id").size().reset_index(name="trip_count"),
filtered_trips.groupby("start_zone_id")["trips"].sum().reset_index(name="trip_count"),
left_on="FPID", right_on="start_zone_id", how="left"
).fillna(0)
filtered_destinations = zones.merge(
filtered_trips.groupby("end_zone_id")["trips"].sum().reset_index(name="trip_count"),
left_on="FPID", right_on="end_zone_id", how="left"
).fillna(0)
return filtered_origins, filtered_destinations
def create_nav_button(button_icon, button_label_text, button_link, button_cls = "btn btn-primary"):
return ui.tags.a(
ui.HTML(f"{fa.icon_svg(button_icon)} {button_label_text}"),
href=button_link,
class_=button_cls
)
def conlogo():
img = {
"src": app_dir / "images" / "logo.png",
"style": "width: 80%; height: auto; max-height: 150px; margin-bottom: 0px;"
}
return img
def vendorlogo():
img = {
"src": app_dir / "images" / "logo2.png",
"style": "width: 80%; height: auto; max-height: 150px; margin-bottom: 0px;"
}
return img
def create_bar_chart(categories, values, plottitle = "Bar Chart Example"):
fig, ax = plt.subplots()
#ax.bar(categories, values, color=["#1f77b4", "#ff7f0e", "#2ca02c"])
ax.bar(categories, values)
ax.set_title(plottitle)
ax.set_ylabel("Values")
ax.set_xlabel("Categories")
return fig
def create_pie_chart(labels, sizes, plottitle):
#sizes = [22, 41, 37]
#colors = ["#00b3b3", "#70d281", "#ff7f0e"]
#explode = (0.1, 0, 0) # Explode the first slice for emphasis
fig, ax = plt.subplots()
wedges, texts, autotexts = ax.pie(
sizes,
#explode=explode,
labels=labels,
autopct="%1.0f%%",
startangle=90,
#colors=colors,
textprops=dict(color="black"),
wedgeprops=dict(width=0.4) # Adjust width for the donut effect
)
# Customizing the labels
for text, label in zip(autotexts, labels):
text.set_color("black")
text.set_fontsize(12)
#ax.set_title("What Types of Trips are Occuring within Napa County on a Weekday?", fontsize=16, fontweight="bold")
ax.set_title(plottitle, fontsize=16, fontweight="bold")
return fig
def create_stacked_bar_chart(categories, intra_napa, into_napa, out_napa):
# Data for the stacked bar chart
#categories = ["Early AM", "AM Peak", "Mid-Day", "PM Peak", "Evening"]
#intra_napa = [2000, 16000, 14000, 12000, 5000]
#into_napa = [1000, 8000, 2000, 3000, 2000]
#out_napa = [2000, 4000, 2000, 5000, 1000]
bar_width = 0.5 # Width of the bars
x = np.arange(len(categories)) # x-axis positions
fig, ax = plt.subplots(figsize=(8, 6))
# Stacking the bars
ax.bar(x, intra_napa, bar_width, label="Intra-Napa County", color="#70d281")
ax.bar(x, into_napa, bar_width, bottom=intra_napa, label="Into Napa County", color="#ff7f0e")
ax.bar(x, out_napa, bar_width, bottom=np.array(intra_napa) + np.array(into_napa), label="Out of Napa County", color="#00b3b3")
# Customizing the plot
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.set_ylabel("Trips")
ax.set_title("Weekday Work Trip Types")
ax.legend(loc="upper right")
# Add value annotations
for i in range(len(categories)):
ax.text(x[i], intra_napa[i] / 2, f"{intra_napa[i]}", ha="center", va="center", color="white")
ax.text(x[i], intra_napa[i] + into_napa[i] / 2, f"{into_napa[i]}", ha="center", va="center", color="white")
ax.text(x[i], intra_napa[i] + into_napa[i] + out_napa[i] / 2, f"{out_napa[i]}", ha="center", va="center", color="white")
plt.tight_layout()
return fig
|