PageSourceSearch

https://corinfaife.co/_next/static/chunks/pages/posts/matplotlib-styling-368903e85c7eedcc.js

js corinfaife.co collected 2026-10-04 00:30:59 UTC 21,820 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1082],{3395:function(t,e,a){(window.__NEXT_P=window.__NEXT_P||[]).push(["/posts/matplotlib-styling",function(){return a(5347)}])},7845:function(t,e,a){"use strict";var n=a(5893),o=a(357),r=a.n(o),i=(new Date).getFullYear();e.Z={footer:(0,n.jsxs)("small",{style:{display:"block",marginTop:"8rem"},className:"jsx-7c359fde634f3543",children:[(0,n.jsx)("time",{className:"jsx-7c359fde634f3543",children:i})," \xa9 Corin Faife.",(0,n.jsx)("a",{href:"/feed.xml",className:"jsx-7c359fde634f3543",children:"RSS"}),(0,n.jsx)(r(),{id:"7c359fde634f3543",children:"a.jsx-7c359fde634f3543{float:right}@media screen and (max-width:480px){article.jsx-7c359fde634f3543{padding-top:2rem;padding-bottom:4rem}}"})]})}},5347:function(t,e,a){"use strict";a.r(e),a.d(e,{default:function(){return p}});var n=a(1799),o=a(9396),r=a(5893),i=a(8616),s=a(3805),l=a(7845),c=a(1151);function d(t){var e=Object.assign({h1:"h1",p:"p",a:"a",img:"img",h3:"h3",pre:"pre",code:"code",em:"em"},(0,c.ah)(),t.components);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h1,{children:"Styling matplotlib for news production"}),"\n",(0,r.jsxs)(e.p,{children:["As a data journalist at ",(0,r.jsx)(e.a,{href:"https://www.afp.com/en",children:"AFP"}),", my daily workflow often uses Python for data analysis and exploratory visualization, then finishes by handing over an SVG to a graphic designer to be refined for publication."]}),"\n",(0,r.jsxs)(e.p,{children:["As time goes on, I've been learning how to tweak ",(0,r.jsx)(e.a,{href:"https://matplotlib.org/",children:"Matplotlib"})," styling to reduce the gap between what I export and a publishable (or near-publishable) graphic in our AFP house style."]}),"\n",(0,r.jsx)(e.p,{children:"So we can go from this:"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.img,{src:"/images/2024/chart/election-turnout-basic.svg",alt:"Basic election chart"})}),"\n",(0,r.jsx)(e.p,{children:"To this:"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.img,{src:"/images/2024/chart/election-turnout-afp.svg",alt:"AFP styled election chart"})}),"\n",(0,r.jsx)(e.p,{children:"Though matplotlib charts look very dry and academic out-of-the-box, I'm slowly coming to appreciate the level of control and flexibility available underneat the hood."}),"\n",(0,r.jsx)(e.p,{children:"Here's a breakdown of the styling tweaks I'm currently using."}),"\n",(0,r.jsx)(e.h3,{children:"Set chart dimensions and line width"}),"\n",(0,r.jsx)(e.p,{children:"AFP's two-column graphic layout corresponds to a 6x4 image ratio, which we define before drawing the chart:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:"plt.figure(figsize=(6, 4))\n"})}),"\n",(0,r.jsx)(e.p,{children:"We'll then draw a simple line chart following the example above \u2013\u2013 US voter turnout over time. When we draw the chart we'll want to increase the line width slightly:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:"plt.plot(df['YEAR'],\n         df['TURNOUT_RATE_PRES'],\n          linewidth=2)\n"})}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.img,{src:"/images/2024/chart/election-turnout-1.svg",alt:"AFP election chart 1"})}),"\n",(0,r.jsx)(e.h3,{children:"Remove frame, calibrate axes"}),"\n",(0,r.jsxs)(e.p,{children:["We're going to do a lot of the chart styling by modifying attributes of the ",(0,r.jsx)(e.a,{href:"https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes",children:"Axes object"}),"."]}),"\n",(0,r.jsxs)(e.p,{children:["First we call the ",(0,r.jsx)(e.code,{children:".gca()"})," function to ",(0,r.jsx)(e.em,{children:"get current axes"})," of the plot and assign that to a variable. We can then use various methods of the ",(0,r.jsx)(e.a,{href:"https://matplotlib.org/stable/api/axes_api.html",children:"axes api"})," to modify plot characteristics \u2013 like setting the frame on or off."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:"ax = plt.gca()\nax.set_frame_on(False)\n"})}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.img,{src:"/images/2024/chart/election-turnout-2.svg",alt:"AFP election chart 2"})}),"\n",(0,r.jsx)(e.p,{children:"We're also going to override the default y axis limits to make sure that we have a value tick above the highest value and below the lowest value of the line."}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:"ax.set_ylim([0.44, 0.75])\n"})}),"\n",(0,r.jsxs)(e.p,{children:["While we're working on the y axis, we'll also want to change the decimal score to a percentage. We do this by first getting a reference to the y ticks, then using Python's ",(0,r.jsx)(e.code,{children:"format()"})," function to ",(0,r.jsx)(e.a,{href:"https://stackoverflow.com/questions/5306756/how-to-print-a-percentage-value",children:"display the decimal string as percent"}),"."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:"ticks = ax.get_yticks()\nax.set_yticklabels(['{:,.0%}'.format(x) for x in ticks])\n"})}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.img,{src:"/images/2024/chart/election-turnout-3.svg",alt:"AFP election chart 3"})}),"\n",(0,r.jsx)(e.h3,{children:"Style grid lines and ticks"}),"\n",(0,r.jsx)(e.p,{children:"AFP line charts and column charts generally use dashed full-width grid lines on the y axis of the chart."}),"\n",(0,r.jsxs)(e.p,{children:["First we'll switch off the y axis ticks, and tuck the x axis ticks closer to the chart. Then we'll ",(0,r.jsx)(e.a,{href:"https://e2eml.school/matplotlib_ticks#grid",children:"draw a full width custom grid line"})," in grey:"]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:"plt.tick_params(axis='y', left=False)\nplt.tick_params(axis='x', length=5, direction='in')\n\nax.grid(axis=\"y\", \n        color=\"grey\", \n        alpha=.5, \n        linewidth=.5, \n        linestyle=\"--\")\n"})}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.img,{src:"/images/2024/chart/election-turnout-4.svg",alt:"AFP election chart 4"})}),"\n",(0,r.jsx)(e.h3,{children:"Define title, subtitle, and footnote"}),"\n",(0,r.jsx)(e.p,{children:"AFP charts are titled, usually use a subheading, and always include source attribution."}),"\n",(0,r.jsxs)(e.p,{children:["To match the house style we can use matplotlib's ",(0,r.jsx)(e.a,{href:"https://matplotlib.org/stable/api/matplotlib_configuration_api.html#default-values-and-styling",children:"rcParams"})," settings to choose a font, in this case Adobe's ",(0,r.jsx)(e.a,{href:"https://fonts.adobe.com/fonts/source-sans",children:"Source Sans"}),". We'll also set ",(0,r.jsx)(e.code,{children:"svg.fonttype"})," to ",(0,r.jsx)(e.code,{children:"none"}),", which instructs matplotlib not to convert text into paths when saving an SVG."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:"plt.rcParams.update(\n                {'font.family': 'Source Sans Pro',\n                \"svg.fonttype\": 'none'\n                })\n"})}),"\n",(0,r.jsxs)(e.p,{children:["Then we'll use ",(0,r.jsx)(e.code,{children:"plt.suptitle()"}),' ("supertitle") for the main heading, and ',(0,r.jsx)(e.code,{children:"title()"})," for the subheading."]}),"\n",(0,r.jsxs)(e.p,{children:["We need to set x and y values to position each of these correctly, though this can be confusing because each one uses a different reference system: ",(0,r.jsx)(e.code,{children:"suptitle()"})," needs a y value of 1 or greater to appear at the top of the chart, whereas ",(0,r.jsx)(e.code,{children:"title()"})," is at the top by default, and takes a ",(0,r.jsx)(e.code,{children:"pad"})," argument to control vertical spacing."]}),"\n",(0,r.jsxs)(e.p,{children:["Both should be horizontally aligned left rather than centered, which we set with the ",(0,r.jsx)(e.code,{children:"ha"})," argument."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:"plt.suptitle(\"US election turnout\",\n             x=0.1,\n             y=1.02,\n             fontsize=20, \n             fontweight='bold',\n             ha='left')\nplt.title(\"Voter turnout in the 2024 election was still among the highest since 1900\",\n          x= -.03,\n          pad=15,\n          fontsize=10,\n          fontweight='semibold',\n          ha='left')\n"})}),"\n",(0,r.jsxs)(e.p,{children:["Lastly we use ",(0,r.jsx)(e.code,{children:"plt.figtext()"})," to add a footnote with the source. As with ",(0,r.jsx)(e.code,{children:"suptitle()"}),", we're giving [x,y] positioning coordinates from the bottom left of the figure."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-python",children:'plt.figtext(0.1, 0.01, \n            "Source: UF Election Lab", \n            ha="left", \n            fontsize=8)\n'})}),"\n",(0,r.jsx)(e.p,{children:"And here's the finished result again:"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.img,{src:"/images/2024/chart/election-turnout-afp-final.svg",alt:"AFP election chart final"})}),"\n",(0,r.jsxs)(e.p,{children:["For complete code to replicate this chart, see ",(0,r.jsx)(e.a,{href:"https://gist.github.com/corintxt/71e691b9a7d5f677e3630a15af46361b",children:"this GitHub gist"}),"."]}),"\n",(0,r.jsx)("script",{src:"https://gist.github.com/corintxt/71e691b9a7d5f677e3630a15af46361b.js"})]})}function h(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=Object.assign({},(0,c.ah)(),t.components),a=e.wrapper;return a?(0,r.jsx)(a,(0,o.Z)((0,n.Z)({},t),{children:(0,r.jsx)(d,(0,n.Z)({},t))})):d(t)}var g=(0,r.jsx)(h,{});function p(t){return(0,s.withSSG)((0,i.Z)({filename:"matplotlib-styling.mdx",route:"/posts/matplotlib-styling",meta:{title:"Styling matplotlib for news production",date:"2024-11-12T00:00:00.000Z",description:"Taking charts from raw to refined",tag:"Python, dataviz, matplotlib",author:"Corin"},pageMap:[{name:"Bytes",children:[{name:"bash-python-args",route:"/Bytes/bash-python-args",frontMatter:{title:"Bash script to execute Python 
1with args",date:"2024-10-15T00:00:00.000Z",tag:"Python, bash",author:"Corin"}},{name:"cd-alias-in-zsh",route:"/Bytes/cd-alias-in-zsh",frontMatter:{title:"Use an alias to change directory quickly",date:"2026/2/9",tag:"command line, zsh, bash",author:"Corin"}},{name:"change-zsh-colors",route:"/Bytes/change-zsh-colors",frontMatter:{title:"Change Zsh terminal colors",date:"2025-2-14",tag:"command line, zsh",author:"Corin"}},{name:"command-line-llm",route:"/Bytes/command-line-llm",frontMatter:{title:"Use Claude from command line with llm tool",date:"2025-2-18",tag:"command line, Claude, llm, API",author:"Corin"}},{name:"conda-to-mamba",route:"/Bytes/conda-to-mamba",frontMatter:{title:"Switch from conda to mamba",date:"2025-3-17",tag:"python, conda, mamba, package management",author:"Corin"}},{name:"conda-vscode-local-env",route:"/Bytes/conda-vscode-local-env",frontMatter:{title:"Create conda env in VSCode",date:"2025-10-14T00:00:00.000Z",tag:"python, conda, vscode",author:"Corin"}},{name:"crontab-guru",route:"/Bytes/crontab-guru",frontMatter:{title:"Check cron syntax with crontab guru",date:"2024-12-16T00:00:00.000Z",tag:"cron, scheduling, syntax",author:"Corin"}},{name:"ctrl-r-bash-history",route:"/Bytes/ctrl-r-bash-history",frontMatter:{title:"Search through bash history",date:"2026/2/12",tag:"command line, bash",author:"Corin"}},{name:"dateformatter-matplotlib-bug",route:"/Bytes/dateformatter-matplotlib-bug",frontMatter:{title:"Fix YearLocator bug with native matplotlib.plt",date:"2025-1-16",tag:"matplotlib, python, pandas",author:"Corin"}},{name:"docker-cloud-run-job",route:"/Bytes/docker-cloud-run-job",frontMatter:{title:"Deploy Docker container as Cloud Run job",date:"2025-12-3",tag:"docker, gcloud, cloud run",author:"Corin"}},{name:"ffplay-command-line",route:"/Bytes/ffplay-command-line",frontMatter:{title:"Play an mp3 from command line with ffplay",date:"2026-02-05T00:00:00.000Z",tag:"CLI, ffmpeg, audio",author:"Corin"}},{name:"find-process-port",route:"/Bytes/find-process-port",frontMatter:{title:"Find and kill a process using a given port",date:"2024/11/12",tag:"networking",author:"Corin"}},{name:"flask-venv",route:"/Bytes/flask-venv",frontMatter:{title:"Install Flask in virtual environment",date:"2024-12-3",tag:"Python, Flask",author:"Corin"}},{name:"git-cherry-pick-debug",route:"/Bytes/git-cherry-pick-debug",frontMatter:{title:"Use git cherry-pick to find breaking changes",date:"2025-12-5",tag:"git",author:"Corin"}},{name:"git-commit-already-files",route:"/Bytes/git-commit-already-files",frontMatter:{title:"Push local git commits to pre-existing remote",date:"2026-01-28T00:00:00.000Z",tag:"git, license, version control",author:"Corin"}},{name:"git-merge-ours",route:"/Bytes/git-merge-ours",frontMatter:{title:"Replace git branch with merge -s ours",date:"2025-3-11",tag:"git",author:"Corin"}},{name:"git-merge-specific-commit",route:"/Bytes/git-merge-specific-commit",frontMatter:{title:"Git merge to previous commit",date:"2025-06-02T00:00:00.000Z",tag:"git",author:"Corin"}},{name:"git-orphan-branch",route:"/Bytes/git-orphan-branch",frontMatter:{title:"Make a git branch with no shared history",date:"2026/3/10",tag:"git",author:"Corin"}},{name:"if-and-sheets",route:"/Bytes/if-and-sheets",frontMatter:{title:"IF AND statement in Sheets",date:"2024-10-29T00:00:00.000Z",tag:"Google sheets",author:"Corin"}},{name:"import-csv-sql",route:"/Bytes/import-csv-sql",frontMatter:{title:"Importing large CSV to SQLite",date:"2024-10-10T00:00:00.000Z",tag:"SQL, CSV",author:"Corin"}},{name:"index",route:"/Bytes",frontMatter:{type:"posts",title:"Bytes",date:"2020-10-01T00:00:00.000Z"}},{name:"introducing",route:"/Bytes/introducing",frontMatter:{title:"First Byte",date:"2024-10-10T00:00:00.000Z",tag:"intro",author:"Corin"}},{name:"local-certificate-verification",route:"/Bytes/local-certificate-verification",frontMatter:{title:"Use local certificate for SSL verification",date:"2025-4-4",tag:"python, API, SSL",author:"Corin"}},{name:"matplotlib-svg-text-object",route:"/Bytes/matplotlib-svg-text-object",frontMatter:{title:"Export matplotlib chart as SVG with text objects",date:"2025-10-6",tag:"Python, matplotlib",author:"Corin"}},{name:"pandas-html-table",route:"/Bytes/pandas-html-table",frontMatter:{title:"Load HTML table into pandas dataframe",date:"2025-4-23",tag:"Python, pandas, HTML",author:"Corin"}},{name:"pandas-sci-notation",route:"/Bytes/pandas-sci-notation",frontMatter:{title:"Switch off scientific notation in pandas",date:"2024-10-16T00:00:00.000Z",tag:"Python, pandas",author:"Corin"}},{name:"pd-json-normalize",route:"/Bytes/pd-json-normalize",frontMatter:{title:"Flatten a JSON file in pandas with normalize()",date:"2025-11-06T00:00:00.000Z",tag:"python, pandas, json",author:"Corin"}},{name:"python-repl",route:"/Bytes/python-repl",frontMatter:{title:"Run Python script and drop into REPL",date:"2024-10-11T00:00:00.000Z",tag:"Python",author:"Corin"}},{name:"rectangle-app",route:"/Bytes/rectangle-app",frontMatter:{title:"Rectangle for Mac window management",date:"2024-10-14T00:00:00.000Z",tag:"macOS, Ubuntu",author:"Corin"}},{name:"reference-variable-dfquery",route:"/Bytes/reference-variable-dfquery",frontMatter:{title:"Use @ to reference variable in df.query()",date:"2025-2-5",tag:"python, pandas",author:"Corin"}},{name:"reset-graph-text-illustrator",route:"/Bytes/reset-graph-text-illustrator",frontMatter:{title:"Reset graph text in Illustrator",date:"2024-10-22T00:00:00.000Z",tag:"Illustrator, graphics",author:"Corin"}},{name:"restore-bigquery-snapshot",route:"/Bytes/restore-bigquery-snapshot",frontMatter:{title:"Restore BigQuery table from snapshot",date:"2026/3/25",tag:"bigquery, GCS, database",author:"Corin"}},{name:"rotate-seaborn-xlabels",route:"/Bytes/rotate-seaborn-xlabels",frontMatter:{title:"Rotate x axis labels in Seaborn",date:"2024-10-17T00:00:00.000Z",tag:"Python, Seaborn, visualization",author:"Corin"}},{name:"store-secrets-dotenv",route:"/Bytes/store-secrets-dotenv",frontMatter:{title:"Store secrets in .env files for Python scripts",date:"2025-10-16T00:00:00.000Z",tag:"python, git",author:"Corin"}},{name:"use-sys-exit",route:"/Bytes/use-sys-exit",frontMatter:{title:"Wrap main() in sys.exit() call",date:"2025-3-03",tag:"Python",author:"Corin"}}],route:"/Bytes"},{name:"draft",children:[{name:"email-analysis-bigquery-vertex-ai",route:"/draft/email-analysis-bigquery-vertex-ai",frontMatter:{title:"Text analysis at scale with BigQuery and VertexAI",date:"2025-12-12T00:00:00.000Z",description:"Using LLMs for text processing at scale",tag:"ai, afp, llm, Google Cloud, BigQuery, Gemini",author:"Corin"}},{name:"ideas",route:"/draft/ideas",frontMatter:{title:"Ideas",date:"2024/1/1",de
1scription:"General ideas.",tag:"draft",author:"<NAME>"}},{name:"illustrator-translation-tool",route:"/draft/illustrator-translation-tool",frontMatter:{title:"Building a translation tool for Adobe Illustrator",date:"2025/2/11",description:"A description.",tag:"draft",author:"Corin"}},{name:"learning-to-log",route:"/draft/learning-to-log",frontMatter:{title:"Learning to log",date:"2025-2-11",description:"A description.",tag:"Python, development, logging",author:"Corin"}},{name:"million-dollar-flight",route:"/draft/million-dollar-flight",frontMatter:{title:"BTS - Million dollar deportation flight",date:"2025/2/11",description:"Making of a story",tag:"afp, OSINT",author:"Corin"}},{name:"template",route:"/draft/template",frontMatter:{title:"Page title",date:"2024/1/1",description:"A description.",tag:"draft",author:"Corin"}}],route:"/draft"},{name:"index",route:"/",frontMatter:{type:"page",title:"About",date:"2023-11-06T00:00:00.000Z"}},{name:"portfolio",route:"/portfolio",frontMatter:{type:"page",title:"Portfolio",date:"2023-06-30T00:00:00.000Z"}},{name:"posts",children:[{name:"afp-2023-work",route:"/posts/afp-2023-work",frontMatter:{title:"Some AFP work (2023)",date:"2024/2/01",description:"I really thought I'd get around to making this post sooner..",tag:"data, graphics, afp",author:"Corin"}},{name:"afp-test",route:"/posts/afp-test",frontMatter:{title:"A data test",date:"2023/7/17",description:"Demonstration charts and analysis",tag:"data, afp",author:"Corin"}},{name:"afp-work-2024-Q1",route:"/posts/afp-work-2024-Q1",frontMatter:{title:"Some graphics work, 2024/Q1",date:"2024/4/3",description:"A dispatch from the first quarter of the year",tag:"data, graphics, afp",author:"Corin"}},{name:"email-data-notification-mailgun",route:"/posts/email-data-notification-mailgun",frontMatter:{title:"How to trigger custom email notifications from a data fetch",date:"2026/02/06",description:"Using Mailgun to send myself a daily digest",tag:"afp, email, Mailgun, API, SAM, Python",author:"Corin"}},{name:"email-text-analysis-bigquery-vertex-ai",route:"/posts/email-text-analysis-bigquery-vertex-ai",frontMatter:{title:"Analyzing an email dump with BigQuery and Gemini",date:"2025-12-12T00:00:00.000Z",description:"Using LLMs for text processing at scale",tag:"ai, afp, llm, Google Cloud, BigQuery, Gemini",author:"Corin"}},{name:"index",route:"/posts",frontMatter:{type:"posts",title:"Blog",date:"2023-06-01T00:00:00.000Z"}},{name:"learning-github-actions",route:"/posts/learning-github-actions",frontMatter:{title:"Learning GitHub Actions (and actually learning)",date:"2024/5/21",description:"Using docs and debugging over ChatGPT",tag:"afp, data, development",author:"Corin"}},{name:"liberating-data-foia-1",route:"/posts/liberating-data-foia-1",frontMatter:{title:"Liberating data with FOIA, part 1",date:"2024/2/13",description:"On finding government databases",tag:"data, foia, investigations",author:"Corin"}},{name:"liberating-data-foia-2",route:"/posts/liberating-data-foia-2",frontMatter:{title:"Liberating data with FOIA, part 2",date:"2024/2/14",description:"On FOIA-ing government databases",tag:"data, foia, investigations",author:"Corin"}},{name:"matplotlib-styling",route:"/posts/matplotlib-styling",frontMatter:{title:"Styling matplotlib for news production",date:"2024-11-12T00:00:00.000Z",description:"Taking charts from raw to refined",tag:"Python, dataviz, matplotlib",author:"Corin"}},{name:"new-blog-framework",route:"/posts/new-blog-framework",frontMatter:{title:"New blog / new framework",date:"2024/2/21",description:"Adventures in MDX",tag:"javascript, blogging, nextjs, experiments",author:"Corin"}},{name:"offline-llms-ollama-gpt-oss",route:"/posts/offline-llms-ollama-gpt-oss",frontMatter:{title:"Testing LLMs offline with Ollama",date:"2025-8-19",description:"The pros and cons of gpt-oss:20b",tag:"ai, afp, llm, gpt-oss, OpenAI",author:"Corin"}},{name:"power-of-small-delays-extendscript",route:"/posts/power-of-small-delays-extendscript",frontMatter:{title:"ExtendScript and the power of small delays",date:"2025-5-2",description:"Lessons in curbing CPU overload",tag:"JavaScript, ExtendScript, Adobe Illustrator",author:"Corin"}},{name:"proxy-scrapes-cloudflare-worker",route:"/posts/proxy-scrapes-cloudflare-worker",frontMatter:{title:"Using a Cloudflare Worker to proxy data scrapes",date:"2026-03-30T00:00:00.000Z",description:"Collecting data while respecting robots.txt",tag:"Cloudflare, Python, JavaScript,scraping, proxy",author:"Corin"}},{name:"write-pandas-google-cloud",route:"/posts/write-pandas-google-cloud",frontMatter:{title:"Writing a pandas dataframe to cloud storage",date:"2024/11/13",description:"In search of simple data sharing",tag:"Python, pandas, cloud",author:"Corin"}}],route:"/posts"},{name:"tags",children:[{name:"[tag]",route:"/tags/[tag]",frontMatter:{type:"tag",title:"Tagged Posts"}}],route:"/tags"}]},l.Z))((0,o.Z)((0,n.Z)({},t),{children:g}))}}},function(t){t.O(0,[9774,2596,2888,179],(function(){return e=3395,t(t.
1s=e);var e}));var e=t.O();_N_E=e}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.