1c. Simulation of a logit model (traditional and Bayesian)

Example of simulation with a logit model

Michel Bierlaire, EPFL Thu Oct 30 2025, 14:03:15

import pandas as pd
from IPython.core.display_functions import display

import biogeme.biogeme_logging as blog
from biogeme.bayesian_estimation import BayesianResults
from biogeme.biogeme import BIOGEME
from biogeme.expressions import Beta, Derive
from biogeme.models import logit

See the data processing script: Data preparation for Swissmetro.

from swissmetro_data import (
    CAR_AV_SP,
    CAR_CO_SCALED,
    CAR_TT,
    SM_AV,
    SM_COST_SCALED,
    SM_TT,
    TRAIN_AV_SP,
    TRAIN_COST_SCALED,
    TRAIN_TT,
    database,
)

logger = blog.get_screen_logger(level=blog.INFO)

Parameters.

asc_car = Beta('asc_car', 0, None, None, 0)
asc_train = Beta('asc_train', 0, None, None, 0)
asc_sm = Beta('asc_sm', 0, None, None, 1)
b_time = Beta('b_time', 0, None, None, 0)
b_cost = Beta('b_cost', 0, None, None, 0)

Definition of the utility functions. As we will calculate the derivative with respect to TRAIN_TT, SM_TT and CAR_TT, they must explicitly appear in the model. If not, the derivative will be zero. Therefore, we do not use the _SCALED version of the attributes. We explicitly include their definition.

v_train = asc_train + b_time * TRAIN_TT / 100 + b_cost * TRAIN_COST_SCALED
v_swissmetro = asc_sm + b_time * SM_TT / 100 + b_cost * SM_COST_SCALED
v_car = asc_car + b_time * CAR_TT / 100 + b_cost * CAR_CO_SCALED

Associate utility functions with the numbering of alternatives.

v = {1: v_train, 2: v_swissmetro, 3: v_car}

Associate the availability conditions with the alternatives.

av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP}

Choice probability.

prob_train = logit(v, av, 1)

Elasticity.

time_elasticity_train = Derive(prob_train, 'TRAIN_TT') * TRAIN_TT / prob_train

Quantities to be simulated.

simulate = {
    'Prob. train': prob_train,
    'train time elasticity': time_elasticity_train,
    'Value of time': b_time / b_cost,
}

Create the Biogeme object.

As we simulate the probability for all alternatives, even when one of them is not available, Biogeme may trigger some warnings.

biosim = BIOGEME(database, simulate)
biosim.model_name = 'b01c_logit_simul'
Biogeme parameters read from biogeme.toml.

Retrieve the estimated values of the parameters.

RESULTS_FILE_NAME = 'saved_results/b01a_logit.nc'
estimation_results = BayesianResults.from_netcdf(filename=RESULTS_FILE_NAME)
betas = estimation_results.get_beta_values()
Loaded NetCDF file size: 855.3 MB
load finished in 4448 ms (4.45 s)
Diagnostics computation took 23.5 seconds (cached).

Simulation using the posterior mean of each parameter

print('Simulation using the posterior mean of each parameter')
results = biosim.simulate(the_beta_values=betas)
display(results)
Simulation using the posterior mean of each parameter
      Prob. train  train time elasticity  Value of time
0        0.167825              -1.192850       1.180578
1        0.184090              -1.075555       1.180578
2        0.142838              -1.426131       1.180578
3        0.161141              -1.105807       1.180578
4        0.139629              -1.431470       1.180578
...           ...                    ...            ...
6763     0.172357              -1.143983       1.180578
6764     0.164421              -1.154953       1.180578
6765     0.149244              -1.175931       1.180578
6766     0.134531              -1.417798       1.180578
6767     0.176696              -1.137986       1.180578

[6768 rows x 3 columns]

Bayesian simulation using the posterior draws

print('Bayesian simulation')
bayesian_results = biosim.simulate_bayesian(
    bayesian_estimation_results=estimation_results, percentage_of_draws_to_use=3
)
with pd.option_context('display.max_columns', None, 'display.expand_frame_repr', False):
    display(bayesian_results)
