diff --git a/.github/workflows/get_pypi_stats.yml b/.github/workflows/get_pypi_stats.yml
new file mode 100644
index 00000000..33bbaea3
--- /dev/null
+++ b/.github/workflows/get_pypi_stats.yml
@@ -0,0 +1,40 @@
+# adapted from icepyx's workflow:
+# https://github.com/icesat2py/icepyx/blob/6c187bd35358d88083a5163d3491118aa1aad45c/.github/workflows/get_pypi_stats.yml
+
+name: Get PyPi Stats
+on:
+ schedule:
+ # runs once a month on the first: "min hr day-of-month month day-of-week"
+ - cron: "00 12 1 * *"
+ # Trigger manually from the Actions tab
+ workflow_dispatch:
+
+jobs:
+ # This workflow contains a single job called "pypi_stats"
+ pypi_stats:
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+ if: github.repository_owner == 'polartoolkit'
+
+ # Steps represent a sequence of tasks that will be executed as part of the job
+ steps:
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - uses: actions/checkout@v3
+ with:
+ ref: "traffic"
+
+ # Calculates pypi stats and clones and stores in CSV file
+ - name: Update pypi stats files
+ run: |
+ pip install -U pip
+ pip install pypistats pandas seaborn matplotlib
+ python ./docs/tracking/stats.py
+
+ # Commits files to repository
+ - name: Commit changes
+ uses: EndBug/add-and-commit@v9
+ with:
+ author_name: pypistats
+ message: "Pypi stats auto-update"
+ add: "./docs/tracking/*"
+# add: "./pypistats/*"
diff --git a/docs/tracking/downloads.png b/docs/tracking/downloads.png
new file mode 100644
index 00000000..d9b24bbe
Binary files /dev/null and b/docs/tracking/downloads.png differ
diff --git a/docs/tracking/downloads_data.csv b/docs/tracking/downloads_data.csv
new file mode 100644
index 00000000..5907a69c
--- /dev/null
+++ b/docs/tracking/downloads_data.csv
@@ -0,0 +1,265 @@
+category,date,downloads
+with_mirrors,2023-08-02,41
+with_mirrors,2023-08-03,20
+with_mirrors,2023-08-04,40
+with_mirrors,2023-08-05,42
+with_mirrors,2023-08-06,38
+with_mirrors,2023-08-08,43
+with_mirrors,2023-08-09,110
+with_mirrors,2023-08-12,7
+with_mirrors,2023-08-13,46
+with_mirrors,2023-08-16,1
+with_mirrors,2023-08-17,2
+with_mirrors,2023-08-18,20
+with_mirrors,2023-08-19,59
+with_mirrors,2023-08-20,3
+with_mirrors,2023-08-21,20
+with_mirrors,2023-08-22,34
+with_mirrors,2023-08-23,95
+with_mirrors,2023-08-24,26
+with_mirrors,2023-08-25,24
+with_mirrors,2023-08-26,31
+with_mirrors,2023-08-27,20
+with_mirrors,2023-08-28,9
+with_mirrors,2023-08-29,20
+with_mirrors,2023-08-30,17
+with_mirrors,2023-08-31,20
+with_mirrors,2023-09-01,6
+with_mirrors,2023-09-02,21
+with_mirrors,2023-09-04,4
+with_mirrors,2023-09-05,20
+with_mirrors,2023-09-06,20
+with_mirrors,2023-09-08,42
+with_mirrors,2023-09-09,26
+with_mirrors,2023-09-12,26
+with_mirrors,2023-09-13,21
+with_mirrors,2023-09-14,46
+with_mirrors,2023-09-17,1
+with_mirrors,2023-09-18,1
+with_mirrors,2023-09-19,43
+with_mirrors,2023-09-20,61
+with_mirrors,2023-09-21,7
+with_mirrors,2023-09-22,8
+with_mirrors,2023-09-23,20
+with_mirrors,2023-09-24,21
+with_mirrors,2023-09-25,26
+with_mirrors,2023-09-26,21
+with_mirrors,2023-09-27,27
+with_mirrors,2023-09-28,9
+with_mirrors,2023-09-29,2
+with_mirrors,2023-09-30,11
+with_mirrors,2023-10-02,22
+with_mirrors,2023-10-03,1
+with_mirrors,2023-10-04,70
+with_mirrors,2023-10-05,41
+with_mirrors,2023-10-06,7
+with_mirrors,2023-10-07,22
+with_mirrors,2023-10-08,2
+with_mirrors,2023-10-09,1
+with_mirrors,2023-10-10,4
+with_mirrors,2023-10-11,24
+with_mirrors,2023-10-12,24
+with_mirrors,2023-10-14,2
+with_mirrors,2023-10-17,42
+with_mirrors,2023-10-18,10
+with_mirrors,2023-10-19,1
+with_mirrors,2023-10-20,47
+with_mirrors,2023-10-21,70
+with_mirrors,2023-10-22,60
+with_mirrors,2023-10-23,36
+with_mirrors,2023-10-24,22
+with_mirrors,2023-10-25,91
+with_mirrors,2023-10-26,60
+with_mirrors,2023-10-27,18
+with_mirrors,2023-10-28,2
+with_mirrors,2023-10-29,20
+with_mirrors,2023-10-30,3
+with_mirrors,2023-10-31,2
+with_mirrors,2023-11-01,49
+with_mirrors,2023-11-02,21
+with_mirrors,2023-11-03,18
+with_mirrors,2023-11-04,62
+with_mirrors,2023-11-06,1
+with_mirrors,2023-11-07,4
+with_mirrors,2023-11-08,44
+with_mirrors,2023-11-09,21
+with_mirrors,2023-11-10,21
+with_mirrors,2023-11-11,20
+with_mirrors,2023-11-12,46
+with_mirrors,2023-11-13,4
+with_mirrors,2023-11-14,19
+with_mirrors,2023-11-15,32
+with_mirrors,2023-11-16,26
+with_mirrors,2023-11-18,28
+with_mirrors,2023-11-21,39
+with_mirrors,2023-11-22,81
+with_mirrors,2023-11-23,135
+with_mirrors,2023-11-24,64
+with_mirrors,2023-11-25,28
+with_mirrors,2023-11-26,9
+with_mirrors,2023-11-27,40
+with_mirrors,2023-11-28,52
+with_mirrors,2023-11-29,57
+with_mirrors,2023-11-30,34
+with_mirrors,2023-12-01,43
+with_mirrors,2023-12-02,20
+with_mirrors,2023-12-03,6
+with_mirrors,2023-12-04,33
+with_mirrors,2023-12-05,40
+with_mirrors,2023-12-06,21
+with_mirrors,2023-12-07,2
+with_mirrors,2023-12-08,40
+with_mirrors,2023-12-09,22
+with_mirrors,2023-12-10,145
+with_mirrors,2023-12-11,46
+with_mirrors,2023-12-12,43
+with_mirrors,2023-12-13,32
+with_mirrors,2023-12-14,74
+with_mirrors,2023-12-15,14
+with_mirrors,2023-12-16,61
+with_mirrors,2023-12-17,29
+with_mirrors,2023-12-18,12
+with_mirrors,2023-12-19,48
+with_mirrors,2023-12-20,6
+with_mirrors,2023-12-21,31
+with_mirrors,2023-12-22,22
+with_mirrors,2023-12-23,15
+with_mirrors,2023-12-24,24
+with_mirrors,2023-12-25,5
+with_mirrors,2023-12-26,23
+with_mirrors,2023-12-27,3
+with_mirrors,2023-12-28,14
+with_mirrors,2023-12-29,28
+with_mirrors,2023-12-30,2
+with_mirrors,2023-12-31,22
+with_mirrors,2024-01-02,13
+with_mirrors,2024-01-03,2
+with_mirrors,2024-01-05,20
+with_mirrors,2024-01-07,1
+with_mirrors,2024-01-08,52
+with_mirrors,2024-01-09,29
+with_mirrors,2024-01-10,18
+with_mirrors,2024-01-11,30
+with_mirrors,2024-01-12,80
+with_mirrors,2024-01-13,17
+with_mirrors,2024-01-14,35
+with_mirrors,2024-01-15,25
+with_mirrors,2024-01-16,3
+with_mirrors,2024-01-17,47
+with_mirrors,2024-01-19,42
+with_mirrors,2024-01-20,11
+with_mirrors,2024-01-21,22
+with_mirrors,2024-01-22,32
+with_mirrors,2024-01-23,25
+with_mirrors,2024-01-24,7
+with_mirrors,2024-01-25,24
+with_mirrors,2024-01-26,177
+with_mirrors,2024-01-26,336
+with_mirrors,2024-01-27,28
+with_mirrors,2024-01-27,49
+with_mirrors,2024-01-28,11
+with_mirrors,2024-01-28,57
+with_mirrors,2024-01-29,139
+with_mirrors,2024-01-29,162
+without_mirrors,2023-08-02,1
+without_mirrors,2023-08-09,7
+without_mirrors,2023-08-12,1
+without_mirrors,2023-08-16,1
+without_mirrors,2023-08-19,2
+without_mirrors,2023-08-20,3
+without_mirrors,2023-08-23,3
+without_mirrors,2023-08-26,11
+without_mirrors,2023-08-30,11
+without_mirrors,2023-09-04,1
+without_mirrors,2023-09-06,20
+without_mirrors,2023-09-12,6
+without_mirrors,2023-09-14,2
+without_mirrors,2023-09-17,1
+without_mirrors,2023-09-18,1
+without_mirrors,2023-09-19,3
+without_mirrors,2023-09-22,1
+without_mirrors,2023-09-26,12
+without_mirrors,2023-09-27,2
+without_mirrors,2023-09-28,3
+without_mirrors,2023-09-29,2
+without_mirrors,2023-09-30,1
+without_mirrors,2023-10-03,1
+without_mirrors,2023-10-04,20
+without_mirrors,2023-10-07,1
+without_mirrors,2023-10-08,2
+without_mirrors,2023-10-11,20
+without_mirrors,2023-10-14,1
+without_mirrors,2023-10-19,1
+without_mirrors,2023-10-20,7
+without_mirrors,2023-10-23,1
+without_mirrors,2023-10-24,2
+without_mirrors,2023-10-25,21
+without_mirrors,2023-10-27,2
+without_mirrors,2023-10-28,2
+without_mirrors,2023-10-30,3
+without_mirrors,2023-10-31,1
+without_mirrors,2023-11-01,28
+without_mirrors,2023-11-02,1
+without_mirrors,2023-11-04,2
+without_mirrors,2023-11-06,1
+without_mirrors,2023-11-10,1
+without_mirrors,2023-11-12,20
+without_mirrors,2023-11-13,4
+without_mirrors,2023-11-14,9
+without_mirrors,2023-11-18,8
+without_mirrors,2023-11-21,19
+without_mirrors,2023-11-22,81
+without_mirrors,2023-11-23,135
+without_mirrors,2023-11-24,37
+without_mirrors,2023-11-25,8
+without_mirrors,2023-11-26,9
+without_mirrors,2023-11-27,39
+without_mirrors,2023-11-28,12
+without_mirrors,2023-11-29,17
+without_mirrors,2023-11-30,14
+without_mirrors,2023-12-01,1
+without_mirrors,2023-12-04,23
+without_mirrors,2023-12-06,21
+without_mirrors,2023-12-07,2
+without_mirrors,2023-12-09,1
+without_mirrors,2023-12-10,57
+without_mirrors,2023-12-11,15
+without_mirrors,2023-12-12,1
+without_mirrors,2023-12-13,18
+without_mirrors,2023-12-14,2
+without_mirrors,2023-12-15,2
+without_mirrors,2023-12-16,3
+without_mirrors,2023-12-17,1
+without_mirrors,2023-12-18,8
+without_mirrors,2023-12-20,4
+without_mirrors,2023-12-21,5
+without_mirrors,2023-12-23,3
+without_mirrors,2023-12-25,3
+without_mirrors,2023-12-26,1
+without_mirrors,2023-12-27,2
+without_mirrors,2023-12-28,12
+without_mirrors,2023-12-29,2
+without_mirrors,2024-01-02,9
+without_mirrors,2024-01-03,2
+without_mirrors,2024-01-05,10
+without_mirrors,2024-01-07,1
+without_mirrors,2024-01-08,4
+without_mirrors,2024-01-10,4
+without_mirrors,2024-01-12,14
+without_mirrors,2024-01-13,6
+without_mirrors,2024-01-14,5
+without_mirrors,2024-01-15,3
+without_mirrors,2024-01-16,3
+without_mirrors,2024-01-17,3
+without_mirrors,2024-01-20,1
+without_mirrors,2024-01-22,10
+without_mirrors,2024-01-23,1
+without_mirrors,2024-01-24,3
+without_mirrors,2024-01-26,86
+without_mirrors,2024-01-26,235
+without_mirrors,2024-01-27,11
+without_mirrors,2024-01-27,18
+without_mirrors,2024-01-28,3
+without_mirrors,2024-01-28,5
+without_mirrors,2024-01-29,62
+without_mirrors,2024-01-29,63
diff --git a/docs/tracking/gather-targeted-package-metrics.ipynb b/docs/tracking/gather-targeted-package-metrics.ipynb
new file mode 100644
index 00000000..6d540a4b
--- /dev/null
+++ b/docs/tracking/gather-targeted-package-metrics.ipynb
@@ -0,0 +1,625 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "8f88d59f-3c0d-4d33-908e-0381578065dd",
+ "metadata": {},
+ "source": [
+ "# Gather Package Download Metrics\n",
+ "\n",
+ "## Setup\n",
+ "\n",
+ "Use of this notebook involves setup via https://github.com/ofek/pypinfo#installation. An environment variable is expected for pypinfo to work properly. For example: `export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "fef169d9-a9ce-4b80-af16-92b02375e24a",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "import json\n",
+ "\n",
+ "import pandas as pd"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "5f6176ba-70a7-40c9-afe9-fa14767dfc02",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['polartoolkit']"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "loi_target_projects = [\n",
+ " # \"antarctic_plots\",\n",
+ " \"polartoolkit\",\n",
+ "]\n",
+ "loi_target_projects"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "fe7448a3-190d-44f4-bfce-5a1a862a4a0f",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " project | \n",
+ " date | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " polartoolkit | \n",
+ " 2021-01-01 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " project date\n",
+ "0 polartoolkit 2021-01-01"
+ ]
+ },
+ "execution_count": 15,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df = pd.DataFrame(data={\"project\": [\"polartoolkit\"], \"date\": [\"2021-01-01\"]})\n",
+ "df[\"date\"] = pd.to_datetime(df.date)\n",
+ "df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 54,
+ "id": "edd46462",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# project = \"polartoolkit\"\n",
+ "project = \"antarctic-plots\"\n",
+ "start_date = \"2021-01-01\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 61,
+ "id": "5c726c40",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "666"
+ ]
+ },
+ "execution_count": 61,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# gather total downloads\n",
+ "total_downloads = json.loads(\n",
+ " subprocess.run(\n",
+ " [\n",
+ " \"pypinfo\",\n",
+ " \"--json\",\n",
+ " \"--start-date\",\n",
+ " start_date,\n",
+ " \"--limit\",\n",
+ " \"1000\",\n",
+ " project,\n",
+ " ],\n",
+ " capture_output=True,\n",
+ " check=True,\n",
+ " ).stdout\n",
+ ")[\"rows\"][0][\"download_count\"]\n",
+ "\n",
+ "total_downloads"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 59,
+ "id": "9dfba3aa",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " download_count | \n",
+ " download_month | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 74 | \n",
+ " 2024-01 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 83 | \n",
+ " 2023-12 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 332 | \n",
+ " 2023-11 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 9 | \n",
+ " 2023-10 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 12 | \n",
+ " 2023-09 | \n",
+ "
\n",
+ " \n",
+ " 5 | \n",
+ " 7 | \n",
+ " 2023-08 | \n",
+ "
\n",
+ " \n",
+ " 6 | \n",
+ " 9 | \n",
+ " 2023-07 | \n",
+ "
\n",
+ " \n",
+ " 7 | \n",
+ " 30 | \n",
+ " 2023-06 | \n",
+ "
\n",
+ " \n",
+ " 8 | \n",
+ " 10 | \n",
+ " 2023-05 | \n",
+ "
\n",
+ " \n",
+ " 9 | \n",
+ " 1 | \n",
+ " 2023-04 | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " 26 | \n",
+ " 2023-03 | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " 7 | \n",
+ " 2023-02 | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " 2 | \n",
+ " 2023-01 | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " 6 | \n",
+ " 2022-12 | \n",
+ "
\n",
+ " \n",
+ " 14 | \n",
+ " 7 | \n",
+ " 2022-11 | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " 4 | \n",
+ " 2022-10 | \n",
+ "
\n",
+ " \n",
+ " 16 | \n",
+ " 24 | \n",
+ " 2022-09 | \n",
+ "
\n",
+ " \n",
+ " 17 | \n",
+ " 4 | \n",
+ " 2022-08 | \n",
+ "
\n",
+ " \n",
+ " 18 | \n",
+ " 19 | \n",
+ " 2022-07 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " download_count download_month\n",
+ "0 74 2024-01\n",
+ "1 83 2023-12\n",
+ "2 332 2023-11\n",
+ "3 9 2023-10\n",
+ "4 12 2023-09\n",
+ "5 7 2023-08\n",
+ "6 9 2023-07\n",
+ "7 30 2023-06\n",
+ "8 10 2023-05\n",
+ "9 1 2023-04\n",
+ "10 26 2023-03\n",
+ "11 7 2023-02\n",
+ "12 2 2023-01\n",
+ "13 6 2022-12\n",
+ "14 7 2022-11\n",
+ "15 4 2022-10\n",
+ "16 24 2022-09\n",
+ "17 4 2022-08\n",
+ "18 19 2022-07"
+ ]
+ },
+ "execution_count": 59,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# gather downloads by year and month, ordered by month\n",
+ "output = json.loads(\n",
+ " subprocess.run(\n",
+ " [\n",
+ " \"pypinfo\",\n",
+ " \"--json\",\n",
+ " \"--start-date\",\n",
+ " start_date,\n",
+ " \"--limit\",\n",
+ " \"1000\",\n",
+ " \"--order\",\n",
+ " \"download_month\",\n",
+ " project,\n",
+ " \"month\",\n",
+ " ],\n",
+ " capture_output=True,\n",
+ " check=True,\n",
+ " ).stdout\n",
+ ")\n",
+ "\n",
+ "monthly_downloads = pd.DataFrame(output[\"rows\"])\n",
+ "monthly_downloads"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 63,
+ "id": "c3a3452b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " country | \n",
+ " download_count | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " US | \n",
+ " 524 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " CN | \n",
+ " 29 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " GB | \n",
+ " 20 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " HK | \n",
+ " 16 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " DE | \n",
+ " 11 | \n",
+ "
\n",
+ " \n",
+ " 5 | \n",
+ " FR | \n",
+ " 11 | \n",
+ "
\n",
+ " \n",
+ " 6 | \n",
+ " NZ | \n",
+ " 10 | \n",
+ "
\n",
+ " \n",
+ " 7 | \n",
+ " IN | \n",
+ " 6 | \n",
+ "
\n",
+ " \n",
+ " 8 | \n",
+ " BR | \n",
+ " 5 | \n",
+ "
\n",
+ " \n",
+ " 9 | \n",
+ " NL | \n",
+ " 5 | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " RU | \n",
+ " 4 | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " CA | \n",
+ " 3 | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " AU | \n",
+ " 3 | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " ID | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " 14 | \n",
+ " FI | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " NO | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 16 | \n",
+ " AT | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 17 | \n",
+ " CO | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 18 | \n",
+ " IR | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 19 | \n",
+ " TW | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 20 | \n",
+ " AE | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 21 | \n",
+ " TR | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 22 | \n",
+ " ES | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 23 | \n",
+ " DZ | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 24 | \n",
+ " JP | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 25 | \n",
+ " UY | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 26 | \n",
+ " IE | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 27 | \n",
+ " KR | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 28 | \n",
+ " DK | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 29 | \n",
+ " BG | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 30 | \n",
+ " EG | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " country download_count\n",
+ "0 US 524\n",
+ "1 CN 29\n",
+ "2 GB 20\n",
+ "3 HK 16\n",
+ "4 DE 11\n",
+ "5 FR 11\n",
+ "6 NZ 10\n",
+ "7 IN 6\n",
+ "8 BR 5\n",
+ "9 NL 5\n",
+ "10 RU 4\n",
+ "11 CA 3\n",
+ "12 AU 3\n",
+ "13 ID 2\n",
+ "14 FI 1\n",
+ "15 NO 1\n",
+ "16 AT 1\n",
+ "17 CO 1\n",
+ "18 IR 1\n",
+ "19 TW 1\n",
+ "20 AE 1\n",
+ "21 TR 1\n",
+ "22 ES 1\n",
+ "23 DZ 1\n",
+ "24 JP 1\n",
+ "25 UY 1\n",
+ "26 IE 1\n",
+ "27 KR 1\n",
+ "28 DK 1\n",
+ "29 BG 1\n",
+ "30 EG 1"
+ ]
+ },
+ "execution_count": 63,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# gather downloads by country\n",
+ "output = json.loads(\n",
+ " subprocess.run(\n",
+ " [\n",
+ " \"pypinfo\",\n",
+ " \"--json\",\n",
+ " \"--start-date\",\n",
+ " start_date,\n",
+ " \"--limit\",\n",
+ " \"1000\",\n",
+ " project,\n",
+ " \"country\",\n",
+ " ],\n",
+ " capture_output=True,\n",
+ " check=True,\n",
+ " ).stdout\n",
+ ")\n",
+ "\n",
+ "country_downloads = pd.DataFrame(output[\"rows\"])\n",
+ "country_downloads"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.0"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/tracking/stats.py b/docs/tracking/stats.py
new file mode 100644
index 00000000..d5fdac64
--- /dev/null
+++ b/docs/tracking/stats.py
@@ -0,0 +1,96 @@
+# package = "antarctic-plots"
+# # package = "polartoolkit"
+# # Show overall downloads over time, excluding mirrors
+# data = pypistats.overall(package, total=True, format="pandas")
+# print(data)
+# data = data.groupby("category").get_group("without_mirrors").sort_values("date")
+
+# chart = data.plot(x="date", y="downloads", figsize=(10, 2))
+# chart.figure.savefig("overall.png")
+
+"""
+Adapted from the package icepyx: https://github.com/icesat2py/icepyx
+
+https://github.com/icesat2py/icepyx/blob/6c187bd35358d88083a5163d3491118aa1aad45c/doc/source/tracking/pypistats/get_pypi_stats.py
+"""
+
+import pathlib
+
+import matplotlib.pyplot as plt
+import pandas as pd
+import pypistats
+import seaborn as sns
+
+sns.set_theme()
+
+cwd = pathlib.Path.cwd()
+
+trackpath = f"{cwd}/docs/tracking/"
+downloadfn = "downloads_data.csv"
+sysdownloadfn = "sys_downloads_data.csv"
+
+antarctic_plots_downloads = pypistats.overall(
+ "antarctic_plots", total=True, format="pandas"
+).drop(columns=["percent"])
+
+polartoolkit_downloads = pypistats.overall(
+ "polartoolkit", total=True, format="pandas"
+).drop(columns=["percent"])
+
+downloads = pd.concat([antarctic_plots_downloads, polartoolkit_downloads])
+
+downloads = downloads[downloads.category != "Total"]
+
+try:
+ exist_downloads = pd.read_csv(trackpath + downloadfn) # .drop(columns=['percent'])
+ # exist_downloads = exist_downloads[exist_downloads.category != "Total"]
+ dl_data = downloads.merge(
+ exist_downloads, how="outer", on=["category", "date", "downloads"]
+ )
+except NameError:
+ dl_data = downloads
+
+total_downloads = dl_data.downloads.sum()
+
+dl_data.sort_values(["category", "date"], ignore_index=True).to_csv(
+ trackpath + downloadfn, index=False
+)
+
+dl_data = dl_data.groupby("category").get_group("without_mirrors").sort_values("date")
+
+# sns.set(rc={'figure.figsize':(10,2)})
+# fig = sns.lineplot(data=dl_data, x="date", y="downloads",)
+# fig.set_xticks(range(len(dl_data.date)), )#labels=range(2011, 2019))
+# fig.figure.savefig(trackpath + "downloads.png")
+
+
+# fig, ax = plt.subplots(figsize=(10, 2))
+# ax .plot(
+# dl_data.date,
+# dl_data.downloads,
+# label="Number of PyPI Downloads",
+# )
+# ax.set_xlabel('Date')
+# ax.set_ylabel('Downloads')
+# plt.savefig(trackpath + "downloads.png")
+
+
+chart = dl_data.plot(
+ x="date",
+ y="downloads",
+ figsize=(10, 2),
+ legend=False,
+)
+
+chart.set_ylabel("Downloads")
+
+chart.set_title(
+ "PyPI Downloads of PolarToolkit",
+ fontdict={"fontsize": "large"},
+)
+
+chart.text(
+ 0, 1, f"{total_downloads} total downloads", va="top", transform=plt.gca().transAxes
+)
+
+chart.figure.savefig(trackpath + "downloads.png")
diff --git a/docs/tracking/usage_stats.md b/docs/tracking/usage_stats.md
new file mode 100644
index 00000000..18f950cc
--- /dev/null
+++ b/docs/tracking/usage_stats.md
@@ -0,0 +1,15 @@
+## PyPI Downloads
+
+Non-mirrored downloads of polartoolkit from the
+`Python Package Index `\_ (e.g. using
+`pip install polartoolkit`).
+
+![Download stats](downloads.png)
+
+## GitHub Traffic
+
+The GitHub repository has automatic tracking of cloning and traffic to the repo
+website, which can be found
+[here](https://github.com/mdtanker/polartoolkit/graphs/traffic).
+
+## Documentation Views
diff --git a/pyproject.toml b/pyproject.toml
index 6ee96e63..e6fd2330 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -50,6 +50,7 @@ dependencies = [
"zarr",
"python-dotenv",
"nptyping",
+ "requests",
]
[project.optional-dependencies]