├── results.png ├── results.parquet ├── make_plot.py ├── README.md ├── LICENSE.txt └── arxiv-aws.ipynb /results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrocklin/arxiv-matplotlib/HEAD/results.png -------------------------------------------------------------------------------- /results.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrocklin/arxiv-matplotlib/HEAD/results.parquet -------------------------------------------------------------------------------- /make_plot.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | import matplotlib.pyplot as plt 4 | from matplotlib.ticker import PercentFormatter 5 | 6 | import pandas as pd 7 | 8 | # read data 9 | by_month = pd.read_parquet("results.parquet").groupby("date").has_matplotlib.mean() 10 | 11 | 12 | # get figure 13 | fig, ax = plt.subplots(layout="constrained") 14 | # plot the data 15 | ax.plot(by_month, "o", color="k", ms=3) 16 | 17 | # over-ride the default auto limits 18 | ax.set_xlim(left=datetime.date(2004, 1, 1)) 19 | ax.set_ylim(bottom=0) 20 | 21 | # turn on a horizontal grid 22 | ax.grid(axis="y") 23 | 24 | # remove the top and right spines 25 | ax.spines.right.set_visible(False) 26 | ax.spines.top.set_visible(False) 27 | 28 | # format y-ticks a percent 29 | ax.yaxis.set_major_formatter(PercentFormatter(xmax=1)) 30 | 31 | # add title and labels 32 | ax.set_xlabel("date") 33 | ax.set_ylabel("% of all papers") 34 | ax.set_title("Matplotlib usage on arXiv") 35 | 36 | fig.savefig("fancy_plot.png") 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # arXiv Matplotlib Query 2 | 3 | Anecdotally the Matplotlib maintainers were told 4 | 5 | *"About 15% of arXiv papers use Matplotlib"* 6 | 7 | Unfortunately the original analysis of this data was lost. We reproduce it here. 8 | 9 | ## Watermark 10 | 11 | Starting in the early 2010s, Matplotlib started including the bytes `b"Matplotlib"` in every PNG and PDF that they produce. These bytes persist in the output PDFs stored on arXiv. As a result, it's pretty simple to check if a PDF contains a Matplotlib image. All we have to do is scan through every PDF and look for these bytes; no parsing required. 12 | 13 | ## Data 14 | 15 | The data is stored in a requester pays bucket at s3://arxiv (more information at https://arxiv.org/help/bulk_data_s3 ) and also on GCS hosted by Kaggle (more information at https://www.kaggle.com/datasets/Cornell-University/arxiv). 16 | 17 | The data is about 1TB in size. We use Dask for this. 18 | 19 | ## Contents 20 | 21 | This repository has the notebook used to generate the data, 22 | the data itself as a parquet file, 23 | and a nice image showing growing usage. 24 | 25 | 26 | ## Results 27 | 28 | ![A plot of Matplotlib usage on arVix showing strong growth from 2004 to 2022 from 0 to 17%](results.png?raw=true "Matplotlib usage on arXiv over time") 29 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Matthew Rocklin 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /arxiv-aws.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "ae977bc3-d3cf-4492-a359-a95f8156fb52", 6 | "metadata": {}, 7 | "source": [ 8 | "# How Popular is Matplotlib?\n", 9 | "\n", 10 | "Anecdotally the Matplotlib maintainers were told \n", 11 | "\n", 12 | "*\"About 15% of arXiv papers use Matplotlib\"*\n", 13 | "\n", 14 | "arXiv is the preeminent repository for scholarly prepreint articles. It stores millions of journal articles used across science. It's also public access, and so we can just scrape the entire thing given enough compute power.\n", 15 | "\n", 16 | "## Watermark\n", 17 | "\n", 18 | "Starting in the early 2010s, Matplotlib started including the bytes `b\"Matplotlib\"` in every PNG and PDF that they produce. These bytes persist in PDFs that contain Matplotlib plots, including the PDFs stored on arXiv. As a result, it's pretty simple to check if a PDF contains a Matplotlib image. All we have to do is scan through every PDF and look for these bytes; no parsing required.\n", 19 | "\n", 20 | "## Data\n", 21 | "\n", 22 | "The data is stored in a requester pays bucket at s3://arxiv (more information at https://arxiv.org/help/bulk_data_s3 ) and also on GCS hosted by Kaggle (more information at https://www.kaggle.com/datasets/Cornell-University/arxiv). \n", 23 | "\n", 24 | "The data is about 1TB in size. We're going to use Dask for this.\n", 25 | "\n", 26 | "This is a good example of writing plain vanilla Python code to solve a problem, running into issues of scale, and then using Dask to easily jump over those problems." 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "id": "6f0965a0-fa87-470b-bd3d-0b5b7ecaca99", 32 | "metadata": {}, 33 | "source": [ 34 | "### Get all filenames\n", 35 | "\n", 36 | "Our data is stored in a requester pays S3 bucket in the `us-east-1` region. Each file is a tar file which contains a directory of papers." 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 1, 42 | "id": "e62539ef-5e91-43c5-afa8-0c3fa51b8f11", 43 | "metadata": {}, 44 | "outputs": [ 45 | { 46 | "data": { 47 | "text/plain": [ 48 | "['arxiv/pdf/arXiv_pdf_0001_001.tar',\n", 49 | " 'arxiv/pdf/arXiv_pdf_0001_002.tar',\n", 50 | " 'arxiv/pdf/arXiv_pdf_0002_001.tar',\n", 51 | " 'arxiv/pdf/arXiv_pdf_0002_002.tar',\n", 52 | " 'arxiv/pdf/arXiv_pdf_0003_001.tar',\n", 53 | " 'arxiv/pdf/arXiv_pdf_0003_002.tar',\n", 54 | " 'arxiv/pdf/arXiv_pdf_0004_001.tar',\n", 55 | " 'arxiv/pdf/arXiv_pdf_0004_002.tar',\n", 56 | " 'arxiv/pdf/arXiv_pdf_0005_001.tar',\n", 57 | " 'arxiv/pdf/arXiv_pdf_0005_002.tar']" 58 | ] 59 | }, 60 | "execution_count": 1, 61 | "metadata": {}, 62 | "output_type": "execute_result" 63 | } 64 | ], 65 | "source": [ 66 | "import s3fs\n", 67 | "s3 = s3fs.S3FileSystem(requester_pays=True)\n", 68 | "\n", 69 | "directories = s3.ls(\"s3://arxiv/pdf\")\n", 70 | "directories[:10]" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 2, 76 | "id": "4bc51124-c61e-4d7e-84ff-ffd551c7ca7f", 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "data": { 81 | "text/plain": [ 82 | "'arxiv/pdf/arXiv_pdf_1407_009.tar'" 83 | ] 84 | }, 85 | "execution_count": 2, 86 | "metadata": {}, 87 | "output_type": "execute_result" 88 | } 89 | ], 90 | "source": [ 91 | "directories[1000]" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "id": "92438ddf-7b02-462d-8a5d-2b2e760dd1a4", 97 | "metadata": {}, 98 | "source": [ 99 | "There are lots of these" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 3, 105 | "id": "9e5cb2b5-1ad5-4a21-b98d-4f0f615dacd6", 106 | "metadata": {}, 107 | "outputs": [ 108 | { 109 | "data": { 110 | "text/plain": [ 111 | "5373" 112 | ] 113 | }, 114 | "execution_count": 3, 115 | "metadata": {}, 116 | "output_type": "execute_result" 117 | } 118 | ], 119 | "source": [ 120 | "len(directories)" 121 | ] 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "id": "a4d3219f-a6ce-487f-b5ae-522a7415c014", 126 | "metadata": {}, 127 | "source": [ 128 | "## Process one file with plain Python\n", 129 | "\n", 130 | "Mostly we have to muck about with tar files. This wasn't hard. The `tarfile` library is in the stardard library. It's not beautiful, but it's also not hard to use." 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": 4, 136 | "id": "85146f13-5e5a-40e3-8d56-a79064f35ce4", 137 | "metadata": { 138 | "tags": [] 139 | }, 140 | "outputs": [], 141 | "source": [ 142 | "import tarfile\n", 143 | "import io\n", 144 | "\n", 145 | "def extract(filename: str):\n", 146 | " \"\"\" Extract and process one directory of arXiv data\n", 147 | " \n", 148 | " Returns\n", 149 | " -------\n", 150 | " filename: str\n", 151 | " contains_matplotlib: boolean\n", 152 | " \"\"\"\n", 153 | " out = []\n", 154 | " with s3.open(filename) as f:\n", 155 | " bytes = f.read()\n", 156 | " with io.BytesIO() as bio:\n", 157 | " bio.write(bytes)\n", 158 | " bio.seek(0)\n", 159 | " with tarfile.TarFile(fileobj=bio) as tf:\n", 160 | " for member in tf.getmembers():\n", 161 | " if member.isfile() and member.name.endswith(\".pdf\"):\n", 162 | " data = tf.extractfile(member).read()\n", 163 | " out.append((\n", 164 | " member.name, \n", 165 | " b\"matplotlib\" in data.lower()\n", 166 | " ))\n", 167 | " return out" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 5, 173 | "id": "de243ca8-bcd2-47b4-8574-bce3f0bda790", 174 | "metadata": {}, 175 | "outputs": [ 176 | { 177 | "name": "stdout", 178 | "output_type": "stream", 179 | "text": [ 180 | "CPU times: user 3.99 s, sys: 1.79 s, total: 5.78 s\n", 181 | "Wall time: 51.5 s\n" 182 | ] 183 | }, 184 | { 185 | "data": { 186 | "text/plain": [ 187 | "[('0011/cs0011019.pdf', False),\n", 188 | " ('0011/gr-qc0011017.pdf', False),\n", 189 | " ('0011/hep-ex0011095.pdf', False),\n", 190 | " ('0011/cond-mat0011373.pdf', False),\n", 191 | " ('0011/hep-ph0011035.pdf', False),\n", 192 | " ('0011/gr-qc0011082.pdf', False),\n", 193 | " ('0011/cond-mat0011202.pdf', False),\n", 194 | " ('0011/hep-ph0011209.pdf', False),\n", 195 | " ('0011/cond-mat0011038.pdf', False),\n", 196 | " ('0011/gr-qc0011014.pdf', False),\n", 197 | " ('0011/hep-ph0011118.pdf', False),\n", 198 | " ('0011/gr-qc0011095.pdf', False),\n", 199 | " ('0011/astro-ph0011090.pdf', False),\n", 200 | " ('0011/hep-ph0011162.pdf', False),\n", 201 | " ('0011/cs0011010.pdf', False),\n", 202 | " ('0011/cond-mat0011086.pdf', False),\n", 203 | " ('0011/hep-lat0011037.pdf', False),\n", 204 | " ('0011/astro-ph0011369.pdf', False),\n", 205 | " ('0011/astro-ph0011187.pdf', False),\n", 206 | " ('0011/astro-ph0011074.pdf', False)]" 207 | ] 208 | }, 209 | "execution_count": 5, 210 | "metadata": {}, 211 | "output_type": "execute_result" 212 | } 213 | ], 214 | "source": [ 215 | "%%time\n", 216 | "\n", 217 | "# See an example of its use\n", 218 | "extract(directories[20])[:20]" 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "id": "9feae86b-4c46-455d-8e5b-09eb80ec3400", 224 | "metadata": {}, 225 | "source": [ 226 | "# Scale function to full dataset\n", 227 | "\n", 228 | "Great, we can get a record of each file and whether or not it used Matplotlib. Each of these takes about a minute to run on my local machine. Processing all 5000 files would take 5000 minutes, or around 100 hours. \n", 229 | "\n", 230 | "We can accelerate this in two ways:\n", 231 | "\n", 232 | "1. **Process closer to the data** by spinning up resources in the same region on the cloud (this also reduces data transfer costs)\n", 233 | "2. **Use hundreds of workers** in parallel\n", 234 | "\n", 235 | "We can do this easily with Dask (parallel computing) and Coiled (set up Dask infrastructure)" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "id": "34748fc3-7f2f-442e-9829-626d88878234", 241 | "metadata": {}, 242 | "source": [ 243 | "## Create Dask Cluster\n", 244 | "\n", 245 | "We start a Dask cluster on AWS in the same region where the data is stored. \n", 246 | "\n", 247 | "We mimic the local software environment on the cluster with `package_sync=True`." 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 6, 253 | "id": "245c269a-c432-4352-aa01-0d9110b63304", 254 | "metadata": {}, 255 | "outputs": [ 256 | { 257 | "data": { 258 | "text/html": [ 259 | "
╭───────────────────────────────────────── Package Issues ─────────────────────────────────────────╮\n",
260 |        "│                    ╷                                                           ╷                 │\n",
261 |        "│   Package           Issue                                                      Risk Level      │\n",
262 |        "│ ╶──────────────────┼───────────────────────────────────────────────────────────┼───────────────╴ │\n",
263 |        "│   libgfortran5     │ 11.3.0 has no install candidate for linux-64              │                 │\n",
264 |        "│   libgfortran      │ 5.0.0 has no install candidate for linux-64               │                 │\n",
265 |        "│   grpcio           │ 1.47.1 has no install candidate for linux-64              │                 │\n",
266 |        "│   grpc-cpp         │ 1.47.1 has no install candidate for linux-64              │                 │\n",
267 |        "│   arrow-cpp        │ 9.0.0 has no install candidate for linux-64               │                 │\n",
268 |        "│   openssl          │ Package ignored                                           │                 │\n",
269 |        "│   libabseil        │ Package ignored                                           │                 │\n",
270 |        "│                    ╵                                                           ╵                 │\n",
271 |        "╰──────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
272 |        "
\n" 273 | ], 274 | "text/plain": [ 275 | "╭───────────────────────────────────────── \u001b[1;32mPackage Issues\u001b[0m ─────────────────────────────────────────╮\n", 276 | "│ ╷ ╷ │\n", 277 | "│ \u001b[1m \u001b[0m\u001b[1mPackage \u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1mIssue \u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1mRisk Level \u001b[0m\u001b[1m \u001b[0m │\n", 278 | "│ ╶──────────────────┼───────────────────────────────────────────────────────────┼───────────────╴ │\n", 279 | "│ libgfortran5 │ 11.3.0 has no install candidate for linux-64 │ │\n", 280 | "│ libgfortran │ 5.0.0 has no install candidate for linux-64 │ │\n", 281 | "│ grpcio │ 1.47.1 has no install candidate for linux-64 │ │\n", 282 | "│ grpc-cpp │ 1.47.1 has no install candidate for linux-64 │ │\n", 283 | "│ arrow-cpp │ 9.0.0 has no install candidate for linux-64 │ │\n", 284 | "│ openssl │ Package ignored │ │\n", 285 | "│ libabseil │ Package ignored │ │\n", 286 | "│ ╵ ╵ │\n", 287 | "╰──────────────────────────────────────────────────────────────────────────────────────────────────╯\n" 288 | ] 289 | }, 290 | "metadata": {}, 291 | "output_type": "display_data" 292 | }, 293 | { 294 | "data": { 295 | "application/vnd.jupyter.widget-view+json": { 296 | "model_id": "f9d8cf6d8cfa42f28fde31ea8131e061", 297 | "version_major": 2, 298 | "version_minor": 0 299 | }, 300 | "text/plain": [ 301 | "Output()" 302 | ] 303 | }, 304 | "metadata": {}, 305 | "output_type": "display_data" 306 | }, 307 | { 308 | "data": { 309 | "text/html": [ 310 | "
\n"
311 |       ],
312 |       "text/plain": []
313 |      },
314 |      "metadata": {},
315 |      "output_type": "display_data"
316 |     },
317 |     {
318 |      "name": "stdout",
319 |      "output_type": "stream",
320 |      "text": [
321 |       "CPU times: user 9.72 s, sys: 1.08 s, total: 10.8 s\n",
322 |       "Wall time: 1min 25s\n"
323 |      ]
324 |     }
325 |    ],
326 |    "source": [
327 |     "%%time\n",
328 |     "\n",
329 |     "import coiled\n",
330 |     "\n",
331 |     "cluster = coiled.Cluster(\n",
332 |     "    n_workers=100,\n",
333 |     "    name=\"arxiv\",\n",
334 |     "    package_sync=True, \n",
335 |     "    backend_options={\"region\": \"us-east-1\"},  # faster and cheaper\n",
336 |     ")"
337 |    ]
338 |   },
339 |   {
340 |    "cell_type": "code",
341 |    "execution_count": 7,
342 |    "id": "f46591e5-664f-4bcc-98f3-c89bbb826331",
343 |    "metadata": {},
344 |    "outputs": [
345 |     {
346 |      "name": "stderr",
347 |      "output_type": "stream",
348 |      "text": [
349 |       "/Users/mrocklin/mambaforge/envs/play/lib/python3.10/site-packages/distributed/client.py:1309: VersionMismatchWarning: Mismatched versions found\n",
350 |       "\n",
351 |       "+-------------+-----------+-----------+----------+\n",
352 |       "| Package     | Client    | Scheduler | Workers  |\n",
353 |       "+-------------+-----------+-----------+----------+\n",
354 |       "| dask        | 2022.10.0 | 2022.9.1  | 2022.9.1 |\n",
355 |       "| distributed | 2022.10.0 | 2022.9.1  | 2022.9.1 |\n",
356 |       "+-------------+-----------+-----------+----------+\n",
357 |       "  warnings.warn(version_module.VersionMismatchWarning(msg[0][\"warning\"]))\n"
358 |      ]
359 |     }
360 |    ],
361 |    "source": [
362 |     "from dask.distributed import Client, wait\n",
363 |     "client = Client(cluster)"
364 |    ]
365 |   },
366 |   {
367 |    "cell_type": "markdown",
368 |    "id": "f9c6042c-917f-46ca-9722-c99e02fb97cb",
369 |    "metadata": {
370 |     "tags": []
371 |    },
372 |    "source": [
373 |     "### Map function across every directory\n",
374 |     "\n",
375 |     "Let's scale up this work across all of the directories in our dataset\n",
376 |     "\n",
377 |     "Hopefully it will also be faster because the Dask workers are in the same region as the dataset itself."
378 |    ]
379 |   },
380 |   {
381 |    "cell_type": "code",
382 |    "execution_count": 8,
383 |    "id": "6ff8f366-4cdf-4ac3-a0c1-08545f6e07ac",
384 |    "metadata": {},
385 |    "outputs": [
386 |     {
387 |      "name": "stdout",
388 |      "output_type": "stream",
389 |      "text": [
390 |       "CPU times: user 11.7 s, sys: 1.77 s, total: 13.5 s\n",
391 |       "Wall time: 5min 58s\n"
392 |      ]
393 |     }
394 |    ],
395 |    "source": [
396 |     "%%time\n",
397 |     "\n",
398 |     "futures = client.map(extract, directories)\n",
399 |     "wait(futures)\n",
400 |     "\n",
401 |     "# We had one error in one file.  Let's just ignore and move on.\n",
402 |     "good = [future for future in futures if future.status == \"finished\"]\n",
403 |     "\n",
404 |     "lists = client.gather(good)"
405 |    ]
406 |   },
407 |   {
408 |    "cell_type": "markdown",
409 |    "id": "84af922e-4f6b-4f4b-97d5-a7097084aa1b",
410 |    "metadata": {},
411 |    "source": [
412 |     "Now that we're done with the large data problem we can turn off Dask and proceed with pure Pandas.  There's no reason to deal with scalable tools if we don't have to."
413 |    ]
414 |   },
415 |   {
416 |    "cell_type": "code",
417 |    "execution_count": 9,
418 |    "id": "f6f61c10-b892-446f-bf5e-c504209b412b",
419 |    "metadata": {},
420 |    "outputs": [],
421 |    "source": [
422 |     "# Scale down now that we're done\n",
423 |     "cluster.close()"
424 |    ]
425 |   },
426 |   {
427 |    "cell_type": "markdown",
428 |    "id": "299b5097-ff28-4036-b569-a18449cca0d9",
429 |    "metadata": {},
430 |    "source": [
431 |     "## Enrich Data\n",
432 |     "\n",
433 |     "Let's enhance our data a bit.  The filenames of each file include the year and month when they were published.  After extracting this data we'll be able to see a timeseries of Matplotlib adoption."
434 |    ]
435 |   },
436 |   {
437 |    "cell_type": "code",
438 |    "execution_count": 10,
439 |    "id": "85d74a56-e7c1-4614-86bd-6342e16d58fd",
440 |    "metadata": {},
441 |    "outputs": [
442 |     {
443 |      "data": {
444 |       "text/html": [
445 |        "
\n", 446 | "\n", 459 | "\n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | " \n", 513 | " \n", 514 | " \n", 515 | " \n", 516 | " \n", 517 | " \n", 518 | " \n", 519 | " \n", 520 | " \n", 521 | " \n", 522 | " \n", 523 | " \n", 524 | "
filenamehas_matplotlib
00001/astro-ph0001477.pdfFalse
10001/hep-th0001095.pdfFalse
20001/astro-ph0001322.pdfFalse
30001/cond-mat0001159.pdfFalse
40001/astro-ph0001132.pdfFalse
.........
6309912/math9912098.pdfFalse
6319912/math9912251.pdfFalse
6329912/solv-int9912013.pdfFalse
6339912/hep-th9912254.pdfFalse
6349912/hep-th9912272.pdfFalse
\n", 525 | "

2122438 rows × 2 columns

\n", 526 | "
" 527 | ], 528 | "text/plain": [ 529 | " filename has_matplotlib\n", 530 | "0 0001/astro-ph0001477.pdf False\n", 531 | "1 0001/hep-th0001095.pdf False\n", 532 | "2 0001/astro-ph0001322.pdf False\n", 533 | "3 0001/cond-mat0001159.pdf False\n", 534 | "4 0001/astro-ph0001132.pdf False\n", 535 | ".. ... ...\n", 536 | "630 9912/math9912098.pdf False\n", 537 | "631 9912/math9912251.pdf False\n", 538 | "632 9912/solv-int9912013.pdf False\n", 539 | "633 9912/hep-th9912254.pdf False\n", 540 | "634 9912/hep-th9912272.pdf False\n", 541 | "\n", 542 | "[2122438 rows x 2 columns]" 543 | ] 544 | }, 545 | "execution_count": 10, 546 | "metadata": {}, 547 | "output_type": "execute_result" 548 | } 549 | ], 550 | "source": [ 551 | "# Convert to Pandas\n", 552 | "\n", 553 | "import pandas as pd\n", 554 | "\n", 555 | "dfs = [\n", 556 | " pd.DataFrame(list, columns=[\"filename\", \"has_matplotlib\"]) \n", 557 | " for list in lists\n", 558 | "]\n", 559 | "\n", 560 | "df = pd.concat(dfs)\n", 561 | "\n", 562 | "df" 563 | ] 564 | }, 565 | { 566 | "cell_type": "code", 567 | "execution_count": 11, 568 | "id": "f98c54e7-fc46-4180-9586-c06eac6432e6", 569 | "metadata": {}, 570 | "outputs": [ 571 | { 572 | "data": { 573 | "text/plain": [ 574 | "Timestamp('2000-05-01 00:00:00')" 575 | ] 576 | }, 577 | "execution_count": 11, 578 | "metadata": {}, 579 | "output_type": "execute_result" 580 | } 581 | ], 582 | "source": [ 583 | "def date(filename):\n", 584 | " year = int(filename.split(\"/\")[0][:2])\n", 585 | " month = int(filename.split(\"/\")[0][2:4])\n", 586 | " if year > 80:\n", 587 | " year = 1900 + year\n", 588 | " else:\n", 589 | " year = 2000 + year\n", 590 | " \n", 591 | " return pd.Timestamp(year=year, month=month, day=1)\n", 592 | "\n", 593 | "date(\"0005/astro-ph0001322.pdf\")" 594 | ] 595 | }, 596 | { 597 | "cell_type": "markdown", 598 | "id": "033451dc-344f-40e0-bd05-f2f6fd80d0c2", 599 | "metadata": {}, 600 | "source": [ 601 | "Yup. That seems to work. Let's map this function over our dataset." 602 | ] 603 | }, 604 | { 605 | "cell_type": "code", 606 | "execution_count": 12, 607 | "id": "315f8de5-c53a-49d9-8f8d-3ba62fcee727", 608 | "metadata": {}, 609 | "outputs": [ 610 | { 611 | "data": { 612 | "text/html": [ 613 | "
\n", 614 | "\n", 627 | "\n", 628 | " \n", 629 | " \n", 630 | " \n", 631 | " \n", 632 | " \n", 633 | " \n", 634 | " \n", 635 | " \n", 636 | " \n", 637 | " \n", 638 | " \n", 639 | " \n", 640 | " \n", 641 | " \n", 642 | " \n", 643 | " \n", 644 | " \n", 645 | " \n", 646 | " \n", 647 | " \n", 648 | " \n", 649 | " \n", 650 | " \n", 651 | " \n", 652 | " \n", 653 | " \n", 654 | " \n", 655 | " \n", 656 | " \n", 657 | " \n", 658 | " \n", 659 | " \n", 660 | " \n", 661 | " \n", 662 | " \n", 663 | " \n", 664 | " \n", 665 | " \n", 666 | " \n", 667 | " \n", 668 | "
filenamehas_matplotlibdate
00001/astro-ph0001477.pdfFalse2000-01-01
10001/hep-th0001095.pdfFalse2000-01-01
20001/astro-ph0001322.pdfFalse2000-01-01
30001/cond-mat0001159.pdfFalse2000-01-01
40001/astro-ph0001132.pdfFalse2000-01-01
\n", 669 | "
" 670 | ], 671 | "text/plain": [ 672 | " filename has_matplotlib date\n", 673 | "0 0001/astro-ph0001477.pdf False 2000-01-01\n", 674 | "1 0001/hep-th0001095.pdf False 2000-01-01\n", 675 | "2 0001/astro-ph0001322.pdf False 2000-01-01\n", 676 | "3 0001/cond-mat0001159.pdf False 2000-01-01\n", 677 | "4 0001/astro-ph0001132.pdf False 2000-01-01" 678 | ] 679 | }, 680 | "execution_count": 12, 681 | "metadata": {}, 682 | "output_type": "execute_result" 683 | } 684 | ], 685 | "source": [ 686 | "df[\"date\"] = df.filename.map(date)\n", 687 | "df.head()" 688 | ] 689 | }, 690 | { 691 | "cell_type": "markdown", 692 | "id": "e64781f1-0486-4eda-81b4-68911383be7a", 693 | "metadata": {}, 694 | "source": [ 695 | "## Plot\n", 696 | "\n", 697 | "Now we can just fool around with Pandas and Matplotlib." 698 | ] 699 | }, 700 | { 701 | "cell_type": "code", 702 | "execution_count": 13, 703 | "id": "270ae46c-ac65-48f1-a7ca-c6f742591c7c", 704 | "metadata": {}, 705 | "outputs": [ 706 | { 707 | "data": { 708 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkkAAAHFCAYAAADmGm0KAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAABtEklEQVR4nO3deVxU5f4H8M8MMDPssgmigLjvpuCGkVqK2WrlzTS3Nq95rav+2szKpbqalWmLmoaZdXOpzDZvSbkrmhqaC6m5gQiyCcM6M8w8vz+GOcwwAzIwMICf9+s1rzvzzHPOec5pXpev32eTCSEEiIiIiMiC3NkNICIiImqMGCQRERER2cAgiYiIiMgGBklERERENjBIIiIiIrKBQRIRERGRDQySiIiIiGxgkERERERkA4MkIiIiIhsYJBE5ybp16yCTySCTybBr1y6r74UQ6NChA2QyGYYOHVqra6xYsQLr1q2rUzvnz58PmUxWq2O//PJLLFu2zOZ3MpkM8+fPlz7v2rXL6llMmTIFXl5etbo2AAwdOhQ9evSw+V12drZVG5oi0+/o0qVLzm6KJDs7G8HBwYiNjYXBYLD4TqvVonfv3oiMjERBQQGAxnkPRACDJCKn8/b2Rnx8vFX57t27cf78eXh7e9f63I4IkuqiuiCpsr59+yIxMRF9+/at30Y1M3fffTcSExPRqlUrZzdFEhgYiI8//hj79u3De++9Z/HdvHnzcOLECaxdu1b6bTfGeyACGCQROd3YsWPxzTffQK1WW5THx8dj0KBBCA8Pd1LLGpaPjw8GDhwIHx8fZzelSQkKCsLAgQOhVCqd3RQAQHFxMQBg9OjRmDBhAl555RUkJycDABITE/H2229jxowZGDZsmHRMY7sHIhMGSURONm7cOADAhg0bpLL8/Hx88803ePzxx20es2DBAgwYMAD+/v7w8fFB3759ER8fD/P9qtu2bYtTp05h9+7dUrde27ZtAVR0bX3xxReYPXs2QkJC4O7ujiFDhiApKemGbTYYDFiyZAm6dOkCpVKJli1bYtKkSbhy5YpUZ+jQofjpp59w+fJl6frVddvZ6m4zOXXqFO644w54enoiKCgIM2bMkP4YO1JWVhamTp2KsLAwKJVKBAUFYfDgwfj111+lOgkJCbj//vvRpk0bqFQqdOjQAf/85z+RnZ1tdb7vvvsOvXr1glKpRLt27bB8+XKb3ZdCCKxYsQK33HIL3N3d4efnhzFjxuDChQs3bLOtripTN+Phw4cRGxsLDw8PtGvXDosXL7bq/rLlo48+wm233YaWLVvC09MTPXv2xJIlS6DT6Szqma6zZ88exMTEwMPDw+I3+/7778Pf3x+TJ0+GWq3G5MmTpXZUdw8zZ86Ep6en1T8cAOM/KoKDg63aQlQfGCQROZmPjw/GjBmDtWvXSmUbNmyAXC7H2LFjbR5z6dIl/POf/8TmzZuxZcsWPPjgg3jmmWfw+uuvS3W+/fZbtGvXDn369EFiYiISExPx7bffWpzn5ZdfxoULF/DJJ5/gk08+wdWrVzF06NAb/nF++umn8eKLL2LEiBH4/vvv8frrr+Pnn39GTEyMFCysWLECgwcPRkhIiHT9xMREu5+PTqfDXXfdhTvuuANbt27FjBkz8PHHH1f5bOpi4sSJ2Lp1K1577TVs374dn3zyCYYPH46cnBypzvnz5zFo0CCsXLkS27dvx2uvvYZDhw7h1ltvtfjD/fPPP+PBBx9EQEAANm3ahCVLlmDDhg347LPPrK77z3/+EzNnzsTw4cOxdetWrFixAqdOnUJMTAyuXbtWq3vJyMjAo48+igkTJuD777/HqFGjMGfOHHzxxRc3PPb8+fMYP348Pv/8c/z444944okn8Pbbb+Of//ynVd309HRMmDAB48ePx7Zt2zB9+nTpOz8/P6xZswaHDx9G3759cf78eaxbtw4eHh7VXv/xxx9HcXExNm/ebFGel5eH7777DhMmTICbm1sNnwRRHQgicopPP/1UABCHDx8WO3fuFADEyZMnhRBC9OvXT0yZMkUIIUT37t3FkCFDqjyPXq8XOp1OLFy4UAQEBAiDwSB9V9Wxpuv17dvXov6lS5eEm5ubePLJJ6WyefPmCfP/q0hOThYAxPTp0y3OeejQIQFAvPzyy1LZ3XffLSIiImy2G4CYN2+eVZt27twplU2ePFkAEMuXL7c49s033xQAxL59+2ye22TIkCGie/fuNr/LysqyaoOXl5eYOXNmtec0ZzAYhE6nE5cvXxYAxHfffSd9169fPxEWFiY0Go1UVlBQIAICAiyeZ2JiogAg3n33XYtzp6amCnd3d/HCCy9U2wbT7+jixYtS2ZAhQwQAcejQIYu63bp1EyNHjqzx/QlR8ftav369cHFxEbm5uVbX+e2336o9R1xcnAAgZsyYUeN76Nu3r4iJibGot2LFCgFAnDhxwq57IKotZpKIGoEhQ4agffv2WLt2LU6cOIHDhw9X2dUGADt27MDw4cPh6+sLFxcXuLm54bXXXkNOTg4yMzNrfN3x48dbdP1EREQgJiYGO3furPIY03dTpkyxKO/fvz+6du2K3377rcbXr6lHH33U4vP48eMt2uIo/fv3x7p16/DGG2/g4MGDNrt0MjMzMW3aNISFhcHV1RVubm6IiIgAAGnsTVFREY4cOYLRo0dDoVBIx3p5eeHee++1ON+PP/4ImUyGCRMmoKysTHqFhISgd+/eNrsfayIkJAT9+/e3KOvVqxcuX758w2OTkpJw3333ISAgQPp9TZo0CXq9HmfPnrWo6+fnh9tvv73Kcx0/fhw7d+6EXC7H7t27odVqa9T+xx57DAcOHMCZM2eksk8//RT9+vWrcsYikaMxSCJqBGQyGR577DF88cUXWLVqFTp16oTY2FibdX///XfExcUBANasWYP9+/fj8OHDmDt3LgCgpKSkxtcNCQmxWWbevVSZ6TtbM5FCQ0OrPbY2XF1dERAQYNVG87ZUd6xer7f5XVlZGQBYdNts2rQJkydPxieffIJBgwbB398fkyZNQkZGBgDjWKy4uDhs2bIFL7zwAn777Tf8/vvvOHjwIICKZ3/9+nUIIRAcHGx13cpl165dk+q6ublZvA4ePGhzrFNNVH5mAKBUKm/4+0hJSUFsbCzS0tKwfPly7N27F4cPH8ZHH31kcY8m1c1I0+l0mDx5MkJDQ7FlyxacPHnSoku4Oo8++iiUSqU0O/P06dM4fPgwHnvssRodT+QIrs5uABEZTZkyBa+99hpWrVqFN998s8p6GzduhJubG3788UeoVCqpfOvWrXZf0/THv3KZrT+wJqbv0tPT0aZNG4vvrl69isDAQLvbUZ2ysjLk5ORYtMnU7uraCRgDksOHD0MIYTVYOi0tTapjEhgYiGXLlmHZsmVISUnB999/j5deegmZmZn4+eefcfLkSRw/fhzr1q3D5MmTpeP+/vtvi3P7+flBJpPZHE9U+ZkHBgZCJpNh7969Nmd3NfSMr61bt6KoqAhbtmyRMmQAcOzYMZv1qxuMv3DhQvz555/49ddfcfvtt2PatGlYvHgxHnjggRsu9eDn54f7778f69evxxtvvIFPP/0UKpVKmuhA1BCYSSJqJFq3bo3nn38e9957r8Uf4MpkMhlcXV3h4uIilZWUlODzzz+3qnujzMGGDRssZsRdvnwZBw4cqHbxSlPXSuUBwIcPH0ZycjLuuOOOGl+/pv773/9afP7yyy8B4IaLbA4fPhxqtRo///yz1XebN2+GXC6vsqsoPDwcM2bMwIgRI/DHH38AqAgIKgcuH3/8scVnT09PREdHY+vWrRbdS4WFhfjxxx8t6t5zzz0QQiAtLQ3R0dFWr549e1Z7j45m6x6FEFizZo1d5zly5AgWL16M6dOnS894yZIlaNOmDaZMmVKjbrfHHnsMV69exbZt2/DFF1/ggQceQIsWLexqB1FdMJNE1IhUnhpty913342lS5di/PjxmDp1KnJycvDOO+/YzDj07NkTGzduxKZNm9CuXTuoVCqLP7qZmZl44IEH8NRTTyE/Px/z5s2DSqXCnDlzqrx+586dMXXqVHzwwQeQy+UYNWoULl26hFdffRVhYWGYNWuWxfW3bNmClStXIioqCnK5HNHR0XY9E4VCgXfffReFhYXo168fDhw4gDfeeAOjRo3CrbfeWu2xjz76KFasWIGHH34YL730Evr164eSkhJs27YNa9aswTPPPIN27doBMC67MGzYMIwfPx5dunSBt7c3Dh8+LM1SA4AuXbqgffv2eOmllyCEgL+/P3744QckJCRYXXvhwoW4++67MXLkSPz73/+GXq/H22+/DS8vL+Tm5kr1Bg8ejKlTp+Kxxx7DkSNHcNttt8HT0xPp6enYt28fevbsiaefftquZ1YXI0aMgEKhwLhx4/DCCy+gtLQUK1euxPXr12t8Do1Gg8mTJyMiIgJvvfWWVO7l5YW1a9fijjvuwOuvv37Drre4uDi0adMG06dPR0ZGBrvaqOE5cdA40U3NfHZbdWzNUFu7dq3o3LmzUCqVol27dmLRokUiPj7eaobQpUuXRFxcnPD29hYApJlmpplkn3/+uXj22WdFUFCQUCqVIjY2Vhw5csTiWpVntwlhnPH01ltviU6dOgk3NzcRGBgoJkyYIFJTUy3q5ebmijFjxogWLVoImUxmcR7UcHabp6en+PPPP8XQoUOFu7u78Pf3F08//bQoLCys9rmZqNVq8cILL4iOHTsKhUIhPDw8RHR0tFi1apXFzL7S0lIxbdo00atXL+Hj4yPc3d1F586dxbx580RRUZFU7/Tp02LEiBHC29tb+Pn5iX/84x8iJSXF6n6EEOLbb78VPXv2FAqFQoSHh4vFixeLZ599Vvj5+Vm1c+3atWLAgAHC09NTuLu7i/bt24tJkyZZ/feorKrZbbZm9U2ePLnK2YbmfvjhB9G7d2+hUqlE69atxfPPPy/+97//Wf33qeo6zz//vJDL5WLv3r02zz99+nTh6uoqjh49WuU9mLz88ssCgAgLCxN6vf6GbSdyJJkQZrl2Irop7Nq1C8OGDcNXX32FMWPGOLs5Nw2dTodbbrkFrVu3xvbt253dHCK6AXa3ERHVkyeeeAIjRoxAq1atkJGRgVWrViE5ORnLly93dtOIqAYYJBER1ZOCggI899xzyMrKgpubG/r27Ytt27Zh+PDhzm4aEdUAu9uIiIiIbOASAEREREQ2MEgiIiIisoFBEhEREZENHLhdSwaDAVevXoW3t3e1y/ITERFR4yGEQEFBAUJDQyGXV58rYpBUS1evXkVYWJizm0FERES1kJqaarX/ZGUMkmrJ29sbgPEh+/j4OLk1REREVBNqtRphYWHS3/HqMEiqJVMXm4+PD4MkIiKiJqYmQ2U4cJuIiIjIBgZJRERERDYwSCIiIiKygUESERERkQ0MkoiIiIhsYJBEREREZAODJCIiIiIbGCQRERER2cAgiYiIiMgGBklERERENjBIIiIiIrKBQRIRERGRDQySiIiIqNkSQqBUp6/VsQySiIiIqNn65+dH0e/NX5FdqLH7WAZJRERE1CxpyvTYfvoaCkrLsPtMlt3HM0giIiKiZunctULpvbwWEQ+DJCIiImqWTqblS++zC7R2H88giYiIiJqlk1fNgiSOSSIiIiIyOpmmlt5nNcUgacWKFYiMjIRKpUJUVBT27t1bZd309HSMHz8enTt3hlwux8yZM63qDB06FDKZzOp19913S3Xmz59v9X1ISEh93B4RERE5QZnegL8yKoKk7MIm1t22adMmzJw5E3PnzkVSUhJiY2MxatQopKSk2Kyv0WgQFBSEuXPnonfv3jbrbNmyBenp6dLr5MmTcHFxwT/+8Q+Let27d7eod+LECYffHxEREdVNRn4pdvx1DUIIu467lFOEUp1B+pzT1DJJS5cuxRNPPIEnn3wSXbt2xbJlyxAWFoaVK1farN+2bVssX74ckyZNgq+vr806/v7+CAkJkV4JCQnw8PCwCpJcXV0t6gUFBTn8/oiIiKhu5mz5E4+vO4I/Uq7bdVxGvmVQ1KTGJGm1Whw9ehRxcXEW5XFxcThw4IDDrhMfH49HHnkEnp6eFuXnzp1DaGgoIiMj8cgjj+DChQvVnkej0UCtVlu8iIiIqH5dU2ss/vdGPvjtHEZ/tB8pucUAgMhA49//nEItDAb7slFOC5Kys7Oh1+sRHBxsUR4cHIyMjAyHXOP333/HyZMn8eSTT1qUDxgwAOvXr8cvv/yCNWvWICMjAzExMcjJyanyXIsWLYKvr6/0CgsLc0gbiYiIqGpavbHLTFNWs61F3k04i2OpefhgxzkAQMeWXgCAMoNAfonOrms7feC2TCaz+CyEsCqrrfj4ePTo0QP9+/e3KB81ahQeeugh9OzZE8OHD8dPP/0EAPjss8+qPNecOXOQn58vvVJTUx3SRiIiIqqatqw8SDIbX1QT6fmlAIAQXxV83d0A2N/l5rQgKTAwEC4uLlZZo8zMTKvsUm0UFxdj48aNVlkkWzw9PdGzZ0+cO3euyjpKpRI+Pj4WLyIiIqpfpiDJlFECAJ3egH3nslGitcwu2RrcHeCpRKCXAoD9ywA4LUhSKBSIiopCQkKCRXlCQgJiYmLqfP7NmzdDo9FgwoQJN6yr0WiQnJyMVq1a1fm6RERE5DhSd5tZJunro1cwIf4QPtxpmdzQlFlnmwK8FAjwUgIwjkuyh6u9jXWk2bNnY+LEiYiOjsagQYOwevVqpKSkYNq0aQCMXVxpaWlYv369dMyxY8cAAIWFhcjKysKxY8egUCjQrVs3i3PHx8dj9OjRCAgIsLruc889h3vvvRfh4eHIzMzEG2+8AbVajcmTJ9ffzRIREZHdpO42szFJpkHZqbklFnULNWVWxwd4KhBUHiQZu9u8anxtpwZJY8eORU5ODhYuXIj09HT06NED27ZtQ0REBADj4pGV10zq06eP9P7o0aP48ssvERERgUuXLknlZ8+exb59+7B9+3ab171y5QrGjRuH7OxsBAUFYeDAgTh48KB0XSIiImocKoKkiixRQalxAHax1jIoKiy1ESR5VXS32TsmyalBEgBMnz4d06dPt/ndunXrrMpqsphUp06dqq23cePGGrePiIiInEMIYTa7rSJIMgVDlTNHtjJJ/p4K+JQP3LYVRFXH6bPbiIiIiGwxH6yt0VV0t5mCoeJKA7cLbARBgV4KeCiMOaEibc2WETBhkERERESNktYse2SeSVLXMJPkKpfBR+UGT6ULAOvuuRthkERERESNUlVBkqnbrMgqSLJcLNLPUwG5XFaRSdIwk0RERETNgEV3W5mN7rZKQU9hpc8BnsYB254KZpKIiIioGbHIJOmsZ7cVacssJmpVHpgdUD6rzUPJTBIRERE1I7a624QQUibJIIBSs+CpcndbgKdxfSQvjkkiIiKi5sR8HJL5ekk6vVn2yGxcUuVMUmgLdwCo9ew2p6+TRERERGSLrTFJlaf5F2nKEORtzBgVlAdM04a0R5C3EvffEgoA8CwPkoptrKNUHQZJRERE1CjZ6m6rPM2/SGudSWrj544JAyt20fAwdbfp9DAYbrwotQm724iIiKhRshkkWWWSrGe9eassc0CmTJIQQImu5l1uDJKIiIioUbKc3WbqbrMcnG2RSSoPkryUlkGSyk0Omcz43p7B2wySiIiIqFGyHJNkfF9QubtNc+MgSSaTVYxLsmPwNoMkIiIiapRq0t1mvqCk6TsvlfWQa49aLCjJIImIiIgaJcsgyXZ3W6GNTJK30s3qXJ5KZpKIiIiomdCYdbfp9AJ6g7Ce3Vb+WW8QUgBk2tDWXEUmiUESERERNXHmmSTTZ6sxSeVBj3nwZKu7zTQmqYRBEhERETV1lYMkTZleWkxSXj5bzZRJMgVJChc5lK42Mknl2aUiOxaUZJBEREREDSpTXYonPzuC3Wezqq1nK5NkGpxtWmXbtASAqdxWVxtglkmyY50krrhNREREDWrHX5n4NfkaAIEhnYKqrKfVWwY0mjKDlDEK8VHhmlojZYZMA7p93K0HbQMVY5KKOLuNiIiIGitTNsd8tWxbzDeyBUzdbcZgKNhHBaBiILa6vLzyatsmptltH+04X+N2MkgiIiKiBmVa8+hGXV+Vu9tKdQYUlgdWLX2M3W2FUiap6un/QEUmqYx7txEREVFjZQp+Sm8QJGmsBm4bUFLeXdbS25hJMnW3qcuDJB/36jNJ9mCQRERERA1KW8tMkqZML3WvBXqVD9zWWC4y6a2qPpNkDwZJRERE1KBMq2ffaM0i873bjMcZpGNals9uyyvWokxvgLqkvLutqjFJCmaSiIiIqJGTMkk3CpLKKs1u0+lRXJ596hrqgxYebijS6vH7xdyK2W1VZZKqWBqgOgySiIiIqEGZMkT2drcVlJZBXz7w2lvliju7hwAAfjyRXjFwu4pMErvbiIiIqNHT6IzBT5lBQFepS81c5e62/JKKzW093Fxwd69WAICfT2bgerEWQNWZJHv2bDNhkEREREQNynzj2uqySaZMkqx8CxJTIKRwkcPVRY5B7QLg5+GG3CIt9p7LBlD17LbYjkFo3cIdD/VtXeN2MkgiIiKiBmXejVZqluHJK9ZabFRrqudVPuj6erExk6RyM4Yvri5ydG3lY3Huqma3+bq7Yd+Lw7Dg/h41bieDJCIiImpQ5usfmTJJpTo9blmYgN4LtkMIYVHPq3ycUV55JsnDbKZaiK/K4txVjUkCAJkpJVVDDJKIiIio3vzvRDrGrDyAtLwSqcx81popSLpa/r3eIKRskmlMkrcUJBkzSeaDsFtVCpKqGpNUGwySiIiIqN48/d8/cOTydbzy7QmpzLy7zdaA6twirUU9UxeaqbvN3SxICvF1tzi2ukySvRgkERERUb1Lzy+V3mtsjEkyH8CdYxUkVe5uMwuSfCp3tzGTRERERE2I+XR+rc0xSRVlOYVai2MqMknGcnezMUnm3W0qNzkUro4LbRgkERERUb3TmAVBWhtLAGjMMkm5RRpjvfJgyqc8k2QKpDzczLvbKoIkdzf7F4ysjtODpBUrViAyMhIqlQpRUVHYu3dvlXXT09Mxfvx4dO7cGXK5HDNnzrSqs27dOshkMqtXaWmpRT17rktERER1Yx4YmQdMpq1JSsuq7m5r6W3ZpWY+JsnfQ1Fxrhus4G0vpwZJmzZtwsyZMzF37lwkJSUhNjYWo0aNQkpKis36Go0GQUFBmDt3Lnr37l3leX18fJCenm7xUqkqHrC91yUiIqK6Mc8UmQdMpTa623ILtTAYBMrKtyAJ8VVanMs8SJLLK6b1m5/DEZwaJC1duhRPPPEEnnzySXTt2hXLli1DWFgYVq5cabN+27ZtsXz5ckyaNAm+vr5VnlcmkyEkJMTiVZfrEhERUd1UNSbJNLut1KK7TWtRP7jS4GwPB3erVcVpQZJWq8XRo0cRFxdnUR4XF4cDBw7U6dyFhYWIiIhAmzZtcM899yApKalBrktERES2mWd5NDbWSbIYuF2ktZgBV3nByNpsVlsbTguSsrOzodfrERwcbFEeHByMjIyMWp+3S5cuWLduHb7//nts2LABKpUKgwcPxrlz5+p0XY1GA7VabfEiIiIi+xgMAjq9kD6br7htcjItH5PiD0mfg63GJFmuhWRaBsBVbt+K2jfi9IHblZcIF0LYvWy4uYEDB2LChAno3bs3YmNjsXnzZnTq1AkffPBBna67aNEi+Pr6Sq+wsLBat5GIiOhmZd6NBlSsk1R54PbxK/kAgCBvJXzd3WAe/1TOJK2d0g8DIv2xYepAh7bVaUFSYGAgXFxcrLI3mZmZVlmeupDL5ejXr5+USartdefMmYP8/HzplZqa6rA2EhERNUemPdhMDAZh0Y0G2O5uM7klrAU+e6w/5HIZ/MxmsblXCpK6hfpg0z8HoV9bf0c1HYATgySFQoGoqCgkJCRYlCckJCAmJsZh1xFC4NixY2jVqlWdrqtUKuHj42PxIiIioqpVzhoVasssBm0DQEl5cKSxMX1/6cO90S3U+PfWz9MsSGqggduO2+CkFmbPno2JEyciOjoagwYNwurVq5GSkoJp06YBMGZv0tLSsH79eumYY8eOATAOzs7KysKxY8egUCjQrVs3AMCCBQswcOBAdOzYEWq1Gu+//z6OHTuGjz76qMbXJSIiorqrHBAVlJZZ1SnRGstKbQRJkYGe0nvz9ZAaauC2U4OksWPHIicnBwsXLkR6ejp69OiBbdu2ISIiAoBx8cjKaxf16dNHen/06FF8+eWXiIiIwKVLlwAAeXl5mDp1KjIyMuDr64s+ffpgz5496N+/f42vS0RERHVXuWutoFQHhYtlJ1ZV3W2tfFUWY4VbeFTsyVa5u62+ODVIAoDp06dj+vTpNr9bt26dVVnl/s3K3nvvPbz33nt1ui4RERHVna1MkmmzWhNbK24DQN9wP4vP/p7mmaSGCV+cHiQRERFR81SzTJKxjqm7rVOwF+QyGV69p5tFPT/Pm6y7jYiIiJov25kkN4uyytuSTL2tPcZEtbE6l/mYpIYauO30dZKIiIioeaocJKlLbcxuq7QticrNdmjiazYmqdmvuE1ERETNm6bSOKOCUp1U5lke6BSbZreVB08qV9sBkHn2qKEGbjNIIiIionphq7vNVObrbswMlVZaJ0lVRVeaeXlVgZSjMUgiIiKielF54La6RCeVtSgfY6TVG1BQqrthd1tEgIf0Xu7gPdqqwoHbREREVC+sZ7eVSWUtfZTQlHnifFYRfk2+Jq2XVFUmqVOwN5Y81AtBPsr6bbQZZpKIiIioXlTelqSgVCd1tyld5binVygA4Ifj6VK3W1WZJAB4uF8YhnVuWU+ttcYgiYiIiOpF5f3Y8ksqgiSFqwvu7W3cV3XP2Szkl+gAAMoGGm9UEwySiIiIqF6YMkl+5dP384orxiQpXeXo0NIbXUK8UWao2E2jqu42Z2CQRERERPVCU96F1tJbBQDIs8gkGUOQLiHeFsdU193W0BpPS4iIiKhZMWWSWpYPts4r1kp7tCnLg6RWLdwtjmEmiYiIiJo9U9Yo2MeYSTIIILdQC6Aik9TKVyXVd5HL4ObSeEKTxtMSIiIiatLK9AaLVbZN772UrtKK2dcKSgEAShdTkFSRSVK5Nq6wpHG1hoiIiJokIQRGr9iP4Ut3Q1fezSZN93eTo0X54O1Mtaa8zBg0mWeSGlNXG8AgiYiIiBygzCBwMk2N1NwSZBcaAyFpJpuLXFphO7M8k6Rwse5ua6iVtGuKQRIRERHVmfk+bcVavUWZ0s0FLcr3asuuNCbJ31MhHWdaK6mxYJBEREREdWYRJGmMQZIpk6RwqehuMzHNbpPJKrJHlTfEdTYGSURERFRn5luQFGvLjGVmayJVDpIa2/gjWxgkERERUZ3Z6m4zX13bNCbJJDLQU3rv0sjGIpkwSCIiIqI6s8wkmYIk4/8qXOXSmCSTjsFe0nu/SgFUY8EgiYiIiOrMMpNk2d2mdHWx6G4L9/eAh8JV+vzogHAAQO82vg3R1BpzvXEVIiIioupV192mcJXDV16RLeoUbLlf24zbO6BTsDcGtvNvgJbWHIMkIiIiqjNb3W1aszFJSrPVtCtvauvmIsfdvVo1QCvtw+42IiIiqjOb3W1689ltZpmkSkFSY8UgiYiIiOrshgO3zcYkdWzphaaAQRIRERHVWbUrbrvK4e+pgIfCuDZSuyBP6xM0QhyTRERERHVmq7vNfJ0kNxc59r4wDDKZDErXxr+QJMAgiYiIiByg+kySMSgK8FI2fMPqgN1tREREVGc32pakKWqarSYiIqJGpXImSac3oMwgABg3uG2KmmariYiIqFHRmWWSSrR6JJ7PAQD4eyrgU2lLkqaCQRIRERFVKSO/FGv3XYS6VFdtPY1ZJqlIW4bvjl0FANzds1Wj3cD2RhgkERERUZUe/eQgFv54Gou2JQMA8kt02PHXNRjKu9JMzLvb8op02H4qAwBw3y2hDddYB2OQRERERFU6n1UEANh1JgsA8NbPf+HxdUfwxk/JFvXMB24XaMpQoClDqK8KUeF+DddYB2OQRERERDfkWz6u6MtDKQCAtfsvWnxvnkky6RfpD3kT7WoDGkGQtGLFCkRGRkKlUiEqKgp79+6tsm56ejrGjx+Pzp07Qy6XY+bMmVZ11qxZg9jYWPj5+cHPzw/Dhw/H77//blFn/vz5kMlkFq+QkBBH3xoREVGTpjfrUjMNvo4MrFgt+3xWofTeVpAU4e9Rj62rf04NkjZt2oSZM2di7ty5SEpKQmxsLEaNGoWUlBSb9TUaDYKCgjB37lz07t3bZp1du3Zh3Lhx2LlzJxITExEeHo64uDikpaVZ1OvevTvS09Ol14kTJxx+f0RERE1ZZkGp9N60pYh5XujH4+nSe/PZbSZhDJJqb+nSpXjiiSfw5JNPomvXrli2bBnCwsKwcuVKm/Xbtm2L5cuXY9KkSfD19bVZ57///S+mT5+OW265BV26dMGaNWtgMBjw22+/WdRzdXVFSEiI9AoKCnL4/RERETVlV66XSO+LNcZVtK8Xa6WytfsvIjW3GIDtTFI4g6Ta0Wq1OHr0KOLi4izK4+LicODAAYddp7i4GDqdDv7+/hbl586dQ2hoKCIjI/HII4/gwoUL1Z5Ho9FArVZbvIiIiJqzNLMgqUBTBoNBIL/EuBRA6xbuyC/R4en/HoXBIKCxkUmKCGgaG9lWxWlBUnZ2NvR6PYKDgy3Kg4ODkZGR4bDrvPTSS2jdujWGDx8ulQ0YMADr16/HL7/8gjVr1iAjIwMxMTHIycmp8jyLFi2Cr6+v9AoLC3NYG4mIiBqjK9eLpfcFpTqoS3UwDVP68qkBcHdzwck0Nc5lFtrMJLX0blp7tVXm9IHbMpnlqHchhFVZbS1ZsgQbNmzAli1boFKppPJRo0bhoYceQs+ePTF8+HD89NNPAIDPPvusynPNmTMH+fn50is1NdUhbSQiImqs0vIqMkmFmjJcLzZmkTwVLogI8ESXVt4AgLPXCmwGSU15ZhsAuDrrwoGBgXBxcbHKGmVmZlpll2rjnXfewX/+8x/8+uuv6NWrV7V1PT090bNnT5w7d67KOkqlEkpl046IiYiI7GE+JqmgtEwaj9TCQwEA6BzsjaSUPJy9VmBz4HZT57RMkkKhQFRUFBISEizKExISEBMTU6dzv/3223j99dfx888/Izo6+ob1NRoNkpOT0apVqzpdl4iIqDkxH5OkNwhk5Btnu/l5GpcD6BRszCSdybDOJLXwaJr7tZlzWiYJAGbPno2JEyciOjoagwYNwurVq5GSkoJp06YBMHZxpaWlYf369dIxx44dAwAUFhYiKysLx44dg0KhQLdu3QAYu9heffVVfPnll2jbtq2UqfLy8oKXlxcA4LnnnsO9996L8PBwZGZm4o033oBarcbkyZMb8O6JiIgat/T8UovPpplsfqZMUogxSDqXWQhvlWVIMbh9YAO0sH7ZHSR99tlnCAwMxN133w0AeOGFF7B69Wp069YNGzZsQERERI3PNXbsWOTk5GDhwoVIT09Hjx49sG3bNukc6enpVmsm9enTR3p/9OhRfPnll4iIiMClS5cAGBen1Gq1GDNmjMVx8+bNw/z58wEAV65cwbhx45CdnY2goCAMHDgQBw8etKvtREREzVmxtgwlOuO0f7kMMAggpTxIMnW3dQw2Jh8u5RRJC0c+F9cJaXmleGFkZye02rFkQghx42oVOnfujJUrV+L2229HYmIi7rjjDixbtgw//vgjXF1dsWXLlvpqa6OiVqvh6+uL/Px8+Pj4OLs5REREDpWaW4zYJTuhcJEj0EuBq/mluK1TEPaczcKkQRFYeH8PCCHQ9/UEaUA3AGyaOhAD2gU4seXVs+fvt92ZpNTUVHTo0AEAsHXrVowZMwZTp07F4MGDMXTo0Fo1mIiIiBoX0yBtf08FvFVuQH4prpgySeVblMhkMnQK9sahi7nScQpXp0+cdxi778TLy0taT2j79u3S+kMqlQolJSXVHUpERERNRE6ReZBkzKmkXrfsbgOsV9VuTkGS3ZmkESNG4Mknn0SfPn1w9uxZaWzSqVOn0LZtW0e3j4iIiJwgt9AYJAV4KeBSvt6RTm8coWOa3QYYgyhzymYUJNl9Jx999BFiYmKQlZWFb775BgEBxn7Ho0ePYty4cQ5vIBERETW83KJK3W1mzDNJfpWCJDeX5hMk2ZVJKisrw/Lly/HCCy9YbcuxYMEChzaMiIiInMe8u61UZ7kGkp9ZkFQ5k9ScutvsuhNXV1e8/fbb0Ov19dUeIiIiagRyizQAgABPBXwqrYHkZ7ZQpL9HpSCpGWWS7L6T4cOHY9euXfXQFCIiImosKrrblPBSVgRJgV5KhPlVDNau3N3WnDJJdg/cHjVqFObMmYOTJ08iKioKnp6eFt/fd999DmscEREROYf5mCRtWUUP0vCuLS02rg1gkFTh6aefBgAsXbrU6juZTMauOCIiombAFCQFeClQUFqxWOSIbpab0FtlkppRd5vdQZLB0Px2+SUiIiJLpoHbfh4KnCkrkMoHd7Dck63yeCWZTIbmok7hXmlp6Y0rERERUZPx459X0WPeLygoLQNg7E67u2crdA72xqzhnaByc7Go35yCosrsDpL0ej1ef/11tG7dGl5eXrhw4QIA4NVXX0V8fLzDG0hEREQN551fzqBQUyZ99nV3g5+nAr/Mug3/Ht7R5jHNNU6yO0h68803sW7dOixZsgQKRUU/ZM+ePfHJJ584tHFERETUsJSulpki80HaVfFS2D16p0mwO0hav349Vq9ejUcffRQuLhUPslevXvjrr78c2jgiIiJqWLnlG9sCQLCPskbHeKmaZ5Bk912lpaWhQ4cOVuUGgwE6nc7GEURERNQUlOr0yCowLiL57O0dMKxLyxodZ76OUnNidyape/fu2Lt3r1X5V199hT59+jikUURERNTw0vONE7Lc3Vwwa0Qn9An3q9Fxns00SLL7rubNm4eJEyciLS0NBoMBW7ZswZkzZ7B+/Xr8+OOP9dFGIiIiagBXrhcDAFr7uds1a827mXa32Z1Juvfee7Fp0yZs27YNMpkMr732GpKTk/HDDz9gxIgR9dFGIiIiagBp10sAAK1buNt1XOdg7/pojtPVKvQbOXIkRo4c6ei2EBERkROl5ZUHSX72BUkzR3TC9WId7u3dqj6a5TS1zo8dOXIEycnJkMlk6Nq1K6KiohzZLiIiImpgtc0keSld8e7DveujSU5ld5B05coVjBs3Dvv370eLFi0AAHl5eYiJicGGDRsQFhbm6DYSERFRA7hSnklqY2cmqbmye0zS448/Dp1Oh+TkZOTm5iI3NxfJyckQQuCJJ56ojzYSERFRPTAYBEp1FRvT1zaT1FzZnUnau3cvDhw4gM6dO0tlnTt3xgcffIDBgwc7tHFERERUf6Z+fgRHL1/HrueGQUBIY5LaB3k5uWWNg91BUnh4uM1FI8vKytC6dWuHNIqIiIjq34HzOSjW6vFXhhqaMgMAICLAA36eihsceXOwu7ttyZIleOaZZ3DkyBEIIQAYB3H/+9//xjvvvOPwBhIREZHjFWvLUKw1drVlFWpwPDUPAHBLWAvnNaqRsTuTNGXKFBQXF2PAgAFwdTUeXlZWBldXVzz++ON4/PHHpbq5ubmOaykRERE5THaB1uy9Bsev5AEAerdp4ZwGNUJ2B0nLli2rh2YQERFRQ8oq1Fi8P1aeSerNTJLE7iBp8uTJ9dEOIiIiakA5ZkHS8dR8ZBdq4SqXoXuojxNb1bjUabOVkpISq0HcPj58uERERI2VtsyAo5evS5vZAsDvF43DYzoGe0Pl5uKspjU6dg/cLioqwowZM9CyZUt4eXnBz8/P4kVERESNx4G/sxG7ZAd2nckEACxNOItxaw5i3venpDpavXFmW7tAT6e0sbGyO0h64YUXsGPHDqxYsQJKpRKffPIJFixYgNDQUKxfv74+2khERES19NOJdKTmlmD76WsAgFW7z1dZt22gR0M1q0mwu7vthx9+wPr16zF06FA8/vjjiI2NRYcOHRAREYH//ve/ePTRR+ujnURERFQLV8pX0c4rNs5m8/Nww/Vi6/UOAaBtADNJ5uzOJOXm5iIyMhKAcfyRaZr/rbfeij179ji2dURERFQnqdeLAQC5RcYgKdhHVWXdSHa3WbA7SGrXrh0uXboEAOjWrRs2b94MwJhhMm14S0RERM4nhJD2Y7teZMweVTcwuy2DJAt2B0mPPfYYjh8/DgCYM2eONDZp1qxZeP755x3eQCIiIqqdrEKNtN1Ibnl3W0GpZVebm4sMAOCtdEUAtyOxYPeYpFmzZknvhw0bhuTkZBw9ehTt27dH7969Hdo4IiIiqr3U3BLp/fUiLYQQKCgts6jTPsgLf2UUoG2gJ2QyWUM3sVGzO5NUWUREBB588MFaB0grVqxAZGQkVCoVoqKisHfv3irrpqenY/z48ejcuTPkcjlmzpxps94333yDbt26QalUolu3bvj222/rdF0iIqKm6Er5eCQAKDMIFGjKoK6USWrf0gsAu9psqVWQ9Ntvv+Gee+5B+/bt0aFDB9xzzz349ddf7T7Ppk2bMHPmTMydOxdJSUmIjY3FqFGjkJKSYrO+RqNBUFAQ5s6dW2VQlpiYiLFjx2LixIk4fvw4Jk6ciIcffhiHDh2q9XWJiIiaItPMNpNMtQalOoNFWfvy4IgrbVuTCSGEPQd8+OGHmDVrFsaMGYNBgwYBAA4ePIivv/4aS5cuxYwZM2p8rgEDBqBv375YuXKlVNa1a1eMHj0aixYtqvbYoUOH4pZbbrHaS27s2LFQq9X43//+J5Xdeeed8PPzw4YNG+p8XRO1Wg1fX1/k5+dzlXEiImqU5mz5Ext+T5U+r50SjcfXHQEA3N6lJW7tEIiH+4Vh79ksDO3cEu6K5r/atj1/v+0ek7Ro0SK89957FsHQs88+i8GDB+PNN9+scZCk1Wpx9OhRvPTSSxblcXFxOHDggL3NkiQmJlqMmwKAkSNHSsFUba+r0Wig0VTsc6NWq2vdRiIiooZgPiYJAC7nGLvfPBUuWDuln1Q+qmerBm1XU2F3d5tarcadd95pVR4XF2dX4JCdnQ29Xo/g4GCL8uDgYGRkZNjbLElGRka156ztdRctWgRfX1/pFRYWVus2EhERNYS0PGOQ5F4+7d8UJPm4uzmtTU2J3UHSfffdZ3Mg9HfffYd7773X7gZUHkkvhKjz6PqanNPe686ZMwf5+fnSKzU1tcq6REREjUFWgbEHpFOwcXD25ZwiAIC3qk7729807H5KXbt2xZtvvoldu3ZZjEnav38//u///g/vv/++VPfZZ5+t8jyBgYFwcXGxyt5kZmZaZXnsERISUu05a3tdpVIJpVJZ63YRERE1pFKdHoUa43T/jsHeOH4lH5dzyzNJKmaSasLuICk+Ph5+fn44ffo0Tp8+LZW3aNEC8fHx0meZTFZtkKRQKBAVFYWEhAQ88MADUnlCQgLuv/9+e5slGTRoEBISEizGJW3fvh0xMTH1el0iIqLGxJRFUrjKEe5v3LjW1N3GTFLN2P2ULl686LCLz549GxMnTkR0dDQGDRqE1atXIyUlBdOmTQNg7OJKS0vD+vXrpWOOHTsGACgsLERWVhaOHTsGhUKBbt26AQD+/e9/47bbbsNbb72F+++/H9999x1+/fVX7Nu3r8bXJSIiauqyC41BUpCXEv7lK2nrDcYJ7d7MJNWIU0PJsWPHIicnBwsXLkR6ejp69OiBbdu2ISIiAoBx8cjKaxf16dNHen/06FF8+eWXiIiIkPaTi4mJwcaNG/HKK6/g1VdfRfv27bFp0yYMGDCgxtclIiJqiv53Ih17/87Ggvu6I7vQuA1JoJdCCpJMfNyZSaoJu9dJIiOuk0RERI1N25d+AgDMv7cbFK4uePnbExjetSUevzUS49dULKr89ND2ePHOLs5qplPZ8/e7ztuSEBERUeNyLrNQ6m4L9FIizM/D4nsO3K4ZBklERETNTF6JzjJI8vdApNnebBy4XTM1CpIefPBBaaHI9evXW6w8TURERI2L2iJIMo5HGto5SPqei0nWTI2CpB9//BFFRcYFqB577DHk5+fXa6OIiIjIPuZDjPNLdMguKB+47W1c429o55bS995KZpJqokZPqUuXLpgzZw6GDRsGIQQ2b95c5WCnSZMmObSBREREdGM6fUWQlFesg6vcuJBkoJcxSBoQ6S997+pSt50tbhY1CpJWrVqF2bNn46effoJMJsMrr7xicwsPmUzGIImIiMgJSnR66X1+iQ6G8jWRTEGSys0FSx7qhWNX8hDTPtApbWxqahQkxcTE4ODBgwAAuVyOs2fPomXLljc4ioiIiBqKplKQZBLkXbGl1sP9wvBwP27QXlN2z267ePEigoKCblyRiIiIGkypzmBVpnCRw4cz2WrN7icXERGBvLw8xMfHIzk5GTKZDF27dsUTTzwBX1/f+mgjERER3YB5d5tJeICHzeExVDN2Z5KOHDmC9u3b47333kNubi6ys7Px3nvvoX379vjjjz/qo41ERER0A6U2gqS7eoQ4oSXNh92ZpFmzZuG+++7DmjVr4OpqPLysrAxPPvkkZs6ciT179ji8kURERFQ9W5mk+24JdUJLmg+7g6QjR45YBEgA4OrqihdeeAHR0dEObRwRERHVjK1MUoeW3k5oSfNhd3ebj48PUlJSrMpTU1Ph7c3/GERERM5gHiQFeimxakJfJ7amebA7kzR27Fg88cQTeOeddxATEwOZTIZ9+/bh+eefx7hx4+qjjURERHQDptltt3YIxBdPDnBya5oHu4Okd955R1o0sqzMuJqnm5sbnn76aSxevNjhDSQiIqIbM2WSVG7cu95R7A6SFAoFli9fjkWLFuH8+fMQQqBDhw7w8PCoj/YRERFRDZRIQZKLk1vSfNR6hSkPDw/07NnTkW0hIiKiWjJ1tzFIchzm5IiIiJqBEna3ORyfJBERUROkNwjoyzexBSr2bnNnJslhGCQRERE1McXaMty2ZCceWnkAxVrjJCqOSXI8BklERERNzOmraqTlleBYah7mf38KgPnsNgZJjlKrgdtnz57Frl27kJmZCYPBctfh1157zSENIyIiItsuZBdJ7zcfuYJ7eoWihAO3Hc7uIGnNmjV4+umnERgYiJCQEIvdhWUyGYMkIiKienbRLEgCgA93/A1fDzcAHJPkSHYHSW+88QbefPNNvPjii/XRHiIiIrqBi1nGIOmfQ9rh032X8PulXChdjSNoOLvNcex+ktevX8c//vGP+mgLERER1YApkzSoXQAe7NsaAKApM3a3MZPkOHYHSf/4xz+wffv2+mgLERER3YDBIHAxxxgktQv0QnRbf4vvOSbJcezubuvQoQNeffVVHDx4ED179oSbm5vF988++6zDGkdERESWruaXQFtmgJuLDK393NEm393ieyW72xzG7iBp9erV8PLywu7du7F7926L72QyGYMkIiKiemTqaosI8ISLXIbWLSyDJHa3OY7dQdLFixfrox1ERERUA6YgKTLQEwAQ4quCXAaYFt9md5vj1CknJ4SAEOLGFYmIiKhWsgo0WJpwFheyCgEYF5IEgE7BXgAANxc5QnxUUn1mkhynVkHS+vXr0bNnT7i7u8Pd3R29evXC559/7ui2ERER3dSyCzW49a0deP+3c3jv13MAgD+v5AMAerb2leq18fOQ3jOT5Dh2d7ctXboUr776KmbMmIHBgwdDCIH9+/dj2rRpyM7OxqxZs+qjnURERDeded+fkqb2H7yQg1KdHmevFQAAepgFScG+zCTVB7uDpA8++AArV67EpEmTpLL7778f3bt3x/z58xkkEREROcjx1DzpfX6JDsnpapQZBPw83CwGbAd4KqT3nN3mOHY/yfT0dMTExFiVx8TEID093SGNIiIiutnp9Aak55dKn7VlBvx8MgOAMYtkvi2YRZDkyiDJUex+kh06dMDmzZutyjdt2oSOHTs6pFFEREQ3u/S8UugNAgpXuTRIe+uxNABArza+FnUDvJTSe/PgierG7u62BQsWYOzYsdizZw8GDx4MmUyGffv24bfffrMZPBEREZH9Uq8XAwDa+LmjQ0svnL1WiGtqDQCgZ+sWFnUHtPOvfDg5gN2ZpIceegiHDh1CYGAgtm7dii1btiAwMBC///47HnjgAbsbsGLFCkRGRkKlUiEqKgp79+6ttv7u3bsRFRUFlUqFdu3aYdWqVRbfDx06FDKZzOp19913S3Xmz59v9X1ISIjdbSciIqovqbnGICnc3wPtg7ykck+FC2I7BlrUbR/khS3TY7D7+aEN2cRmz+5MEgBERUXhiy++qPPFN23a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169vqFusN7aeGwDx6aefSnUMBoOYN2+eCAkJEUqlUtx2223ixIkTFucpKSkRM2bMEP7+/sLd3V3cc889IiUlpcrrNpffXkM+v+b2+3PUs5s3b94Nz2OOvz37n19z++1VRSaEEA7ptyMiIiJqRjhwm4iIiMgGBklERERENjBIIiIiIrKBQRIRERGRDQySiIiIiGxgkERERERkA4MkIiIiIhsYJBHRTWfo0KGYOXOms5tBRI0cgyQiomrs2rULMpkMeXl5zm4KETUwBklERERENjBIIqJmraioCJMmTYKXlxdatWqFd9991+L7L774AtHR0fD29kZISAjGjx+PzMxMAMClS5cwbNgwAICfnx9kMhmmTJkCABBCYMmSJWjXrh3c3d3Ru3dvfP311w16b0RUvxgkEVGz9vzzz2Pnzp349ttvsX37duzatQtHjx6VvtdqtXj99ddx/PhxbN26FRcvXpQCobCwMHzzzTcAgDNnziA9PR3Lly8HALzyyiv49NNPsXLlSpw6dQqzZs3ChAkTsHv37ga/RyKqH9zgloiarcLCQgQEBGD9+vUYO3YsACA3Nxdt2rTB1KlTsWzZMqtjDh8+jP79+6OgoABeXl7YtWsXhg0bhuvXr6NFixYAjNmpwMBA7NixA4MGDZKOffLJJ1FcXIwvv/yyIW6PiOqZq7MbQERUX86fPw+tVmsRyPj7+6Nz587S56SkJMyfPx/Hjh1Dbm4uDAYDACAlJQXdunWzed7Tp0+jtLQUI0aMsCjXarXo06dPPdwJETkDgyQiarZulCgvKipCXFwc4uLi8MUXXyAoKAgpKSkYOXIktFptlceZAqmffvoJrVu3tvhOqVTWveFE1CgwSCKiZqtDhw5wc3PDwYMHER4eDgC4fv06zp49iyFDhuCvv/5CdnY2Fi9ejLCwMADAkSNHLM6hUCgAAHq9Xirr1q0blEolUlJSMGTIkAa6GyJqaAySiKjZ8vLywhNPPIHnn38eAQEBCA4Oxty5cyGXG+eshIeHQ6FQ4IMPPsC0adNw8uRJvP766xbniIiIgEwmw48//oi77roL7u7u8Pb2xnPPPYdZs2bBYDDg1ltvhVqtxoEDB+Dl5YXJkyc743aJyME4u42ImrW3334bt912G+677z4MHz4ct956K6KiogAAQUFBWLduHb766it069YNixcvxjvvvGNxfOvWrbFgwQK89NJLCA4OxowZMwAAr7/+Ol577TUsWrQIXbt2xciRI/HDDz8gMjKywe+RiOoHZ7cRERER2cBMEhEREZENDJKIiIiIbGCQRERERGQDgyQiIiIiGxgkEREREdnAIImIiIjIBgZJRERERDYwSCIiIiKygUESERERkQ0MkoiIiIhsYJBEREREZAODJCIiIiIb/h/3T5nbvgRw0QAAAABJRU5ErkJggg==\n", 709 | "text/plain": [ 710 | "
" 711 | ] 712 | }, 713 | "metadata": {}, 714 | "output_type": "display_data" 715 | } 716 | ], 717 | "source": [ 718 | "df.groupby(\"date\").has_matplotlib.mean().plot(\n", 719 | " title=\"Matplotlib Usage in arXiv\", \n", 720 | " ylabel=\"Fraction of papers\"\n", 721 | ").get_figure().savefig(\"results.png\")" 722 | ] 723 | }, 724 | { 725 | "cell_type": "markdown", 726 | "id": "bd3a2592-d153-4139-a4e2-a80f4a466c24", 727 | "metadata": {}, 728 | "source": [ 729 | "I did the plot above. Then Thomas Caswell (matplotlib maintainer) came by and, in true form, made something much better 🙂" 730 | ] 731 | }, 732 | { 733 | "cell_type": "code", 734 | "execution_count": 14, 735 | "id": "cf83b666-05c1-47f3-a2e3-55bbe8f5eeb8", 736 | "metadata": {}, 737 | "outputs": [ 738 | { 739 | "data": { 740 | "text/plain": [ 741 | "Text(0.5, 1.0, 'Matplotlib usage on arXiv')" 742 | ] 743 | }, 744 | "execution_count": 14, 745 | "metadata": {}, 746 | "output_type": "execute_result" 747 | }, 748 | { 749 | "data": { 750 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAosAAAHrCAYAAACn9tfQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAA9hAAAPYQGoP6dpAABrTUlEQVR4nO3deVxUVf8H8M8MIooLisqi6IgBmrnkgqKWIKa45JKatoJKgqKGEj7q0+JWQW65pCY6LqW5PWZZ+qSYQKVoWJjmCgXqFKa4QJICzpzfH/5mHoaZgRmYgRnm83695lVz77n3ngN2/XaW75EIIQSIiIiIiPSQVncFiIiIiMh6MVgkIiIiIoMYLBIRERGRQQwWiYiIiMggBotEREREZBCDRSIiIiIyiMEiERERERnEYJGIiIiIDGKwSEREREQGMVgksgNbtmyBRCKBRCJBcnKyznkhBHx8fCCRSBAUFFShZ6xduxZbtmypVD3nz58PiURSoWs/++wzrFixQu85iUSC+fPna74nJyfr/CzGjx+P+vXrV+jZZD0++eQTSCQSJCQk6Jw7fvw4HBwcEBsbqzkWFBRU4T/zRPaCwSKRHWnQoAHkcrnO8ZSUFPz2229o0KBBhe9tjmCxMsoKFkvr2rUrUlNT0bVrV8tWiqpcaGgoRowYgTfeeAPZ2dma4wUFBQgLC4Ofnx/effddzfG1a9di7dq11VBTItvBYJHIjowbNw579+5Ffn6+1nG5XI5evXqhVatW1VSzqtWwYUMEBASgYcOG1V0VMhOlUonCwkIAwPr16+Hk5IQJEyZACAEAmDVrFrKysrB161bUqVNHc1379u3Rvn37aqkzka1gsEhkR1588UUAwI4dOzTH8vLysHfvXkycOFHvNQsWLEDPnj3h6uqKhg0bomvXrpDL5Zq/hAGgdevWOHfuHFJSUjTD3a1btwbwvyHfbdu2ISYmBh4eHqhbty4CAwORnp5ebp1VKhUWL16Mdu3awcnJCW5ubggNDYVCodCUCQoKwoEDB3DlyhXN88saztY3DK127tw59O/fH/Xq1UOzZs0wbdo0/PPPP+XWs3Xr1hg/frzO8dLDnCqVCu+++y7atm2LunXrolGjRujUqRNWrlypKZOZmYkJEybA19cXzs7OaNGiBYYNG4azZ8/qre/AgQPh7OyMZs2aYerUqThw4IDe9h05cgT9+/dHw4YN4ezsjD59+uDbb78tt20AcPXqVbzyyitwc3ODk5MTHn/8cSxbtgwqlUpTJjs7GxKJBEuXLsXy5cvh7e2N+vXro1evXjhx4kS5z7h58yaioqLQvn171K9fH25ubggODsb333+vVU79nMWLF+Pdd9+Ft7c3nJyckJSUBABwd3fH2rVrkZycjNWrVyMxMRHr1q3DnDlz0KNHD617lfz9FBcXw83NDa+++qpO3e7evYu6desiJibGqJ8XUU3CYJHIjjRs2BBjxozBpk2bNMd27NgBqVSKcePG6b0mOzsbkZGR2L17Nz7//HOMGjUK06dPx6JFizRl9u3bhzZt2qBLly5ITU1Famoq9u3bp3Wff//73/j999+xceNGbNy4EX/++SeCgoLw+++/l1nnKVOmYPbs2RgwYAD279+PRYsW4ZtvvkHv3r2Rm5sL4NFQYp8+feDh4aF5fmpqqsk/n+LiYgwZMgT9+/fHF198gWnTpmH9+vUGfzYVsXjxYsyfPx8vvvgiDhw4gF27diE8PBx3797VlPnzzz/RpEkTxMfH45tvvsGaNWtQq1Yt9OzZE5cuXdKUy8nJQWBgIC5duoR169bhk08+wd9//41p06bpPHfbtm0YOHAgGjZsiK1bt2L37t1wdXVFSEhIuQHjzZs30bt3bxw+fBiLFi3C/v378cwzzyA2Nlbvs9asWYPExESsWLEC27dvR0FBAYYMGYK8vLwyn3P79m0AwLx583DgwAFs3rwZbdq0QVBQkN7AftWqVTh69CiWLl2K//73v2jXrp3m3NixYzF27FjMnTsXYWFh6NSpE955550yn+/o6IhXXnlFb+/7jh078ODBA0yYMKHMexDVSIKIarzNmzcLACItLU0kJSUJAOLXX38VQgjh7+8vxo8fL4QQ4oknnhCBgYEG76NUKkVxcbFYuHChaNKkiVCpVJpzhq5VP69r165a5bOzs4Wjo6N47bXXNMfmzZsnSr6WLly4IACIqKgorXuePHlSABD//ve/NceGDh0qZDKZ3noDEPPmzdOpU1JSkuZYWFiYACBWrlypde17770nAIgffvhB773VZDKZCAsL0zkeGBio9XN59tlnxZNPPlnmvUp7+PChKCoqEr6+vmLmzJma47NmzRISiUScO3dOq3xISIhW+woKCoSrq6sYNmyYVjmlUik6d+4sevToUebz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\n", 751 | "text/plain": [ 752 | "
" 753 | ] 754 | }, 755 | "metadata": {}, 756 | "output_type": "display_data" 757 | } 758 | ], 759 | "source": [ 760 | "import datetime\n", 761 | "import matplotlib.pyplot as plt\n", 762 | "from matplotlib.ticker import PercentFormatter\n", 763 | "\n", 764 | "import pandas as pd\n", 765 | "\n", 766 | "# read data\n", 767 | "by_month = pd.read_parquet(\"results.parquet\").groupby(\"date\").has_matplotlib.mean()\n", 768 | "\n", 769 | "\n", 770 | "# get figure\n", 771 | "fig, ax = plt.subplots(layout=\"constrained\")\n", 772 | "# plot the data\n", 773 | "ax.plot(by_month, \"o\", color=\"k\", ms=3)\n", 774 | "\n", 775 | "# over-ride the default auto limits\n", 776 | "ax.set_xlim(left=datetime.date(2004, 1, 1))\n", 777 | "ax.set_ylim(bottom=0)\n", 778 | "\n", 779 | "# turn on a horizontal grid\n", 780 | "ax.grid(axis=\"y\")\n", 781 | "\n", 782 | "# remove the top and right spines\n", 783 | "ax.spines.right.set_visible(False)\n", 784 | "ax.spines.top.set_visible(False)\n", 785 | "\n", 786 | "# format y-ticks a percent\n", 787 | "ax.yaxis.set_major_formatter(PercentFormatter(xmax=1))\n", 788 | "\n", 789 | "# add title and labels\n", 790 | "ax.set_xlabel(\"date\")\n", 791 | "ax.set_ylabel(\"% of all papers\")\n", 792 | "ax.set_title(\"Matplotlib usage on arXiv\")" 793 | ] 794 | }, 795 | { 796 | "cell_type": "markdown", 797 | "id": "81198952-f6ba-4e1b-9792-36e54a5fe491", 798 | "metadata": {}, 799 | "source": [ 800 | "Yup. Matplotlib is used pretty commonly on arXiv. Go team." 801 | ] 802 | }, 803 | { 804 | "cell_type": "markdown", 805 | "id": "a59d3a1d-289c-405c-8330-fc249e376b70", 806 | "metadata": {}, 807 | "source": [ 808 | "## Save results\n", 809 | "\n", 810 | "This data was slighly painful to procure. Let's save the results locally for future analysis. That way other researchers can further analyze the results without having to muck about with parallelism or cloud stuff." 811 | ] 812 | }, 813 | { 814 | "cell_type": "code", 815 | "execution_count": null, 816 | "id": "3ae0d6ff-4471-4a45-bbe1-6bcd8a8d72a3", 817 | "metadata": {}, 818 | "outputs": [], 819 | "source": [ 820 | "df.to_csv(\"arxiv-matplotlib.csv\")" 821 | ] 822 | }, 823 | { 824 | "cell_type": "code", 825 | "execution_count": null, 826 | "id": "623becf0-a84d-4cf7-b719-883bfe60eef4", 827 | "metadata": {}, 828 | "outputs": [], 829 | "source": [ 830 | "!du -hs arxiv-matplotlib.csv" 831 | ] 832 | }, 833 | { 834 | "cell_type": "code", 835 | "execution_count": null, 836 | "id": "1755b7a4-8b92-441c-9083-2bc0b51e2f81", 837 | "metadata": {}, 838 | "outputs": [], 839 | "source": [ 840 | "df.to_parquet(\"arxiv-matplotlib.parquet\", compression=\"snappy\")" 841 | ] 842 | }, 843 | { 844 | "cell_type": "code", 845 | "execution_count": null, 846 | "id": "afc412d6-38b3-424e-8ca5-b4141d1b776f", 847 | "metadata": {}, 848 | "outputs": [], 849 | "source": [ 850 | "!du -hs arxiv-matplotlib.parquet" 851 | ] 852 | }, 853 | { 854 | "cell_type": "markdown", 855 | "id": "f637b60b-7051-4898-9c99-b3b436acd1ae", 856 | "metadata": {}, 857 | "source": [ 858 | "## Conclusion\n", 859 | "\n", 860 | "### Matplotlib + arXiv\n", 861 | "\n", 862 | "It's incredible to see the steady growth of Matplotlib across arXiv. It's worth noting that this is *all* papers, even from fields like theoretical mathematics that are unlikely to include computer generated plots. Is this matplotlib growing in popularity? Is it Python generally?\n", 863 | "\n", 864 | "For future work, we should break this down by subfield. The filenames actually contained the name of the field for a while, like \"hep-ex\" for \"high energy physics, experimental\", but it looks like arXiv stopped doing this at some point. My guess is that there is a list mapping filenames to fields somewhere though. The filenames are all in the Pandas dataframe / parquet dataset, so doing this analysis shouldn't require any scalable computing.\n", 865 | "\n", 866 | "### Dask + Coiled\n", 867 | "\n", 868 | "Dask and Coiled were built to make it easy to answer large questions. \n", 869 | "\n", 870 | "We started this notebook with some generic Python code. When we wanted to scale up we invoked Dask+Coiled, did some work, and then tore things down, all in about ten minutes. The problem of scale or \"big data\" didn't get in the way of us analyzing data and making a delightful discovery. \n", 871 | "\n", 872 | "This is exactly why these projects exist." 873 | ] 874 | } 875 | ], 876 | "metadata": { 877 | "kernelspec": { 878 | "display_name": "Python [conda env:play]", 879 | "language": "python", 880 | "name": "conda-env-play-py" 881 | }, 882 | "language_info": { 883 | "codemirror_mode": { 884 | "name": "ipython", 885 | "version": 3 886 | }, 887 | "file_extension": ".py", 888 | "mimetype": "text/x-python", 889 | "name": "python", 890 | "nbconvert_exporter": "python", 891 | "pygments_lexer": "ipython3", 892 | "version": "3.10.6" 893 | } 894 | }, 895 | "nbformat": 4, 896 | "nbformat_minor": 5 897 | } 898 | --------------------------------------------------------------------------------