Untitled

 avatar
unknown
plain_text
a year ago
7.3 kB
10
Indexable
import pandas as pd
import numpy as np
import streamlit as st
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.patches as mpatches
import json
import os

# Function to get the modification time of the JSON file
def get_file_mtime(filepath):
    return os.path.getmtime(filepath)

# Function to load JSON data
@st.cache_data
def load_json_data():
    with open('path_to_your_json_file.json', 'r') as f:
        data = json.load(f)
    df = pd.DataFrame(data)
    df['CRASH_DATE'] = pd.to_datetime(df['CRASH_DATE'])
    return df

def create_monthly_dataframes(df):
    df = df.sort_values('CRASH_DATE')
    monthly_dfs = []
    for _, group in df.groupby([df['CRASH_DATE'].dt.year, df['CRASH_DATE'].dt.month]):
        monthly_dfs.append(group)
    return monthly_dfs

def update_charts(df, year, month):
    # Top 15 streets by accident count
    fig1, ax1 = plt.subplots(figsize=(15, 10))
    streets = df['STREET_NAME'].value_counts().head(15)
    streets.plot(kind='barh', ax=ax1)
    ax1.set_xlabel('Collisions', size=20)
    ax1.set_ylabel('Street', size=20)
    ax1.set_title(f'Total Number of Collisions by Street - Up to {year}, Month {month}', size=20)
    ax1.tick_params(axis='both', which='major', labelsize=15)
    for i, v in enumerate(streets):
        ax1.text(v, i, str(v), va='center', fontsize=12)

    # Severity of collisions map
    fig2, ax2 = plt.subplots(figsize=(15, 10))
    killed_df = df[df['INJURIES_FATAL'] > 0]
    injured_df = df[(df['INJURIES_TOTAL'] > 0) & (df['INJURIES_FATAL'] == 0)]
    nothing_df = df[(df['INJURIES_FATAL'] == 0) & (df['INJURIES_TOTAL'] == 0)]

    ax2.scatter(nothing_df['LONGITUDE'], nothing_df['LATITUDE'], alpha=0.04, s=1, color='blue')
    ax2.scatter(injured_df['LONGITUDE'], injured_df['LATITUDE'], alpha=0.1, s=1, color='yellow')
    ax2.scatter(killed_df['LONGITUDE'], killed_df['LATITUDE'], color='red', s=5)

    blue_patch = mpatches.Patch(label='car body damage', alpha=0.2, color='blue')
    yellow_patch = mpatches.Patch(color='yellow', label='personal injury', alpha=0.5)
    red_patch = mpatches.Patch(color='red', label='fatal accidents')
    
    ax2.legend([blue_patch, yellow_patch, red_patch], 
               ('car body damage', 'personal injury', 'fatal accidents'),
               loc='upper left', prop={'size': 20})
    
    ax2.set_title(f'Severity of Motor Vehicle Collisions in Chicago - Up to {year}, Month {month}', size=20)
    ax2.set_xlim((-87.92, -87.52))
    ax2.set_ylim((41.64, 42.03))
    ax2.set_xlabel('Longitude', size=20)
    ax2.set_ylabel('Latitude', size=20)

    # Top 10 streets map
    fig3, ax3 = plt.subplots(figsize=(15, 10))
    street_names = df['STREET_NAME'].value_counts().head(10).index.tolist()
    
    ax3.scatter(df['LONGITUDE'], df['LATITUDE'], s=1, color='darkseagreen', alpha=0.1)
    
    colors = ['red', 'blue', 'magenta', 'orange', 'yellow', 'purple', 'black', 'chartreuse', 'brown', 'darkgreen']
    for i, street in enumerate(street_names):
        street_df = df[df['STREET_NAME'] == street]
        ax3.scatter(street_df['LONGITUDE'], street_df['LATITUDE'], s=2, color=colors[i], label=street, alpha=0.5)
    
    ax3.legend(loc='upper left', prop={'size': 12})
    ax3.set_title(f'Vehicle Collisions in Chicago - Top 10 Streets - Up to {year}, Month {month}', size=20)
    ax3.set_xlim((-87.92, -87.52))
    ax3.set_ylim((41.64, 42.03))
    ax3.set_xlabel('Longitude', size=20)
    ax3.set_ylabel('Latitude', size=20)

    # Collisions by hour (horizontal bar chart)
    fig4, ax4 = plt.subplots(figsize=(15, 10))
    by_hour = df['CRASH_HOUR'].value_counts().sort_index()
    colors = ['g', '0.75', 'y', 'k', 'b', 'r'] * 4  # Repeat colors to ensure we have enough
    by_hour.plot(kind='barh', ax=ax4, color=colors[:len(by_hour)])
    ax4.set_xlabel('Collisions', size=20)
    ax4.set_ylabel('Hour of the Day', size=20)
    ax4.set_title(f'Total Number of Collisions by Hour of the Day - Up to {year}, Month {month}', size=20)
    
    full_hours = range(24)
    full_labels = [f"{h:02d}" for h in full_hours]
    ax4.set_yticks(full_hours)
    ax4.set_yticklabels(full_labels, fontsize=15)
    
    ax4.set_ylim(-0.5, 23.5)
    ax4.set_xlim(0, max(by_hour) * 1.1)  # Add some padding to the right
    
    # Add value labels to the end of each bar
    for i, v in enumerate(by_hour):
        ax4.text(v, i, str(v), va='center', fontsize=12)

    # Collisions by day of the week
    fig5, ax5 = plt.subplots(figsize=(15, 10))
    by_day = df['CRASH_DAY_OF_WEEK'].value_counts().sort_index()
    colors = ['g', '0.75', 'y', 'k', 'b', 'r', 'c']  # One color for each day
    by_day.plot(kind='barh', ax=ax5, color=colors[:len(by_day)])
    ax5.set_xlabel('Collisions', size=20)
    ax5.set_ylabel('Day of the Week', size=20)
    ax5.set_title(f'Total Number of Collisions by Day of the Week - Up to {year}, Month {month}', size=20)
    
    full_days = range(1, 8)  # Assuming 1-7 represent Monday-Sunday
    day_labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    ax5.set_yticks(full_days)
    ax5.set_yticklabels(day_labels, fontsize=15)
    
    ax5.set_ylim(0.5, 7.5)
    ax5.set_xlim(0, max(by_day) * 1.1)  # Add some padding to the right
    
    # Add value labels to the end of each bar
    for i, v in enumerate(by_day):
        ax5.text(v, i+1, str(v), va='center', fontsize=12)

    return fig1, fig2, fig3, fig4, fig5

