Skip to content

plot

check_ij(i, j, k)

Check if indices i and j are valid for the number of features k. Args: i (int): Index of the first dimension. j (int): Index of the second dimension. k (int): Total number of features.

Source code in spotpython/surrogate/plot.py
360
361
362
363
364
365
366
367
368
369
370
371
def check_ij(i: int, j: int, k: int) -> None:
    """
    Check if indices i and j are valid for the number of features k.
    Args:
        i (int): Index of the first dimension.
        j (int): Index of the second dimension.
        k (int): Total number of features.
    """
    if i >= k or j >= k:
        raise ValueError(f"Dimensions i and j must be less than the number of features (k={k}).")
    if i == j:
        raise ValueError("Dimensions i and j must be different.")

error_color(z_actual, z_predicted, eps=0.0001, max_error=0.001)

Returns a grayscale color string based on the error between actual and predicted values. Underprediction (z_predicted < z_actual) is black, overprediction is white, zero error is gray. The mapping is linear between -max_error (black) and +max_error (white).

Parameters:

Name Type Description Default
z_actual float

The actual value.

required
z_predicted float

The predicted value.

required
eps float

Tolerance for considering values as close. Default is 1e-4.

0.0001
max_error float

Maximum error for color scaling. Default is 1e-3.

0.001

Returns:

Name Type Description
str str

Hex color string in the format “#RRGGBB”.

str str

Edge color indicating overprediction or underprediction. “black” for overprediction, “white” for underprediction.

Source code in spotpython/surrogate/plot.py
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def error_color(z_actual: float, z_predicted: float, eps: float = 1e-4, max_error: float = 1e-3) -> str:
    """
    Returns a grayscale color string based on the error between actual and predicted values.
    Underprediction (z_predicted < z_actual) is black, overprediction is white, zero error is gray.
    The mapping is linear between -max_error (black) and +max_error (white).

    Args:
        z_actual (float): The actual value.
        z_predicted (float): The predicted value.
        eps (float): Tolerance for considering values as close. Default is 1e-4.
        max_error (float): Maximum error for color scaling. Default is 1e-3.

    Returns:
        str: Hex color string in the format "#RRGGBB".
        str: Edge color indicating overprediction or underprediction.
            "black" for overprediction, "white" for underprediction.
    """
    diff = z_predicted - z_actual
    if diff > 0:
        edge_color = "black"  # prediction is too large (overprediction)
    else:
        edge_color = "grey"  # prediction is too small (underprediction)
    if abs(diff) <= eps:
        scale = 0.5  # gray
    else:
        # Clamp diff to [-max_error, max_error]
        diff = max(-max_error, min(diff, max_error))
        scale = 0.5 + 0.5 * (diff / max_error)
    scale = min(max(scale, 0.0), 1.0)
    grey = int(scale * 255)
    return f"#{grey:02x}{grey:02x}{grey:02x}", edge_color

generate_mesh_grid(X=None, i=0, j=1, num=100, lower=None, upper=None, var_type=None, use_floor=True)

Generate a mesh grid for two selected dimensions, filling remaining dimensions with their mean values
(if X is given) or the mean of the lower and upper bound (if lower and upper are given).

Args:
    X (np.ndarray, optional): Input data of shape (n_samples, k). Required if lower/upper are not given.
    i (int): Index of the first dimension to vary.
    j (int): Index of the second dimension to vary.
    num (int): Number of grid points per dimension.
    lower (np.ndarray, optional): Lower bounds for each dimension (shape (k,)).
    upper (np.ndarray, optional): Upper bounds for each dimension (shape (k,)).
    var_type (list of str, optional): List of variable types for each dimension. Can be either "num", "int", or "factor".
    use_floor (bool): If True, applies floor to non-numeric variables. Default is True.

Returns:
    X_i (np.ndarray): Meshgrid for the i-th dimension.
    X_j (np.ndarray): Meshgrid for the j-th dimension.
    grid_points (np.ndarray): Grid points of shape (num*num, k) for prediction.

Examples:
    >>> import numpy as np
    >>> from spotpython.surrogate.plot import generate_mesh_grid
    >>> # Example 1: Using input data
    >>> X = np.random.rand(4, 3)  # 5 samples with 3 dimensions
    >>> print(f"X:

{X}”) >>> X_i, X_j, grid_points = generate_mesh_grid(X, i=0, j=1, num=5) >>> print(f”X_i: {X_i}, X_j: {X_j}, grid_points: {grid_points}”) >>> # Example 2: Using lower and upper bounds >>> lower = np.array([-5, 0, 0]) >>> upper = np.array([10, 15, 3]) >>> X_i, X_j, grid_points = generate_mesh_grid(lower=lower, upper=upper, i=0, j=1, num=5) >>> print(f”X_i: {X_i}, X_j: {X_j}, grid_points: {grid_points}”)

