<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Jules Walzer-Goldfeld</title>
<link>https://juleswg.me/blog.html</link>
<atom:link href="https://juleswg.me/blog.xml" rel="self" type="application/rss+xml"/>
<description></description>
<generator>quarto-1.8.26</generator>
<lastBuildDate>Mon, 04 Aug 2025 00:00:00 GMT</lastBuildDate>
<item>
  <title>A Great Summer of Great Tables</title>
  <dc:creator>Jules Walzer-Goldfeld</dc:creator>
  <link>https://juleswg.me/posts/Posit-Internship-Reflection/</link>
  <description><![CDATA[ 





<p>I spent the summer working for Posit (formerly known as RStudio), and I loved it. I was on the tinytools squad, as an intern for <a href="https://posit-dev.github.io/great-tables/"><strong>Great Tables</strong></a>, the Python port of {gt} in R. My team was responsible for many of the major ports from Posit’s R packages to Python. They are awesome – this is certainly an incomplete list, but they’ve created the Python versions of {ggplot2}, {pointblank}, {scales}, {forcats}, {dplyr}, and {reactable}, to name a few.</p>
<p>My summer consisted of:</p>
<ul>
<li>Building and packaging a Python library (<a href="https://posit-dev.github.io/gt-extras/"><strong>gt-extras</strong></a>)</li>
<li>Contributing fixes and features upstream to <strong>Great Tables</strong></li>
<li>Presenting and promoting the open source work</li>
<li>Pairing with mentors and collaborating across Posit</li>
</ul>
<section id="what-i-did" class="level2">
<h2 class="anchored" data-anchor-id="what-i-did">What I Did</h2>
<p>The technical work at first largely consisted of work on my own package, an addition to the Great Tables ecosystem by way of extension. Then I was able to contribute directly to Great Tables as well, which was very satisfying. I also had the unexpected (and welcome) task of presenting and promoting my work to the open‑source community.</p>
<p>I also got to meet tons of folks from the wider Posit community, thanks to internal weekly matchmaking, fun talks/hangouts (and even an in-person meetup). I’ve met so many wonderful people over the past few months that I couldn’t possibly list them all here. Suffice to say that from intern hangouts to coffee chats with Posit developers in Europe, to career advice with former python open source team members, to data science talks, the remote world of my internship has not been all too remote.</p>
<section id="gt-extras" class="level3">
<h3 class="anchored" data-anchor-id="gt-extras">gt-extras</h3>
<p>If you’re here I’ll assume you know about the <a href="https://posit-dev.github.io/gt-extras/"><strong>gt-extras</strong></a> package, or at the very least you know who I am, so I’ll avoid the shameless plug. The overwhelming majority of my work this summer has entailed a port of the {gtExtras} R package to Python, a task that was made more complex and interesting because of the underlying differences between the R and Python versions of Great Tables.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://juleswg.me/images/gap.png" class="img-fluid quarto-figure quarto-figure-center figure-img" style="width:36em"></p>
</figure>
</div>
<p>The core tasks of the gt-extras library are to:</p>
<ol type="1">
<li>make existing features of Great Tables easier to use</li>
<li>add in-cell plotting</li>
<li>compose styles to replicate the themes of famous publications</li>
<li>execute simple html and post-processing steps</li>
</ol>
<p>Rich Iannone (one of my great mentors) got me started with the package structure, since he had already written a minimal version with one theme. That class of functions turned out to be the most bang for my buck – take the exact styling options researched and implemented by Thomas Mock in {gtExtras}, and with minimal syntax changes I had finished the themes!</p>
<p>But it wasn’t all copy and paste. In fact, after that, just about every function had a pretty critical deviation from the R version. The underlying dataframe in the Python package is different from R, and gtExtras had access to ggplot2, two elements that were inaccessible to me. Since we wanted to keep dependencies light, I did all of the data wrangling and graphics myself.</p>
<p>Michael Chow (my other great mentor) pointed me towards Narwhals (a library meant for handling different dataframe libraries). Both he and Rich encouraged me to try out different approaches to plotting, and while they could have easily told me “do it this way,” I am very grateful that I was trusted enough to make those decisions and discoveries myself.</p>
<p>Over the first couple of weeks, I met with both daily, and later we made longer term targets and paired for the more critical decisions. One of which was the first external contribution into my package, which was a delight to see. For the most part, I was given low-level autonomy over implementation choices, and reserved pairing for decisions like how to approach building plots or how to unify competing underlying dataframes (looking at you, Narwhals 👀). The independence was freeing, as it helped me learn what I could do myself, even when at first it felt like a good thing to ask for help on (like designing the documentation website).</p>
<p>Okay, fine – I can’t help but show off some of the cool things it can do. We can see a summary of the 2011 NFL season, my favorite being the winloss charts, primarily because of how much winning my New York Giants did that season.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://juleswg.me/images/2011-nfl-season.png" class="img-fluid figure-img" style="width:36em"></p>
<figcaption>A mega-example built with the gt-extras library</figcaption>
</figure>
</div>
</section>
<section id="great-tables" class="level3">
<h3 class="anchored" data-anchor-id="great-tables">Great Tables</h3>
<p>The very first PR I made to Great Tables was an entirely <a href="https://github.com/posit-dev/great-tables/pull/696">new feature</a>, to rotate column labels 90 degrees. I don’t think I realized it at the time, but the workflow of that task was exactly how I approached the functions in gt-extras. Namely, I had to write a function, write a docstring with an example, add it to the documentation, and then write tests. This last part kind of grew on me, even though I’d embarrassingly never really done it before.</p>
<p>It didn’t stop there – as I progressed through styling and coloring functions, I uncovered little improvements I wanted to make to Great Tables. The bonus side effect of spending all those hours extending Great Tables is that I became perhaps the most frequent user (and tester) of the package. Eventually, I got to a point where I was fluent enough with Great Tables source code, and tacked some larger features and known bugs. So a number of my own GitHub issues (and my subsequent PRs) made their way into the repository:</p>
<!-- Add link to the PR that closes https://github.com/posit-dev/great-tables/pull/755, https://github.com/posit-dev/great-tables/issues/761 -->
<ul>
<li>a grand 😉 new <a href="https://github.com/posit-dev/great-tables/pull/765">feature</a></li>
<li>a collection of many <a href="https://github.com/posit-dev/great-tables/pull/756">different</a> <a href="https://github.com/posit-dev/great-tables/pull/754">fixes</a> to old group bugs</li>
<li>a row striping indexing <a href="https://github.com/posit-dev/great-tables/issues/701">bug</a> with grouped data</li>
<li>a data coloring palette <a href="https://github.com/posit-dev/great-tables/issues/718">bug</a></li>
<li>an <a href="https://github.com/posit-dev/great-tables/issues/745">improvement</a> to autocoloring the text of striped rows</li>
<li>an <a href="https://github.com/posit-dev/great-tables/issues/747">improvement</a> to autocoloring in semi-transparent elements</li>
</ul>
</section>
<section id="package-promotion" class="level3">
<h3 class="anchored" data-anchor-id="package-promotion">Package Promotion</h3>
<p>It seems obvious now, but I had never thought about what happens to a package after we write it. It’s a good thing I had Michael and Rich pushing me through this step because, had it been up to me, the world would never have learned about this package. Talking about the package doesn’t come easily to me, especially when it’s to an audience of more than just my roommate, but it really helped that the team gave me the first boost (and it certainly didn’t hurt to have the Posit organization promoting it too).</p>
<p>And selfishly I must admit the effect of broadcasting the package far and wide is rewarding. Seeing the package featured on a blog post, or used in someone’s repository will make my day. Because it’s so cool to know the design choices I stayed awake thinking about were (possibly) appreciated by a fellow data enthusiast.</p>
</section>
</section>
<section id="what-i-learned" class="level2">
<h2 class="anchored" data-anchor-id="what-i-learned">What I Learned</h2>
<p>This summer touched on so many aspects of open source code, from the technical to the collaborative. I learned how to take an idea and turn it into a fully functioning Python package, and I gained hands-on experience with the whole development workflow. Beyond the code itself, I also learned the importance of communicating my work, whether through documentation, blog posts, or presentations.</p>
<section id="package-development" class="level3">
<h3 class="anchored" data-anchor-id="package-development">Package Development</h3>
<!-- todo -->
<p>Before this summer, I had no idea what really went into making a Python package from scratch. I learned how to set everything up, from the folder structure, to setup files, to GitHub actions and beyond. I got comfortable with things like versioning, documentation, and publishing to PyPI. Now packaging up code feels way less mysterious and way more doable.</p>
<p>The open process taught me to write code that is readable and maintainable, not just functional. I also gained a deeper appreciation for documentation, not just as a reference, but as a way to welcome new users and contributors.</p>
</section>
<section id="development-organization" class="level3">
<h3 class="anchored" data-anchor-id="development-organization">Development Organization</h3>
<p>With a little shame, I must admit I never knew how to use a branch. That’s an exaggeration. I knew what a branch <em>was</em>, and I knew to make one so I didn’t have to commit to the main branch. The shameful part is once I had a branch, all the new code went into that. (🙈 Don’t look at the repository for this website). And then one day, when I felt like there was probably too much code I hadn’t committed to the main branch, I’d merge it and ta-da, surely that was good enough… right? Fortunately, I learned about how to separate code into isolated pieces, to then merge code in a way that keeps the project organized and maintainable.</p>
<p>With even more shame, I have to admit I didn’t know how to write a suite of tests. Again, I knew what tests were supposed to do, but the concept seemed like something meant for more professional environments, never for code that I worked on. Until my work became code that other people could theoretically rely on – then I knew it had to be dependable. So from snapshot tests, to checking for the presence of css and html content, future changes and dependency upgrades can be relied on not to break the package.</p>
<p>I’m not claiming to be a pro, but thanks to Rich and Michael’s mentoring, I am now much <em>better</em> at adhering to these practices than I used to be.</p>
</section>
<section id="writing-things-like-this" class="level3">
<h3 class="anchored" data-anchor-id="writing-things-like-this">Writing things like this!</h3>
<!-- add link to posit blog post -->
<p>Whether it’s a blog post for me (this one!), a blog <a href="https://posit-dev.github.io/great-tables/blog/plots-in-tables/">post</a> for Great Tables or a blog post for the entirety of Posit, I have had no shortage of opportunities to talk about my work. As you might guess, this doesn’t come naturally to me, but it’s yet another skill I’ve gotten to practice and hone in my summer at Posit.</p>
<p>In every instance (yes, even the <a href="../../talks/Posit-Open-Source-Reflection/index.html">slides</a>), I’ve presented my musings using Quarto markdown. I promise I’m not getting paid to say this, but having never used Quarto before this summer, I can confidently say I can’t imagine a life without it. Life with Quarto was especially easy when the team that maintains it was part of the organization I worked for :) which I’ll definitely miss. Instead, I guess you’ll find me lurking in GitHub issues.</p>
</section>
</section>
<section id="whats-next-its-not-over-yet" class="level2">
<h2 class="anchored" data-anchor-id="whats-next-its-not-over-yet">What’s Next (It’s not over yet)</h2>
<p>At the time of publication, I still have a few weeks remaining in my time at Posit. Big things are still planned, from more features in gt-extras, to upgrades for Great Tables. Stick around here or give <a href="https://github.com/posit-dev/gt-extras"><strong>gt-extras</strong></a> a star and follow along with my work there.</p>


</section>

 ]]></description>
  <category>Python</category>
  <category>Great Tables</category>
  <category>Posit</category>
  <guid>https://juleswg.me/posts/Posit-Internship-Reflection/</guid>
  <pubDate>Mon, 04 Aug 2025 00:00:00 GMT</pubDate>
  <media:content url="https://juleswg.me/images/2011-nfl-season.png" medium="image" type="image/png" height="101" width="144"/>
