Update src/streamlit_app.py
Browse files- src/streamlit_app.py +12 -25
src/streamlit_app.py
CHANGED
@@ -22,16 +22,11 @@ def fetch_live_data(start_date, end_date, min_mag):
|
|
22 |
"""
|
23 |
Fetches live earthquake data from the IRIS FDSN web service using ObsPy.
|
24 |
"""
|
25 |
-
# Initialize the FDSN client
|
26 |
client = Client("IRIS")
|
27 |
-
|
28 |
-
# Convert dates to ObsPy's UTCDateTime format
|
29 |
start_time = UTCDateTime(start_date)
|
30 |
-
# Add one day to the end date to ensure the entire day is included
|
31 |
end_time = UTCDateTime(end_date) + timedelta(days=1)
|
32 |
|
33 |
try:
|
34 |
-
# Fetch the earthquake catalog
|
35 |
catalog = client.get_events(
|
36 |
starttime=start_time,
|
37 |
endtime=end_time,
|
@@ -39,32 +34,34 @@ def fetch_live_data(start_date, end_date, min_mag):
|
|
39 |
)
|
40 |
except Exception as e:
|
41 |
st.error(f"Could not retrieve data from IRIS FDSN service: {e}")
|
42 |
-
return pd.DataFrame()
|
43 |
|
44 |
-
# Process the catalog into a list of dictionaries
|
45 |
event_list = []
|
46 |
for event in catalog:
|
47 |
-
# Skip events that lack a preferred origin or magnitude to prevent errors
|
48 |
if not (event.preferred_origin() and event.preferred_magnitude()):
|
49 |
continue
|
50 |
|
51 |
origin = event.preferred_origin()
|
52 |
magnitude = event.preferred_magnitude()
|
53 |
-
|
54 |
-
#
|
|
|
55 |
description = "N/A"
|
56 |
-
if
|
57 |
-
|
|
|
|
|
|
|
58 |
|
59 |
event_list.append({
|
60 |
"latitude": origin.latitude,
|
61 |
"longitude": origin.longitude,
|
62 |
-
"depth": origin.depth / 1000,
|
63 |
"magnitude": magnitude.mag,
|
64 |
"time": origin.time.datetime,
|
65 |
"place": description,
|
66 |
})
|
67 |
-
|
68 |
if not event_list:
|
69 |
return pd.DataFrame()
|
70 |
|
@@ -76,21 +73,15 @@ st.markdown("Data is fetched in real-time from the **IRIS FDSN** web service.")
|
|
76 |
|
77 |
with st.sidebar:
|
78 |
st.header("π Search Parameters")
|
79 |
-
|
80 |
-
# Set default dates: today and 30 days prior
|
81 |
today = date.today()
|
82 |
thirty_days_ago = today - timedelta(days=30)
|
83 |
-
|
84 |
start_date = st.date_input("Start Date", value=thirty_days_ago)
|
85 |
end_date = st.date_input("End Date", value=today)
|
86 |
-
|
87 |
min_magnitude = st.slider("Minimum Magnitude", 0.0, 10.0, 5.0, 0.1)
|
88 |
-
|
89 |
search_button = st.button("Search Earthquakes", type="primary", use_container_width=True)
|
90 |
|
91 |
# --- Main Content Area ---
|
92 |
if search_button:
|
93 |
-
# Validate date range
|
94 |
if start_date > end_date:
|
95 |
st.error("Error: Start date cannot be after end date.")
|
96 |
else:
|
@@ -100,16 +91,13 @@ if search_button:
|
|
100 |
if not df.empty:
|
101 |
st.success(f"Found {len(df)} earthquakes matching your criteria.")
|
102 |
|
103 |
-
# --- Display Summary Metrics ---
|
104 |
st.subheader("π Summary Statistics")
|
105 |
col1, col2, col3 = st.columns(3)
|
106 |
col1.metric("Total Earthquakes", f"{len(df):,}")
|
107 |
col2.metric("Largest Magnitude", f"{df['magnitude'].max():.1f}")
|
108 |
col3.metric("Deepest Event (km)", f"{df['depth'].max():.1f}")
|
109 |
-
|
110 |
-
st.markdown("---")
|
111 |
|
112 |
-
|
113 |
st.subheader("π Interactive Earthquake Map")
|
114 |
st.markdown("Hover over points for details. Circle size represents magnitude.")
|
115 |
|
@@ -128,7 +116,6 @@ if search_button:
|
|
128 |
fig.update_layout(margin={"r":0,"t":40,"l":0,"b":0}, coloraxis_colorbar_title_text='Depth (km)')
|
129 |
st.plotly_chart(fig, use_container_width=True)
|
130 |
|
131 |
-
# --- Show Earthquakes in a Table ---
|
132 |
st.subheader("π Detailed Earthquake Data")
|
133 |
display_df = df[['time', 'place', 'magnitude', 'depth']].copy()
|
134 |
st.dataframe(
|
|
|
22 |
"""
|
23 |
Fetches live earthquake data from the IRIS FDSN web service using ObsPy.
|
24 |
"""
|
|
|
25 |
client = Client("IRIS")
|
|
|
|
|
26 |
start_time = UTCDateTime(start_date)
|
|
|
27 |
end_time = UTCDateTime(end_date) + timedelta(days=1)
|
28 |
|
29 |
try:
|
|
|
30 |
catalog = client.get_events(
|
31 |
starttime=start_time,
|
32 |
endtime=end_time,
|
|
|
34 |
)
|
35 |
except Exception as e:
|
36 |
st.error(f"Could not retrieve data from IRIS FDSN service: {e}")
|
37 |
+
return pd.DataFrame()
|
38 |
|
|
|
39 |
event_list = []
|
40 |
for event in catalog:
|
|
|
41 |
if not (event.preferred_origin() and event.preferred_magnitude()):
|
42 |
continue
|
43 |
|
44 |
origin = event.preferred_origin()
|
45 |
magnitude = event.preferred_magnitude()
|
46 |
+
|
47 |
+
# --- CORRECTED CODE IS HERE ---
|
48 |
+
# Get location description safely.
|
49 |
description = "N/A"
|
50 |
+
# First, check if the 'descriptions' attribute exists.
|
51 |
+
if hasattr(event, 'descriptions'):
|
52 |
+
# If it exists, then check if it's a non-empty list with text.
|
53 |
+
if event.descriptions and event.descriptions[0].text:
|
54 |
+
description = event.descriptions[0].text
|
55 |
|
56 |
event_list.append({
|
57 |
"latitude": origin.latitude,
|
58 |
"longitude": origin.longitude,
|
59 |
+
"depth": origin.depth / 1000,
|
60 |
"magnitude": magnitude.mag,
|
61 |
"time": origin.time.datetime,
|
62 |
"place": description,
|
63 |
})
|
64 |
+
|
65 |
if not event_list:
|
66 |
return pd.DataFrame()
|
67 |
|
|
|
73 |
|
74 |
with st.sidebar:
|
75 |
st.header("π Search Parameters")
|
|
|
|
|
76 |
today = date.today()
|
77 |
thirty_days_ago = today - timedelta(days=30)
|
|
|
78 |
start_date = st.date_input("Start Date", value=thirty_days_ago)
|
79 |
end_date = st.date_input("End Date", value=today)
|
|
|
80 |
min_magnitude = st.slider("Minimum Magnitude", 0.0, 10.0, 5.0, 0.1)
|
|
|
81 |
search_button = st.button("Search Earthquakes", type="primary", use_container_width=True)
|
82 |
|
83 |
# --- Main Content Area ---
|
84 |
if search_button:
|
|
|
85 |
if start_date > end_date:
|
86 |
st.error("Error: Start date cannot be after end date.")
|
87 |
else:
|
|
|
91 |
if not df.empty:
|
92 |
st.success(f"Found {len(df)} earthquakes matching your criteria.")
|
93 |
|
|
|
94 |
st.subheader("π Summary Statistics")
|
95 |
col1, col2, col3 = st.columns(3)
|
96 |
col1.metric("Total Earthquakes", f"{len(df):,}")
|
97 |
col2.metric("Largest Magnitude", f"{df['magnitude'].max():.1f}")
|
98 |
col3.metric("Deepest Event (km)", f"{df['depth'].max():.1f}")
|
|
|
|
|
99 |
|
100 |
+
st.markdown("---")
|
101 |
st.subheader("π Interactive Earthquake Map")
|
102 |
st.markdown("Hover over points for details. Circle size represents magnitude.")
|
103 |
|
|
|
116 |
fig.update_layout(margin={"r":0,"t":40,"l":0,"b":0}, coloraxis_colorbar_title_text='Depth (km)')
|
117 |
st.plotly_chart(fig, use_container_width=True)
|
118 |
|
|
|
119 |
st.subheader("π Detailed Earthquake Data")
|
120 |
display_df = df[['time', 'place', 'magnitude', 'depth']].copy()
|
121 |
st.dataframe(
|