Source code in spotpython/surrogate/plot.py
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def generate_mesh_grid(
    X: Optional[np.ndarray] = None,
    i: int = 0,
    j: int = 1,
    num: int = 100,
    lower: Optional[np.ndarray] = None,
    upper: Optional[np.ndarray] = None,
    var_type: Optional[List[str]] = None,
    use_floor: bool = True,
):
    """
    Generate a mesh grid for two selected dimensions, filling remaining dimensions with their mean values
    (if X is given) or the mean of the lower and upper bound (if lower and upper are given).

    Args:
        X (np.ndarray, optional): Input data of shape (n_samples, k). Required if lower/upper are not given.
        i (int): Index of the first dimension to vary.
        j (int): Index of the second dimension to vary.
        num (int): Number of grid points per dimension.
        lower (np.ndarray, optional): Lower bounds for each dimension (shape (k,)).
        upper (np.ndarray, optional): Upper bounds for each dimension (shape (k,)).
        var_type (list of str, optional): List of variable types for each dimension. Can be either "num", "int", or "factor".
        use_floor (bool): If True, applies floor to non-numeric variables. Default is True.

    Returns:
        X_i (np.ndarray): Meshgrid for the i-th dimension.
        X_j (np.ndarray): Meshgrid for the j-th dimension.
        grid_points (np.ndarray): Grid points of shape (num*num, k) for prediction.

    Examples:
        >>> import numpy as np
        >>> from spotpython.surrogate.plot import generate_mesh_grid
        >>> # Example 1: Using input data
        >>> X = np.random.rand(4, 3)  # 5 samples with 3 dimensions
        >>> print(f"X:\n{X}")
        >>> X_i, X_j, grid_points = generate_mesh_grid(X, i=0, j=1, num=5)
        >>> print(f"X_i:\n{X_i},\nX_j:\n{X_j},\ngrid_points:\n{grid_points}")
        >>> # Example 2: Using lower and upper bounds
        >>> lower = np.array([-5, 0, 0])
        >>> upper = np.array([10, 15, 3])
        >>> X_i, X_j, grid_points = generate_mesh_grid(lower=lower, upper=upper, i=0, j=1, num=5)
        >>> print(f"X_i:\n{X_i},\nX_j:\n{X_j},\ngrid_points:\n{grid_points}")
    """
    # Check that exactly one of (X) or (lower and upper) is provided
    if (X is not None and (lower is not None or upper is not None)) or (X is None and (lower is None or upper is None)):
        raise ValueError("Provide either X or both lower and upper, but not both or neither.")

    if X is not None:
        k = X.shape[1]
        mean_values = X.mean(axis=0)
        x_i = linspace(X[:, i].min(), X[:, i].max(), num=num)
        x_j = linspace(X[:, j].min(), X[:, j].max(), num=num)
    else:
        k = len(lower)
        mean_values = (np.array(lower) + np.array(upper)) / 2.0
        x_i = linspace(lower[i], upper[i], num=num)
        x_j = linspace(lower[j], upper[j], num=num)

    X_i, X_j = meshgrid(x_i, x_j)
    grid_points = np.zeros((X_i.size, k))
    grid_points[:, i] = X_i.ravel()
    grid_points[:, j] = X_j.ravel()

    # Set the remaining dimensions to their mean values
    for dim in range(k):
        if dim != i and dim != j:
            grid_points[:, dim] = mean_values[dim]

    # Apply floor to mean_values for non-"num" columns if var_type is provided
    if var_type is not None:
        if use_floor:
            grid_points = np.where(np.array([vt != "num" for vt in var_type]), np.floor(grid_points + 0.5), grid_points)
        else:
            grid_points = np.where(np.array([vt != "num" for vt in var_type]), np.ceil(grid_points - 0.5), grid_points)

    return X_i, X_j, grid_points

plot1d(model, X, y, show=True)

Plots the 1D Kriging surrogate model.

Parameters:

Name Type Description Default
model object

A fitted Kriging model.

required
X ndarray

Training input data of shape (n_samples, 1).

required
y ndarray

Training target values of shape (n_samples,).

required
show bool

If True, displays the plot. Defaults to True.

True

Returns:

Type Description
None

None

Examples:

>>> import numpy as np
>>> from spotpython.surrogate.kriging import Kriging
>>> # Training data
>>> X_train = np.array([[0.0], [0.5], [1.0]])
>>> y_train = np.array([0.1, 0.2, 0.3])
>>> # Initialize and fit the Kriging model
>>> model = Kriging().fit(X_train, y_train)
>>> # Plot the 1D Kriging surrogate
>>> plot1d(model, X_train, y_train)
Source code in spotpython/surrogate/plot.py
 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
def plot1d(model, X: np.ndarray, y: np.ndarray, show: Optional[bool] = True) -> None:
    """
    Plots the 1D Kriging surrogate model.

    Args:
        model (object): A fitted Kriging model.
        X (np.ndarray): Training input data of shape (n_samples, 1).
        y (np.ndarray): Training target values of shape (n_samples,).
        show (bool): If True, displays the plot. Defaults to True.

    Returns:
        None

    Examples:
        >>> import numpy as np
        >>> from spotpython.surrogate.kriging import Kriging
        >>> # Training data
        >>> X_train = np.array([[0.0], [0.5], [1.0]])
        >>> y_train = np.array([0.1, 0.2, 0.3])
        >>> # Initialize and fit the Kriging model
        >>> model = Kriging().fit(X_train, y_train)
        >>> # Plot the 1D Kriging surrogate
        >>> plot1d(model, X_train, y_train)
    """
    if X.shape[1] != 1:
        raise ValueError("plot1d is only supported for 1D input data.")

    _ = plt.figure(figsize=(9, 6))
    num = 100
    x = linspace(X[:, 0].min(), X[:, 0].max(), num=num).reshape(-1, 1)
    y_pred, y_std = model.predict(x, return_std=True)

    plt.plot(x, y_pred, "k", label="Prediction")
    plt.fill_between(
        x.ravel(),
        y_pred - 1.96 * y_std,
        y_pred + 1.96 * y_std,
        alpha=0.2,
        label="95% Confidence Interval",
    )
    plt.scatter(X, y, color="red", label="Training Data")
    plt.xlabel("X")
    plt.ylabel("Prediction")
    plt.title("1D Kriging Surrogate")
    plt.legend()
    if show:
        plt.show()

plot_3d_contour(X, Y, Z, vmin, vmax, var_name=None, i=0, j=1, show=True, filename=None, contour_levels=10, dpi=200, title=None, figsize=(12, 6), tkagg=False, cmap='jet')

Plots a 3D surface and filled contour for a surrogate model’s predictions over a grid.

Parameters:

Name Type Description Default
X ndarray

2D array of x-coordinates for the grid.

required
Y ndarray

2D array of y-coordinates for the grid.

required
Z ndarray

2D array of z-coordinates (predictions) for the grid.

required
vmin float

Minimum value for the color scale.

required
vmax float

Maximum value for the color scale.

required
var_name list or None

List of variable names for axis labeling. If None, generic labels are used.

None
i int

Index of the first variable to plot. Default is 0.

0
j int

Index of the second variable to plot. Default is 1.

1
show bool

If True, displays the plot interactively. Default is True.

True
filename str

If provided, saves the plot to this file. Default is None.

None
contour_levels int

Number of contour levels in the filled contour plot. Default is 10.

10
dpi int

Dots per inch for saved figure. Default is 200.

200
title str

Title for the plot. Default is None.

None
figsize tuple

Figure size in inches (width, height). Default is (12, 6).

(12, 6)
tkagg bool

If True, use TkAgg backend for matplotlib. Default is False.

False
cmap str

Colormap for the surface and contour plots. Default is “jet”.

'jet'

Returns:

Type Description
None

None

Examples:

