File size: 3,146 Bytes
3f98d52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"""Ubuntu plots from explicit evaluation records; never invent missing measurements."""
from pathlib import Path
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib import font_manager

GOLD = "#C68B25"
INK = "#302B25"

def configure_fonts(font_dir=None):
    if font_dir is None:
        font_dir = Path(__file__).resolve().parent/"fonts"
    for path in Path(font_dir).glob("*.ttf"):
        font_manager.fontManager.addfont(str(path))
    available = {f.name for f in font_manager.fontManager.ttflist}
    if "Ubuntu" not in available:
        raise ValueError("Ubuntu is unavailable; provide --font-dir pointing to the included fonts")
    plt.rcParams.update({"font.family": "Ubuntu", "font.size": 10, "mathtext.fontset": "cm",
                         "pdf.fonttype": 42, "ps.fonttype": 42, "axes.spines.top": False,
                         "axes.spines.right": False, "axes.labelcolor": INK, "text.color": INK,
                         "savefig.bbox": "tight", "figure.dpi": 160})

def plot_summary(summary, output, font_dir=None, title="Retrospective endpoint evaluation"):
    configure_fonts(font_dir)
    frame = pd.read_csv(summary) if not isinstance(summary, pd.DataFrame) else summary
    output = Path(output); output.mkdir(parents=True, exist_ok=True)
    for metric in frame.metric.unique():
        group = frame[frame.metric == metric].sort_values("mean", ascending=metric != "success")
        fig, ax = plt.subplots(figsize=(6.6, max(2.8, .38*len(group))))
        y = np.arange(len(group))
        colors = [GOLD if m == "remedi" else "#8C8982" for m in group.method]
        ax.barh(y, group["mean"], color=colors, height=.65)
        ax.errorbar(group["mean"], y, xerr=np.vstack([np.maximum(0, group["mean"]-group.ci_low), np.maximum(0, group.ci_high-group["mean"])]),
                    fmt="none", ecolor=INK, capsize=2, linewidth=.8)
        ax.set_yticks(y, group.method); ax.invert_yaxis()
        ax.set_xlabel(metric.replace("_", " ")); ax.set_title(title, loc="left", fontsize=11)
        fig.savefig(output/f"{metric}.pdf"); fig.savefig(output/f"{metric}.png"); plt.close(fig)

def plot_curve(csv, output, x, y, hue="method", lower=None, upper=None, font_dir=None):
    configure_fonts(font_dir)
    frame = pd.read_csv(csv)
    for field in [x, y, hue]:
        if field not in frame: raise ValueError(f"Missing plot column {field}")
    fig, ax = plt.subplots(figsize=(5.2, 3.4))
    palette = [GOLD, "#74716B", "#9E4A35", "#457679", "#756589"]
    for i, (name, group) in enumerate(frame.groupby(hue, sort=True)):
        group = group.sort_values(x)
        ax.plot(group[x], group[y], marker="o", markersize=3.5, label=name,
                color=GOLD if name == "remedi" else palette[(i+1) % len(palette)])
        if lower and upper:
            ax.fill_between(group[x], group[lower], group[upper], alpha=.13)
    ax.set_xlabel(x.replace("_", " ")); ax.set_ylabel(y.replace("_", " ")); ax.legend(frameon=False)
    output = Path(output); output.parent.mkdir(parents=True, exist_ok=True)
    fig.savefig(output); plt.close(fig)