st.set_page_config(layout="wide")

st.title('Chicago Traffic Crashes Analysis - Real-time Updates')

# Create placeholders for the charts
with st.container():
    col1, col2 = st.columns(2)
    chart1 = col1.empty()
    chart2 = col2.empty()

with st.container():
    col3, col4 = st.columns(2)
    chart3 = col3.empty()
    chart4 = col4.empty()

chart5 = st.empty()

# Get the initial modification time of the JSON file
json_file_path = 'path_to_your_json_file.json'
last_mtime = get_file_mtime(json_file_path)

# Main loop for updates
while True:
    # Check if the JSON file has been modified
    current_mtime = get_file_mtime(json_file_path)
    
    if current_mtime != last_mtime:
        # Load the latest data from JSON
        collisions_df = load_json_data()
        
        # Create monthly dataframes
        monthly_dataframes = create_monthly_dataframes(collisions_df)
        
        # Initialize empty DataFrame for cumulative data
        cumulative_df = pd.DataFrame()
        
        for i, month_df in enumerate(monthly_dataframes):
            cumulative_df = pd.concat([cumulative_df, month_df])
            year = month_df['CRASH_DATE'].dt.year.iloc[0]
            month = month_df['CRASH_DATE'].dt.month.iloc[0]
            
            # Update the charts
            fig1, fig2, fig3, fig4, fig5 = update_charts(cumulative_df, year, month)
            
            # Update the charts in the layout
            chart1.pyplot(fig3)
            chart2.pyplot(fig2)
            chart3.pyplot(fig1)
            chart4.pyplot(fig5)
            chart5.pyplot(fig4)
            
            # Clear the matplotlib figures to free up memory
            plt.close(fig1)
            plt.close(fig2)
            plt.close(fig3)
            plt.close(fig4)
            plt.close(fig5)
        
        # Update the last modification time
        last_mtime = current_mtime
    
    # Rerun the app
    st.rerun()
Editor is loading...
Leave a Comment