>>> # Example 1: Using output from Spot
>>> # Assume S is a Spot object with a fitted surrogate
>>> plot_data = S.prepare_plot(i=0, j=1, num=100)
>>> from spotpython.surrogate.plot import plot_3d_contour
>>> plot_3d_contour(
...     plot_data,
...     var_name=S.var_name,
...     i=0,
...     j=1,
...     title="Surrogate Model Contour",
...     contour_levels=25,
...     show=True
... )
>>> # Example 2: Using plot_3d_contour from scratch
>>> import numpy as np
>>> from spotpython.surrogate.plot import plot_3d_contour
>>> # Create a grid
>>> x = np.linspace(-5, 5, 100)
>>> y = np.linspace(-5, 5, 100)
>>> X, Y = np.meshgrid(x, y)
>>> # Define a function over the grid
>>> Z = np.sin(np.sqrt(X**2 + Y**2))
>>> plot_data = {
...     "X_combined": X,
...     "Y_combined": Y,
...     "Z_combined": Z,
...     "min_z": Z.min(),
...     "max_z": Z.max(),
... }
>>> plot_3d_contour(
...     plot_data,
...     var_name=["x", "y"],
...     i=0,
...     j=1,
...     title="Sine Surface",
...     contour_levels=20,
...     show=True
... )
Source code in spotpython/surrogate/plot.py
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
def plot_3d_contour(X, Y, Z, vmin, vmax, var_name=None, i=0, j=1, show=True, filename=None, contour_levels=10, dpi=200, title=None, figsize=(12, 6), tkagg=False, cmap="jet") -> None:
    """
    Plots a 3D surface and filled contour for a surrogate model's predictions over a grid.

    Args:
        X (np.ndarray): 2D array of x-coordinates for the grid.
        Y (np.ndarray): 2D array of y-coordinates for the grid.
        Z (np.ndarray): 2D array of z-coordinates (predictions) for the grid.
        vmin (float): Minimum value for the color scale.
        vmax (float): Maximum value for the color scale.
        var_name (list or None): List of variable names for axis labeling. If None, generic labels are used.
        i (int, optional): Index of the first variable to plot. Default is 0.
        j (int, optional): Index of the second variable to plot. Default is 1.
        show (bool, optional): If True, displays the plot interactively. Default is True.
        filename (str, optional): If provided, saves the plot to this file. Default is None.
        contour_levels (int, optional): Number of contour levels in the filled contour plot. Default is 10.
        dpi (int, optional): Dots per inch for saved figure. Default is 200.
        title (str, optional): Title for the plot. Default is None.
        figsize (tuple, optional): Figure size in inches (width, height). Default is (12, 6).
        tkagg (bool, optional): If True, use TkAgg backend for matplotlib. Default is False.
        cmap (str, optional): Colormap for the surface and contour plots. Default is "jet".

    Returns:
        None

    Examples:
        >>> # Example 1: Using output from Spot
        >>> # Assume S is a Spot object with a fitted surrogate
        >>> plot_data = S.prepare_plot(i=0, j=1, num=100)
        >>> from spotpython.surrogate.plot import plot_3d_contour
        >>> plot_3d_contour(
        ...     plot_data,
        ...     var_name=S.var_name,
        ...     i=0,
        ...     j=1,
        ...     title="Surrogate Model Contour",
        ...     contour_levels=25,
        ...     show=True
        ... )
        >>> # Example 2: Using plot_3d_contour from scratch
        >>> import numpy as np
        >>> from spotpython.surrogate.plot import plot_3d_contour
        >>> # Create a grid
        >>> x = np.linspace(-5, 5, 100)
        >>> y = np.linspace(-5, 5, 100)
        >>> X, Y = np.meshgrid(x, y)
        >>> # Define a function over the grid
        >>> Z = np.sin(np.sqrt(X**2 + Y**2))
        >>> plot_data = {
        ...     "X_combined": X,
        ...     "Y_combined": Y,
        ...     "Z_combined": Z,
        ...     "min_z": Z.min(),
        ...     "max_z": Z.max(),
        ... }
        >>> plot_3d_contour(
        ...     plot_data,
        ...     var_name=["x", "y"],
        ...     i=0,
        ...     j=1,
        ...     title="Sine Surface",
        ...     contour_levels=20,
        ...     show=True
        ... )
    """
    if tkagg:
        matplotlib.use("TkAgg")
    fig = pylab.figure(figsize=figsize)

    ax_3d = fig.add_subplot(121, projection="3d")
    ax_3d.plot_surface(X, Y, Z, rstride=3, cstride=3, alpha=0.9, cmap=cmap, vmin=vmin, vmax=vmax)
    set_contour_labels(ax_3d, i=i, j=j, var_name=var_name, title=title)

    ax_contour = fig.add_subplot(122)
    contour = ax_contour.contourf(X, Y, Z, levels=contour_levels, zorder=1, cmap=cmap, vmin=vmin, vmax=vmax)
    pylab.colorbar(contour, ax=ax_contour)
    set_contour_labels(ax_contour, i=i, j=j, var_name=var_name, title=title)

    if filename:
        pylab.savefig(filename, bbox_inches="tight", dpi=dpi, pad_inches=0)
    if show:
        pylab.show()

plot_3d_surface(Z, i, j, ax, X=None, y=None, model=None, surface_label='Prediction Surface', zlabel='y', var_name=None, alpha=0.8, eps=0.0001, max_error=0.001, cmap='jet', error_surface=False, add_points=False, vmin=None, vmax=None)

Plot a 3D surface and scatter input points, colored by prediction error.

Parameters:

Name Type Description Default
Z tuple or ndarray

Surface values to plot, shape matching meshgrid.

required
i int

Index of first varied dimension.

required
j int

Index of second varied dimension.

required
ax Axes

Matplotlib 3D axis.

required
X ndarray

Input data, shape (n_samples, k).

None
y ndarray

Target values, shape (n_samples,).

None
model object

Fitted model with predict().

None
surface_label str

Title for the surface.

'Prediction Surface'
zlabel str

Label for the z-axis.

'y'
var_name list of str or None

List of axis labels or None.

None
alpha float

Surface transparency. alpha=1.0 is fully opaque, alpha=0.0 is fully transparent. Default is 0.8.

0.8
eps float

Tolerance for error coloring.

0.0001
max_error float

Maximum error for color scaling.

0.001
cmap str

Colormap for the surface.

'jet'
error_surface bool

If True, scatter z is abs(y_actual - y_predicted).

False
add_points bool

If True, adds scatter points to the surface plot.

False

Returns:

Type Description
None

None

