Visualize generated scenarios¶
(from the /llm/generate/scenario endpoint)
Demonstrate a generated scenario (curl)¶
In [12]:
# %%sh
# curl -X 'POST' \
# 'http://localhost:8001/llm/generate/scenario' \
# -H 'accept: application/json' \
# -H 'Content-Type: application/json' \
# -d '{
# "query": "A healthy patient."
# }'
Generate using the pfun-cma-model CLI¶
In [13]:
# !pfun-cma-model generate-scenario
Load the scenario¶
In [14]:
import json
from pathlib import Path
import pandas as pd
response_fpath = Path('../../results/generated-responses/response_1760175858463.json')
response_json = json.loads(response_fpath.read_text())
response_json
Out[14]:
{'qualitative_description': 'This individual leads a very structured and healthy lifestyle, which contributes to excellent glycemic control. They maintain a balanced diet with consistent carbohydrate intake at each meal, engage in moderate physical activity daily, such as a brisk walk after dinner, and prioritize getting 7-8 hours of quality sleep each night. Their stress levels are low, and they live in a temperate climate with consistent daylight hours throughout the year. As a result, their blood glucose levels are generally stable and predictable.',
'parameters': {'d': 0, 'taup': 1, 'taug': 1, 'B': 0.05, 'Cm': 0, 'toff': 0},
'sample_solutions': [{'t': 0,
'c': 0.0830452722,
'm': 0.8535533906,
'a': 0.2507233447,
'I_S': 0.1529527985,
'I_E': 0.0383488372,
'L': 0,
'g_0': 0.1,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3,
'is_meal': False},
{'t': 1.0434782609,
'c': 0.0380090513,
'm': 0.9358301507,
'a': 0.2539293579,
'I_S': 0.0835026721,
'I_E': 0.0212037799,
'L': 3e-08,
'g_0': 0.1,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3,
'is_meal': False},
{'t': 2.0869565217,
'c': 0.0214209099,
'm': 0.98574969,
'a': 0.2627732222,
'I_S': 0.0388959914,
'I_E': 0.010220825,
'L': 1.14478e-05,
'g_0': 0.1,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3,
'is_meal': False},
{'t': 3.1304347826,
'c': 0.018137561,
'm': 0.9970919474,
'a': 0.2807421255,
'I_S': 0.028649172,
'I_E': 0.0080430294,
'L': 0.0008732045,
'g_0': 0.1,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3,
'is_meal': False},
{'t': 4.1739130435,
'c': 0.0406263784,
'm': 0.9241524904,
'a': 0.3102280959,
'I_S': 0.0942280173,
'I_E': 0.0292321784,
'L': 0.0182225189,
'g_0': 0.1,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3,
'is_meal': False},
{'t': 5.2173913043,
'c': 0.3938120152,
'm': 0.5992820998,
'a': 0.3490666056,
'I_S': 0.3281195997,
'I_E': 0.1145355949,
'L': 0.1325418824,
'g_0': 0.1,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3,
'is_meal': False},
{'t': 6.2608695652,
'c': 0.9279522878,
'm': 0.1703963935,
'a': 0.4056274734,
'I_S': 0.6212864721,
'I_E': 0.252010862,
'L': 0.4097470471,
'g_0': 0.1,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3,
'is_meal': False},
{'t': 7.3043478261,
'c': 0.990231427,
'm': 0.0183183028,
'a': 0.4707866406,
'I_S': 0.7544780181,
'I_E': 0.3551981715,
'L': 0.7051652291,
'g_0': 0.8497368405,
'g_1': 0.1,
'g_2': 0.1,
'G': 1.0497368405,
'is_meal': True},
{'t': 8.347826087,
'c': 0.9453827912,
'm': 0.0007943753,
'a': 0.5408364261,
'I_S': 0.781791414,
'I_E': 0.4228212743,
'L': 0.8892608874,
'g_0': 0.4417664486,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.6417664486,
'is_meal': False},
{'t': 9.3913043478,
'c': 0.8959669925,
'm': 1.08762e-05,
'a': 0.611056308,
'I_S': 0.7939170419,
'I_E': 0.4851280164,
'L': 0.9710630727,
'g_0': 0.1755985361,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3755985361,
'is_meal': False},
{'t': 10.4347826087,
'c': 0.8468895341,
'm': 1.67e-08,
'a': 0.6741481839,
'I_S': 0.8052153909,
'I_E': 0.5428344935,
'L': 0.9962487446,
'g_0': 0.1205483507,
'g_1': 0.1,
'g_2': 0.1,
'G': 0.3205483507,
'is_meal': False},
{'t': 11.4782608696,
'c': 0.7978302583,
'm': 0,
'a': 0.7213867602,
'I_S': 0.8164990406,
'I_E': 0.5890115976,
'L': 0.999953688,
'g_0': 0.1066890291,
'g_1': 0.9165036625,
'g_2': 0.1,
'G': 1.1231926916,
'is_meal': True},
{'t': 12.5217391304,
'c': 0.7495150179,
'm': 0,
'a': 0.7433882267,
'I_S': 0.8276115459,
'I_E': 0.6152366795,
'L': 0.999953688,
'g_0': 0.1025138173,
'g_1': 0.333193076,
'g_2': 0.1,
'G': 0.5357068932,
'is_meal': False},
{'t': 13.5652173913,
'c': 0.7021980408,
'm': 1.8e-09,
'a': 0.7319539205,
'I_S': 0.8384944488,
'I_E': 0.6137392992,
'L': 0.9962487446,
'g_0': 0.1010632036,
'g_1': 0.1555741319,
'g_2': 0.1,
'G': 0.3566373354,
'is_meal': False},
{'t': 14.6086956522,
'c': 0.655778862,
'm': 6.35e-08,
'a': 0.6828954289,
'I_S': 0.8491708001,
'I_E': 0.5798948577,
'L': 0.9710630727,
'g_0': 0.1004971256,
'g_1': 0.1165474896,
'g_2': 0.1,
'G': 0.3170446152,
'is_meal': False},
{'t': 15.652173913,
'c': 0.6109701511,
'm': 9.8731e-06,
'a': 0.5990683435,
'I_S': 0.8594672884,
'I_E': 0.5148796447,
'L': 0.8892608874,
'g_0': 0.100253301,
'g_1': 0.1059282822,
'g_2': 0.1,
'G': 0.3061815832,
'is_meal': False},
{'t': 16.6956521739,
'c': 0.5652728153,
'm': 0.0012420615,
'a': 0.4927579526,
'I_S': 0.8687824528,
'I_E': 0.4280994627,
'L': 0.7051652291,
'g_0': 0.1001385657,
'g_1': 0.1024473713,
'g_2': 0.1,
'G': 0.302585937,
'is_meal': False},
{'t': 17.7391304348,
'c': 0.4727659974,
'm': 0.0253236297,
'a': 0.3862959294,
'I_S': 0.8666998998,
'I_E': 0.3348026433,
'L': 0.4097470471,
'g_0': 0.1000800258,
'g_1': 0.1011226915,
'g_2': 0.6652589215,
'G': 0.8664616388,
'is_meal': True},
{'t': 18.7826086957,
'c': 0.2936575613,
'm': 0.1473735678,
'a': 0.3061460908,
'I_S': 0.7895064001,
'I_E': 0.2417042981,
'L': 0.1325418824,
'g_0': 0.1000482904,
'g_1': 0.1005590015,
'g_2': 0.5310349728,
'G': 0.7316422646,
'is_meal': False},
{'t': 19.8260869565,
'c': 0.1823035565,
'm': 0.3300231124,
'a': 0.2652540915,
'I_S': 0.637947763,
'I_E': 0.1692182543,
'L': 0.0182225189,
'g_0': 0.1000297827,
'g_1': 0.100292864,
'g_2': 0.20462541,
'G': 0.4049480567,
'is_meal': False},
{'t': 20.8695652174,
'c': 0.1327959552,
'm': 0.4816654608,
'a': 0.2524778631,
'I_S': 0.5022414334,
'I_E': 0.1268048439,
'L': 0.0008732045,
'g_0': 0.1000184894,
'g_1': 0.1001579958,
'g_2': 0.1302813849,
'G': 0.3304578701,
'is_meal': False},
{'t': 21.9130434783,
'c': 0.0873966752,
'm': 0.6183609732,
'a': 0.2502021979,
'I_S': 0.3800886207,
'I_E': 0.0950990083,
'L': 1.14478e-05,
'g_0': 0.1000116861,
'g_1': 0.1000883661,
'g_2': 0.1103485482,
'G': 0.3104486004,
'is_meal': False},
{'t': 22.9565217391,
'c': 0.046089926,
'm': 0.7450550414,
'a': 0.2500020598,
'I_S': 0.2666959268,
'I_E': 0.0666745311,
'L': 3e-08,
'g_0': 0.1000075448,
'g_1': 0.1000512318,
'g_2': 0.1040296155,
'G': 0.3040883921,
'is_meal': False},
{'t': 24,
'c': 0.0202182535,
'm': 0.8535533906,
'a': 0.2499990113,
'I_S': 0.1674030129,
'I_E': 0.0418505877,
'L': 0,
'g_0': 0.1000049613,
'g_1': 0.1000306209,
'g_2': 0.1017335231,
'G': 0.3017691052,
'is_meal': False}],
'causal_explanation': [{'action': 'Ate balanced meals with consistent carbohydrate content at regular intervals',
'probability': 0.6},
{'action': 'Engaged in physical activity after dinner', 'probability': 0.3},
{'action': 'Maintained a consistent sleep schedule and low stress levels',
'probability': 0.1}]}
In [15]:
# Description
for sentence in response_json["qualitative_description"].split('. '):
print(f"- {sentence.strip()}.")
- This individual leads a very structured and healthy lifestyle, which contributes to excellent glycemic control. - They maintain a balanced diet with consistent carbohydrate intake at each meal, engage in moderate physical activity daily, such as a brisk walk after dinner, and prioritize getting 7-8 hours of quality sleep each night. - Their stress levels are low, and they live in a temperate climate with consistent daylight hours throughout the year. - As a result, their blood glucose levels are generally stable and predictable..
In [16]:
df = pd.DataFrame.from_records(response_json["sample_solutions"])
df.head()
Out[16]:
| t | c | m | a | I_S | I_E | L | g_0 | g_1 | g_2 | G | is_meal | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.000000 | 0.083045 | 0.853553 | 0.250723 | 0.152953 | 0.038349 | 0.000000e+00 | 0.1 | 0.1 | 0.1 | 0.3 | False |
| 1 | 1.043478 | 0.038009 | 0.935830 | 0.253929 | 0.083503 | 0.021204 | 3.000000e-08 | 0.1 | 0.1 | 0.1 | 0.3 | False |
| 2 | 2.086957 | 0.021421 | 0.985750 | 0.262773 | 0.038896 | 0.010221 | 1.144780e-05 | 0.1 | 0.1 | 0.1 | 0.3 | False |
| 3 | 3.130435 | 0.018138 | 0.997092 | 0.280742 | 0.028649 | 0.008043 | 8.732045e-04 | 0.1 | 0.1 | 0.1 | 0.3 | False |
| 4 | 4.173913 | 0.040626 | 0.924152 | 0.310228 | 0.094228 | 0.029232 | 1.822252e-02 | 0.1 | 0.1 | 0.1 | 0.3 | False |
Visualize (simple)¶
Glucose¶
In [17]:
df.plot(x="t", y="G")
Out[17]:
<Axes: xlabel='t'>
Endogenous currents¶
- I_S : Insulin secretion (endogenous)
- I_E : Effective Insulin (injected + endogenous)
- L : ("Light") Photoperiod conveyed via hypothalamus
In [18]:
df.plot(x="t", y=["I_S", "I_E", "L", ])
Out[18]:
<Axes: xlabel='t'>
Visualize using pfun tools¶
In [19]:
from pfun_cma_model.engine.cma_plot import CMAPlotConfig
import matplotlib.pyplot as plt
plt.close('all')
cma_plot = CMAPlotConfig(plot_cols=["c", "m", "a"])
df['G_soln'] = df['G'] # just to satisfy the plot function
cma_plot().plot(df, plot_cols=["c", "m", "a"], separate2subplots=False)
Out[19]:
(<Figure size 1400x1000 with 2 Axes>, array([<Axes: >, <Axes: >], dtype=object))
Export notebook to HTML¶
In [20]:
%%sh
uv run jupyter nbconvert --to html visualize-generated-scenarios.ipynb --output visualize-generated-scenarios.html
cp visualize-generated-scenarios.html ../../pfun_cma_model/static/notebooks/visualize-generated-scenarios.html
[NbConvertApp] Converting notebook visualize-generated-scenarios.ipynb to html [NbConvertApp] WARNING | Alternative text is missing on 3 image(s). [NbConvertApp] Writing 467597 bytes to visualize-generated-scenarios.html
In [22]:
%%sh
uv run jupyter nbconvert --to pdf visualize-generated-scenarios.ipynb --output visualize-generated-scenarios.pdf
cp visualize-generated-scenarios.pdf ../../pfun_cma_model/static/notebooks/visualize-generated-scenarios.pdf
[NbConvertApp] Converting notebook visualize-generated-scenarios.ipynb to pdf
[NbConvertApp] ERROR | Error while converting 'visualize-generated-scenarios.ipynb'
Traceback (most recent call last):
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/nbconvertapp.py", line 487, in export_single_notebook
output, resources = self.exporter.from_filename(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/templateexporter.py", line 390, in from_filename
return super().from_filename(filename, resources, **kw) # type:ignore[return-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/exporter.py", line 201, in from_filename
return self.from_file(f, resources=resources, **kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/templateexporter.py", line 396, in from_file
return super().from_file(file_stream, resources, **kw) # type:ignore[return-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/exporter.py", line 220, in from_file
return self.from_notebook_node(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/pdf.py", line 184, in from_notebook_node
latex, resources = super().from_notebook_node(nb, resources=resources, **kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/latex.py", line 92, in from_notebook_node
return super().from_notebook_node(nb, resources, **kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/exporters/templateexporter.py", line 429, in from_notebook_node
output = self.template.render(nb=nb_copy, resources=resources)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/jinja2/environment.py", line 1295, in render
self.environment.handle_exception()
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/jinja2/environment.py", line 942, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/index.tex.j2", line 8, in top-level template code
((* extends cell_style *))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/style_jupyter.tex.j2", line 176, in top-level template code
\prompt{(((prompt)))}{(((prompt_color)))}{(((execution_count)))}{(((extra_space)))}
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/base.tex.j2", line 7, in top-level template code
((*- extends 'document_contents.tex.j2' -*))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/document_contents.tex.j2", line 51, in top-level template code
((*- block figure scoped -*))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/display_priority.j2", line 5, in top-level template code
((*- extends 'null.j2' -*))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/null.j2", line 30, in top-level template code
((*- block body -*))
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/base.tex.j2", line 241, in block 'body'
((( super() )))
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/null.j2", line 32, in block 'body'
((*- block any_cell scoped -*))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/null.j2", line 85, in block 'any_cell'
((*- block markdowncell scoped-*)) ((*- endblock markdowncell -*))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/share/jupyter/nbconvert/templates/latex/document_contents.tex.j2", line 68, in block 'markdowncell'
((( cell.source | citation2latex | strip_files_prefix | convert_pandoc('markdown+tex_math_double_backslash', 'json',extra_args=[]) | resolve_references | convert_explicitly_relative_paths | convert_pandoc('json','latex'))))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/filters/pandoc.py", line 36, in convert_pandoc
return pandoc(source, from_format, to_format, extra_args=extra_args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/utils/pandoc.py", line 50, in pandoc
check_pandoc_version()
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/utils/pandoc.py", line 98, in check_pandoc_version
v = get_pandoc_version()
^^^^^^^^^^^^^^^^^^^^
File "/home/robbiec/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/nbconvert/utils/pandoc.py", line 75, in get_pandoc_version
raise PandocMissing()
nbconvert.utils.pandoc.PandocMissing: Pandoc wasn't found.
Please check that pandoc is installed:
https://pandoc.org/installing.html
cp: cannot stat 'visualize-generated-scenarios.pdf': No such file or directory
--------------------------------------------------------------------------- CalledProcessError Traceback (most recent call last) Cell In[22], line 1 ----> 1 get_ipython().run_cell_magic('sh', '', '\nuv run jupyter nbconvert --to pdf visualize-generated-scenarios.ipynb --output visualize-generated-scenarios.pdf\ncp visualize-generated-scenarios.pdf ../../pfun_cma_model/static/notebooks/visualize-generated-scenarios.pdf\n') File ~/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/IPython/core/interactiveshell.py:2565, in InteractiveShell.run_cell_magic(self, magic_name, line, cell) 2563 with self.builtin_trap: 2564 args = (magic_arg_s, cell) -> 2565 result = fn(*args, **kwargs) 2567 # The code below prevents the output from being displayed 2568 # when using magics with decorator @output_can_be_silenced 2569 # when the last Python token in the expression is a ';'. 2570 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False): File ~/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/IPython/core/magics/script.py:160, in ScriptMagics._make_script_magic.<locals>.named_script_magic(line, cell) 158 else: 159 line = script --> 160 return self.shebang(line, cell) File ~/Git/pfun-cma-model/.venv/lib/python3.12/site-packages/IPython/core/magics/script.py:348, in ScriptMagics.shebang(self, line, cell) 343 if args.raise_error and p.returncode != 0: 344 # If we get here and p.returncode is still None, we must have 345 # killed it but not yet seen its return code. We don't wait for it, 346 # in case it's stuck in uninterruptible sleep. -9 = SIGKILL 347 rc = p.returncode or -9 --> 348 raise CalledProcessError(rc, cell) CalledProcessError: Command 'b'\nuv run jupyter nbconvert --to pdf visualize-generated-scenarios.ipynb --output visualize-generated-scenarios.pdf\ncp visualize-generated-scenarios.pdf ../../pfun_cma_model/static/notebooks/visualize-generated-scenarios.pdf\n'' returned non-zero exit status 1.
In [ ]: