spider plot enhancement
Browse files- src/app_utils.py +81 -2
src/app_utils.py
CHANGED
|
@@ -192,7 +192,7 @@ def spider_plot(df: pd.DataFrame) -> None:
|
|
| 192 |
|
| 193 |
|
| 194 |
# Create a new function in app_utils.py that returns the figure instead of showing it
|
| 195 |
-
def
|
| 196 |
spider_plot_cols = ['Beta norm.', 'Debt to Equity norm.', '1-year Return norm.', 'Revenue Growth norm.', 'Volatility norm.']
|
| 197 |
plot_data = df[df['Field'].isin(spider_plot_cols)].set_index('Field')
|
| 198 |
values = plot_data.loc[spider_plot_cols, 'Value'].fillna(0.5).astype(float).tolist()
|
|
@@ -252,4 +252,83 @@ def get_spider_plot_fig(df: pd.DataFrame):
|
|
| 252 |
height=500
|
| 253 |
)
|
| 254 |
|
| 255 |
-
return fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
|
| 193 |
|
| 194 |
# Create a new function in app_utils.py that returns the figure instead of showing it
|
| 195 |
+
def get_spider_plot_fig_v0(df: pd.DataFrame):
|
| 196 |
spider_plot_cols = ['Beta norm.', 'Debt to Equity norm.', '1-year Return norm.', 'Revenue Growth norm.', 'Volatility norm.']
|
| 197 |
plot_data = df[df['Field'].isin(spider_plot_cols)].set_index('Field')
|
| 198 |
values = plot_data.loc[spider_plot_cols, 'Value'].fillna(0.5).astype(float).tolist()
|
|
|
|
| 252 |
height=500
|
| 253 |
)
|
| 254 |
|
| 255 |
+
return fig
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
def get_spider_plot_fig(df: pd.DataFrame):
|
| 259 |
+
spider_plot_cols = ['Beta norm.', 'Debt to Equity norm.', '1-year Return norm.', 'Revenue Growth norm.', 'Volatility norm.']
|
| 260 |
+
plot_data = df[df['Field'].isin(spider_plot_cols)].set_index('Field')
|
| 261 |
+
values = plot_data.loc[spider_plot_cols, 'Value'].fillna(0.5).astype(float).tolist()
|
| 262 |
+
metrics_to_invert = ['Debt to Equity norm.', 'Beta norm.', 'Volatility norm.']
|
| 263 |
+
values = [1 - v if col in metrics_to_invert else v for v, col in zip(values, spider_plot_cols)]
|
| 264 |
+
|
| 265 |
+
# Calculate average strength score
|
| 266 |
+
avg_strength = round(np.mean(values) * 100)
|
| 267 |
+
|
| 268 |
+
# Determine color based on score
|
| 269 |
+
if avg_strength < 30:
|
| 270 |
+
profile_color = 'red'
|
| 271 |
+
elif avg_strength < 50:
|
| 272 |
+
profile_color = 'gold'
|
| 273 |
+
elif avg_strength < 70:
|
| 274 |
+
profile_color = 'blue'
|
| 275 |
+
else:
|
| 276 |
+
profile_color = 'green'
|
| 277 |
+
|
| 278 |
+
categories = [s.replace(' norm.', '').replace('1-year', '1yr').replace('Debt to Equity', 'D/E') for s in spider_plot_cols]
|
| 279 |
+
company_name = df.loc[df['Field'] == 'Name', 'Value'].values[0]
|
| 280 |
+
fig = go.Figure()
|
| 281 |
+
|
| 282 |
+
fig.add_trace(go.Scatterpolar(
|
| 283 |
+
r=values + [values[0]],
|
| 284 |
+
theta=categories + [categories[0]],
|
| 285 |
+
fill='toself',
|
| 286 |
+
name='Company Profile',
|
| 287 |
+
line=dict(color=profile_color),
|
| 288 |
+
fillcolor=f'rgba({",".join(["255,0,0,0.2" if profile_color == "red" else "255,215,0,0.2" if profile_color == "gold" else "0,0,255,0.2" if profile_color == "blue" else "0,128,0,0.2"])})'
|
| 289 |
+
))
|
| 290 |
+
|
| 291 |
+
fig.add_trace(go.Scatterpolar(
|
| 292 |
+
r=[0.5] * len(categories) + [0.5],
|
| 293 |
+
theta=categories + [categories[0]],
|
| 294 |
+
mode='lines',
|
| 295 |
+
line=dict(dash='dot', color='grey'),
|
| 296 |
+
fill='toself',
|
| 297 |
+
fillcolor='rgba(0,0,0,0)',
|
| 298 |
+
name='Median (0.5)'
|
| 299 |
+
))
|
| 300 |
+
|
| 301 |
+
legend_text = (
|
| 302 |
+
f"<b>Avg. strength: {avg_strength}</b><br>"
|
| 303 |
+
"<b>Quantile Scale: 0 to 1</b><br>"
|
| 304 |
+
"D/E, Beta, and Volatility:<br>"
|
| 305 |
+
"0 is highest, 1 is lowest<br>"
|
| 306 |
+
"Rev. growth and 1yr return:<br>"
|
| 307 |
+
"0 is lowest, 1 is highest<br>"
|
| 308 |
+
)
|
| 309 |
+
|
| 310 |
+
fig.update_layout(
|
| 311 |
+
polar=dict(
|
| 312 |
+
radialaxis=dict(
|
| 313 |
+
visible=True,
|
| 314 |
+
range=[0, 1]
|
| 315 |
+
)),
|
| 316 |
+
showlegend=True,
|
| 317 |
+
title=f'{company_name} - Normalized Metrics',
|
| 318 |
+
annotations=[
|
| 319 |
+
go.layout.Annotation(
|
| 320 |
+
text=legend_text,
|
| 321 |
+
align='right',
|
| 322 |
+
showarrow=False,
|
| 323 |
+
xref='paper',
|
| 324 |
+
yref='paper',
|
| 325 |
+
x=1.41,
|
| 326 |
+
y=-0.1
|
| 327 |
+
)
|
| 328 |
+
],
|
| 329 |
+
margin=dict(b=120),
|
| 330 |
+
width=600,
|
| 331 |
+
height=500
|
| 332 |
+
)
|
| 333 |
+
|
| 334 |
+
return fig
|