Source code in spotpython/surrogate/plot.py
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
def plot_3d_surface(
    Z,
    i: int,
    j: int,
    ax: "matplotlib.axes.Axes",
    X: np.ndarray = None,
    y: np.ndarray = None,
    model=None,
    surface_label: str = "Prediction Surface",
    zlabel: str = "y",
    var_name: Optional[List[str]] = None,
    alpha: float = 0.8,
    eps: float = 1e-4,
    max_error: float = 1e-3,
    cmap: str = "jet",
    error_surface: bool = False,
    add_points: bool = False,
    vmin: float = None,
    vmax: float = None,
) -> None:
    """
    Plot a 3D surface and scatter input points, colored by prediction error.

    Args:
        Z (tuple or np.ndarray): Surface values to plot, shape matching meshgrid.
        i (int): Index of first varied dimension.
        j (int): Index of second varied dimension.
        ax (matplotlib.axes.Axes): Matplotlib 3D axis.
        X (np.ndarray): Input data, shape (n_samples, k).
        y (np.ndarray): Target values, shape (n_samples,).
        model (object): Fitted model with predict().
        surface_label (str): Title for the surface.
        zlabel (str): Label for the z-axis.
        var_name (list of str or None): List of axis labels or None.
        alpha (float): Surface transparency. alpha=1.0 is fully opaque, alpha=0.0 is fully transparent. Default is 0.8.
        eps (float): Tolerance for error coloring.
        max_error (float): Maximum error for color scaling.
        cmap (str): Colormap for the surface.
        error_surface (bool): If True, scatter z is abs(y_actual - y_predicted).
        add_points (bool): If True, adds scatter points to the surface plot.

    Returns:
        None
    """
    ax.plot_surface(*Z[:2], Z[2], cmap=cmap, alpha=alpha, vmin=vmin, vmax=vmax) if isinstance(Z, tuple) else ax.plot_surface(Z[0], Z[1], Z[2], cmap=cmap, alpha=alpha, vmin=vmin, vmax=vmax)
    ax.set_title(surface_label)
    ax.set_xlabel(var_name[i] if var_name else f"Dimension {i}")
    ax.set_ylabel(var_name[j] if var_name else f"Dimension {j}")
    ax.set_zlabel(zlabel)
    if add_points and X is not None and y is not None and model is not None:
        plot_error_points(ax, X, y, model, i, j, eps, max_error, var_name, z_mode="error" if error_surface else "actual")

plot_contour_and_err(X_i, X_j, Z, i, j, ax, X=None, y=None, model=None, eps=0.0001, max_error=0.001, var_name=None, cmap='jet', levels=30, title='Prediction Contour', add_points=False, vmin=None, vmax=None, grid_visible=True)

Plot a filled contour plot with scatter points colored by prediction error.

Parameters:

Name Type Description Default
X_i ndarray

Meshgrid for the i-th dimension.

required
X_j ndarray

Meshgrid for the j-th dimension.

required
Z ndarray

Contour values (predicted or error), shape matching meshgrid.

required
i int

Index of first varied dimension.

required
j int

Index of second varied dimension.

required
ax Axes

The matplotlib axis to plot on.

required
X ndarray

Input data, shape (n_samples, k).

None
y ndarray

Target values, shape (n_samples,).

None
model object

Fitted model with predict().

None
eps float

Tolerance for coloring points based on prediction error.

0.0001
max_error float

Maximum error for color scaling.

0.001
var_name list of str or None

List of axis labels or None.

None
cmap str

Colormap for the contour plot.

'jet'
levels int

Number of contour levels.

30
title str

Title for the plot.

'Prediction Contour'
add_points bool

If True, adds scatter points to the contour plot.

False
vmin float

Minimum value for color scaling.

None
vmax float

Maximum value for color scaling.

None
grid_visible bool

If True, displays a grid on the plot.

True

Returns:

Type Description
None

None

