{"id":239,"date":"2019-07-25T18:30:39","date_gmt":"2019-07-25T18:30:39","guid":{"rendered":"https:\/\/www.allendowney.com\/blog\/?p=239"},"modified":"2019-07-25T18:30:39","modified_gmt":"2019-07-25T18:30:39","slug":"matplotlib-animation-in-jupyter","status":"publish","type":"post","link":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/","title":{"rendered":"Matplotlib animation in Jupyter"},"content":{"rendered":"\n<p>For two of my books, <em><a href=\"https:\/\/greenteapress.com\/wp\/think-complexity-2e\/\">Think Complexity<\/a><\/em> and <em><a href=\"https:\/\/greenteapress.com\/wp\/modsimpy\/\">Modeling and Simulation in Python<\/a><\/em>, many of the examples involve animation.  Fortunately, there are <a href=\"https:\/\/stackoverflow.com\/questions\/35532498\/animation-in-ipython-notebook\/46878531#46878531\">several ways to do animation with Matplotlib in Jupyter<\/a>.  Unfortunately, none of them is ideal.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">FuncAnimation<\/h4>\n\n\n\n<p>Until recently, I was using <code>FuncAnimation<\/code>, provided by the <a href=\"https:\/\/matplotlib.org\/3.1.1\/api\/_as_gen\/matplotlib.animation.FuncAnimation.html\"><code>matplotlib.animation<\/code><\/a> package, as in <a href=\"https:\/\/github.com\/AllenDowney\/ThinkComplexity2\/blob\/72fc41cce7659c7d5d2027527f9623097b59dfcc\/code\/Cell2D.py#L117\">this example<\/a> from <em>Think Complexity<\/em>.  The documentation of this function is pretty sparse, but if you want to use it, you can find examples.<\/p>\n\n\n\n<p>For me, there are a few drawbacks:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>It requires a back end like <code>ffmpeg<\/code> to display the animation.  Based on my email, many readers have trouble installing packages like this, so I avoid using them.<\/li><li>It runs the entire computation before showing the result, so it takes longer to debug, and makes for a less engaging interactive experience.<\/li><li>For each element you want to animate, you have to use one API to create the element and another to update it.<\/li><\/ul>\n\n\n\n<p>For example, if you are using <code>imshow<\/code> to visualize an array, you would run<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">    im = plt.imshow(a, **options)<\/pre>\n\n\n\n<p>to create an <code>AxesImage<\/code>, and then<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">    im.set_array(a)<\/pre>\n\n\n\n<p>to update it.  For beginners, this is a lot to ask.  And even for experienced people, it can be hard to find documentation that shows how to update various display elements.  <\/p>\n\n\n\n<p>As another example, suppose you have a 2-D array and plot it like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">    plot(a)<\/pre>\n\n\n\n<p>The result is a list of <code>Line2D<\/code> objects.  To update them, you have to traverse the list and invoke <code>set_xdata()<\/code> on each one.<\/p>\n\n\n\n<p>Updating a display is often more complicated than creating it, and requires substantial navigation of the documentation.  Wouldn&#8217;t it be nice to just call <code>plot(a)<\/code> again?<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Clear output<\/h4>\n\n\n\n<p>Recently I discovered simpler alternative using <a href=\"https:\/\/ipython.readthedocs.io\/en\/stable\/api\/generated\/IPython.display.html#functions\"><code>clear_output()<\/code> from <code>Ipython.display<\/code><\/a> and <code>sleep()<\/code> from the <code>time<\/code> module.  If you have Python and Jupyter, you already have these modules, so there&#8217;s nothing to install.<\/p>\n\n\n\n<p>Here&#8217;s a minimal example using <code>imshow<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">%matplotlib inline\n\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom IPython.display import clear_output\nfrom time import sleep\n\nn = 10\na = np.zeros((n, n))\nplt.figure()\n\nfor i in range(n):\n    plt.imshow(a)\n    plt.show()\n    a[i, i] = 1\n    sleep(0.1)\n    clear_output(wait=True)<\/pre>\n\n\n\n<p>The drawback of this method is that it is relatively slow, but for the examples I&#8217;ve worked on, the performance has been good enough.<\/p>\n\n\n\n<p>In the ModSimPy library, I provide a function that encapsulates this pattern:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def animate(results, draw_func, interval=None):\n    plt.figure()\n    try:\n        for t, state in results.iterrows():\n            draw_func(state, t)\n            plt.show()\n            if interval:\n                sleep(interval)\n            clear_output(wait=True)\n        draw_func(state, t)\n        plt.show()\n    except KeyboardInterrupt:\n        pass<\/pre>\n\n\n\n<p><code>results<\/code> is a Pandas DataFrame that contains results from a simulation; each row represents the state of a system at a point in time.<\/p>\n\n\n\n<p><code>draw_func<\/code> is a function that takes a state and draws it in whatever way is appropriate for the context.<\/p>\n\n\n\n<p><code>interval<\/code> is the time between frames in seconds (not counting the time to draw the frame).<\/p>\n\n\n\n<p>Because the loop is wrapped in a <code>try<\/code> statement that captures <code>KeyboardInterrupt<\/code>, you can interrupt an animation cleanly.<\/p>\n\n\n\n<p>You can see an example that uses this function in <a href=\"https:\/\/github.com\/AllenDowney\/ModSimPy\/blob\/master\/notebooks\/chap22.ipynb\">this notebook from Chapter 22<\/a> of <em>Modeling and Simulation in Python<\/em>, and you can <a href=\"https:\/\/mybinder.org\/v2\/gh\/AllenDowney\/ModSimPy\/master?filepath=notebooks%2Fchap22.ipynb\">run it on Binder<\/a>.<\/p>\n\n\n\n<p>And here&#8217;s <a href=\"https:\/\/github.com\/AllenDowney\/ThinkComplexity2\/blob\/master\/notebooks\/chap06.ipynb\">an example from Chapter 6<\/a> of <em>Think Complexity<\/em>, which you can also <a href=\"https:\/\/mybinder.org\/v2\/gh\/AllenDowney\/ThinkComplexity2\/master?filepath=notebooks%2Fchap06.ipynb\">run on Binder<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For two of my books, Think Complexity and Modeling and Simulation in Python, many of the examples involve animation. Fortunately, there are several ways to do animation with Matplotlib in Jupyter. Unfortunately, none of them is ideal. FuncAnimation Until recently, I was using FuncAnimation, provided by the matplotlib.animation package, as in this example from Think Complexity. The documentation of this function is pretty sparse, but if you want to use it, you can find examples. For me, there are a&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[25,24,16],"class_list":["post-239","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-animation","tag-jupyter","tag-python"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Matplotlib animation in Jupyter - Probably Overthinking It<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Matplotlib animation in Jupyter - Probably Overthinking It\" \/>\n<meta property=\"og:description\" content=\"For two of my books, Think Complexity and Modeling and Simulation in Python, many of the examples involve animation. Fortunately, there are several ways to do animation with Matplotlib in Jupyter. Unfortunately, none of them is ideal. FuncAnimation Until recently, I was using FuncAnimation, provided by the matplotlib.animation package, as in this example from Think Complexity. The documentation of this function is pretty sparse, but if you want to use it, you can find examples. For me, there are a... Read More Read More\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/\" \/>\n<meta property=\"og:site_name\" content=\"Probably Overthinking It\" \/>\n<meta property=\"article:published_time\" content=\"2019-07-25T18:30:39+00:00\" \/>\n<meta name=\"author\" content=\"AllenDowney\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@AllenDowney\" \/>\n<meta name=\"twitter:site\" content=\"@AllenDowney\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"AllenDowney\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/\"},\"author\":{\"name\":\"AllenDowney\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/#\/schema\/person\/4e5bfb2e9af6c3446cb0031a7bf83207\"},\"headline\":\"Matplotlib animation in Jupyter\",\"datePublished\":\"2019-07-25T18:30:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/\"},\"wordCount\":455,\"publisher\":{\"@id\":\"https:\/\/www.allendowney.com\/blog\/#organization\"},\"keywords\":[\"animation\",\"jupyter\",\"python\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/\",\"url\":\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/\",\"name\":\"Matplotlib animation in Jupyter - Probably Overthinking It\",\"isPartOf\":{\"@id\":\"https:\/\/www.allendowney.com\/blog\/#website\"},\"datePublished\":\"2019-07-25T18:30:39+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.allendowney.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Matplotlib animation in Jupyter\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/#website\",\"url\":\"https:\/\/www.allendowney.com\/blog\/\",\"name\":\"Probably Overthinking It\",\"description\":\"Data science, Bayesian Statistics, and other ideas\",\"publisher\":{\"@id\":\"https:\/\/www.allendowney.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.allendowney.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/#organization\",\"name\":\"Probably Overthinking It\",\"url\":\"https:\/\/www.allendowney.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.allendowney.com\/blog\/wp-content\/uploads\/2025\/03\/probably_logo.png\",\"contentUrl\":\"https:\/\/www.allendowney.com\/blog\/wp-content\/uploads\/2025\/03\/probably_logo.png\",\"width\":714,\"height\":784,\"caption\":\"Probably Overthinking It\"},\"image\":{\"@id\":\"https:\/\/www.allendowney.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/AllenDowney\",\"https:\/\/www.linkedin.com\/in\/allendowney\/\",\"https:\/\/bsky.app\/profile\/allendowney.bsky.social\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/#\/schema\/person\/4e5bfb2e9af6c3446cb0031a7bf83207\",\"name\":\"AllenDowney\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.allendowney.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/fb01b3a7f7190bea1bbf7f0852e686c2f8c03b099222df2ce4bc7926f15bcb43?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/fb01b3a7f7190bea1bbf7f0852e686c2f8c03b099222df2ce4bc7926f15bcb43?s=96&d=mm&r=g\",\"caption\":\"AllenDowney\"},\"url\":\"https:\/\/www.allendowney.com\/blog\/author\/allendowney_6dbrc4\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Matplotlib animation in Jupyter - Probably Overthinking It","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/","og_locale":"en_US","og_type":"article","og_title":"Matplotlib animation in Jupyter - Probably Overthinking It","og_description":"For two of my books, Think Complexity and Modeling and Simulation in Python, many of the examples involve animation. Fortunately, there are several ways to do animation with Matplotlib in Jupyter. Unfortunately, none of them is ideal. FuncAnimation Until recently, I was using FuncAnimation, provided by the matplotlib.animation package, as in this example from Think Complexity. The documentation of this function is pretty sparse, but if you want to use it, you can find examples. For me, there are a... Read More Read More","og_url":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/","og_site_name":"Probably Overthinking It","article_published_time":"2019-07-25T18:30:39+00:00","author":"AllenDowney","twitter_card":"summary_large_image","twitter_creator":"@AllenDowney","twitter_site":"@AllenDowney","twitter_misc":{"Written by":"AllenDowney","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/#article","isPartOf":{"@id":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/"},"author":{"name":"AllenDowney","@id":"https:\/\/www.allendowney.com\/blog\/#\/schema\/person\/4e5bfb2e9af6c3446cb0031a7bf83207"},"headline":"Matplotlib animation in Jupyter","datePublished":"2019-07-25T18:30:39+00:00","mainEntityOfPage":{"@id":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/"},"wordCount":455,"publisher":{"@id":"https:\/\/www.allendowney.com\/blog\/#organization"},"keywords":["animation","jupyter","python"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/","url":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/","name":"Matplotlib animation in Jupyter - Probably Overthinking It","isPartOf":{"@id":"https:\/\/www.allendowney.com\/blog\/#website"},"datePublished":"2019-07-25T18:30:39+00:00","breadcrumb":{"@id":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.allendowney.com\/blog\/2019\/07\/25\/matplotlib-animation-in-jupyter\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.allendowney.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Matplotlib animation in Jupyter"}]},{"@type":"WebSite","@id":"https:\/\/www.allendowney.com\/blog\/#website","url":"https:\/\/www.allendowney.com\/blog\/","name":"Probably Overthinking It","description":"Data science, Bayesian Statistics, and other ideas","publisher":{"@id":"https:\/\/www.allendowney.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.allendowney.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.allendowney.com\/blog\/#organization","name":"Probably Overthinking It","url":"https:\/\/www.allendowney.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.allendowney.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.allendowney.com\/blog\/wp-content\/uploads\/2025\/03\/probably_logo.png","contentUrl":"https:\/\/www.allendowney.com\/blog\/wp-content\/uploads\/2025\/03\/probably_logo.png","width":714,"height":784,"caption":"Probably Overthinking It"},"image":{"@id":"https:\/\/www.allendowney.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/AllenDowney","https:\/\/www.linkedin.com\/in\/allendowney\/","https:\/\/bsky.app\/profile\/allendowney.bsky.social"]},{"@type":"Person","@id":"https:\/\/www.allendowney.com\/blog\/#\/schema\/person\/4e5bfb2e9af6c3446cb0031a7bf83207","name":"AllenDowney","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.allendowney.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/fb01b3a7f7190bea1bbf7f0852e686c2f8c03b099222df2ce4bc7926f15bcb43?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/fb01b3a7f7190bea1bbf7f0852e686c2f8c03b099222df2ce4bc7926f15bcb43?s=96&d=mm&r=g","caption":"AllenDowney"},"url":"https:\/\/www.allendowney.com\/blog\/author\/allendowney_6dbrc4\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":235,"url":"https:\/\/www.allendowney.com\/blog\/2019\/07\/10\/report-from-scipy-2019\/","url_meta":{"origin":239,"position":0},"title":"Report from SciPy 2019","author":"AllenDowney","date":"July 10, 2019","format":false,"excerpt":"Greetings from Austin and SciPy 2019. In this post, I've collected the materials for my tutorials and talks. On Monday morning I presented Bayesian Statistics Made Simple in an extended 4-hour format: Here are the slidesCode and Jupyter notebooks are in this repositorySetup instructions are here In the afternoon I\u2026","rel":"","context":"Similar post","block_context":{"text":"Similar post","link":""},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1229,"url":"https:\/\/www.allendowney.com\/blog\/2024\/02\/15\/think-python-third-edition\/","url_meta":{"origin":239,"position":1},"title":"Think Python third edition!","author":"AllenDowney","date":"February 15, 2024","format":false,"excerpt":"I am happy to announce the third edition of Think Python, which will be published by O'Reilly Media later this year. You can read the online version of the book here. I've posted the Preface and the first four chapters -- more on the way soon! You can read the\u2026","rel":"","context":"Similar post","block_context":{"text":"Similar post","link":""},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.allendowney.com\/blog\/wp-content\/uploads\/2024\/02\/image.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":883,"url":"https:\/\/www.allendowney.com\/blog\/2023\/03\/20\/the-bayesian-killer-app\/","url_meta":{"origin":239,"position":2},"title":"The Bayesian Killer App","author":"AllenDowney","date":"March 20, 2023","format":false,"excerpt":"It's been a while since anyone said \"killer app\" without irony, so let me remind you that a killer app is software \"so necessary or desirable that it proves the core value of some larger technology,\" quoth Wikipedia. For example, most people didn't have much use for the internet until\u2026","rel":"","context":"Similar post","block_context":{"text":"Similar post","link":""},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/img.youtube.com\/vi\/fsdbneHgi58\/0.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1255,"url":"https:\/\/www.allendowney.com\/blog\/2024\/03\/08\/think-python-goes-to-production\/","url_meta":{"origin":239,"position":3},"title":"Think Python Goes to Production","author":"AllenDowney","date":"March 8, 2024","format":false,"excerpt":"Think Python has moved into production, on schedule for the official publication date in July -- but maybe earlier if things go well. To celebrate, I have posted the next batch of chapters on the new site, up through Chapter 12, which is about Markov text analysis and generation, one\u2026","rel":"","context":"Similar post","block_context":{"text":"Similar post","link":""},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.allendowney.com\/blog\/wp-content\/uploads\/2024\/03\/Think_Python_3e_cover.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1704,"url":"https:\/\/www.allendowney.com\/blog\/2026\/01\/09\/bayesian-decision-analysis\/","url_meta":{"origin":239,"position":4},"title":"Bayesian Decision Analysis","author":"AllenDowney","date":"January 9, 2026","format":false,"excerpt":"At PyData Global 2025 I presented a workshop on Bayesian Decision Analysis with PyMC. The video is available now. This workshop is based on the first session of the Applied Bayesian Modeling Workshop I teach along with my colleagues at PyMC Labs. If you would like to learn more, it\u2026","rel":"","context":"In \"bayesian statistics\"","block_context":{"text":"bayesian statistics","link":"https:\/\/www.allendowney.com\/blog\/tag\/bayesian-statistics\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/img.youtube.com\/vi\/PLGVZCDnMOq0qmerwB1eITnr5AfYRGm0DF\/0.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1553,"url":"https:\/\/www.allendowney.com\/blog\/2025\/05\/28\/announcing-think-linear-algebra\/","url_meta":{"origin":239,"position":5},"title":"Announcing Think Linear Algebra","author":"AllenDowney","date":"May 28, 2025","format":false,"excerpt":"I've been thinking about Think Linear Algebra for more than a decade, and recently I started working on it in earnest. If you want to get a sense of it, I've posted a draft chapter as a Jupyter notebook. In one way, I am glad I waited -- I think\u2026","rel":"","context":"In \"linear algebra\"","block_context":{"text":"linear algebra","link":"https:\/\/www.allendowney.com\/blog\/tag\/linear-algebra\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.allendowney.com\/blog\/wp-content\/uploads\/2025\/05\/think_linear_algebra_fake_cover.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/posts\/239","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/comments?post=239"}],"version-history":[{"count":3,"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/posts\/239\/revisions"}],"predecessor-version":[{"id":242,"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/posts\/239\/revisions\/242"}],"wp:attachment":[{"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/media?parent=239"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/categories?post=239"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.allendowney.com\/blog\/wp-json\/wp\/v2\/tags?post=239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}