Bayesian simulation
Bayesian simulation performed with 3% of the draws, that is 240/8000 draws. Adjust the parameter "percentage_of_draws_to_use" if you need a different number of draws.

  0%|          | 0/240 [00:00<?, ?it/s]
  0%|          | 1/240 [00:00<00:55,  4.30it/s]
  1%|          | 2/240 [00:00<00:54,  4.34it/s]
  1%|▏         | 3/240 [00:00<00:54,  4.38it/s]
  2%|▏         | 4/240 [00:00<00:54,  4.37it/s]
  2%|▏         | 5/240 [00:01<00:54,  4.35it/s]
  2%|▎         | 6/240 [00:01<00:53,  4.36it/s]
  3%|▎         | 7/240 [00:01<00:53,  4.37it/s]
  3%|▎         | 8/240 [00:01<00:53,  4.38it/s]
  4%|▍         | 9/240 [00:02<00:52,  4.36it/s]
  4%|▍         | 10/240 [00:02<00:52,  4.38it/s]
  5%|▍         | 11/240 [00:02<00:52,  4.36it/s]
  5%|▌         | 12/240 [00:02<00:52,  4.34it/s]
  5%|▌         | 13/240 [00:02<00:52,  4.35it/s]
  6%|▌         | 14/240 [00:03<00:51,  4.35it/s]
  6%|▋         | 15/240 [00:03<00:52,  4.32it/s]
  7%|▋         | 16/240 [00:03<00:51,  4.34it/s]
  7%|▋         | 17/240 [00:03<00:51,  4.37it/s]
  8%|▊         | 18/240 [00:04<00:51,  4.34it/s]
  8%|▊         | 19/240 [00:04<00:50,  4.37it/s]
  8%|▊         | 20/240 [00:04<00:50,  4.39it/s]
  9%|▉         | 21/240 [00:04<00:50,  4.37it/s]
  9%|▉         | 22/240 [00:05<00:50,  4.31it/s]
 10%|▉         | 23/240 [00:05<00:50,  4.29it/s]
 10%|█         | 24/240 [00:05<00:50,  4.31it/s]
 10%|█         | 25/240 [00:05<00:49,  4.35it/s]
 11%|█         | 26/240 [00:05<00:48,  4.37it/s]
 11%|█▏        | 27/240 [00:06<00:48,  4.37it/s]
 12%|█▏        | 28/240 [00:06<00:48,  4.39it/s]
 12%|█▏        | 29/240 [00:06<00:47,  4.40it/s]
 12%|█▎        | 30/240 [00:06<00:47,  4.39it/s]
 13%|█▎        | 31/240 [00:07<00:47,  4.38it/s]
 13%|█▎        | 32/240 [00:07<00:47,  4.39it/s]
 14%|█▍        | 33/240 [00:07<00:47,  4.40it/s]
 14%|█▍        | 34/240 [00:07<00:46,  4.39it/s]
 15%|█▍        | 35/240 [00:08<00:46,  4.39it/s]
 15%|█▌        | 36/240 [00:08<00:46,  4.36it/s]
 15%|█▌        | 37/240 [00:08<00:46,  4.34it/s]
 16%|█▌        | 38/240 [00:08<00:46,  4.35it/s]
 16%|█▋        | 39/240 [00:08<00:47,  4.26it/s]
 17%|█▋        | 40/240 [00:09<00:47,  4.21it/s]
 17%|█▋        | 41/240 [00:09<00:46,  4.26it/s]
 18%|█▊        | 42/240 [00:09<00:47,  4.20it/s]
 18%|█▊        | 43/240 [00:09<00:47,  4.18it/s]
 18%|█▊        | 44/240 [00:10<00:49,  3.99it/s]
 19%|█▉        | 45/240 [00:10<00:48,  4.04it/s]
 19%|█▉        | 46/240 [00:10<00:46,  4.14it/s]
 20%|█▉        | 47/240 [00:10<00:46,  4.19it/s]
 20%|██        | 48/240 [00:11<00:45,  4.23it/s]
 20%|██        | 49/240 [00:11<00:44,  4.28it/s]
 21%|██        | 50/240 [00:11<00:43,  4.34it/s]
 21%|██▏       | 51/240 [00:11<00:43,  4.34it/s]
 22%|██▏       | 52/240 [00:12<00:43,  4.35it/s]
 22%|██▏       | 53/240 [00:12<00:43,  4.34it/s]
 22%|██▎       | 54/240 [00:12<00:42,  4.37it/s]
 23%|██▎       | 55/240 [00:12<00:42,  4.38it/s]
 23%|██▎       | 56/240 [00:12<00:42,  4.38it/s]
 24%|██▍       | 57/240 [00:13<00:41,  4.39it/s]
 24%|██▍       | 58/240 [00:13<00:41,  4.39it/s]
 25%|██▍       | 59/240 [00:13<00:40,  4.42it/s]
 25%|██▌       | 60/240 [00:13<00:40,  4.44it/s]
 25%|██▌       | 61/240 [00:14<00:40,  4.47it/s]
 26%|██▌       | 62/240 [00:14<00:39,  4.46it/s]
 26%|██▋       | 63/240 [00:14<00:39,  4.45it/s]
 27%|██▋       | 64/240 [00:14<00:39,  4.44it/s]
 27%|██▋       | 65/240 [00:14<00:39,  4.43it/s]
 28%|██▊       | 66/240 [00:15<00:39,  4.41it/s]
 28%|██▊       | 67/240 [00:15<00:39,  4.39it/s]
 28%|██▊       | 68/240 [00:15<00:39,  4.40it/s]
 29%|██▉       | 69/240 [00:15<00:38,  4.40it/s]
 29%|██▉       | 70/240 [00:16<00:38,  4.38it/s]
 30%|██▉       | 71/240 [00:16<00:38,  4.35it/s]
 30%|███       | 72/240 [00:16<00:38,  4.35it/s]
 30%|███       | 73/240 [00:16<00:38,  4.36it/s]
 31%|███       | 74/240 [00:17<00:38,  4.36it/s]
 31%|███▏      | 75/240 [00:17<00:37,  4.35it/s]
 32%|███▏      | 76/240 [00:17<00:37,  4.37it/s]
 32%|███▏      | 77/240 [00:17<00:37,  4.38it/s]
 32%|███▎      | 78/240 [00:17<00:36,  4.38it/s]
 33%|███▎      | 79/240 [00:18<00:36,  4.39it/s]
 33%|███▎      | 80/240 [00:18<00:36,  4.38it/s]
 34%|███▍      | 81/240 [00:18<00:36,  4.40it/s]
 34%|███▍      | 82/240 [00:18<00:35,  4.40it/s]
 35%|███▍      | 83/240 [00:19<00:35,  4.40it/s]
 35%|███▌      | 84/240 [00:19<00:35,  4.44it/s]
 35%|███▌      | 85/240 [00:19<00:35,  4.38it/s]
 36%|███▌      | 86/240 [00:19<00:35,  4.36it/s]
 36%|███▋      | 87/240 [00:20<00:35,  4.36it/s]
 37%|███▋      | 88/240 [00:20<00:34,  4.35it/s]
 37%|███▋      | 89/240 [00:20<00:34,  4.32it/s]
 38%|███▊      | 90/240 [00:20<00:34,  4.33it/s]
 38%|███▊      | 91/240 [00:20<00:34,  4.32it/s]
 38%|███▊      | 92/240 [00:21<00:34,  4.34it/s]
 39%|███▉      | 93/240 [00:21<00:34,  4.31it/s]
 39%|███▉      | 94/240 [00:21<00:33,  4.31it/s]
 40%|███▉      | 95/240 [00:21<00:34,  4.22it/s]
 40%|████      | 96/240 [00:22<00:38,  3.78it/s]
 40%|████      | 97/240 [00:22<00:41,  3.48it/s]
 41%|████      | 98/240 [00:22<00:39,  3.63it/s]
 41%|████▏     | 99/240 [00:23<00:37,  3.81it/s]
 42%|████▏     | 100/240 [00:23<00:35,  3.93it/s]
 42%|████▏     | 101/240 [00:23<00:34,  4.05it/s]
 42%|████▎     | 102/240 [00:23<00:33,  4.08it/s]
 43%|████▎     | 103/240 [00:26<02:14,  1.02it/s]
 43%|████▎     | 104/240 [00:26<01:43,  1.32it/s]
 44%|████▍     | 105/240 [00:26<01:21,  1.66it/s]
 44%|████▍     | 106/240 [00:27<01:06,  2.02it/s]
 45%|████▍     | 107/240 [00:27<00:55,  2.39it/s]
 45%|████▌     | 108/240 [00:27<00:48,  2.74it/s]
 45%|████▌     | 109/240 [00:27<00:42,  3.09it/s]
 46%|████▌     | 110/240 [00:28<00:38,  3.36it/s]
 46%|████▋     | 111/240 [00:28<00:35,  3.59it/s]
 47%|████▋     | 112/240 [00:28<00:33,  3.77it/s]
 47%|████▋     | 113/240 [00:28<00:32,  3.95it/s]
 48%|████▊     | 114/240 [00:29<00:31,  3.98it/s]
 48%|████▊     | 115/240 [00:29<00:30,  4.05it/s]
 48%|████▊     | 116/240 [00:29<00:30,  4.06it/s]
 49%|████▉     | 117/240 [00:29<00:29,  4.13it/s]
 49%|████▉     | 118/240 [00:29<00:29,  4.19it/s]
 50%|████▉     | 119/240 [00:30<00:28,  4.19it/s]
 50%|█████     | 120/240 [00:30<00:28,  4.24it/s]
 50%|█████     | 121/240 [00:30<00:28,  4.24it/s]
 51%|█████     | 122/240 [00:30<00:27,  4.26it/s]
 51%|█████▏    | 123/240 [00:31<00:27,  4.30it/s]
 52%|█████▏    | 124/240 [00:31<00:26,  4.33it/s]
 52%|█████▏    | 125/240 [00:31<00:26,  4.37it/s]
 52%|█████▎    | 126/240 [00:31<00:26,  4.34it/s]
 53%|█████▎    | 127/240 [00:32<00:25,  4.35it/s]
 53%|█████▎    | 128/240 [00:32<00:25,  4.31it/s]
 54%|█████▍    | 129/240 [00:32<00:25,  4.32it/s]
 54%|█████▍    | 130/240 [00:32<00:25,  4.34it/s]
 55%|█████▍    | 131/240 [00:32<00:24,  4.36it/s]
 55%|█████▌    | 132/240 [00:33<00:24,  4.35it/s]
 55%|█████▌    | 133/240 [00:33<00:24,  4.32it/s]
 56%|█████▌    | 134/240 [00:33<00:24,  4.32it/s]
 56%|█████▋    | 135/240 [00:33<00:24,  4.34it/s]
 57%|█████▋    | 136/240 [00:34<00:24,  4.32it/s]
 57%|█████▋    | 137/240 [00:34<00:23,  4.34it/s]
 57%|█████▊    | 138/240 [00:34<00:23,  4.35it/s]
 58%|█████▊    | 139/240 [00:34<00:23,  4.36it/s]
 58%|█████▊    | 140/240 [00:35<00:22,  4.38it/s]
 59%|█████▉    | 141/240 [00:35<00:22,  4.35it/s]
 59%|█████▉    | 142/240 [00:35<00:22,  4.36it/s]
 60%|█████▉    | 143/240 [00:35<00:22,  4.35it/s]
 60%|██████    | 144/240 [00:35<00:22,  4.25it/s]
 60%|██████    | 145/240 [00:36<00:22,  4.16it/s]
 61%|██████    | 146/240 [00:36<00:22,  4.14it/s]
 61%|██████▏   | 147/240 [00:36<00:22,  4.15it/s]
 62%|██████▏   | 148/240 [00:36<00:21,  4.20it/s]
 62%|██████▏   | 149/240 [00:37<00:21,  4.22it/s]
 62%|██████▎   | 150/240 [00:37<00:21,  4.26it/s]
 63%|██████▎   | 151/240 [00:37<00:20,  4.29it/s]
 63%|██████▎   | 152/240 [00:37<00:20,  4.30it/s]
 64%|██████▍   | 153/240 [00:38<00:20,  4.23it/s]
 64%|██████▍   | 154/240 [00:38<00:20,  4.28it/s]
 65%|██████▍   | 155/240 [00:38<00:19,  4.29it/s]
 65%|██████▌   | 156/240 [00:38<00:19,  4.34it/s]
 65%|██████▌   | 157/240 [00:39<00:19,  4.35it/s]
 66%|██████▌   | 158/240 [00:39<00:18,  4.34it/s]
 66%|██████▋   | 159/240 [00:39<00:18,  4.34it/s]
 67%|██████▋   | 160/240 [00:39<00:18,  4.35it/s]
 67%|██████▋   | 161/240 [00:39<00:18,  4.39it/s]
 68%|██████▊   | 162/240 [00:40<00:17,  4.40it/s]
 68%|██████▊   | 163/240 [00:40<00:17,  4.39it/s]
 68%|██████▊   | 164/240 [00:40<00:17,  4.40it/s]
 69%|██████▉   | 165/240 [00:40<00:17,  4.37it/s]
 69%|██████▉   | 166/240 [00:41<00:17,  4.35it/s]
 70%|██████▉   | 167/240 [00:41<00:16,  4.34it/s]
 70%|███████   | 168/240 [00:41<00:16,  4.37it/s]
 70%|███████   | 169/240 [00:41<00:16,  4.40it/s]
 71%|███████   | 170/240 [00:42<00:16,  4.35it/s]
 71%|███████▏  | 171/240 [00:42<00:15,  4.34it/s]
 72%|███████▏  | 172/240 [00:42<00:15,  4.35it/s]
 72%|███████▏  | 173/240 [00:42<00:15,  4.36it/s]
 72%|███████▎  | 174/240 [00:42<00:15,  4.22it/s]
 73%|███████▎  | 175/240 [00:43<00:15,  4.26it/s]
 73%|███████▎  | 176/240 [00:43<00:14,  4.29it/s]
 74%|███████▍  | 177/240 [00:43<00:14,  4.34it/s]
 74%|███████▍  | 178/240 [00:43<00:14,  4.33it/s]
 75%|███████▍  | 179/240 [00:44<00:14,  4.30it/s]
 75%|███████▌  | 180/240 [00:44<00:13,  4.32it/s]
 75%|███████▌  | 181/240 [00:44<00:13,  4.33it/s]
 76%|███████▌  | 182/240 [00:44<00:13,  4.35it/s]
 76%|███████▋  | 183/240 [00:45<00:13,  4.37it/s]
 77%|███████▋  | 184/240 [00:45<00:12,  4.36it/s]
 77%|███████▋  | 185/240 [00:45<00:12,  4.37it/s]
 78%|███████▊  | 186/240 [00:45<00:12,  4.38it/s]
 78%|███████▊  | 187/240 [00:45<00:12,  4.38it/s]
 78%|███████▊  | 188/240 [00:46<00:11,  4.36it/s]
 79%|███████▉  | 189/240 [00:46<00:11,  4.30it/s]
 79%|███████▉  | 190/240 [00:46<00:11,  4.31it/s]
 80%|███████▉  | 191/240 [00:46<00:11,  4.34it/s]
 80%|████████  | 192/240 [00:47<00:11,  4.34it/s]
 80%|████████  | 193/240 [00:47<00:10,  4.33it/s]
 81%|████████  | 194/240 [00:47<00:10,  4.34it/s]
 81%|████████▏ | 195/240 [00:47<00:10,  4.34it/s]
 82%|████████▏ | 196/240 [00:48<00:10,  4.34it/s]
 82%|████████▏ | 197/240 [00:48<00:09,  4.30it/s]
 82%|████████▎ | 198/240 [00:48<00:09,  4.23it/s]
 83%|████████▎ | 199/240 [00:48<00:09,  4.19it/s]
 83%|████████▎ | 200/240 [00:48<00:09,  4.21it/s]
 84%|████████▍ | 201/240 [00:49<00:09,  4.24it/s]
 84%|████████▍ | 202/240 [00:49<00:08,  4.27it/s]
 85%|████████▍ | 203/240 [00:49<00:08,  4.28it/s]
 85%|████████▌ | 204/240 [00:49<00:08,  4.23it/s]
 85%|████████▌ | 205/240 [00:50<00:08,  4.24it/s]
 86%|████████▌ | 206/240 [00:50<00:08,  4.23it/s]
 86%|████████▋ | 207/240 [00:50<00:07,  4.28it/s]
 87%|████████▋ | 208/240 [00:50<00:07,  4.31it/s]
 87%|████████▋ | 209/240 [00:51<00:07,  4.31it/s]
 88%|████████▊ | 210/240 [00:51<00:06,  4.33it/s]
 88%|████████▊ | 211/240 [00:51<00:06,  4.35it/s]
 88%|████████▊ | 212/240 [00:51<00:06,  4.37it/s]
 89%|████████▉ | 213/240 [00:51<00:06,  4.37it/s]
 89%|████████▉ | 214/240 [00:52<00:05,  4.34it/s]
 90%|████████▉ | 215/240 [00:55<00:25,  1.04s/it]
 90%|█████████ | 216/240 [00:55<00:19,  1.26it/s]
 90%|█████████ | 217/240 [00:55<00:14,  1.59it/s]
 91%|█████████ | 218/240 [00:55<00:11,  1.96it/s]
 91%|█████████▏| 219/240 [00:56<00:08,  2.33it/s]
 92%|█████████▏| 220/240 [00:56<00:07,  2.69it/s]
 92%|█████████▏| 221/240 [00:56<00:06,  3.04it/s]
 92%|█████████▎| 222/240 [00:56<00:05,  3.34it/s]
 93%|█████████▎| 223/240 [00:57<00:04,  3.59it/s]
 93%|█████████▎| 224/240 [00:57<00:04,  3.75it/s]
 94%|█████████▍| 225/240 [00:57<00:03,  3.92it/s]
 94%|█████████▍| 226/240 [00:57<00:03,  4.04it/s]
 95%|█████████▍| 227/240 [00:57<00:03,  4.11it/s]
 95%|█████████▌| 228/240 [00:58<00:02,  4.15it/s]
 95%|█████████▌| 229/240 [00:58<00:02,  4.20it/s]
 96%|█████████▌| 230/240 [00:58<00:02,  4.22it/s]
 96%|█████████▋| 231/240 [00:58<00:02,  4.28it/s]
 97%|█████████▋| 232/240 [00:59<00:01,  4.30it/s]
 97%|█████████▋| 233/240 [00:59<00:01,  4.33it/s]
 98%|█████████▊| 234/240 [00:59<00:01,  4.39it/s]
 98%|█████████▊| 235/240 [00:59<00:01,  4.41it/s]
 98%|█████████▊| 236/240 [01:00<00:00,  4.37it/s]
 99%|█████████▉| 237/240 [01:00<00:00,  4.39it/s]
 99%|█████████▉| 238/240 [01:00<00:00,  4.37it/s]