Source code in spotpython/surrogate/plot.py
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
def plot_contour_and_err(
    X_i: np.ndarray,
    X_j: np.ndarray,
    Z: np.ndarray,
    i: int,
    j: int,
    ax: "matplotlib.axes.Axes",
    X: np.ndarray = None,
    y: np.ndarray = None,
    model=None,
    eps: float = 1e-4,
    max_error: float = 1e-3,
    var_name: Optional[List[str]] = None,
    cmap: str = "jet",
    levels: int = 30,
    title: str = "Prediction Contour",
    add_points: bool = False,
    vmin: float = None,
    vmax: float = None,
    grid_visible: bool = True,
) -> None:
    """
    Plot a filled contour plot with scatter points colored by prediction error.

    Args:
        X_i (np.ndarray): Meshgrid for the i-th dimension.
        X_j (np.ndarray): Meshgrid for the j-th dimension.
        Z (np.ndarray): Contour values (predicted or error), shape matching meshgrid.
        i (int): Index of first varied dimension.
        j (int): Index of second varied dimension.
        ax (matplotlib.axes.Axes): The matplotlib axis to plot on.
        X (np.ndarray): Input data, shape (n_samples, k).
        y (np.ndarray): Target values, shape (n_samples,).
        model (object): Fitted model with predict().
        eps (float): Tolerance for coloring points based on prediction error.
        max_error (float): Maximum error for color scaling.
        var_name (list of str or None): List of axis labels or None.
        cmap (str): Colormap for the contour plot.
        levels (int): Number of contour levels.
        title (str): Title for the plot.
        add_points (bool): If True, adds scatter points to the contour plot.
        vmin (float): Minimum value for color scaling.
        vmax (float): Maximum value for color scaling.
        grid_visible (bool): If True, displays a grid on the plot.

    Returns:
        None
    """
    contour = ax.contourf(X_i, X_j, Z, cmap=cmap, levels=levels, vmin=vmin, vmax=vmax)
    ax.set_xlabel(var_name[i] if var_name else f"Dimension {i}")
    ax.set_ylabel(var_name[j] if var_name else f"Dimension {j}")
    # add a grid
    ax.grid(visible=grid_visible)
    plt.colorbar(contour, ax=ax)
    if add_points and X is not None and y is not None and model is not None:
        plot_error_points(ax, X, y, model, i, j, eps, max_error, var_name, title, z_mode=None)

plot_error_points(ax, X, y, model, i, j, eps=0.0001, max_error=0.001, var_name=None, title=None, z_mode='actual', s=25)

Scatter input points colored by prediction error.

Parameters:

Name Type Description Default
ax Axes

The matplotlib axis to plot on.

required
X ndarray

Input data, shape (n_samples, k).

required
y ndarray

Target values, shape (n_samples,).

required
model object

Fitted model with predict().

required
i int

Index of first varied dimension.

required
j int

Index of second varied dimension.

required
eps float

Tolerance for coloring points based on prediction error.

0.0001
max_error float

Maximum error for color scaling.

0.001
var_name list of str or None

List of axis labels or None.

None
title str or None

Title for the plot.

None
z_mode str

“actual” for z_actual (for 3D), “error” for abs error (for 3D error surface), or None (for 2D).

'actual'
s int

Size of the scatter points. Default is 25.

25
Source code in spotpython/surrogate/plot.py
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
def plot_error_points(
    ax,
    X: np.ndarray,
    y: np.ndarray,
    model,
    i: int,
    j: int,
    eps: float = 1e-4,
    max_error: float = 1e-3,
    var_name: Optional[List[str]] = None,
    title: Optional[str] = None,
    z_mode: str = "actual",  # "actual", "error", or None,
    s: int = 25,
) -> None:
    """
    Scatter input points colored by prediction error.

    Args:
        ax (matplotlib.axes.Axes): The matplotlib axis to plot on.
        X (np.ndarray): Input data, shape (n_samples, k).
        y (np.ndarray): Target values, shape (n_samples,).
        model (object): Fitted model with predict().
        i (int): Index of first varied dimension.
        j (int): Index of second varied dimension.
        eps (float): Tolerance for coloring points based on prediction error.
        max_error (float): Maximum error for color scaling.
        var_name (list of str or None): List of axis labels or None.
        title (str or None): Title for the plot.
        z_mode (str): "actual" for z_actual (for 3D), "error" for abs error (for 3D error surface), or None (for 2D).
        s (int): Size of the scatter points. Default is 25.
    """
    n, k = X.shape
    check_ij(i, j, k)
    for idx in range(n):
        x_point = X[idx, i]
        y_point_ = X[idx, j]
        z_actual = y[idx]
        z_predicted = model.predict(X[idx].reshape(1, -1))[0]
        color, edge_color = error_color(z_actual, z_predicted, eps, max_error)
        if z_mode == "actual":
            ax.scatter(x_point, y_point_, z_actual, color=color, s=s, edgecolor=edge_color)
        elif z_mode == "error":
            ax.scatter(x_point, y_point_, abs(z_actual - z_predicted), color=color, s=s, edgecolor=edge_color)
        else:
            ax.scatter(x_point, y_point_, color=color, s=s, edgecolor="black")
    if title is not None:
        ax.set_title(title)
    if var_name is not None:
        ax.set_xlabel(var_name[i])
        ax.set_ylabel(var_name[j])
    else:
        ax.set_xlabel(f"Dimension {i}")
        ax.set_ylabel(f"Dimension {j}")

plotkd(model, X, y, i=0, j=1, show=True, alpha=0.8, eps=0.0001, max_error=0.001, var_name=None, var_type=None, cmap='jet', num=100, vmin=None, vmax=None, add_points=False, grid_visible=True, contour_levels=30, use_floor=True)

Plots the Kriging surrogate model for k-dimensional input data by varying two dimensions (i, j).

Parameters:

Name Type Description Default
model object

A fitted Kriging model.

required
X ndarray

Training input data of shape (n_samples, k).

required
y ndarray

Training target values of shape (n_samples,).

required
i int

