{"id":1535,"date":"2024-04-15T19:15:54","date_gmt":"2024-04-15T17:15:54","guid":{"rendered":"https:\/\/lorentzen.ch\/?p=1535"},"modified":"2025-07-06T15:36:14","modified_gmt":"2025-07-06T13:36:14","slug":"interactive-plotting-backend-for-model-diagnostics","status":"publish","type":"post","link":"https:\/\/lorentzen.ch\/index.php\/2024\/04\/15\/interactive-plotting-backend-for-model-diagnostics\/","title":{"rendered":"Interactive Plotting Backend for Model-Diagnostics"},"content":{"rendered":"\n<p>With its newest <a href=\"https:\/\/github.com\/lorentzenchr\/model-diagnostics\/releases\/tag\/v1.1.0\">release 1.1.0<\/a>, the Python package <a href=\"https:\/\/lorentzenchr.github.io\/model-diagnostics\/\" data-type=\"link\" data-id=\"https:\/\/lorentzenchr.github.io\/model-diagnostics\/\">model-diagnostics<\/a> got the concept of a <em>plotting backend<\/em>. Before this release, all plots were constructed with <a href=\"https:\/\/matplotlib.org\">matplotlib<\/a>. This is still the default. But additionally, the user can now select <a href=\"https:\/\/plotly.com\/python\/\">plotly<\/a>, if it is installed.<\/p>\n\n\n\n<p>There are 2 ways to specify the plotting backend explicitly<\/p>\n\n\n<div class=\"wp-block-ub-content-toggle wp-block-ub-content-toggle-block\" id=\"ub-content-toggle-block-c7fbc97e-4a96-4d77-8693-5f181fdaba9b\" data-mobilecollapse=\"false\" data-desktopcollapse=\"false\" data-preventcollapse=\"false\" data-showonlyone=\"false\">\n<div class=\"wp-block-ub-content-toggle-accordion\" style=\"border-color: #f1f1f1; \" id=\"ub-content-toggle-panel-block-ee23ef53-3ed5-47ea-82da-f3d0f43abeba\">\n\t\t\t<div class=\"wp-block-ub-content-toggle-accordion-title-wrap\" style=\"background-color: #f1f1f1;\" aria-controls=\"ub-content-toggle-panel-0-c7fbc97e-4a96-4d77-8693-5f181fdaba9b\" tabindex=\"0\">\n\t\t\t<p class=\"wp-block-ub-content-toggle-accordion-title ub-content-toggle-title-c7fbc97e-4a96-4d77-8693-5f181fdaba9b\" style=\"color: #000000; \">Setting the plotting backend via global configuation<\/p>\n\t\t\t<div class=\"wp-block-ub-content-toggle-accordion-toggle-wrap right\" style=\"color: #000000;\"><span class=\"wp-block-ub-content-toggle-accordion-state-indicator wp-block-ub-chevron-down open\"><\/span><\/div>\n\t\t<\/div>\n\t\t\t<div role=\"region\" aria-expanded=\"true\" class=\"wp-block-ub-content-toggle-accordion-content-wrap\" id=\"ub-content-toggle-panel-0-c7fbc97e-4a96-4d77-8693-5f181fdaba9b\">\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting='{\"showPanel\":true,\"languageLabel\":\"language\",\"fullScreenButton\":true,\"copyButton\":true,\"mode\":\"python\",\"mime\":\"text\/x-python\",\"theme\":\"material\",\"lineNumbers\":false,\"styleActiveLine\":false,\"lineWrapping\":false,\"readOnly\":true,\"fileName\":\"Python\",\"language\":\"Python\",\"maxHeight\":\"400px\",\"modeName\":\"python\"}'>from model_diagnostics import set_config\n\nset_config(plot_backend=\"plotly\")<\/pre><\/div>\n\n<\/div>\n\t\t<\/div>\n\n<div class=\"wp-block-ub-content-toggle-accordion\" style=\"border-color: #f1f1f1; \" id=\"ub-content-toggle-panel-block-9a6f046f-95e2-40b7-93e3-6f30b4d64b48\">\n\t\t\t<div class=\"wp-block-ub-content-toggle-accordion-title-wrap\" style=\"background-color: #f1f1f1;\" aria-controls=\"ub-content-toggle-panel-1-c7fbc97e-4a96-4d77-8693-5f181fdaba9b\" tabindex=\"0\">\n\t\t\t<p class=\"wp-block-ub-content-toggle-accordion-title ub-content-toggle-title-c7fbc97e-4a96-4d77-8693-5f181fdaba9b\" style=\"color: #000000; \">Setting the plotting backend via a context manager<\/p>\n\t\t\t<div class=\"wp-block-ub-content-toggle-accordion-toggle-wrap right\" style=\"color: #000000;\"><span class=\"wp-block-ub-content-toggle-accordion-state-indicator wp-block-ub-chevron-down open\"><\/span><\/div>\n\t\t<\/div>\n\t\t\t<div role=\"region\" aria-expanded=\"true\" class=\"wp-block-ub-content-toggle-accordion-content-wrap\" id=\"ub-content-toggle-panel-1-c7fbc97e-4a96-4d77-8693-5f181fdaba9b\">\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting='{\"showPanel\":true,\"languageLabel\":\"language\",\"fullScreenButton\":true,\"copyButton\":true,\"mode\":\"python\",\"mime\":\"text\/x-python\",\"theme\":\"material\",\"lineNumbers\":false,\"styleActiveLine\":false,\"lineWrapping\":false,\"readOnly\":true,\"fileName\":\"Python\",\"language\":\"Python\",\"maxHeight\":\"400px\",\"modeName\":\"python\"}'>from model_diagnostics import config_context\nfrom model_diagnostics.calibration import plot_bias\n\nwith config_context(plot_backend=\"plotly\"):\n    plot_bias(...)<\/pre><\/div>\n\n<\/div>\n\t\t<\/div>\n<\/div>\n\n\n<p>The context manager has precedence over the global setting. Here is an example of an interactive reliability diagram backed by plotly:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text\/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Python&quot;,&quot;language&quot;:&quot;Python&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;python&quot;}\">import numpy as np\nfrom model_diagnostics.calibration import plot_reliability_diagram\nfrom model_diagnostics import set_config\n\nset_config(plot_backend=&quot;plotly&quot;)\n\nx = np.linspace(0, 2 * np.pi, 100)\ny_obs = np.cos(x)\n# A poor linear interpolation through extrema as predictions. \ny_pred = np.interp(x, [0, np.pi, 2 * np.pi], [1, -1, 1])\nax = plot_reliability_diagram(y_obs=y_obs, y_pred=y_pred)<\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"591\" src=\"https:\/\/lorentzen.ch\/wp-content\/uploads\/2024\/04\/Screenshot-2024-04-15-at-19.08.43-1024x591.png\" alt=\"\" class=\"wp-image-1552\" srcset=\"https:\/\/lorentzen.ch\/wp-content\/uploads\/2024\/04\/Screenshot-2024-04-15-at-19.08.43-1024x591.png 1024w, https:\/\/lorentzen.ch\/wp-content\/uploads\/2024\/04\/Screenshot-2024-04-15-at-19.08.43-300x173.png 300w, https:\/\/lorentzen.ch\/wp-content\/uploads\/2024\/04\/Screenshot-2024-04-15-at-19.08.43-768x443.png 768w, https:\/\/lorentzen.ch\/wp-content\/uploads\/2024\/04\/Screenshot-2024-04-15-at-19.08.43.png 1182w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>If you wonder why this graph is not interactive despite promised to be, here is why: While this graph renders nicely in a juper lab notebook, for instance, this website is built with wordpress and I was simply unable to figure out a way to get the html of the graph rendered properly\u2014without wordpress crashing. I you know a way, please contact me.<\/p>\n\n\n\n<p>Code above as notebook: <a href=\"https:\/\/github.com\/lorentzenchr\/notebooks\/blob\/master\/blogposts\/2024-04-15%20reliability_plot_plotly.ipynb\">https:\/\/github.com\/lorentzenchr\/notebooks\/blob\/master\/blogposts\/2024-04-15%20reliability_plot_plotly.ipynb<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>With its newest release 1.1.0, the Python package model-diagnostics got the concept of a plotting backend. Before this release, all plots were constructed with matplotlib. This is still the default. But additionally, the user can now select plotly, if it is installed. There are 2 ways to specify the plotting backend explicitly The context manager [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[],"class_list":["post-1535","post","type-post","status-publish","format-standard","hentry","category-programming"],"featured_image_src":null,"author_info":{"display_name":"Christian Lorentzen","author_link":"https:\/\/lorentzen.ch\/index.php\/author\/christian\/"},"_links":{"self":[{"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/posts\/1535","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/comments?post=1535"}],"version-history":[{"count":21,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/posts\/1535\/revisions"}],"predecessor-version":[{"id":1976,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/posts\/1535\/revisions\/1976"}],"wp:attachment":[{"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/media?parent=1535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/categories?post=1535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lorentzen.ch\/index.php\/wp-json\/wp\/v2\/tags?post=1535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}