Skip to content

Commit

Permalink
Refactor plotting code (#137)
Browse files Browse the repository at this point in the history
* move remaining analysis logic from plot.py to analyze.py

* add `Model.model_label`

* move repeated plotting code to new `PlotData`

* doc `ModelHash`->`Model` in analysis.rst

* convert logo text to paths

* change font size spec for axis vis; rename `NORMAL_NODE_COLOR` -> `DEFAULT_NODE_COLOT`

---------

Co-authored-by: Daniel Weindl <[email protected]>
  • Loading branch information
dilpath and dweindl authored Jan 7, 2025
1 parent 6c5d621 commit 85c355c
Show file tree
Hide file tree
Showing 16 changed files with 898 additions and 559 deletions.
17 changes: 17 additions & 0 deletions doc/analysis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,20 @@ to get a quick overview over all models, as a pandas dataframe.

Additionally, see the Python API docs for the :mod:`petab_select.analyze` module, which contains some methods to subset and group models,
or compute "weights" (e.g. Akaike weights).

Model hashes
^^^^^^^^^^^^

Model hashes are special objects in the library, that are generated from model-specific information that is unique within a single PEtab Select problem.

This means you can reconstruct the model given some model hash. For example, with this model hash `M1-000`, you can reconstruct the :class:`petab_select.ModelHash` from a string, then reconstruct the :class:`petab_select.Model`.

.. code-block:: language
ModelHash.from_hash("M1-000").get_model(petab_select_problem)
You can use this to get the uncalibrated version of a calibrated model.

.. code-block:: language
model.hash.get_model(petab_select_problem)
78 changes: 39 additions & 39 deletions doc/examples/calibrated_models/calibrated_models.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
estimated_parameters:
sigma_x2: 4.462298422134608
iteration: 1
model_hash: M_0-000
model_id: M_0-000
model_subspace_id: M_0
model_hash: M-000
model_id: M-000
model_subspace_id: M
model_subspace_indices:
- 0
- 0
- 0
parameters:
k1: 0
k2: 0
k1: 0.2
k2: 0.1
k3: 0
model_subspace_petab_yaml: petab_problem.yaml
predecessor_model_hash: virtual_initial_model-
Expand All @@ -24,59 +24,59 @@
k3: 0.0
sigma_x2: 0.12242920113658338
iteration: 2
model_hash: M_1-000
model_id: M_1-000
model_subspace_id: M_1
model_hash: M-001
model_id: M-001
model_subspace_id: M
model_subspace_indices:
- 0
- 0
- 0
- 1
parameters:
k1: 0.2
k2: 0.1
k3: estimate
model_subspace_petab_yaml: petab_problem.yaml
predecessor_model_hash: M_0-000
predecessor_model_hash: M-000
- criteria:
AICc: -0.27451438069575573
NLLH: -4.137257190347878
estimated_parameters:
k2: 0.10147824307890803
sigma_x2: 0.12142219599557078
iteration: 2
model_hash: M_2-000
model_id: M_2-000
model_subspace_id: M_2
model_hash: M-010
model_id: M-010
model_subspace_id: M
model_subspace_indices:
- 0
- 0
- 1
- 0
parameters:
k1: 0.2
k2: estimate
k3: 0
model_subspace_petab_yaml: petab_problem.yaml
predecessor_model_hash: M_0-000
predecessor_model_hash: M-000
- criteria:
AICc: -0.7053270766271886
NLLH: -4.352663538313594
estimated_parameters:
k1: 0.20160925279667963
sigma_x2: 0.11714017664827497
iteration: 2
model_hash: M_3-000
model_id: M_3-000
model_subspace_id: M_3
model_hash: M-100
model_id: M-100
model_subspace_id: M
model_subspace_indices:
- 0
- 1
- 0
- 0
parameters:
k1: estimate
k2: 0.1
k3: 0
model_subspace_petab_yaml: petab_problem.yaml
predecessor_model_hash: M_0-000
predecessor_model_hash: M-000
- criteria:
AICc: 9.294672923372811
NLLH: -4.352663538313594
Expand All @@ -85,19 +85,19 @@
k3: 0.0
sigma_x2: 0.11714017664827497
iteration: 3
model_hash: M_5-000
model_id: M_5-000
model_subspace_id: M_5
model_hash: M-101
model_id: M-101
model_subspace_id: M
model_subspace_indices:
- 1
- 0
- 0
- 0
- 1
parameters:
k1: estimate
k2: 0.1
k3: estimate
model_subspace_petab_yaml: petab_problem.yaml
predecessor_model_hash: M_3-000
predecessor_model_hash: M-100
- criteria:
AICc: 7.8521704398854
NLLH: -5.0739147800573
Expand All @@ -106,19 +106,19 @@
k2: 0.0859052351446815
sigma_x2: 0.10386846319370771
iteration: 3
model_hash: M_6-000
model_id: M_6-000
model_subspace_id: M_6
model_hash: M-110
model_id: M-110
model_subspace_id: M
model_subspace_indices:
- 0
- 0
- 1
- 1
- 0
parameters:
k1: estimate
k2: estimate
k3: 0
model_subspace_petab_yaml: petab_problem.yaml
predecessor_model_hash: M_3-000
predecessor_model_hash: M-100
- criteria:
AICc: 35.94352968170024
NLLH: -6.028235159149878
Expand All @@ -128,16 +128,16 @@
k3: 0.0010850434974038557
sigma_x2: 0.08859278245811462
iteration: 4
model_hash: M_7-000
model_id: M_7-000
model_subspace_id: M_7
model_hash: M-111
model_id: M-111
model_subspace_id: M
model_subspace_indices:
- 0
- 0
- 0
- 1
- 1
- 1
parameters:
k1: estimate
k2: estimate
k3: estimate
model_subspace_petab_yaml: petab_problem.yaml
predecessor_model_hash: M_3-000
predecessor_model_hash: M-100
9 changes: 1 addition & 8 deletions doc/examples/calibrated_models/model_space.tsv
Original file line number Diff line number Diff line change
@@ -1,9 +1,2 @@
model_subspace_id petab_yaml k1 k2 k3
M_0 petab_problem.yaml 0 0 0
M_1 petab_problem.yaml 0.2 0.1 estimate
M_2 petab_problem.yaml 0.2 estimate 0
M_3 petab_problem.yaml estimate 0.1 0
M_4 petab_problem.yaml 0.2 estimate estimate
M_5 petab_problem.yaml estimate 0.1 estimate
M_6 petab_problem.yaml estimate estimate 0
M_7 petab_problem.yaml estimate estimate estimate
M petab_problem.yaml 0.2;estimate 0.1;estimate 0
71 changes: 28 additions & 43 deletions doc/examples/visualization.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"\n",
"import petab_select\n",
"import petab_select.plot\n",
"from petab_select import VIRTUAL_INITIAL_MODEL\n",
"\n",
"models = petab_select.Models.from_yaml(\n",
" \"calibrated_models/calibrated_models.yaml\"\n",
Expand All @@ -45,7 +44,9 @@
"metadata": {},
"outputs": [],
"source": [
"models.df.style.background_gradient(\n",
"models.df.drop(\n",
" columns=[petab_select.Criterion.AIC, petab_select.Criterion.BIC]\n",
").style.background_gradient(\n",
" cmap=matplotlib.colormaps.get_cmap(\"summer\"),\n",
" subset=[petab_select.Criterion.AICC],\n",
")"
Expand All @@ -56,7 +57,7 @@
"id": "aaeb0606",
"metadata": {},
"source": [
"We customize the labels here to just be the second part of a model hash: a binary string that describes their estimated parameters. We additionally set a custom color for a couple of models, and the default color for the other models. We also set a nicer label for the \"virtual initial model\", which is a hypothetical model that PEtab Select uses by default to initialize a forward search (with no parameters)."
"To use the plotting methods, we need to first setup an object that contains information common to multiple plotting methods. This can include the models, custom colors and labels, and the criterion."
]
},
{
Expand All @@ -66,25 +67,21 @@
"metadata": {},
"outputs": [],
"source": [
"# Custom labels\n",
"labels = {}\n",
"for model in models:\n",
" labels[model.hash] = \"M_\" + \"\".join(\n",
" \"1\" if value == petab_select.ESTIMATE else \"0\"\n",
" for value in model.parameters.values()\n",
" )\n",
"labels[VIRTUAL_INITIAL_MODEL.hash] = \"\\n\".join(\n",
" petab_select.VIRTUAL_INITIAL_MODEL.model_subspace_id.split(\"_\")\n",
").title()\n",
"\n",
"# Custom colors for some models\n",
"colors = {\n",
" \"M_000\": \"lightgreen\",\n",
" \"M_001\": \"lightgreen\",\n",
" \"M-000\": \"lightgreen\",\n",
" \"M-001\": \"lightgreen\",\n",
"}\n",
"\n",
"plot_data = petab_select.plot.PlotData(\n",
" models=models,\n",
" criterion=petab_select.Criterion.AICC,\n",
" colors=colors,\n",
" relative_criterion=True,\n",
")\n",
"\n",
"# Change default color\n",
"petab_select.plot.NORMAL_NODE_COLOR = \"darkgray\""
"petab_select.plot.DEFAULT_NODE_COLOR = \"darkgray\""
]
},
{
Expand All @@ -106,7 +103,7 @@
"metadata": {},
"outputs": [],
"source": [
"petab_select.plot.upset(models=models, criterion=petab_select.Criterion.AICC);"
"petab_select.plot.upset(plot_data=plot_data);"
]
},
{
Expand All @@ -128,11 +125,7 @@
"metadata": {},
"outputs": [],
"source": [
"petab_select.plot.line_best_by_iteration(\n",
" models=models,\n",
" criterion=petab_select.Criterion.AICC,\n",
" labels=labels,\n",
");"
"petab_select.plot.line_best_by_iteration(plot_data=plot_data);"
]
},
{
Expand All @@ -152,12 +145,11 @@
"metadata": {},
"outputs": [],
"source": [
"petab_select.plot.graph_history(\n",
" models=models,\n",
" criterion=petab_select.Criterion.AICC,\n",
" labels=labels,\n",
" colors=colors,\n",
");"
"# Add the relative criterion value to each label\n",
"plot_data.augment_labels(criterion=True)\n",
"petab_select.plot.graph_history(plot_data=plot_data)\n",
"# Reset the labels (remove the relative criterion)\n",
"plot_data.augment_labels()"
]
},
{
Expand All @@ -177,12 +169,7 @@
"metadata": {},
"outputs": [],
"source": [
"petab_select.plot.bar_criterion_vs_models(\n",
" models=models,\n",
" criterion=petab_select.Criterion.AICC,\n",
" labels=labels,\n",
" colors=colors,\n",
");"
"petab_select.plot.bar_criterion_vs_models(plot_data=plot_data);"
]
},
{
Expand All @@ -207,10 +194,7 @@
"outputs": [],
"source": [
"petab_select.plot.scatter_criterion_vs_n_estimated(\n",
" models=models,\n",
" criterion=petab_select.Criterion.AICC,\n",
" labels=labels,\n",
" colors=colors,\n",
" plot_data=plot_data,\n",
" # Uncomment to turn off jitter.\n",
" # max_jitter=0,\n",
");"
Expand All @@ -231,7 +215,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "5ce191fc",
"id": "21157e4d-b2ba-4cb1-95f6-e14052c86959",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -244,10 +228,11 @@
"# cmap = matplotlib.colors.LinearSegmentedColormap.from_list(\"\", [\"green\",\"lightgreen\"])\n",
"# colorbar_mappable = matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)\n",
"\n",
"# Augment labels with the changes in parameters of each model, compared to their predecessor model\n",
"plot_data.augment_labels(added_parameters=True, removed_parameters=True)\n",
"\n",
"petab_select.plot.graph_iteration_layers(\n",
" models=models,\n",
" criterion=petab_select.Criterion.AICC,\n",
" labels=labels,\n",
" plot_data=plot_data,\n",
" draw_networkx_kwargs={\n",
" \"arrowstyle\": \"-|>\",\n",
" \"node_shape\": \"s\",\n",
Expand Down
1 change: 1 addition & 0 deletions doc/logo/editable/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The text in these copies is still text. In the copies in the parent directory, the text is converted to paths (e.g. `Path -> Object to Path` in Inkscape), for consistent rendering on systems that don't have the fonts installed.
Loading

0 comments on commit 85c355c

Please sign in to comment.