Index of the first dimension to vary. Default is 0.

0
j int

Index of the second dimension to vary. Default is 1.

1
show bool

If True, displays the plot. Default is True.

True
alpha float

Transparency of the surface plot. Default is 0.8.

0.8
eps float

Tolerance for coloring points based on prediction error. Default is 1e-4.

0.0001
max_error float

Maximum error for color scaling. Default is 1e-3.

0.001
var_name list of str

List of variable names for axis labeling. If None, generic labels are used.

None
var_type list of str

List of variable types for each dimension. Can be either “num”, “int”, or “factor”.

None
cmap str

Colormap for the surface and contour plots. Default is “jet”.

'jet'
num int

Number of grid points per dimension for the mesh grid. Default is 100.

100
vmin float

Minimum value for the color scale. If None, determined from predictions.

None
vmax float

Maximum value for the color scale. If None, determined from predictions.

None
add_points bool

If True, adds scatter points to the surface and contour plots. Default is False.

False
grid_visible bool

If True, displays a grid on the contour plots. Default is True.

True
contour_levels int

Number of contour levels in the filled contour plot. Default is 30.

30
use_floor bool

If True, applies floor to non-numeric variables. Default is True.

True

Examples:

>>> import numpy as np
>>> from spotpython.surrogate.kriging import Kriging
>>> from spotpython.surrogate.plot import plotkd
>>> # Training data
>>> X_train = np.random.rand(100, 3)  # 100 samples with 3 dimensions
>>> y_train = np.sin(X_train[:, 0]) + np.cos(X_train[:, 1]) + X_train[:, 2]  # Example target function
>>> # Initialize and fit the Kriging model
>>> model = Kriging().fit(X_train, y_train)
>>> # Plot the Kriging surrogate for dimensions 0 and 1
>>> plotkd(model, X_train, y_train, i=0, j=1, show=True)
Source code in spotpython/surrogate/plot.py
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
def plotkd(
    model,
    X: np.ndarray,
    y: np.ndarray,
    i: int = 0,
    j: int = 1,
    show: Optional[bool] = True,
    alpha: float = 0.8,
    eps: float = 1e-4,
    max_error: float = 1e-3,
    var_name: Optional[List[str]] = None,
    var_type: Optional[List[str]] = None,
    cmap: str = "jet",
    num: int = 100,
    vmin: Optional[float] = None,
    vmax: Optional[float] = None,
    add_points: bool = False,
    grid_visible: bool = True,
    contour_levels: int = 30,
    use_floor: bool = True,
) -> None:
    """
    Plots the Kriging surrogate model for k-dimensional input data by varying two dimensions (i, j).

    Args:
        model (object): A fitted Kriging model.
        X (np.ndarray): Training input data of shape (n_samples, k).
        y (np.ndarray): Training target values of shape (n_samples,).
        i (int): Index of the first dimension to vary. Default is 0.
        j (int): Index of the second dimension to vary. Default is 1.
        show (bool): If True, displays the plot. Default is True.
        alpha (float): Transparency of the surface plot. Default is 0.8.
        eps (float): Tolerance for coloring points based on prediction error. Default is 1e-4.
        max_error (float): Maximum error for color scaling. Default is 1e-3.
        var_name (list of str, optional): List of variable names for axis labeling. If None, generic labels are used.
        var_type (list of str, optional): List of variable types for each dimension. Can be either "num", "int", or "factor".
        cmap (str): Colormap for the surface and contour plots. Default is "jet".
        num (int): Number of grid points per dimension for the mesh grid. Default is 100.
        vmin (float, optional): Minimum value for the color scale. If None, determined from predictions.
        vmax (float, optional): Maximum value for the color scale. If None, determined from predictions.
        add_points (bool): If True, adds scatter points to the surface and contour plots. Default is False.
        grid_visible (bool): If True, displays a grid on the contour plots. Default is True.
        contour_levels (int): Number of contour levels in the filled contour plot. Default is 30.
        use_floor (bool): If True, applies floor to non-numeric variables. Default is True.

    Examples:
        >>> import numpy as np
        >>> from spotpython.surrogate.kriging import Kriging
        >>> from spotpython.surrogate.plot import plotkd
        >>> # Training data
        >>> X_train = np.random.rand(100, 3)  # 100 samples with 3 dimensions
        >>> y_train = np.sin(X_train[:, 0]) + np.cos(X_train[:, 1]) + X_train[:, 2]  # Example target function
        >>> # Initialize and fit the Kriging model
        >>> model = Kriging().fit(X_train, y_train)
        >>> # Plot the Kriging surrogate for dimensions 0 and 1
        >>> plotkd(model, X_train, y_train, i=0, j=1, show=True)

    """
    k = X.shape[1]
    check_ij(i, j, k)
    X_i, X_j, grid_points = generate_mesh_grid(X, i, j, num, var_type=var_type, use_floor=use_floor)

    # Predict the values and standard deviations
    y_pred, y_std = model.predict(grid_points, return_std=True)
    Z_pred = y_pred.reshape(X_i.shape)
    Z_std = y_std.reshape(X_i.shape)

    fig = plt.figure(figsize=(12, 10))

    # Plot predicted values. Add_ppoints=False to avoid adding points in the 3D surface plot
    ax1 = fig.add_subplot(221, projection="3d")
    plot_3d_surface(
        (X_i, X_j, Z_pred),
        i,
        j,
        ax1,
        X,
        y,
        model,
        surface_label="Prediction Surface",
        zlabel="Prediction",
        var_name=var_name,
        alpha=alpha,
        eps=eps,
        max_error=max_error,
        cmap=cmap,
        error_surface=False,
        vmin=vmin,
        vmax=vmax,
        add_points=False,
    )

    # Plot prediction error. Add_points=False to avoid adding points in the 3D surface plot
    ax2 = fig.add_subplot(222, projection="3d")
    plot_3d_surface(
        (X_i, X_j, Z_std),
        i,
        j,
        ax2,
        X,
        y,
        model,
        surface_label="Prediction Error Surface",
        zlabel="Error",
        var_name=var_name,
        alpha=alpha,
        eps=eps,
        max_error=max_error,
        cmap=cmap,
        error_surface=True,
        vmin=vmin,
        vmax=vmax,
        add_points=False,
    )

    # Contour plot of predicted values
    ax3 = fig.add_subplot(223)
    plot_contour_and_err(
        X_i,
        X_j,
        Z_pred,
        i,
        j,
        ax3,
        X,
        y,
        model,
        eps=eps,
        max_error=max_error,
        var_name=var_name,
        cmap=cmap,
        levels=contour_levels,
        title="Prediction Contour",
        vmin=vmin,
        vmax=vmax,
        add_points=add_points,
        grid_visible=grid_visible,
    )

    # Contour plot of prediction error
    ax4 = fig.add_subplot(224)
    plot_contour_and_err(
        X_i,
        X_j,
        Z_std,
        i,
        j,
        ax4,
        X,
        y,
        model,
        eps=eps,
        max_error=max_error,
        var_name=var_name,
        cmap=cmap,
        levels=contour_levels,
        title="Error Contour",
        vmin=vmin,
        vmax=vmax,
        add_points=add_points,
        grid_visible=grid_visible,
    )

    if show:
        plt.show()

