50 lines
1.6 KiB
Python
50 lines
1.6 KiB
Python
import os
|
|
import pandas as pd
|
|
import plotly.graph_objects as go
|
|
from flask import url_for
|
|
from abc import ABC, abstractmethod
|
|
|
|
from .base import BaseAnalysis
|
|
from app.analysis.data_utils import prepare_data, mk_plotdir
|
|
|
|
# -------------------------------------------
|
|
# Base Class for All Plotly Plot Analyses
|
|
# -------------------------------------------
|
|
class BasePlotlyAnalysis(BaseAnalysis, ABC):
|
|
"""
|
|
Base class for all Plotly plot-based analyses.
|
|
It enforces a structure for:
|
|
- Data preparation
|
|
- Transformation
|
|
- Plot generation
|
|
- Memory cleanup
|
|
"""
|
|
|
|
plot_filename = "default_plot.html"
|
|
alt_text = "Default Alt Text"
|
|
|
|
def execute(self, df: pd.DataFrame):
|
|
"""Executes the full analysis pipeline"""
|
|
df = prepare_data(df) # Step 1: Prepare data
|
|
|
|
paths = mk_plotdir(self.plot_filename)
|
|
self.output_path, self.plot_url = paths['output_path'], paths['plot_url']
|
|
|
|
df = self.transform_data(df) # Step 2: Transform data (implemented by subclass)
|
|
self.plot_data(df) # Step 3: Create the plot
|
|
|
|
# Save the plot as an HTML file
|
|
self.fig.write_html(self.output_path)
|
|
|
|
del df # Step 4: Free memory
|
|
return f'<iframe src="{self.plot_url}" width="100%" height="600"></iframe>'
|
|
|
|
@abstractmethod
|
|
def transform_data(self, df: pd.DataFrame) -> pd.DataFrame:
|
|
"""Subclasses must define how they transform the data"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def plot_data(self, df: pd.DataFrame):
|
|
"""Subclasses must define how they generate the plot"""
|
|
pass |