Saumith devarsetty
Refactor: Consolidated insights, updated visualizations to Plotly, and updated README
4032138 | """ | |
| Plotly visualizations - Interactive charts with hover tooltips. | |
| Used by Smart Dashboard for better user experience. | |
| """ | |
| import plotly.express as px | |
| import plotly.graph_objects as go | |
| import pandas as pd | |
| from typing import Optional | |
| def create_plotly_distribution(df: pd.DataFrame, column: str, title: Optional[str] = None): | |
| """Creates an interactive histogram with hover details.""" | |
| fig = px.histogram( | |
| df, | |
| x=column, | |
| nbins=30, | |
| title=title or f'Distribution of {column}', | |
| labels={column: column, 'count': 'Frequency'}, | |
| color_discrete_sequence=['#636EFA'], | |
| template='plotly_dark' | |
| ) | |
| # Add mean and median lines | |
| mean_val = df[column].mean() | |
| median_val = df[column].median() | |
| fig.add_vline(x=mean_val, line_dash="dash", line_color="red", | |
| annotation_text=f"Mean: {mean_val:.2f}", annotation_position="top") | |
| fig.add_vline(x=median_val, line_dash="dash", line_color="green", | |
| annotation_text=f"Median: {median_val:.2f}", annotation_position="bottom") | |
| fig.update_layout( | |
| hovermode='x unified', | |
| showlegend=False, | |
| height=400 | |
| ) | |
| return fig | |
| def create_plotly_category(df: pd.DataFrame, category_column: str, | |
| value_column: Optional[str] = None, | |
| agg_method: str = 'count', | |
| top_n: int = 10, | |
| offset: int = 0, | |
| title: Optional[str] = None): | |
| """Creates an interactive bar chart with hover details.""" | |
| # Aggregate data | |
| if value_column is None or agg_method == 'count': | |
| data = df[category_column].value_counts() | |
| total_items = len(data) | |
| data = data.iloc[offset : offset + top_n].reset_index() | |
| data.columns = [category_column, 'Count'] | |
| y_col = 'Count' | |
| else: | |
| if agg_method == 'sum': | |
| data = df.groupby(category_column)[value_column].sum() | |
| elif agg_method == 'mean': | |
| data = df.groupby(category_column)[value_column].mean() | |
| else: | |
| data = df.groupby(category_column)[value_column].sum() | |
| data = data.sort_values(ascending=False) | |
| total_items = len(data) | |
| data = data.iloc[offset : offset + top_n].reset_index() | |
| y_col = value_column | |
| # Update title to reflect pagination | |
| if title is None: | |
| end_idx = min(offset + top_n, total_items) | |
| title = f'Top {category_column} (Rank {offset+1}-{end_idx})' | |
| fig = px.bar( | |
| data, | |
| x=category_column, | |
| y=y_col, | |
| title=title or f'Top {top_n} {category_column}', | |
| color=y_col, | |
| color_continuous_scale='Viridis', | |
| template='plotly_dark' | |
| ) | |
| fig.update_layout( | |
| xaxis_tickangle=-45, | |
| showlegend=False, | |
| height=400 | |
| ) | |
| return fig | |
| def create_plotly_scatter(df: pd.DataFrame, x_col: str, y_col: str, | |
| color_col: Optional[str] = None, | |
| title: Optional[str] = None): | |
| """Creates an interactive scatter plot with hover details.""" | |
| fig = px.scatter( | |
| df, | |
| x=x_col, | |
| y=y_col, | |
| color=color_col, | |
| title=title or f'{y_col} vs {x_col}', | |
| opacity=0.7, | |
| template='plotly_dark' | |
| ) | |
| fig.update_layout( | |
| hovermode='closest', | |
| height=400 | |
| ) | |
| return fig | |
| def create_plotly_heatmap(df: pd.DataFrame, title: Optional[str] = None): | |
| """Creates an interactive correlation heatmap with hover details.""" | |
| from utils import get_column_types | |
| col_types = get_column_types(df) | |
| if len(col_types['numerical']) < 2: | |
| return None | |
| corr_matrix = df[col_types['numerical']].corr() | |
| fig = go.Figure(data=go.Heatmap( | |
| z=corr_matrix.values, | |
| x=corr_matrix.columns, | |
| y=corr_matrix.columns, | |
| colorscale='RdBu', | |
| zmid=0, | |
| text=corr_matrix.values, | |
| texttemplate='%{text:.2f}', | |
| textfont={"size": 10}, | |
| colorbar=dict(title="Correlation") | |
| )) | |
| fig.update_layout( | |
| title=title or 'Correlation Heatmap', | |
| xaxis_tickangle=-45, | |
| height=500, | |
| width=600 | |
| ) | |
| return fig | |
| def create_plotly_timeseries(df: pd.DataFrame, date_col: str, value_col: str, | |
| agg_method: str = 'sum', | |
| title: Optional[str] = None): | |
| """Creates an interactive time series with hover details.""" | |
| # Aggregate by date | |
| if agg_method == 'sum': | |
| data = df.groupby(date_col)[value_col].sum().reset_index() | |
| elif agg_method == 'mean': | |
| data = df.groupby(date_col)[value_col].mean().reset_index() | |
| else: | |
| data = df.groupby(date_col)[value_col].sum().reset_index() | |
| fig = px.line( | |
| data, | |
| x=date_col, | |
| y=value_col, | |
| title=title or f'{value_col} Trend', | |
| markers=True, | |
| template='plotly_dark' | |
| ) | |
| fig.update_layout( | |
| hovermode='x unified', | |
| height=400 | |
| ) | |
| return fig | |