from datetime import date from gradio import BarPlot from langcodes import Language from pandas import DataFrame, concat from dataset_data import DatasetData from df_utils import DfUtils _TOP_N: int = 5 _OTHER_LABEL: str = "Other" class DescriptionLanguagePresenter: def __init__(self, data: DatasetData): self.__data = data @staticmethod def __language_name(code: str) -> str: return Language.get(code).display_name() def present(self) -> BarPlot: all_dfs: dict[date, DataFrame] = self.__data.get_parquet_dict() non_null_dfs: dict[date, DataFrame] = {} for day, df in all_dfs.items(): language_df: DataFrame = DfUtils.extract_description_language(df[["id", "anki_web"]]) non_null_dfs[day] = language_df[language_df["description_language"].notna()] all_languages_df: DataFrame = concat(non_null_dfs.values(), ignore_index=True) top_languages: list[str] = all_languages_df["description_language"].value_counts().head(_TOP_N).index.tolist() rows: list[dict] = [] for day, df in non_null_dfs.items(): total: int = len(df) if total == 0: continue counted_top: int = 0 for language in top_languages: count: int = int((df["description_language"] == language).sum()) counted_top += count rows.append( { "Date": str(day), "Language": self.__language_name(language), "Percentage": round(100 * count / total, 1), } ) other_count: int = total - counted_top rows.append( {"Date": str(day), "Language": _OTHER_LABEL, "Percentage": round(100 * other_count / total, 1)} ) plot_df: DataFrame = DataFrame(rows, columns=["Date", "Language", "Percentage"]) return BarPlot( plot_df, x="Date", y="Percentage", color="Language", y_title="Percentage of addons (%)", x_title="Snapshot date", y_lim=[0, 100], y_axis_format=".1f", sort="x", )