Spaces:
Sleeping
Sleeping
Jonas
Add error handling and placeholder charts in app.py; implement create_placeholder_chart in plotting.py
2262f59
import plotly.graph_objects as go | |
import pandas as pd | |
from typing import Dict, Any, Optional | |
def create_placeholder_chart(message: str) -> go.Figure: | |
""" | |
Creates a placeholder chart with a text message. | |
Args: | |
message (str): The message to display on the chart. | |
Returns: | |
go.Figure: A Plotly figure object with the message. | |
""" | |
fig = go.Figure() | |
fig.add_annotation( | |
text=message, | |
xref="paper", | |
yref="paper", | |
showarrow=False, | |
font=dict(size=16) | |
) | |
fig.update_layout( | |
xaxis=dict(showgrid=False, zeroline=False, visible=False), | |
yaxis=dict(showgrid=False, zeroline=False, visible=False), | |
plot_bgcolor="rgba(0,0,0,0)", | |
paper_bgcolor="rgba(0,0,0,0)", | |
) | |
return fig | |
def create_bar_chart(data: dict, drug_name: str): | |
""" | |
Creates a Plotly bar chart from the OpenFDA data. | |
Args: | |
data (dict): The data from the OpenFDA client. | |
drug_name (str): The name of the drug. | |
Returns: | |
A Plotly Figure object if data is valid, otherwise None. | |
""" | |
if "error" in data or "results" not in data or not data["results"]: | |
return None | |
try: | |
df = pd.DataFrame(data["results"]) | |
df = df.rename(columns={"term": "Adverse Event", "count": "Report Count"}) | |
# Ensure 'Report Count' is numeric | |
df['Report Count'] = pd.to_numeric(df['Report Count']) | |
# Sort for better visualization | |
df = df.sort_values(by="Report Count", ascending=True) | |
fig = go.Figure( | |
go.Bar( | |
x=df["Report Count"], | |
y=df["Adverse Event"], | |
orientation='h', | |
marker=dict(color='skyblue') | |
) | |
) | |
fig.update_layout( | |
title_text=f"Top Reported Adverse Events for {drug_name.title()}", | |
xaxis_title="Number of Reports", | |
yaxis_title="Adverse Event", | |
yaxis=dict(automargin=True), | |
height=max(400, len(df) * 30) # Dynamically adjust height | |
) | |
return fig | |
except Exception: | |
return None | |
def create_outcome_chart(data: dict, drug_name: str): | |
""" | |
Creates a Plotly bar chart for serious outcomes from OpenFDA data. | |
Args: | |
data (dict): The data from the OpenFDA client. | |
drug_name (str): The name of the drug. | |
Returns: | |
A Plotly Figure object if data is valid, otherwise None. | |
""" | |
if "error" in data or "results" not in data or not data["results"]: | |
return None | |
try: | |
df = pd.DataFrame(data["results"]) | |
df = df.rename(columns={"term": "Serious Outcome", "count": "Report Count"}) | |
df['Report Count'] = pd.to_numeric(df['Report Count']) | |
df = df.sort_values(by="Report Count", ascending=True) | |
fig = go.Figure( | |
go.Bar( | |
x=df["Report Count"], | |
y=df["Serious Outcome"], | |
orientation='h', | |
marker=dict(color='crimson') # Different color for distinction | |
) | |
) | |
fig.update_layout( | |
title_text=f"Top Serious Outcomes for {drug_name.title()}", | |
xaxis_title="Number of Reports", | |
yaxis_title="Serious Outcome", | |
yaxis=dict(automargin=True), | |
height=max(400, len(df) * 40) | |
) | |
return fig | |
except Exception: | |
return None | |
def create_time_series_chart(data: dict, drug_name: str, event_name: str, time_aggregation: str = 'Y'): | |
""" | |
Creates a Plotly time-series chart from OpenFDA data. | |
Args: | |
data (dict): The data from the OpenFDA client. | |
drug_name (str): The name of the drug. | |
event_name (str): The name of the adverse event. | |
time_aggregation (str): The time unit for aggregation ('Y' for year, 'Q' for quarter). | |
Returns: | |
A Plotly Figure object if data is valid, otherwise None. | |
""" | |
if "error" in data or "results" not in data or not data["results"]: | |
return None | |
try: | |
df = pd.DataFrame(data["results"]) | |
df['time'] = pd.to_datetime(df['time'], format='%Y%m%d') | |
# Resample data | |
df = df.set_index('time').resample(time_aggregation)['count'].sum().reset_index() | |
aggregation_label = "Year" if time_aggregation == 'Y' else "Quarter" | |
fig = go.Figure( | |
go.Scatter( | |
x=df["time"], | |
y=df["count"], | |
mode='lines+markers', | |
line=dict(color='royalblue'), | |
) | |
) | |
fig.update_layout( | |
title_text=f"Report Trend for {drug_name.title()} and {event_name.title()}", | |
xaxis_title=f"Report {aggregation_label}", | |
yaxis_title="Number of Reports", | |
yaxis=dict(automargin=True), | |
) | |
return fig | |
except Exception as e: | |
print(f"Error creating time-series chart: {e}") | |
return None | |
def create_pie_chart(data: dict, drug_name: str): | |
""" | |
Creates a Plotly pie chart for report source breakdown. | |
Args: | |
data (dict): The data from the OpenFDA client. | |
drug_name (str): The name of the drug. | |
Returns: | |
A Plotly Figure object if data is valid, otherwise None. | |
""" | |
if "error" in data or "results" not in data or not data["results"]: | |
return None | |
try: | |
df = pd.DataFrame(data["results"]) | |
df = df.rename(columns={"term": "Source", "count": "Count"}) | |
fig = go.Figure( | |
go.Pie( | |
labels=df["Source"], | |
values=df["Count"], | |
hole=.3, | |
pull=[0.05] * len(df) # Explode slices slightly | |
) | |
) | |
fig.update_layout( | |
title_text=f"Report Sources for {drug_name.title()}", | |
showlegend=True | |
) | |
return fig | |
except Exception as e: | |
print(f"Error creating pie chart: {e}") | |
return None |