(heatmap: pd.Series, agg: Union[Callable, str], ncols: int,
filename: str = '', plot_width: int = 1200, open_browser: bool = True)
| 719 | |
| 720 | |
| 721 | def plot_heatmaps(heatmap: pd.Series, agg: Union[Callable, str], ncols: int, |
| 722 | filename: str = '', plot_width: int = 1200, open_browser: bool = True): |
| 723 | if not (isinstance(heatmap, pd.Series) and |
| 724 | isinstance(heatmap.index, pd.MultiIndex)): |
| 725 | raise ValueError('heatmap must be heatmap Series as returned by ' |
| 726 | '`Backtest.optimize(..., return_heatmap=True)`') |
| 727 | if len(heatmap.index.levels) < 2: |
| 728 | raise ValueError('`plot_heatmap()` requires at least two optimization ' |
| 729 | 'variables to plot') |
| 730 | |
| 731 | _bokeh_reset(filename) |
| 732 | |
| 733 | param_combinations = combinations(heatmap.index.names, 2) |
| 734 | dfs = [heatmap.groupby(list(dims)).agg(agg).to_frame(name='_Value') |
| 735 | for dims in param_combinations] |
| 736 | figs: list[_figure] = [] |
| 737 | cmap = LinearColorMapper(palette='Viridis256', |
| 738 | low=min(df.min().min() for df in dfs), |
| 739 | high=max(df.max().max() for df in dfs), |
| 740 | nan_color='white') |
| 741 | for df in dfs: |
| 742 | name1, name2 = df.index.names |
| 743 | level1 = df.index.levels[0].astype(str).tolist() |
| 744 | level2 = df.index.levels[1].astype(str).tolist() |
| 745 | df = df.reset_index() |
| 746 | df[name1] = df[name1].astype('str') |
| 747 | df[name2] = df[name2].astype('str') |
| 748 | |
| 749 | fig = _figure(x_range=level1, # type: ignore[call-arg] |
| 750 | y_range=level2, |
| 751 | x_axis_label=name1, |
| 752 | y_axis_label=name2, |
| 753 | width=plot_width // ncols, |
| 754 | height=plot_width // ncols, |
| 755 | tools='box_zoom,reset,save', |
| 756 | tooltips=[(name1, '@' + name1), |
| 757 | (name2, '@' + name2), |
| 758 | ('Value', '@_Value{0.[000]}')]) |
| 759 | fig.grid.grid_line_color = None # type: ignore[attr-defined] |
| 760 | fig.axis.axis_line_color = None # type: ignore[attr-defined] |
| 761 | fig.axis.major_tick_line_color = None # type: ignore[attr-defined] |
| 762 | fig.axis.major_label_standoff = 0 # type: ignore[attr-defined] |
| 763 | |
| 764 | if not len(figs): |
| 765 | _watermark(fig) |
| 766 | |
| 767 | fig.rect(x=name1, |
| 768 | y=name2, |
| 769 | width=1, |
| 770 | height=1, |
| 771 | source=df, |
| 772 | line_color=None, |
| 773 | fill_color=dict(field='_Value', |
| 774 | transform=cmap)) |
| 775 | figs.append(fig) |
| 776 | |
| 777 | fig = gridplot( |
| 778 | figs, # type: ignore |
nothing calls this directly
no test coverage detected