in src/evaluate/visualization.py [0:0]
def radar_plot(data, model_names, invert_range=[], config=None, fig=None):
"""Create a complex radar chart with different scales for each variable
Source: https://towardsdatascience.com/how-to-create-and-visualize-complex-radar-charts-f7764d0f3652
Args:
data (`List[dict]`): the results (list of metric + value pairs).
E.g. data = [{"accuracy": 0.9, "precision":0.8},{"accuracy": 0.7, "precision":0.6}]
names (`List[dict]`): model names.
E.g. names = ["model1", "model 2", ...]
invert_range (`List[dict]`, optional): the metrics to invert (in cases when smaller is better, e.g. speed)
E.g. invert_range=["latency_in_seconds"]
config (`dict`, optional) : a specification of the formatting configurations, namely:
- rad_ln_args (`dict`, default `{"visible": True}`): The visibility of the radial (circle) lines.
- outer_ring (`dict`, default `{"visible": True}`): The visibility of the outer ring.
- angle_ln_args (`dict`, default `{"visible": True}`): The visibility of the angle lines.
- rgrid_tick_lbls_args (`dict`, default `{"fontsize": 12}`): The font size of the tick labels on the scales.
- theta_tick_lbls (`dict`, default `{"fontsize": 12}`): The font size of the variable labels on the plot.
- theta_tick_lbls_pad (`int`, default `3`): The padding of the variable labels on the plot.
- theta_tick_lbls_brk_lng_wrds (`bool`, default `True` ): Whether long words in the label are broken up or not.
- theta_tick_lbls_txt_wrap (`int`, default `15`): Text wrap for tick labels
- incl_endpoint (`bool`, default `False`): Include value endpoints on calse
- marker (`str`, default `"o"`): the shape of the marker used in the radar plot.
- markersize (`int`, default `3`): the shape of the marker used in the radar plot.
- legend_loc (`str`, default `"upper right"`): the location of the legend in the radar plot. Must be one of: 'upper left', 'upper right', 'lower left', 'lower right'.
- bbox_to_anchor (`tuple`, default `(2, 1)`: anchor for the legend.
fig (`matplotlib.figure.Figure`, optional): figure used to plot the radar plot.
Returns:
`matplotlib.figure.Figure`
"""
data = pd.DataFrame(data)
data.index = model_names
variables = data.keys()
if all(x in variables for x in invert_range) is False:
raise ValueError("All of the metrics in `invert_range` should be in the data provided.")
min_max_per_variable = data.describe().T[["min", "max"]]
min_max_per_variable["min"] = min_max_per_variable["min"] - 0.1 * (
min_max_per_variable["max"] - min_max_per_variable["min"]
)
min_max_per_variable["max"] = min_max_per_variable["max"] + 0.1 * (
min_max_per_variable["max"] - min_max_per_variable["min"]
)
ranges = list(min_max_per_variable.itertuples(index=False, name=None))
ranges = [
(max_value, min_value) if var in invert_range else (min_value, max_value)
for var, (min_value, max_value) in zip(variables, ranges)
]
format_cfg = {
"axes_args": {},
"rad_ln_args": {"visible": True},
"outer_ring": {"visible": True},
"angle_ln_args": {"visible": True},
"rgrid_tick_lbls_args": {"fontsize": 12},
"theta_tick_lbls": {"fontsize": 12},
"theta_tick_lbls_pad": 3,
"theta_tick_lbls_brk_lng_wrds": True,
"theta_tick_lbls_txt_wrap": 15,
"incl_endpoint": False,
"marker": "o",
"markersize": 3,
"legend_loc": "upper right",
"bbox_to_anchor": (2, 1),
}
if config is not None:
format_cfg.update(config)
if fig is None:
fig = plt.figure()
radar = ComplexRadar(
fig,
variables,
ranges,
n_ring_levels=3,
show_scales=True,
format_cfg=format_cfg,
)
for g in zip(data.index):
radar.plot(data.loc[g].values, label=g, marker=format_cfg["marker"], markersize=format_cfg["markersize"])
radar.use_legend(**{"loc": format_cfg["legend_loc"], "bbox_to_anchor": format_cfg["bbox_to_anchor"]})
return fig