</item>
<item>
  <title>Adding Plots to Great Tables</title>
  <dc:creator>Jules Walzer-Goldfeld and Michael Chow</dc:creator>
  <link>https://juleswg.me/posts/Posit-adding-plots-to-great-tables/</link>
  <description><![CDATA[ 





<p>While working on <a href="https://posit-dev.github.io/gt-extras/articles/intro.html"><strong>gt-extras</strong></a>, I’ve been exploring how to add small plots to Great Tables. These can go by many names, like spark lines, nanoplots, and so on. In this post, I’ll look at three approaches I tried: adding plots with <a href="https://plotnine.org/"><code>plotnine</code></a>, <a href="https://github.com/orsinium-labs/svg.py"><code>svg.py</code></a>, or adding HTML directly. In the first two cases, the plots are SVGs, while the latter entails a collection of composed HTML div elements.</p>
<p>Here are the pieces I’ll cover:</p>
<ul>
<li><strong>svg.py</strong>: creating your own tiny chart directly for a row.</li>
<li><strong>direct HTML</strong>: adding HTML divs directly.</li>
<li><strong>plotnine</strong>: adding a full, stripped-down chart to a row.</li>
</ul>
<p>In the end, it’s often simplest to use <code>svg.py</code>, since you can create basic charts with minimal overhead. Building elements with HTML has even <em>less</em> overhead, but it is also slightly less user-friendly. At the other end of the spectrum, as your charts become more complex, using existing packages like the more exhaustive <code>plotnine</code> is a good alternative.</p>
<div id="2e756791" class="cell" data-execution_count="1">
<div class="cell-output cell-output-display" data-execution_count="1">
<div id="rfsjkdimrj" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
#rfsjkdimrj table {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }

#rfsjkdimrj thead, tbody, tfoot, tr, td, th { border-style: none; }
 tr { background-color: transparent; }
#rfsjkdimrj p { margin: 0; padding: 0; }
 #rfsjkdimrj .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
 #rfsjkdimrj .gt_caption { padding-top: 4px; padding-bottom: 4px; }
 #rfsjkdimrj .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
 #rfsjkdimrj .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
 #rfsjkdimrj .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #rfsjkdimrj .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #rfsjkdimrj .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #rfsjkdimrj .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
 #rfsjkdimrj .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
 #rfsjkdimrj .gt_column_spanner_outer:first-child { padding-left: 0; }
 #rfsjkdimrj .gt_column_spanner_outer:last-child { padding-right: 0; }
 #rfsjkdimrj .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
 #rfsjkdimrj .gt_spanner_row { border-bottom-style: hidden; }
 #rfsjkdimrj .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
 #rfsjkdimrj .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
 #rfsjkdimrj .gt_from_md> :first-child { margin-top: 0; }
 #rfsjkdimrj .gt_from_md> :last-child { margin-bottom: 0; }
 #rfsjkdimrj .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
 #rfsjkdimrj .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
 #rfsjkdimrj .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
 #rfsjkdimrj .gt_row_group_first td { border-top-width: 2px; }
 #rfsjkdimrj .gt_row_group_first th { border-top-width: 2px; }
 #rfsjkdimrj .gt_striped { color: #333333; background-color: #F4F4F4; }
 #rfsjkdimrj .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #rfsjkdimrj .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
 #rfsjkdimrj .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
 #rfsjkdimrj .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
 #rfsjkdimrj .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
 #rfsjkdimrj .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
 #rfsjkdimrj .gt_left { text-align: left; }
 #rfsjkdimrj .gt_center { text-align: center; }
 #rfsjkdimrj .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
 #rfsjkdimrj .gt_font_normal { font-weight: normal; }
 #rfsjkdimrj .gt_font_bold { font-weight: bold; }
 #rfsjkdimrj .gt_font_italic { font-style: italic; }
 #rfsjkdimrj .gt_super { font-size: 65%; }
 #rfsjkdimrj .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
 #rfsjkdimrj .gt_asterisk { font-size: 100%; vertical-align: 0; }
 
</style>
<table class="gt_table" data-quarto-disable-processing="false" data-quarto-bootstrap="false">
<thead>

<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="Animal">Animal</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Legs">Legs</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Plot">Plot</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td class="gt_row gt_left">Ostrich</td>
    <td class="gt_row gt_right">2</td>
    <td class="gt_row gt_right">2</td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Spider</td>
    <td class="gt_row gt_right">8</td>
    <td class="gt_row gt_right">8</td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Lion</td>
    <td class="gt_row gt_right">4</td>
    <td class="gt_row gt_right">4</td>
  </tr>
</tbody>


</table>

</div>
        
</div>
</div>
<p>Here is the final result:</p>
<div id="57cbbcc1" class="cell" data-execution_count="2">
<details class="code-fold">
<summary>Code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> polars <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pl</span>
<span id="cb1-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> great_tables <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> GT</span>
<span id="cb1-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> svg <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> SVG, Rect, Line</span>
<span id="cb1-4"></span>
<span id="cb1-5">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pl.DataFrame({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Animal"</span>: [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ostrich"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Spider"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Lion"</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Legs"</span>: [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Plot"</span>: [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]})</span>
<span id="cb1-6"></span>
<span id="cb1-7">width <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span></span>
<span id="cb1-8">height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span></span>
<span id="cb1-9">max_legs_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Legs"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>()</span>
<span id="cb1-10"></span>
<span id="cb1-11"></span>
<span id="cb1-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> create_plot_svg_py(val: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>:</span>
<span id="cb1-13">    canvas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> SVG(</span>
<span id="cb1-14">        width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>width,</span>
<span id="cb1-15">        height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>height,</span>
<span id="cb1-16">        elements<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[</span>
<span id="cb1-17">            Rect(</span>
<span id="cb1-18">                x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,</span>
<span id="cb1-19">                y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,</span>
<span id="cb1-20">                width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>width <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (val <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> max_legs_value),</span>
<span id="cb1-21">                height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb1-22">                fill<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"blue"</span>,</span>
<span id="cb1-23">            ),</span>
<span id="cb1-24">            Line(x1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, x2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, y1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, y2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>height, stroke<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"black"</span>),</span>
<span id="cb1-25">        ],</span>
<span id="cb1-26">    )</span>
<span id="cb1-27"></span>
<span id="cb1-28">    html <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"&lt;div&gt;</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>canvas<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">&lt;/div&gt;"</span></span>
<span id="cb1-29">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> html</span>
<span id="cb1-30"></span>
<span id="cb1-31"></span>
<span id="cb1-32">GT(df).fmt(fns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>create_plot_svg_py, columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Plot"</span>])</span></code></pre></div></div>
</details>
<div class="cell-output cell-output-display" data-execution_count="2">
<div id="gwwbicljnr" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
#gwwbicljnr table {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }

#gwwbicljnr thead, tbody, tfoot, tr, td, th { border-style: none; }
 tr { background-color: transparent; }
#gwwbicljnr p { margin: 0; padding: 0; }
 #gwwbicljnr .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
 #gwwbicljnr .gt_caption { padding-top: 4px; padding-bottom: 4px; }
 #gwwbicljnr .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
 #gwwbicljnr .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
 #gwwbicljnr .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #gwwbicljnr .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #gwwbicljnr .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #gwwbicljnr .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
 #gwwbicljnr .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
 #gwwbicljnr .gt_column_spanner_outer:first-child { padding-left: 0; }
 #gwwbicljnr .gt_column_spanner_outer:last-child { padding-right: 0; }
 #gwwbicljnr .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
 #gwwbicljnr .gt_spanner_row { border-bottom-style: hidden; }
 #gwwbicljnr .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
 #gwwbicljnr .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
 #gwwbicljnr .gt_from_md> :first-child { margin-top: 0; }
 #gwwbicljnr .gt_from_md> :last-child { margin-bottom: 0; }
 #gwwbicljnr .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
 #gwwbicljnr .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
 #gwwbicljnr .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
 #gwwbicljnr .gt_row_group_first td { border-top-width: 2px; }
 #gwwbicljnr .gt_row_group_first th { border-top-width: 2px; }
 #gwwbicljnr .gt_striped { color: #333333; background-color: #F4F4F4; }
 #gwwbicljnr .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #gwwbicljnr .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
 #gwwbicljnr .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
 #gwwbicljnr .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
 #gwwbicljnr .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
 #gwwbicljnr .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
 #gwwbicljnr .gt_left { text-align: left; }
 #gwwbicljnr .gt_center { text-align: center; }
 #gwwbicljnr .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
 #gwwbicljnr .gt_font_normal { font-weight: normal; }
 #gwwbicljnr .gt_font_bold { font-weight: bold; }
 #gwwbicljnr .gt_font_italic { font-style: italic; }
 #gwwbicljnr .gt_super { font-size: 65%; }
 #gwwbicljnr .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
 #gwwbicljnr .gt_asterisk { font-size: 100%; vertical-align: 0; }
 
</style>
<table class="gt_table" data-quarto-disable-processing="false" data-quarto-bootstrap="false">
<thead>

<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="Animal">Animal</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Legs">Legs</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Plot">Plot</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td class="gt_row gt_left">Ostrich</td>
    <td class="gt_row gt_right">2</td>
    <td class="gt_row gt_right"><div><svg xmlns="http://www.w3.org/2000/svg" width="50" height="30"><rect x="0" y="7.5" width="12.5" height="15.0" fill="blue"></rect><line stroke="black" x1="0" y1="0" x2="0" y2="30"></line></svg></div></td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Spider</td>
    <td class="gt_row gt_right">8</td>
    <td class="gt_row gt_right"><div><svg xmlns="http://www.w3.org/2000/svg" width="50" height="30"><rect x="0" y="7.5" width="50.0" height="15.0" fill="blue"></rect><line stroke="black" x1="0" y1="0" x2="0" y2="30"></line></svg></div></td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Lion</td>
    <td class="gt_row gt_right">4</td>
    <td class="gt_row gt_right"><div><svg xmlns="http://www.w3.org/2000/svg" width="50" height="30"><rect x="0" y="7.5" width="25.0" height="15.0" fill="blue"></rect><line stroke="black" x1="0" y1="0" x2="0" y2="30"></line></svg></div></td>
  </tr>
</tbody>


</table>

</div>
        
</div>
</div>
<section id="setup" class="level2">
<h2 class="anchored" data-anchor-id="setup">Setup</h2>
<p>Here is the code to start:</p>
<div id="4480acfc" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> polars <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pl</span>
<span id="cb2-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> great_tables <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> GT</span>
<span id="cb2-3"></span>
<span id="cb2-4">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pl.DataFrame(</span>
<span id="cb2-5">    {</span>
<span id="cb2-6">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Animal"</span>: [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ostrich"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Spider"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Lion"</span>],</span>
<span id="cb2-7">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Legs"</span>: [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>],</span>
<span id="cb2-8">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Plot"</span>: [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>],</span>
<span id="cb2-9">    }</span>
<span id="cb2-10">)</span>
<span id="cb2-11"></span>
<span id="cb2-12">gt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GT(df)</span></code></pre></div></div>
</div>
</section>
<section id="the-binding-component-gt.fmt" class="level2">
<h2 class="anchored" data-anchor-id="the-binding-component-gt.fmt">The Binding Component: GT.fmt()</h2>
<p>Let’s take advantage of the <a href="https://posit-dev.github.io/great-tables/reference/GT.fmt.html#great_tables.GT.fmt"><code>fmt()</code></a> method to apply a plotting function that formats our row values into plots. To see how we might use <code>fmt()</code>, we first need to define a formatting function to apply to each cell in a column. It will take as input the value in the cell, and should return whatever you want in that cell. Before plotting, let’s imagine we wanted to replace the number with a tally of the number of legs:</p>
<div id="34c35dcc" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> create_leg_tally(value: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>:</span>
<span id="cb3-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"|"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> value</span>
<span id="cb3-3"></span>
<span id="cb3-4"></span>
<span id="cb3-5">gt.fmt(fns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>create_leg_tally, columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Plot"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="4">
<div id="pizkqhldak" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
#pizkqhldak table {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }

#pizkqhldak thead, tbody, tfoot, tr, td, th { border-style: none; }
 tr { background-color: transparent; }
#pizkqhldak p { margin: 0; padding: 0; }
 #pizkqhldak .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
 #pizkqhldak .gt_caption { padding-top: 4px; padding-bottom: 4px; }
 #pizkqhldak .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
 #pizkqhldak .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
 #pizkqhldak .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #pizkqhldak .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #pizkqhldak .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #pizkqhldak .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
 #pizkqhldak .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
 #pizkqhldak .gt_column_spanner_outer:first-child { padding-left: 0; }
 #pizkqhldak .gt_column_spanner_outer:last-child { padding-right: 0; }
 #pizkqhldak .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
 #pizkqhldak .gt_spanner_row { border-bottom-style: hidden; }
 #pizkqhldak .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
 #pizkqhldak .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
 #pizkqhldak .gt_from_md> :first-child { margin-top: 0; }
 #pizkqhldak .gt_from_md> :last-child { margin-bottom: 0; }
 #pizkqhldak .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
 #pizkqhldak .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
 #pizkqhldak .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
 #pizkqhldak .gt_row_group_first td { border-top-width: 2px; }
 #pizkqhldak .gt_row_group_first th { border-top-width: 2px; }
 #pizkqhldak .gt_striped { color: #333333; background-color: #F4F4F4; }
 #pizkqhldak .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #pizkqhldak .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
 #pizkqhldak .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
 #pizkqhldak .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
 #pizkqhldak .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
 #pizkqhldak .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
 #pizkqhldak .gt_left { text-align: left; }
 #pizkqhldak .gt_center { text-align: center; }
 #pizkqhldak .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
 #pizkqhldak .gt_font_normal { font-weight: normal; }
 #pizkqhldak .gt_font_bold { font-weight: bold; }
 #pizkqhldak .gt_font_italic { font-style: italic; }
 #pizkqhldak .gt_super { font-size: 65%; }
 #pizkqhldak .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
 #pizkqhldak .gt_asterisk { font-size: 100%; vertical-align: 0; }
 
</style>
<table class="gt_table" data-quarto-disable-processing="false" data-quarto-bootstrap="false">
<thead>

<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="Animal">Animal</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Legs">Legs</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Plot">Plot</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td class="gt_row gt_left">Ostrich</td>
    <td class="gt_row gt_right">2</td>
    <td class="gt_row gt_right">||</td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Spider</td>
    <td class="gt_row gt_right">8</td>
    <td class="gt_row gt_right">||||||||</td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Lion</td>
    <td class="gt_row gt_right">4</td>
    <td class="gt_row gt_right">||||</td>
  </tr>
</tbody>


</table>

</div>
        
</div>
</div>
</section>
<section id="a-lightweight-approach-svg.py" class="level2">
<h2 class="anchored" data-anchor-id="a-lightweight-approach-svg.py">A Lightweight Approach: Svg.py</h2>
<p>Now we can apply that same logic to making our plots. Let’s start with the function that will eventually be passed into <code>fmt()</code>:</p>
<div id="1b641ab5" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> svg <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> SVG, Rect, Line</span>
<span id="cb4-2"></span>
<span id="cb4-3">height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span></span>
<span id="cb4-4">width <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span></span>
<span id="cb4-5"></span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> create_plot_svg_py(val: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>:</span>
<span id="cb4-8">    canvas <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> SVG(</span>
<span id="cb4-9">        width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>width,</span>
<span id="cb4-10">        height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>height,</span>
<span id="cb4-11">        elements<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[</span>
<span id="cb4-12">            Rect(</span>
<span id="cb4-13">                x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>,</span>
<span id="cb4-14">                y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,</span>
<span id="cb4-15">                width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>width <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (val <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> max_legs_value),</span>
<span id="cb4-16">                height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb4-17">                fill<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"blue"</span>,</span>
<span id="cb4-18">            ),</span>
<span id="cb4-19">            Line(x1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, x2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, y1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, y2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>height, stroke<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"black"</span>),</span>
<span id="cb4-20">        ],</span>
<span id="cb4-21">    )</span>
<span id="cb4-22"></span>
<span id="cb4-23">    html <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"&lt;div&gt;</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>canvas<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">&lt;/div&gt;"</span></span>
<span id="cb4-24">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> html</span></code></pre></div></div>
</div>
<p>Here you get to call <code>fmt()</code> to modify the column you want to apply the plotting function to.</p>
<div id="6b43d77a" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1">gt.fmt(fns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>create_plot_svg_py, columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Plot"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="6">
<div id="tfttetazpg" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
#tfttetazpg table {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }

#tfttetazpg thead, tbody, tfoot, tr, td, th { border-style: none; }
 tr { background-color: transparent; }
#tfttetazpg p { margin: 0; padding: 0; }
 #tfttetazpg .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
 #tfttetazpg .gt_caption { padding-top: 4px; padding-bottom: 4px; }
 #tfttetazpg .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
 #tfttetazpg .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
 #tfttetazpg .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #tfttetazpg .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #tfttetazpg .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #tfttetazpg .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
 #tfttetazpg .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
 #tfttetazpg .gt_column_spanner_outer:first-child { padding-left: 0; }
 #tfttetazpg .gt_column_spanner_outer:last-child { padding-right: 0; }
 #tfttetazpg .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
 #tfttetazpg .gt_spanner_row { border-bottom-style: hidden; }
 #tfttetazpg .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
 #tfttetazpg .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
 #tfttetazpg .gt_from_md> :first-child { margin-top: 0; }
 #tfttetazpg .gt_from_md> :last-child { margin-bottom: 0; }
 #tfttetazpg .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
 #tfttetazpg .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
 #tfttetazpg .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
 #tfttetazpg .gt_row_group_first td { border-top-width: 2px; }
 #tfttetazpg .gt_row_group_first th { border-top-width: 2px; }
 #tfttetazpg .gt_striped { color: #333333; background-color: #F4F4F4; }
 #tfttetazpg .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #tfttetazpg .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
 #tfttetazpg .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
 #tfttetazpg .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
 #tfttetazpg .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
 #tfttetazpg .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
 #tfttetazpg .gt_left { text-align: left; }
 #tfttetazpg .gt_center { text-align: center; }
 #tfttetazpg .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
 #tfttetazpg .gt_font_normal { font-weight: normal; }
 #tfttetazpg .gt_font_bold { font-weight: bold; }
 #tfttetazpg .gt_font_italic { font-style: italic; }
 #tfttetazpg .gt_super { font-size: 65%; }
 #tfttetazpg .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
 #tfttetazpg .gt_asterisk { font-size: 100%; vertical-align: 0; }
 
</style>
<table class="gt_table" data-quarto-disable-processing="false" data-quarto-bootstrap="false">
<thead>

<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="Animal">Animal</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Legs">Legs</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Plot">Plot</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td class="gt_row gt_left">Ostrich</td>
    <td class="gt_row gt_right">2</td>
    <td class="gt_row gt_right"><div><svg xmlns="http://www.w3.org/2000/svg" width="50" height="30"><rect x="0" y="7.5" width="12.5" height="15.0" fill="blue"></rect><line stroke="black" x1="0" y1="0" x2="0" y2="30"></line></svg></div></td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Spider</td>
    <td class="gt_row gt_right">8</td>
    <td class="gt_row gt_right"><div><svg xmlns="http://www.w3.org/2000/svg" width="50" height="30"><rect x="0" y="7.5" width="50.0" height="15.0" fill="blue"></rect><line stroke="black" x1="0" y1="0" x2="0" y2="30"></line></svg></div></td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Lion</td>
    <td class="gt_row gt_right">4</td>
    <td class="gt_row gt_right"><div><svg xmlns="http://www.w3.org/2000/svg" width="50" height="30"><rect x="0" y="7.5" width="25.0" height="15.0" fill="blue"></rect><line stroke="black" x1="0" y1="0" x2="0" y2="30"></line></svg></div></td>
  </tr>
</tbody>


</table>

</div>
        
</div>
</div>
<p>This was very direct, we didn’t have save to a buffer or import heavy duty plotting functions. We built the string with the help of <code>svg.py</code> and were able to insert into the table. See the string below:</p>
<!-- I would really like to wrap the output here, but nothing I've tried has worked -->
<!-- https://github.com/quarto-dev/quarto-cli/discussions/6017 -->
<div id="cb52d033" class="cell" data-execution_count="7">
<div class="cell-output cell-output-display" data-execution_count="7">
<pre><code>'&lt;div&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="50" height="30"&gt;&lt;rect x="0" y="7.5" width="25.0" height="15.0" fill="blue"/&gt;&lt;line stroke="black" x1="0" y1="0" x2="0" y2="30"/&gt;&lt;/svg&gt;&lt;/div&gt;'</code></pre>
</div>
</div>
<p>Even in its outputted form the string is still easily readable, which is another upside of using an SVG generation package.</p>
</section>
<section id="extreme-minimalism-adding-html-directly" class="level2">
<h2 class="anchored" data-anchor-id="extreme-minimalism-adding-html-directly">Extreme Minimalism: Adding HTML directly</h2>
<p>In the previous section, note that <code>svg.py</code> simply generated a string of HTML. You can do the same thing directly.</p>
<div id="9a386462" class="cell" data-execution_count="8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> create_plot_html(val: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>:</span>
<span id="cb7-2">    bar_element <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"""</span></span>
<span id="cb7-3"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">    &lt;div style="position: absolute;</span></span>
<span id="cb7-4"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">                width: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>width <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> val <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> max_legs_value<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">px;</span></span>
<span id="cb7-5"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">                height: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">px;</span></span>
<span id="cb7-6"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">                background-color: purple;</span></span>
<span id="cb7-7"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">                margin-top: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">px;</span></span>
<span id="cb7-8"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">    "&gt;&lt;/div&gt;"""</span></span>
<span id="cb7-9"></span>
<span id="cb7-10">    line_element <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb7-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">    &lt;div style="position: absolute;</span></span>
<span id="cb7-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                top: 0;</span></span>
<span id="cb7-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                bottom: 0;</span></span>
<span id="cb7-14"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                width: 1px;</span></span>
<span id="cb7-15"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                background-color: black;</span></span>
<span id="cb7-16"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">    "&gt;&lt;/div&gt;"""</span></span>
<span id="cb7-17"></span>
<span id="cb7-18">    html <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"""</span></span>
<span id="cb7-19"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">    &lt;div style="position: relative; width: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>width<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">px; height: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>height<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">px;"&gt;</span></span>
<span id="cb7-20"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">        </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>bar_element<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-21"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">        </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>line_element<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-22"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">    &lt;/div&gt;</span></span>
<span id="cb7-23"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb7-24"></span>
<span id="cb7-25">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> html</span></code></pre></div></div>
</div>
<p>Now that we’ve defined our <code>create_plot_*</code> formatting function, the call to <code>fmt()</code> is identical to the one above.</p>
<div id="f1f7e459" class="cell" data-execution_count="9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1">gt.fmt(fns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>create_plot_html, columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Plot"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="9">
<div id="budqbtjuya" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
#budqbtjuya table {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }

#budqbtjuya thead, tbody, tfoot, tr, td, th { border-style: none; }
 tr { background-color: transparent; }
#budqbtjuya p { margin: 0; padding: 0; }
 #budqbtjuya .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
 #budqbtjuya .gt_caption { padding-top: 4px; padding-bottom: 4px; }
 #budqbtjuya .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
 #budqbtjuya .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
 #budqbtjuya .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #budqbtjuya .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #budqbtjuya .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #budqbtjuya .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
 #budqbtjuya .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
 #budqbtjuya .gt_column_spanner_outer:first-child { padding-left: 0; }
 #budqbtjuya .gt_column_spanner_outer:last-child { padding-right: 0; }
 #budqbtjuya .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
 #budqbtjuya .gt_spanner_row { border-bottom-style: hidden; }
 #budqbtjuya .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
 #budqbtjuya .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
 #budqbtjuya .gt_from_md> :first-child { margin-top: 0; }
 #budqbtjuya .gt_from_md> :last-child { margin-bottom: 0; }
 #budqbtjuya .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
 #budqbtjuya .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
 #budqbtjuya .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
 #budqbtjuya .gt_row_group_first td { border-top-width: 2px; }
 #budqbtjuya .gt_row_group_first th { border-top-width: 2px; }
 #budqbtjuya .gt_striped { color: #333333; background-color: #F4F4F4; }
 #budqbtjuya .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #budqbtjuya .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
 #budqbtjuya .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
 #budqbtjuya .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
 #budqbtjuya .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
 #budqbtjuya .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
 #budqbtjuya .gt_left { text-align: left; }
 #budqbtjuya .gt_center { text-align: center; }
 #budqbtjuya .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
 #budqbtjuya .gt_font_normal { font-weight: normal; }
 #budqbtjuya .gt_font_bold { font-weight: bold; }
 #budqbtjuya .gt_font_italic { font-style: italic; }
 #budqbtjuya .gt_super { font-size: 65%; }
 #budqbtjuya .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
 #budqbtjuya .gt_asterisk { font-size: 100%; vertical-align: 0; }
 
</style>
<table class="gt_table" data-quarto-disable-processing="false" data-quarto-bootstrap="false">
<thead>

<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="Animal">Animal</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Legs">Legs</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Plot">Plot</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td class="gt_row gt_left">Ostrich</td>
    <td class="gt_row gt_right">2</td>
    <td class="gt_row gt_right">
    <div style="position: relative; width: 50px; height: 30px;">
        
    <div style="position: absolute;
                width: 12.5px;
                height: 15.0px;
                background-color: purple;
                margin-top: 7.5px;
    "></div>
        
    <div style="position: absolute;
                top: 0;
                bottom: 0;
                width: 1px;
                background-color: black;
    "></div>
    </div>
    </td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Spider</td>
    <td class="gt_row gt_right">8</td>
    <td class="gt_row gt_right">
    <div style="position: relative; width: 50px; height: 30px;">
        
    <div style="position: absolute;
                width: 50.0px;
                height: 15.0px;
                background-color: purple;
                margin-top: 7.5px;
    "></div>
        
    <div style="position: absolute;
                top: 0;
                bottom: 0;
                width: 1px;
                background-color: black;
    "></div>
    </div>
    </td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Lion</td>
    <td class="gt_row gt_right">4</td>
    <td class="gt_row gt_right">
    <div style="position: relative; width: 50px; height: 30px;">
        
    <div style="position: absolute;
                width: 25.0px;
                height: 15.0px;
                background-color: purple;
                margin-top: 7.5px;
    "></div>
        
    <div style="position: absolute;
                top: 0;
                bottom: 0;
                width: 1px;
                background-color: black;
    "></div>
    </div>
    </td>
  </tr>
</tbody>


</table>

</div>
        
</div>
</div>
<p>At first glance, encoding HTML in multi-line strings may not be aesthetically pleasing, nor is it particularly more lightweight than <code>svg.py</code>. Still, it provides a good alternative if you are like me and insist on being as close to the output as possible. Separately, I have found the inclusion of text to be simpler with HTML on account of the default text handling behavior that comes along with it.</p>
</section>
<section id="a-comprehensive-package-plotnine" class="level2">
<h2 class="anchored" data-anchor-id="a-comprehensive-package-plotnine">A Comprehensive Package: Plotnine</h2>
<div id="a5d7a2dd" class="cell" data-execution_count="10">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> io <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> StringIO</span>
<span id="cb9-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> plotnine <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> (</span>
<span id="cb9-3">    ggplot,</span>
<span id="cb9-4">    aes,</span>
<span id="cb9-5">    coord_flip,</span>
<span id="cb9-6">    geom_col,</span>
<span id="cb9-7">    scale_y_continuous,</span>
<span id="cb9-8">    scale_x_continuous,</span>
<span id="cb9-9">    theme_void,</span>
<span id="cb9-10">    geom_hline,</span>
<span id="cb9-11">)</span>
<span id="cb9-12"></span>
<span id="cb9-13">max_legs_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Legs"</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>()</span>
<span id="cb9-14"></span>
<span id="cb9-15"></span>
<span id="cb9-16"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> create_plot_plotnine(val: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>:</span>
<span id="cb9-17">    plot <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb9-18">        ggplot()</span>
<span id="cb9-19">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> aes(x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>val)</span>
<span id="cb9-20">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> geom_col(width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, fill<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"green"</span>, show_legend<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb9-21">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> scale_y_continuous(limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, max_legs_value))</span>
<span id="cb9-22">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> scale_x_continuous(limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span>))</span>
<span id="cb9-23">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> coord_flip()</span>
<span id="cb9-24">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> theme_void()</span>
<span id="cb9-25">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> geom_hline(yintercept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb9-26">    )</span>
<span id="cb9-27"></span>
<span id="cb9-28">    buf <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> StringIO()</span>
<span id="cb9-29">    plot.save(buf, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">format</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"svg"</span>, width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.3</span>, verbose<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb9-30">    svg_content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> buf.getvalue()</span>
<span id="cb9-31">    buf.close()</span>
<span id="cb9-32"></span>
<span id="cb9-33">    html <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"&lt;div&gt;</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>svg_content<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">&lt;/div&gt;"</span></span>
<span id="cb9-34">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> html</span>
<span id="cb9-35"></span>
<span id="cb9-36"></span>
<span id="cb9-37"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># This might be familiar by now</span></span>
<span id="cb9-38">gt.fmt(fns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>create_plot_plotnine, columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Plot"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="10">
<div id="onpqwmvsyi" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
#onpqwmvsyi table {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }

#onpqwmvsyi thead, tbody, tfoot, tr, td, th { border-style: none; }
 tr { background-color: transparent; }
#onpqwmvsyi p { margin: 0; padding: 0; }
 #onpqwmvsyi .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
 #onpqwmvsyi .gt_caption { padding-top: 4px; padding-bottom: 4px; }
 #onpqwmvsyi .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
 #onpqwmvsyi .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
 #onpqwmvsyi .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #onpqwmvsyi .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #onpqwmvsyi .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
 #onpqwmvsyi .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
 #onpqwmvsyi .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
 #onpqwmvsyi .gt_column_spanner_outer:first-child { padding-left: 0; }
 #onpqwmvsyi .gt_column_spanner_outer:last-child { padding-right: 0; }
 #onpqwmvsyi .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
 #onpqwmvsyi .gt_spanner_row { border-bottom-style: hidden; }
 #onpqwmvsyi .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
 #onpqwmvsyi .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
 #onpqwmvsyi .gt_from_md> :first-child { margin-top: 0; }
 #onpqwmvsyi .gt_from_md> :last-child { margin-bottom: 0; }
 #onpqwmvsyi .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
 #onpqwmvsyi .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
 #onpqwmvsyi .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
 #onpqwmvsyi .gt_row_group_first td { border-top-width: 2px; }
 #onpqwmvsyi .gt_row_group_first th { border-top-width: 2px; }
 #onpqwmvsyi .gt_striped { color: #333333; background-color: #F4F4F4; }
 #onpqwmvsyi .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
 #onpqwmvsyi .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
 #onpqwmvsyi .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
 #onpqwmvsyi .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
 #onpqwmvsyi .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
 #onpqwmvsyi .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
 #onpqwmvsyi .gt_left { text-align: left; }
 #onpqwmvsyi .gt_center { text-align: center; }
 #onpqwmvsyi .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
 #onpqwmvsyi .gt_font_normal { font-weight: normal; }
 #onpqwmvsyi .gt_font_bold { font-weight: bold; }
 #onpqwmvsyi .gt_font_italic { font-style: italic; }
 #onpqwmvsyi .gt_super { font-size: 65%; }
 #onpqwmvsyi .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
 #onpqwmvsyi .gt_asterisk { font-size: 100%; vertical-align: 0; }
 
</style>
<table class="gt_table" data-quarto-disable-processing="false" data-quarto-bootstrap="false">
<thead>

<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="Animal">Animal</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Legs">Legs</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="Plot">Plot</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td class="gt_row gt_left">Ostrich</td>
    <td class="gt_row gt_right">2</td>
    <td class="gt_row gt_right"><div><!--?xml version="1.0" encoding="utf-8" standalone="no"?-->

<svg xlink="http://www.w3.org/1999/xlink" width="36pt" height="21.6pt" viewbox="0 0 36 21.6" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <metadata>
  <rdf:rdf xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
   <cc:work>
    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"></dc:type>
    <dc:date>2025-11-11T11:52:41.639051</dc:date>
    <dc:format>image/svg+xml</dc:format>
    <dc:creator>
     <cc:agent>
      <dc:title>Matplotlib v3.9.4, https://matplotlib.org/</dc:title>
     </cc:agent>
    </dc:creator>
   </cc:work>
  </rdf:rdf>
 </metadata>
 <defs>
  <style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>
 </defs>
 <g id="figure_1">
  <g id="axes_1">
   <g id="matplotlib.axis_1">
    <g id="xtick_1"></g>
    <g id="xtick_2"></g>
    <g id="xtick_3"></g>
    <g id="xtick_4"></g>
    <g id="xtick_5"></g>
    <g id="xtick_6"></g>
    <g id="xtick_7"></g>
    <g id="xtick_8"></g>
    <g id="xtick_9"></g>
   </g>
   <g id="matplotlib.axis_2">
    <g id="ytick_1"></g>
    <g id="ytick_2"></g>
    <g id="ytick_3"></g>
    <g id="ytick_4"></g>
    <g id="ytick_5"></g>
    <g id="ytick_6"></g>
    <g id="ytick_7"></g>
    <g id="ytick_8"></g>
    <g id="ytick_9"></g>
   </g>
   <g id="PolyCollection_1">
    <path d="M 1.636364 15.709091 
L 1.636364 5.890909 
L 9.818182 5.890909 
L 9.818182 15.709091 
z
" clip-path="url(#p7f6eb57194)" style="fill: #008000"></path>
   </g>
   <g id="LineCollection_1">
    <path d="M 1.636364 21.6 
L 1.636364 -0 
" clip-path="url(#p7f6eb57194)" style="fill: none; stroke: #000000; stroke-width: 0.886227"></path>
   </g>
  </g>
 </g>
 <defs>
  <clippath id="p7f6eb57194">
   <rect x="0" y="0" width="36" height="21.6"></rect>
  </clippath>
 </defs>
</svg>
</div></td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Spider</td>
    <td class="gt_row gt_right">8</td>
    <td class="gt_row gt_right"><div><!--?xml version="1.0" encoding="utf-8" standalone="no"?-->

<svg xlink="http://www.w3.org/1999/xlink" width="36pt" height="21.6pt" viewbox="0 0 36 21.6" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <metadata>
  <rdf:rdf xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
   <cc:work>
    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"></dc:type>
    <dc:date>2025-11-11T11:52:41.695352</dc:date>
    <dc:format>image/svg+xml</dc:format>
    <dc:creator>
     <cc:agent>
      <dc:title>Matplotlib v3.9.4, https://matplotlib.org/</dc:title>
     </cc:agent>
    </dc:creator>
   </cc:work>
  </rdf:rdf>
 </metadata>
 <defs>
  <style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>
 </defs>
 <g id="figure_1">
  <g id="axes_1">
   <g id="matplotlib.axis_1">
    <g id="xtick_1"></g>
    <g id="xtick_2"></g>
    <g id="xtick_3"></g>
    <g id="xtick_4"></g>
    <g id="xtick_5"></g>
    <g id="xtick_6"></g>
    <g id="xtick_7"></g>
    <g id="xtick_8"></g>
    <g id="xtick_9"></g>
   </g>
   <g id="matplotlib.axis_2">
    <g id="ytick_1"></g>
    <g id="ytick_2"></g>
    <g id="ytick_3"></g>
    <g id="ytick_4"></g>
    <g id="ytick_5"></g>
    <g id="ytick_6"></g>
    <g id="ytick_7"></g>
    <g id="ytick_8"></g>
    <g id="ytick_9"></g>
   </g>
   <g id="PolyCollection_1">
    <path d="M 1.636364 15.709091 
L 1.636364 5.890909 
L 34.363636 5.890909 
L 34.363636 15.709091 
z
" clip-path="url(#pe56df8db66)" style="fill: #008000"></path>
   </g>
   <g id="LineCollection_1">
    <path d="M 1.636364 21.6 
L 1.636364 -0 
" clip-path="url(#pe56df8db66)" style="fill: none; stroke: #000000; stroke-width: 0.886227"></path>
   </g>
  </g>
 </g>
 <defs>
  <clippath id="pe56df8db66">
   <rect x="0" y="0" width="36" height="21.6"></rect>
  </clippath>
 </defs>
</svg>
</div></td>
  </tr>
  <tr>
    <td class="gt_row gt_left">Lion</td>
    <td class="gt_row gt_right">4</td>
    <td class="gt_row gt_right"><div><!--?xml version="1.0" encoding="utf-8" standalone="no"?-->

<svg xlink="http://www.w3.org/1999/xlink" width="36pt" height="21.6pt" viewbox="0 0 36 21.6" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <metadata>
  <rdf:rdf xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
   <cc:work>
    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"></dc:type>
    <dc:date>2025-11-11T11:52:41.749777</dc:date>
    <dc:format>image/svg+xml</dc:format>
    <dc:creator>
     <cc:agent>
      <dc:title>Matplotlib v3.9.4, https://matplotlib.org/</dc:title>
     </cc:agent>
    </dc:creator>
   </cc:work>
  </rdf:rdf>
 </metadata>
 <defs>
  <style type="text/css">*{stroke-linejoin: round; stroke-linecap: butt}</style>
 </defs>
 <g id="figure_1">
  <g id="axes_1">
   <g id="matplotlib.axis_1">
    <g id="xtick_1"></g>
    <g id="xtick_2"></g>
    <g id="xtick_3"></g>
    <g id="xtick_4"></g>
    <g id="xtick_5"></g>
    <g id="xtick_6"></g>
    <g id="xtick_7"></g>
    <g id="xtick_8"></g>
    <g id="xtick_9"></g>
   </g>
   <g id="matplotlib.axis_2">
    <g id="ytick_1"></g>
    <g id="ytick_2"></g>
    <g id="ytick_3"></g>
    <g id="ytick_4"></g>
    <g id="ytick_5"></g>
    <g id="ytick_6"></g>
    <g id="ytick_7"></g>
    <g id="ytick_8"></g>
    <g id="ytick_9"></g>
   </g>
   <g id="PolyCollection_1">
    <path d="M 1.636364 15.709091 
L 1.636364 5.890909 
L 18 5.890909 
L 18 15.709091 
z
" clip-path="url(#p878680717a)" style="fill: #008000"></path>
   </g>
   <g id="LineCollection_1">
    <path d="M 1.636364 21.6 
L 1.636364 -0 
" clip-path="url(#p878680717a)" style="fill: none; stroke: #000000; stroke-width: 0.886227"></path>
   </g>
  </g>
 </g>
 <defs>
  <clippath id="p878680717a">
   <rect x="0" y="0" width="36" height="21.6"></rect>
  </clippath>
 </defs>
</svg>
</div></td>
  </tr>
</tbody>


</table>

</div>
        
</div>
</div>
<p>Nice! But that was a sizable chunk of code just to create plots comprised of one bar each. If you’re like me, you’ll find it’s not at all trivial to do, especially without experience using the plotting package.</p>
<p>However, this isn’t the only graphic you might want to have on display – when you come across a use case that necessitates more detailed plots, a comprehensive plotting package like <code>plotnine</code> could very well be your best bet. Imagine we are passing in a list of tuples and want to generate a scatterplot, writing all of those as <code>svg.py</code> elements or direct HTML would be quite cumbersome.</p>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>How you choose to add plots to Great Tables is up to you. In writing graphical plotting functions for <a href="https://posit-dev.github.io/gt-extras/articles/intro.html"><strong>gt-extras</strong></a>, I’ve personally turned towards an HTML-only approach that I’ve felt comfortable with in other settings. With that said, I do believe converting table values to graphic output is a task best done with a little bit of help (whether it be <code>svg-py</code> or another plotting package will depend on how detailed your plots are).</p>
<p>The choice ultimately depends on your specific needs: simplicity and directness, versus abstraction and power. By understanding the trade-offs, you will be able to tailor your approach to the needs of your project.</p>


</section>

 ]]></description>
  <category>Python</category>
  <category>Great Tables</category>
  <category>Posit</category>
  <guid>https://juleswg.me/posts/Posit-adding-plots-to-great-tables/</guid>
  <pubDate>Thu, 03 Jul 2025 00:00:00 GMT</pubDate>
  <media:content url="https://juleswg.me/images/adding-plots-to-great-tables.png" medium="image" type="image/png" height="150" width="144"/>
</item>
</channel>
</rss>
