Plot evaluation result during training. Only for demonstration purpose as it's quite slow to draw using matplotlib.
| 19 | |
| 20 | |
| 21 | class Plotting(xgb.callback.TrainingCallback): |
| 22 | """Plot evaluation result during training. Only for demonstration purpose as it's |
| 23 | quite slow to draw using matplotlib. |
| 24 | |
| 25 | """ |
| 26 | |
| 27 | def __init__(self, rounds: int) -> None: |
| 28 | self.fig = plt.figure() |
| 29 | self.ax = self.fig.add_subplot(111) |
| 30 | self.rounds = rounds |
| 31 | self.lines: Dict[str, plt.Line2D] = {} |
| 32 | self.fig.show() |
| 33 | self.x = np.linspace(0, self.rounds, self.rounds) |
| 34 | plt.ion() |
| 35 | |
| 36 | def _get_key(self, data: str, metric: str) -> str: |
| 37 | return f"{data}-{metric}" |
| 38 | |
| 39 | def after_iteration( |
| 40 | self, model: xgb.Booster, epoch: int, evals_log: Dict[str, dict] |
| 41 | ) -> bool: |
| 42 | """Update the plot.""" |
| 43 | if not self.lines: |
| 44 | for data, metric in evals_log.items(): |
| 45 | for metric_name, log in metric.items(): |
| 46 | key = self._get_key(data, metric_name) |
| 47 | expanded = log + [0] * (self.rounds - len(log)) |
| 48 | (self.lines[key],) = self.ax.plot(self.x, expanded, label=key) |
| 49 | self.ax.legend() |
| 50 | else: |
| 51 | # https://pythonspot.com/matplotlib-update-plot/ |
| 52 | for data, metric in evals_log.items(): |
| 53 | for metric_name, log in metric.items(): |
| 54 | key = self._get_key(data, metric_name) |
| 55 | expanded = log + [0] * (self.rounds - len(log)) |
| 56 | self.lines[key].set_ydata(expanded) |
| 57 | self.fig.canvas.draw() |
| 58 | # False to indicate training should not stop. |
| 59 | return False |
| 60 | |
| 61 | |
| 62 | def custom_callback() -> None: |