100%|█████████▉| 239/240 [01:00<00:00,  4.34it/s]
100%|██████████| 240/240 [01:00<00:00,  4.35it/s]
100%|██████████| 240/240 [01:00<00:00,  3.94it/s]
                             Prob. train_mean  Prob. train_q025  Prob. train_q975  train time elasticity_mean  train time elasticity_q025  train time elasticity_q975  Value of time_mean  Value of time_q025  Value of time_q975
__biogeme_internal_obs_id__
0                                    0.167515          0.157977          0.178539                   -1.189251                   -1.286882                   -1.088971            1.181914            1.049833            1.313146
1                                    0.183722          0.172976          0.195906                   -1.072349                   -1.158776                   -0.983756            1.181914            1.049833            1.313146
2                                    0.142630          0.135141          0.152021                   -1.421745                   -1.542036                   -1.297560            1.181914            1.049833            1.313146
3                                    0.160822          0.151748          0.171163                   -1.102525                   -1.196037                   -1.006631            1.181914            1.049833            1.313146
4                                    0.139444          0.131443          0.149657                   -1.427078                   -1.550104                   -1.300481            1.181914            1.049833            1.313146
...                                       ...               ...               ...                         ...                         ...                         ...                 ...                 ...                 ...
6763                                 0.172081          0.163140          0.183298                   -1.140513                   -1.234750                   -1.043042            1.181914            1.049833            1.313146
6764                                 0.164130          0.154941          0.175101                   -1.151497                   -1.248836                   -1.052276            1.181914            1.049833            1.313146
6765                                 0.149016          0.141000          0.158921                   -1.172342                   -1.271547                   -1.069987            1.181914            1.049833            1.313146
6766                                 0.134394          0.126414          0.144618                   -1.413400                   -1.535721                   -1.286135            1.181914            1.049833            1.313146
6767                                 0.176372          0.166627          0.188252                   -1.134603                   -1.229517                   -1.038149            1.181914            1.049833            1.313146

[6768 rows x 9 columns]

Total running time of the script: (1 minutes 41.239 seconds)

Gallery generated by Sphinx-Gallery