Skip to content

Commit 271b049

Browse files
authored
Merge branch 'main' into gradient_free_optimizers
2 parents e9659e0 + 0f65cb4 commit 271b049

File tree

6 files changed

+411
-137
lines changed

6 files changed

+411
-137
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "0",
6+
"metadata": {},
7+
"source": [
8+
"# How to change the plotting backend"
9+
]
10+
},
11+
{
12+
"cell_type": "markdown",
13+
"id": "1",
14+
"metadata": {},
15+
"source": [
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+
":::\n",
42+
"\n",
43+
"::::"
44+
]
45+
},
46+
{
47+
"cell_type": "markdown",
48+
"id": "3",
49+
"metadata": {},
50+
"source": [
51+
"In the following guide, we showcase the criterion plot visualized using different\n",
52+
"backends."
53+
]
54+
},
55+
{
56+
"cell_type": "code",
57+
"execution_count": null,
58+
"id": "4",
59+
"metadata": {},
60+
"outputs": [],
61+
"source": [
62+
"import numpy as np\n",
63+
"\n",
64+
"import optimagic as om\n",
65+
"\n",
66+
"\n",
67+
"def sphere(x):\n",
68+
" return x @ x\n",
69+
"\n",
70+
"\n",
71+
"results = {}\n",
72+
"for algo in [\"scipy_lbfgsb\", \"scipy_neldermead\"]:\n",
73+
" results[algo] = om.minimize(sphere, params=np.arange(5), algorithm=algo)"
74+
]
75+
},
76+
{
77+
"cell_type": "markdown",
78+
"id": "5",
79+
"metadata": {},
80+
"source": [
81+
"## Plotly"
82+
]
83+
},
84+
{
85+
"cell_type": "markdown",
86+
"id": "6",
87+
"metadata": {},
88+
"source": [
89+
":::{note}\n",
90+
"\n",
91+
"**Choose the Plotly renderer according to your environment:**\n",
92+
"\n",
93+
"- Use `plotly.io.renderers.default = \"notebook_connected\"` in Jupyter notebooks for interactive plots.\n",
94+
"- Use `plotly.io.renderers.default = \"browser\"` to open plots in your default web browser when running as a script.\n",
95+
"\n",
96+
"Refer to the [Plotly documentation](https://plotly.com/python/renderers/) for more details.\n",
97+
"\n",
98+
":::"
99+
]
100+
},
101+
{
102+
"cell_type": "code",
103+
"execution_count": null,
104+
"id": "7",
105+
"metadata": {},
106+
"outputs": [],
107+
"source": [
108+
"import plotly.io as pio\n",
109+
"\n",
110+
"pio.renderers.default = \"notebook_connected\"\n",
111+
"\n",
112+
"fig = om.criterion_plot(results, backend=\"plotly\") # Also the default\n",
113+
"fig.show()"
114+
]
115+
},
116+
{
117+
"cell_type": "markdown",
118+
"id": "8",
119+
"metadata": {},
120+
"source": [
121+
"## Matplotlib"
122+
]
123+
},
124+
{
125+
"cell_type": "code",
126+
"execution_count": null,
127+
"id": "9",
128+
"metadata": {},
129+
"outputs": [],
130+
"source": [
131+
"ax = om.criterion_plot(results, backend=\"matplotlib\")"
132+
]
133+
}
134+
],
135+
"metadata": {
136+
"kernelspec": {
137+
"display_name": "Python 3",
138+
"language": "python",
139+
"name": "python3"
140+
},
141+
"language_info": {
142+
"codemirror_mode": {
143+
"name": "ipython",
144+
"version": 3
145+
},
146+
"file_extension": ".py",
147+
"mimetype": "text/x-python",
148+
"name": "python",
149+
"nbconvert_exporter": "python",
150+
"pygments_lexer": "ipython3",
151+
"version": "3.10.18"
152+
}
153+
},
154+
"nbformat": 4,
155+
"nbformat_minor": 5
156+
}

