Source code for attribench.plot._mad_ratio_plot

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from attribench.plot import Plot


def mad_ratio(df):
    # Basically the F-ratio but using MAD instead of SS
    # MAD = median of absolute deviation to median
    # Mean of MADs for each method
    group_medians = df.median()
    within_mad = df.sub(group_medians).abs().median().mean()

    # MAD of group medians to global median
    global_median = df.stack().median()
    # between_mad = group_medians.sub(global_median).abs().median()
    between_mad = df.stack().sub(global_median).abs().median()

    return between_mad / within_mad


[docs]class MADRatioPlot(Plot): """ Bar plot of the MAD (Median Absolute Deviation) ratio for each metric. The MAD ratio is the ratio of the total MAD to the MAD within groups. If this ratio is high, it means that there are differences in method behaviour. If the ratio is close to 1, it means that the methods behave similarly. This can be viewed as a one-way ANOVA test, but using non-parametric MAD instead of sum-of-squares. """
[docs] def render( self, title: str | None = None, figsize=(10, 10), fontsize=20 ) -> Figure: """Render the plot. Parameters ---------- title : str | None, optional Title of the figure, by default None figsize : tuple, optional Size of the figure, by default (10, 10) fontsize : int, optional Font size of x and y axis ticks, by default 20 Returns ------- Figure Rendered Matplotlib figure. """ ratios = {} for metric_name, (df, inverted) in self.dfs.items(): ratios[metric_name] = mad_ratio(df) df = pd.DataFrame(ratios, index=["MAD Ratio"]).transpose() fig, ax = plt.subplots() plt.xticks(fontsize=fontsize) plt.yticks(fontsize=fontsize) df.plot.barh(figsize=figsize, ax=ax) if title is not None: ax.set_title(title) fig.tight_layout() return fig