set_contour_labels(ax, i=0, j=1, var_name=None, title=None)

Set axis labels and title for a contour plot.

Parameters:

Name Type Description Default
ax Axes

The matplotlib Axes object to label.

required
i int

Index of the first variable (x-axis).

0
j int

Index of the second variable (y-axis).

1
var_name list or None

List of variable names, or None for generic labels.

None
title str or None

Title for the plot, or None.

None

Returns:

Type Description
None

None

Source code in spotpython/surrogate/plot.py
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
def set_contour_labels(ax, i=0, j=1, var_name=None, title=None) -> None:
    """
    Set axis labels and title for a contour plot.

    Args:
        ax (matplotlib.axes.Axes): The matplotlib Axes object to label.
        i (int): Index of the first variable (x-axis).
        j (int): Index of the second variable (y-axis).
        var_name (list or None): List of variable names, or None for generic labels.
        title (str or None): Title for the plot, or None.

    Returns:
        None
    """
    if var_name is None:
        ax.set_xlabel(f"x{i}")
        ax.set_ylabel(f"x{j}")
    else:
        ax.set_xlabel(f"x{i}: {var_name[i]}")
        ax.set_ylabel(f"x{j}: {var_name[j]}")
    if title is not None:
        ax.set_title(title)

simple_error_color(z_actual, z_predicted, eps=0.001)

Returns a color string based on the error between actual and predicted values.

Parameters:

Name Type Description Default
z_actual float

The actual value.

required
z_predicted float

The predicted value.

required
eps float

Tolerance for considering values as close. Default is 1e-3.

0.001

Returns:

Name Type Description
str str

“black” if actual > predicted + eps, “white” if actual < predicted - eps, “grey” otherwise.

Source code in spotpython/surrogate/plot.py
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
def simple_error_color(z_actual: float, z_predicted: float, eps: float = 1e-3) -> str:
    """
    Returns a color string based on the error between actual and predicted values.

    Args:
        z_actual (float): The actual value.
        z_predicted (float): The predicted value.
        eps (float): Tolerance for considering values as close. Default is 1e-3.

    Returns:
        str: "black" if actual > predicted + eps,
             "white" if actual < predicted - eps,
             "grey" otherwise.
    """
    # predicted value is smaller than actual value
    if z_actual > z_predicted + eps:
        return "black"
    # predicted value is larger than actual value
    elif z_actual < z_predicted - eps:
        return "white"
    # predicted value is close to actual value
    else:
        return "grey"