|
14 | 14 | "metadata": {}, |
15 | 15 | "source": [ |
16 | 16 | "optimagic supports various visualization libraries as plotting backends, which can be\n", |
17 | | - "selected using the `backend` argument." |
18 | | - ] |
19 | | - }, |
20 | | - { |
21 | | - "cell_type": "markdown", |
22 | | - "id": "2", |
23 | | - "metadata": {}, |
24 | | - "source": [ |
25 | | - "::::{tab-set}\n", |
26 | | - "\n", |
27 | | - ":::{tab-item} Plotly\n", |
28 | | - "\n", |
29 | | - "The default plotting library. To select the Plotly backend explicitly, set `backend=\"plotly\"`.\n", |
30 | | - "\n", |
31 | | - "The returned figure object is a [`plotly.graph_objects.Figure`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html).\n", |
32 | | - "\n", |
33 | | - ":::\n", |
34 | | - "\n", |
35 | | - ":::{tab-item} Matplotlib\n", |
36 | | - "\n", |
37 | | - "To select the Matplotlib backend, set `backend=\"matplotlib\"`.\n", |
38 | | - "\n", |
39 | | - "The returned figure object is a [`matplotlib.axes.Axes`](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html).\n", |
40 | | - "\n", |
41 | | - "```{note}\n", |
42 | | - "In case of grid plots (such as `convergence_plot` or `slice_plot`), the returned object is a 2-dimensional numpy array of `Axes` objects: [`numpy.ndarray`](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html)[[`matplotlib.axes.Axes`]](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html) of shape `(n_rows, n_cols)`.\n", |
43 | | - "```\n", |
44 | | - "\n", |
45 | | - ":::\n", |
46 | | - "\n", |
47 | | - ":::{tab-item} Bokeh\n", |
48 | | - "\n", |
49 | | - "To select the Bokeh backend, set `backend=\"bokeh\"`.\n", |
50 | | - "\n", |
51 | | - "The returned figure object is a [`bokeh.plotting.figure`](https://docs.bokeh.org/en/latest/docs/reference/plotting/figure.html).\n", |
52 | | - "\n", |
53 | | - "```{note}\n", |
54 | | - "In case of grid plots (such as `convergence_plot` or `slice_plot`), the returned object is a [`bokeh.models.GridPlot`](https://docs.bokeh.org/en/latest/docs/reference/models/plots.html#bokeh.models.GridPlot) object.\n", |
55 | | - "```\n", |
56 | | - "\n", |
57 | | - "```{warning}\n", |
58 | | - "Bokeh applies themes globally. Passing the `template` parameter to a plotting function updates the theme for all existing and future Bokeh plots. If you do not pass `template`, a default template is applied, which will also change the global theme.\n", |
59 | | - "```\n", |
60 | | - "\n", |
61 | | - ":::\n", |
62 | | - "\n", |
63 | | - ":::{tab-item} Altair\n", |
64 | | - "To select the Altair backend, set `backend=\"altair\"`.\n", |
65 | | - "\n", |
66 | | - "The returned figure object is an [`altair.Chart`](https://altair-viz.github.io/user_guide/generated/toplevel/altair.Chart.html).\n", |
67 | | - "\n", |
68 | | - "```{note}\n", |
69 | | - "In case of grid plots (such as `convergence_plot` or `slice_plot`), the returned object is either an [`altair.Chart`](https://altair-viz.github.io/user_guide/generated/toplevel/altair.Chart.html) if there is only one subplot, an [`altair.HConcatChart`](https://altair-viz.github.io/user_guide/generated/toplevel/altair.HConcatChart.html) if there is only one row, or an [`altair.VConcatChart`](https://altair-viz.github.io/user_guide/generated/toplevel/altair.VConcatChart.html) otherwise.\n", |
70 | | - "```\n", |
71 | | - "\n", |
72 | | - ":::\n", |
73 | | - "\n", |
74 | | - "::::" |
75 | | - ] |
76 | | - }, |
77 | | - { |
78 | | - "cell_type": "markdown", |
79 | | - "id": "3", |
80 | | - "metadata": {}, |
81 | | - "source": [ |
82 | | - "In the following guide, we showcase the criterion plot visualized using different\n", |
83 | | - "backends." |
| 17 | + "selected using the `backend` argument. In the following guide, we showcase the \n", |
| 18 | + "`criterion_plot` visualized using different backends." |
84 | 19 | ] |
85 | 20 | }, |
86 | 21 | { |
87 | 22 | "cell_type": "code", |
88 | 23 | "execution_count": null, |
89 | | - "id": "4", |
| 24 | + "id": "2", |
90 | 25 | "metadata": {}, |
91 | 26 | "outputs": [], |
92 | 27 | "source": [ |
|
106 | 41 | }, |
107 | 42 | { |
108 | 43 | "cell_type": "markdown", |
109 | | - "id": "5", |
| 44 | + "id": "3", |
110 | 45 | "metadata": {}, |
111 | 46 | "source": [ |
112 | | - "## Plotly" |
| 47 | + "## Backends" |
113 | 48 | ] |
114 | 49 | }, |
115 | 50 | { |
116 | 51 | "cell_type": "markdown", |
117 | | - "id": "6", |
| 52 | + "id": "4", |
| 53 | + "metadata": {}, |
| 54 | + "source": [ |
| 55 | + "### Plotly" |
| 56 | + ] |
| 57 | + }, |
| 58 | + { |
| 59 | + "cell_type": "markdown", |
| 60 | + "id": "5", |
118 | 61 | "metadata": {}, |
119 | 62 | "source": [ |
120 | | - ":::{note}\n", |
| 63 | + "The default plotting library. To select the Plotly backend explicitly, set `backend=\"plotly\"`.\n", |
| 64 | + "\n", |
| 65 | + "The returned figure object is a [`plotly.graph_objects.Figure`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html).\n", |
121 | 66 | "\n", |
| 67 | + "```{note}\n", |
122 | 68 | "**Choose the Plotly renderer according to your environment:**\n", |
123 | 69 | "\n", |
124 | 70 | "- Use `plotly.io.renderers.default = \"notebook_connected\"` in Jupyter notebooks for interactive plots.\n", |
125 | 71 | "- Use `plotly.io.renderers.default = \"browser\"` to open plots in your default web browser when running as a script.\n", |
126 | 72 | "\n", |
127 | 73 | "Refer to the [Plotly documentation](https://plotly.com/python/renderers/) for more details.\n", |
128 | | - "\n", |
129 | | - ":::" |
| 74 | + "```" |
130 | 75 | ] |
131 | 76 | }, |
132 | 77 | { |
133 | 78 | "cell_type": "code", |
134 | 79 | "execution_count": null, |
135 | | - "id": "7", |
| 80 | + "id": "6", |
136 | 81 | "metadata": {}, |
137 | 82 | "outputs": [], |
138 | 83 | "source": [ |
|
144 | 89 | "fig.show()" |
145 | 90 | ] |
146 | 91 | }, |
| 92 | + { |
| 93 | + "cell_type": "markdown", |
| 94 | + "id": "7", |
| 95 | + "metadata": {}, |
| 96 | + "source": [ |
| 97 | + "### Matplotlib" |
| 98 | + ] |
| 99 | + }, |
147 | 100 | { |
148 | 101 | "cell_type": "markdown", |
149 | 102 | "id": "8", |
150 | 103 | "metadata": {}, |
151 | 104 | "source": [ |
152 | | - "## Matplotlib" |
| 105 | + "To select the Matplotlib backend, set `backend=\"matplotlib\"`.\n", |
| 106 | + "\n", |
| 107 | + "The returned figure object is a [`matplotlib.axes.Axes`](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html).\n", |
| 108 | + "\n", |
| 109 | + "In case of grid plots (such as `convergence_plot` or `slice_plot`), the returned object is a 2-dimensional numpy array of `Axes` objects: [`numpy.ndarray`](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html)[[`matplotlib.axes.Axes`]](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html) of shape `(n_rows, n_cols)`." |
153 | 110 | ] |
154 | 111 | }, |
155 | 112 | { |
|
167 | 124 | "id": "10", |
168 | 125 | "metadata": {}, |
169 | 126 | "source": [ |
170 | | - "## Bokeh" |
| 127 | + "### Bokeh" |
| 128 | + ] |
| 129 | + }, |
| 130 | + { |
| 131 | + "cell_type": "markdown", |
| 132 | + "id": "11", |
| 133 | + "metadata": {}, |
| 134 | + "source": [ |
| 135 | + "To select the Bokeh backend, set `backend=\"bokeh\"`.\n", |
| 136 | + "\n", |
| 137 | + "The returned figure object is a [`bokeh.plotting.figure`](https://docs.bokeh.org/en/latest/docs/reference/plotting/figure.html).\n", |
| 138 | + "\n", |
| 139 | + "In case of grid plots (such as `convergence_plot` or `slice_plot`), the returned object is a [`bokeh.models.GridPlot`](https://docs.bokeh.org/en/latest/docs/reference/models/plots.html#bokeh.models.GridPlot) object.\n", |
| 140 | + "\n", |
| 141 | + "```{warning}\n", |
| 142 | + "- Bokeh applies themes globally. Passing the `template` parameter to a plotting function updates the theme for all existing and future Bokeh plots. If you do not pass `template`, a default template is applied, which will also change the global theme.\n", |
| 143 | + "- Bokeh doesn't support titles for grid plots. So, the `title` parameter in `slice_plot` is ignored when using the Bokeh backend.\n", |
| 144 | + "```\n" |
171 | 145 | ] |
172 | 146 | }, |
173 | 147 | { |
174 | 148 | "cell_type": "code", |
175 | 149 | "execution_count": null, |
176 | | - "id": "11", |
| 150 | + "id": "12", |
177 | 151 | "metadata": {}, |
178 | 152 | "outputs": [], |
179 | 153 | "source": [ |
|
187 | 161 | }, |
188 | 162 | { |
189 | 163 | "cell_type": "markdown", |
190 | | - "id": "12", |
| 164 | + "id": "13", |
191 | 165 | "metadata": {}, |
192 | 166 | "source": [ |
193 | | - "## Altair" |
| 167 | + "### Altair" |
194 | 168 | ] |
195 | 169 | }, |
196 | 170 | { |
197 | 171 | "cell_type": "markdown", |
198 | | - "id": "13", |
| 172 | + "id": "14", |
199 | 173 | "metadata": {}, |
200 | 174 | "source": [ |
201 | | - ":::{note}\n", |
| 175 | + "To select the Altair backend, set `backend=\"altair\"`.\n", |
| 176 | + "\n", |
| 177 | + "The returned figure object is an [`altair.Chart`](https://altair-viz.github.io/user_guide/generated/toplevel/altair.Chart.html).\n", |
| 178 | + "\n", |
| 179 | + "In case of grid plots (such as `convergence_plot` or `slice_plot`), the returned object is either an [`altair.Chart`](https://altair-viz.github.io/user_guide/generated/toplevel/altair.Chart.html) if there is only one subplot, an [`altair.HConcatChart`](https://altair-viz.github.io/user_guide/generated/toplevel/altair.HConcatChart.html) if there is only one row, or an [`altair.VConcatChart`](https://altair-viz.github.io/user_guide/generated/toplevel/altair.VConcatChart.html) otherwise.\n", |
| 180 | + "\n", |
| 181 | + "```{warning}\n", |
| 182 | + "Altair applies themes globally. Passing the `template` parameter to a plotting function updates the theme for all existing and future Altair plots. If you do not pass `template`, a default template is applied, which will also change the global theme.\n", |
| 183 | + "```\n", |
202 | 184 | "\n", |
| 185 | + "```{note}\n", |
203 | 186 | "It is mostly not required to set the renderer manually, as Altair automatically\n", |
204 | 187 | "selects the appropriate renderer based on your environment. In this example,\n", |
205 | 188 | "we explicitly set the renderer to ensure correct display within the documentation.\n", |
206 | 189 | "\n", |
207 | 190 | "Refer to the [Altair documentation](https://altair-viz.github.io/user_guide/display_frontends.html) for more details.\n", |
208 | | - "\n", |
209 | | - ":::" |
| 191 | + "```\n" |
210 | 192 | ] |
211 | 193 | }, |
212 | 194 | { |
213 | 195 | "cell_type": "code", |
214 | 196 | "execution_count": null, |
215 | | - "id": "14", |
| 197 | + "id": "15", |
216 | 198 | "metadata": {}, |
217 | 199 | "outputs": [], |
218 | 200 | "source": [ |
|
224 | 206 | "chart = om.criterion_plot(results, backend=\"altair\")\n", |
225 | 207 | "chart.show()" |
226 | 208 | ] |
| 209 | + }, |
| 210 | + { |
| 211 | + "cell_type": "markdown", |
| 212 | + "id": "16", |
| 213 | + "metadata": {}, |
| 214 | + "source": [ |
| 215 | + "## Customizing plots" |
| 216 | + ] |
| 217 | + }, |
| 218 | + { |
| 219 | + "cell_type": "markdown", |
| 220 | + "id": "17", |
| 221 | + "metadata": {}, |
| 222 | + "source": [ |
| 223 | + "Here, we provide a simple example of how to customize plots created with different backends.\n", |
| 224 | + "\n", |
| 225 | + "::::{tab-set}\n", |
| 226 | + "\n", |
| 227 | + ":::{tab-item} Plotly\n", |
| 228 | + "\n", |
| 229 | + "```python\n", |
| 230 | + "fig = om.criterion_plot(results, backend=\"plotly\")\n", |
| 231 | + "\n", |
| 232 | + "# Configure Axes\n", |
| 233 | + "fig.update_yaxes(title_text=\"Custom Y Label\", title_font_size=20)\n", |
| 234 | + "fig.update_xaxes(range=[0, 100])\n", |
| 235 | + "\n", |
| 236 | + "# Change legend position\n", |
| 237 | + "fig.update_layout(legend=dict(xanchor=\"left\", yanchor=\"top\", x=1, y=0.6))\n", |
| 238 | + "\n", |
| 239 | + "# Configure line properties\n", |
| 240 | + "# The index corresponding to a line, can be inferred from the legend\n", |
| 241 | + "# In case of criterion_plot, it is the order of optimizers in `results`\n", |
| 242 | + "fig.data[0].update(line=dict(width=4))\n", |
| 243 | + "fig.data[1].update(line=dict(dash=\"dashdot\"))\n", |
| 244 | + "\n", |
| 245 | + "fig.show()\n", |
| 246 | + "```\n", |
| 247 | + ":::\n", |
| 248 | + "\n", |
| 249 | + ":::{tab-item} Matplotlib\n", |
| 250 | + "\n", |
| 251 | + "```python\n", |
| 252 | + "ax = om.criterion_plot(results, backend=\"matplotlib\")\n", |
| 253 | + "\n", |
| 254 | + "# Configure Axis\n", |
| 255 | + "ax.set_ylabel(ylabel=\"Custom Y Label\", fontsize=20)\n", |
| 256 | + "ax.set_xlim(0, 100)\n", |
| 257 | + "\n", |
| 258 | + "# Change legend position\n", |
| 259 | + "ax.figure.legends[0].set_loc(\"outside center right\")\n", |
| 260 | + "\n", |
| 261 | + "# Configure line properties\n", |
| 262 | + "# The index corresponding to a line, can be inferred from the legend\n", |
| 263 | + "# In case of criterion_plot, it is the order of optimizers in `results`\n", |
| 264 | + "ax.lines[0].set_linewidth(4)\n", |
| 265 | + "ax.lines[1].set_linestyle(\"dashdot\")\n", |
| 266 | + "```\n", |
| 267 | + "\n", |
| 268 | + ":::\n", |
| 269 | + "\n", |
| 270 | + ":::{tab-item} Bokeh\n", |
| 271 | + "\n", |
| 272 | + "```python\n", |
| 273 | + "from bokeh.models import Range1d\n", |
| 274 | + "\n", |
| 275 | + "p = om.criterion_plot(results, backend=\"bokeh\")\n", |
| 276 | + "\n", |
| 277 | + "# Configure Axes\n", |
| 278 | + "p.yaxis.axis_label = \"Custom Y Label\"\n", |
| 279 | + "p.yaxis.axis_label_text_font_size = \"20pt\"\n", |
| 280 | + "p.x_range = Range1d(0, 100)\n", |
| 281 | + "\n", |
| 282 | + "# Change legend position\n", |
| 283 | + "p.add_layout(p.legend[0], \"right\")\n", |
| 284 | + "p.legend[0].location = \"center\"\n", |
| 285 | + "\n", |
| 286 | + "# Configure line properties\n", |
| 287 | + "# The index corresponding to a line, can be inferred from the legend\n", |
| 288 | + "# In case of criterion_plot, it is the order of optimizers in `results`\n", |
| 289 | + "p.renderers[0].glyph.line_width = 4\n", |
| 290 | + "p.renderers[1].glyph.line_dash = \"dashdot\"\n", |
| 291 | + "\n", |
| 292 | + "show(p)\n", |
| 293 | + "```\n", |
| 294 | + "\n", |
| 295 | + ":::\n", |
| 296 | + "\n", |
| 297 | + ":::{tab-item} Altair\n", |
| 298 | + "\n", |
| 299 | + "```{note}\n", |
| 300 | + "Due to the nature of Altair charts, top-level configuration may not work as expected. In these cases, it might be necessary to override the encoding.\n", |
| 301 | + "```\n", |
| 302 | + "\n", |
| 303 | + "```python\n", |
| 304 | + "import altair as alt\n", |
| 305 | + "\n", |
| 306 | + "chart = om.criterion_plot(results, backend=\"altair\")\n", |
| 307 | + "\n", |
| 308 | + "# Configure Axes\n", |
| 309 | + "chart = chart.encode(\n", |
| 310 | + " y=alt.Y(\"y\", axis=alt.Axis(title=\"Custom Y Label\", titleFontSize=20)),\n", |
| 311 | + " x=alt.X(\"x\", scale=alt.Scale(domain=(0, 100))),\n", |
| 312 | + ")\n", |
| 313 | + "\n", |
| 314 | + "# Configure lines\n", |
| 315 | + "chart = chart.encode(\n", |
| 316 | + " strokeWidth=alt.condition(\n", |
| 317 | + " alt.datum.name == \"scipy_lbfgsb\", alt.value(4), alt.value(2)\n", |
| 318 | + " ),\n", |
| 319 | + " strokeDash=alt.condition(\n", |
| 320 | + " alt.datum.name == \"scipy_neldermead\", alt.value([8, 4, 2, 4]), alt.value([1, 0])\n", |
| 321 | + " ),\n", |
| 322 | + ")\n", |
| 323 | + "\n", |
| 324 | + "chart.show()\n", |
| 325 | + "```\n", |
| 326 | + "\n", |
| 327 | + ":::\n", |
| 328 | + "\n", |
| 329 | + "::::" |
| 330 | + ] |
227 | 331 | } |
228 | 332 | ], |
229 | 333 | "metadata": { |
|
0 commit comments