Untitled

mail@pastecode.io avatar
unknown
plain_text
4 months ago
7.3 kB
3
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()
Leave a Comment