12.Retrieve earthquake data for the past 7 weeks using the USGS Earthquake API. Extract the following fields: Magnitude, Place, Time, Longitude, Latitude, Depth, and Tsunami Status. Perform statistical and time-series analysis on the retrieved earthquake data. Visualize the results using suitable charts and develop a dashboard to display the earthquake data, statistical analysis, time-series visualizations, and findings.

Input:
https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2026-08-07&endtime=2026-09-25&minmagnitude=2.5&orderby=time

pip install requests pandas matplotlib streamlit plotly

earthquake_dashboard/
│
└── app.py

streamlit

app.py:


import requests
import pandas as pd
import streamlit as st
import plotly.express as px
from datetime import datetime, timedelta, timezone

# USGS Earthquake API - Past 7 weeks
end_datetime = datetime.now(timezone.utc)
start_datetime = end_datetime - timedelta(weeks=7)

URL = (
    "https://earthquake.usgs.gov/fdsnws/event/1/query"
    f"?format=geojson"
    f"&starttime={start_datetime.strftime('%Y-%m-%dT%H:%M:%S')}"
    f"&endtime={end_datetime.strftime('%Y-%m-%dT%H:%M:%S')}"
    "&minmagnitude=2.5"
    "&orderby=time"
)

st.set_page_config(
    page_title="Earthquake Analytics Dashboard",
    layout="wide"
)

st.title(" Earthquake Data Analytics Dashboard")
st.write("Analysis of earthquake data retrieved from the USGS API")

# Retrieve earthquake data
@st.cache_data(ttl=300)
def get_data():

    response = requests.get(URL, timeout=30)
    response.raise_for_status()

    json_data = response.json()

    records = []

    for feature in json_data["features"]:

        properties = feature["properties"]
        coordinates = feature["geometry"]["coordinates"]

        records.append({
            "Magnitude": properties["mag"],
            "Place": properties["place"],
            "Time": pd.to_datetime(
                properties["time"], unit="ms", utc=True
            ),
            "Longitude": coordinates[0],
            "Latitude": coordinates[1],
            "Depth": coordinates[2],
            "Tsunami": properties["tsunami"]
        })

    return pd.DataFrame(records)


try:

    df = get_data()

    if df.empty:
        st.warning("No earthquake records found.")
        st.stop()

    # Data preprocessing
    df = df.dropna(subset=["Magnitude", "Time"])

    if df.empty:
        st.warning("No valid earthquake records available.")
        st.stop()

    df["Tsunami Status"] = df["Tsunami"].map({
        0: "No",
        1: "Yes"
    })

    # Sidebar
    st.sidebar.header("Filters")

    min_mag = float(df["Magnitude"].min())
    max_mag = float(df["Magnitude"].max())

    selected_mag = st.sidebar.slider(
        "Magnitude Range",
        min_value=min_mag,
        max_value=max_mag,
        value=(min_mag, max_mag)
    )

    filtered = df[
        (df["Magnitude"] >= selected_mag[0]) &
        (df["Magnitude"] <= selected_mag[1])
    ]

    # Key statistics
    st.subheader("Earthquake Statistics")

    c1, c2, c3, c4 = st.columns(4)

    c1.metric("Total Earthquakes", len(filtered))

    c2.metric(
        "Average Magnitude",
        round(filtered["Magnitude"].mean(), 2)
    )

    c3.metric(
        "Maximum Magnitude",
        round(filtered["Magnitude"].max(), 2)
    )

    c4.metric(
        "Average Depth (km)",
        round(filtered["Depth"].mean(), 2)
    )

    # Statistical analysis
    st.subheader("Statistical Analysis")

    st.dataframe(
        filtered[
            ["Magnitude", "Latitude", "Longitude", "Depth"]
        ].describe(),
        use_container_width=True
    )

    # Magnitude distribution
    st.subheader("Magnitude Distribution")

    fig1 = px.histogram(
        filtered,
        x="Magnitude",
        nbins=20,
        title="Earthquake Magnitude Distribution"
    )

    st.plotly_chart(fig1, use_container_width=True)

    # Top 10 strongest earthquakes
    st.subheader("Top 10 Strongest Earthquakes")

    top10 = filtered.nlargest(10, "Magnitude")

    fig2 = px.bar(
        top10,
        x="Place",
        y="Magnitude",
        title="Top 10 Earthquakes by Magnitude"
    )

    st.plotly_chart(fig2, use_container_width=True)

    # Time series analysis
    st.subheader("Earthquake Activity Over Time")

    daily = (
        filtered.set_index("Time")
        .resample("D")
        .size()
        .reset_index(name="Earthquake Count")
    )

    fig3 = px.line(
        daily,
        x="Time",
        y="Earthquake Count",
        title="Daily Earthquake Frequency",
        markers=True
    )

    st.plotly_chart(fig3, use_container_width=True)

    # Depth analysis
    st.subheader("Magnitude vs Depth")

    fig4 = px.scatter(
        filtered,
        x="Depth",
        y="Magnitude",
        color="Tsunami Status",
        hover_name="Place",
        title="Earthquake Magnitude vs Depth"
    )

    st.plotly_chart(fig4, use_container_width=True)

    # Earthquake location map
    st.subheader("Earthquake Locations")

    fig5 = px.scatter_geo(
        filtered,
        lat="Latitude",
        lon="Longitude",
        color="Magnitude",
        hover_name="Place",
        title="Global Earthquake Locations"
    )

    st.plotly_chart(fig5, use_container_width=True)

    # Tsunami analysis
    st.subheader("Tsunami Status")

    tsunami_count = (
        filtered.groupby("Tsunami Status")
        .size()
        .reset_index(name="Count")
    )

    fig6 = px.pie(
        tsunami_count,
        names="Tsunami Status",
        values="Count",
        title="Earthquake Tsunami Status Distribution"
    )

    st.plotly_chart(fig6, use_container_width=True)

    # Raw data
    st.subheader("Earthquake Records")

    st.dataframe(filtered, use_container_width=True)

    # Download CSV
    csv = filtered.to_csv(index=False).encode("utf-8")

    st.download_button(
        "Download Earthquake Data CSV",
        csv,
        "earthquake_data.csv",
        "text/csv"
    )

    # Findings
    st.subheader("Key Findings")

    st.write(
        "Total earthquakes:", len(filtered)
    )

    st.write(
        "Highest magnitude:", filtered["Magnitude"].max()
    )

    st.write(
        "Most active day:",
        daily.loc[daily["Earthquake Count"].idxmax(), "Time"].date()
    )

    st.write(
        "Tsunami-related records:",
        (filtered["Tsunami"] == 1).sum()
    )

except Exception as e:
    st.error(f"Error retrieving or processing data: {e}")