docs/source/how_to/how_to_visualize_histories.ipynb

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,26 @@
7777
"cell_type": "markdown",
7878
"id": "6",
7979
"metadata": {},
80+
"source": [
81+
":::{note}\n",
82+
"\n",
83+
"For details on using other plotting backends, see [How to change the plotting backend](how_to_change_plotting_backend.ipynb).\n",
84+
"\n",
85+
":::"
86+
]
87+
},
88+
{
89+
"cell_type": "markdown",
90+
"id": "7",
91+
"metadata": {},
8092
"source": [
8193
"## Compare two optimizations in a criterion plot"
8294
]
8395
},
8496
{
8597
"cell_type": "code",
8698
"execution_count": null,
87-
"id": "7",
99+
"id": "8",
88100
"metadata": {},
89101
"outputs": [],
90102
"source": [
@@ -94,16 +106,16 @@
94106
},
95107
{
96108
"cell_type": "markdown",
97-
"id": "8",
109+
"id": "9",
98110
"metadata": {},
99111
"source": [
100-
"## Use some advanced options of criterion_plot"
112+
"## Use some advanced options of criterion plot"
101113
]
102114
},
103115
{
104116
"cell_type": "code",
105117
"execution_count": null,
106-
"id": "9",
118+
"id": "10",
107119
"metadata": {},
108120
"outputs": [],
109121
"source": [
@@ -119,7 +131,7 @@
119131
},
120132
{
121133
"cell_type": "markdown",
122-
"id": "10",
134+
"id": "11",
123135
"metadata": {},
124136
"source": [
125137
"## Make a params plot"
@@ -128,7 +140,7 @@
128140
{
129141
"cell_type": "code",
130142
"execution_count": null,
131-
"id": "11",
143+
"id": "12",
132144
"metadata": {},
133145
"outputs": [],
134146
"source": [
@@ -138,7 +150,7 @@
138150
},
139151
{
140152
"cell_type": "markdown",
141-
"id": "12",
153+
"id": "13",
142154
"metadata": {},
143155
"source": [
144156
"## Use advanced options of params plot"
@@ -147,7 +159,7 @@
147159
{
148160
"cell_type": "code",
149161
"execution_count": null,
150-
"id": "13",
162+
"id": "14",
151163
"metadata": {},
152164
"outputs": [],
153165
"source": [
@@ -163,16 +175,16 @@
163175
},
164176
{
165177
"cell_type": "markdown",
166-
"id": "14",
178+
"id": "15",
167179
"metadata": {},
168180
"source": [
169-
"## criterion_plot with multistart optimization"
181+
"## Criterion plot with multistart optimization"
170182
]
171183
},
172184
{
173185
"cell_type": "code",
174186
"execution_count": null,
175-
"id": "15",
187+
"id": "16",
176188
"metadata": {},
177189
"outputs": [],
178190
"source": [
@@ -192,7 +204,7 @@
192204
{
193205
"cell_type": "code",
194206
"execution_count": null,
195-
"id": "16",
207+
"id": "17",
196208
"metadata": {},
197209
"outputs": [],
198210
"source": [
@@ -203,7 +215,7 @@
203215
],
204216
"metadata": {
205217
"kernelspec": {
206-
"display_name": "Python 3 (ipykernel)",
218+
"display_name": "Python 3",
207219
"language": "python",
208220
"name": "python3"
209221
},
@@ -217,7 +229,7 @@
217229
"name": "python",
218230
"nbconvert_exporter": "python",
219231
"pygments_lexer": "ipython3",
220-
"version": "3.10.14"
232+
"version": "3.10.17"
221233
}
222234
},
223235
"nbformat": 4,

docs/source/how_to/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ how_to_constraints
1919
how_to_globalization
2020
how_to_multistart
2121
how_to_visualize_histories
22+
how_to_change_plotting_backend
2223
how_to_scaling
2324
how_to_logging
2425
how_to_errors_during_optimization

src/optimagic/visualization/backends.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
from typing import Any, Literal, Protocol, runtime_checkable
1+
from typing import TYPE_CHECKING, Any, Literal, Protocol, runtime_checkable
22

33
import plotly.graph_objects as go
44

55
from optimagic.config import IS_MATPLOTLIB_INSTALLED
66
from optimagic.exceptions import InvalidPlottingBackendError, NotInstalledError
77
from optimagic.visualization.plotting_utilities import LineData
88

9-
if IS_MATPLOTLIB_INSTALLED:
9+
if TYPE_CHECKING:
1010
import matplotlib.pyplot as plt
1111

1212

@@ -38,7 +38,7 @@ def _line_plot_plotly(
3838
legend_properties: dict[str, Any] | None,
3939
) -> go.Figure:
4040
if template is None:
41-
template = "plotly"
41+
template = "simple_white"
4242

4343
fig = go.Figure()
4444

@@ -49,6 +49,7 @@ def _line_plot_plotly(
4949
name=line.name,
5050
line_color=line.color,
5151
mode="lines",
52+
showlegend=line.show_in_legend,
5253
)
5354
fig.add_trace(trace)
5455

@@ -78,6 +79,16 @@ def _line_plot_matplotlib(
7879
width: int | None,
7980
legend_properties: dict[str, Any] | None,
8081
) -> "plt.Axes":
82+
import matplotlib.pyplot as plt
83+
84+
# In interactive environments (like Jupyter), explicitly enable matplotlib's
85+
# interactive mode. If it is not enabled, matplotlib's context manager will
86+
# revert to non-interactive mode after creating the first figure, causing
87+
# subsequent figures to not display inline.
88+
# See: https://github.com/matplotlib/matplotlib/issues/26716
89+
if plt.get_backend() == "module://matplotlib_inline.backend_inline":
90+
plt.ion()
91+
8192
if template is None:
8293
template = "default"
8394

@@ -123,6 +134,8 @@ def line_plot(
123134
124135
Args:
125136
lines: List of objects each containing data for a line in the plot.
137+
The order of lines in the list determines the order in which they are
138+
plotted, with later lines being rendered on top of earlier ones.
126139
backend: The backend to use for plotting.
127140
title: Title of the plot.
128141
xlabel: Label for the x-axis.

0 commit comments

Comments
 (0)