Download counts for nteract

In [1]:
!pip install matplotlib seaborn
Collecting matplotlib
  Downloading https://files.pythonhosted.org/packages/49/b8/89dbd27f2fb171ce753bb56220d4d4f6dbc5fe32b95d8edc4415782ef07f/matplotlib-2.2.2-cp36-cp36m-manylinux1_x86_64.whl (12.6MB)
    100% |████████████████████████████████| 12.6MB 125kB/s 
Collecting seaborn
  Downloading https://files.pythonhosted.org/packages/a8/76/220ba4420459d9c4c9c9587c6ce607bf56c25b3d3d2de62056efe482dadc/seaborn-0.9.0-py3-none-any.whl (208kB)
    100% |████████████████████████████████| 215kB 4.6MB/s 
Requirement already satisfied: pytz in ./venv/lib/python3.6/site-packages (from matplotlib)
Requirement already satisfied: six>=1.10 in ./venv/lib/python3.6/site-packages (from matplotlib)
Requirement already satisfied: python-dateutil>=2.1 in ./venv/lib/python3.6/site-packages (from matplotlib)
Requirement already satisfied: numpy>=1.7.1 in ./venv/lib/python3.6/site-packages (from matplotlib)
Collecting cycler>=0.10 (from matplotlib)
  Downloading https://files.pythonhosted.org/packages/f7/d2/e07d3ebb2bd7af696440ce7e754c59dd546ffe1bbe732c8ab68b9c834e61/cycler-0.10.0-py2.py3-none-any.whl
Collecting pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 (from matplotlib)
  Downloading https://files.pythonhosted.org/packages/6a/8a/718fd7d3458f9fab8e67186b00abdd345b639976bc7fb3ae722e1b026a50/pyparsing-2.2.0-py2.py3-none-any.whl (56kB)
    100% |████████████████████████████████| 61kB 5.4MB/s 
Collecting kiwisolver>=1.0.1 (from matplotlib)
  Downloading https://files.pythonhosted.org/packages/69/a7/88719d132b18300b4369fbffa741841cfd36d1e637e1990f27929945b538/kiwisolver-1.0.1-cp36-cp36m-manylinux1_x86_64.whl (949kB)
    100% |████████████████████████████████| 952kB 1.5MB/s 
Collecting scipy>=0.14.0 (from seaborn)
  Downloading https://files.pythonhosted.org/packages/a8/0b/f163da98d3a01b3e0ef1cab8dd2123c34aee2bafbb1c5bffa354cc8a1730/scipy-1.1.0-cp36-cp36m-manylinux1_x86_64.whl (31.2MB)
    100% |████████████████████████████████| 31.2MB 49kB/s 
Requirement already satisfied: pandas>=0.15.2 in ./venv/lib/python3.6/site-packages (from seaborn)
Requirement already satisfied: setuptools in ./venv/lib/python3.6/site-packages (from kiwisolver>=1.0.1->matplotlib)
Installing collected packages: cycler, pyparsing, kiwisolver, matplotlib, scipy, seaborn
Successfully installed cycler-0.10.0 kiwisolver-1.0.1 matplotlib-2.2.2 pyparsing-2.2.0 scipy-1.1.0 seaborn-0.9.0
You are using pip version 9.0.1, however version 18.0 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [2]:
import IPython.display
import pandas as pd
/usr/local/lib/python3.6/importlib/_bootstrap.py:205: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
  return f(*args, **kwds)
/usr/local/lib/python3.6/importlib/_bootstrap.py:205: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
  return f(*args, **kwds)
In [3]:
import requests

# Note: 
data = requests.get('https://api.github.com/repos/nteract/nteract/releases').json()
In [4]:
print("{}:\n\t{}\n\t{}".format(
  data[0]['tag_name'],
  data[0]['assets'][0]['browser_download_url'],
  data[0]['assets'][0]['download_count']
))
v0.10.0:
	https://github.com/nteract/nteract/releases/download/v0.10.0/latest-linux.yml
	364

The releases API only has context of the filename, so we'll convert:

https://github.com/nteract/nteract/releases/download/v0.0.13/nteract-darwin-x64.zip

to

darwin-x64

Which means we're reliant on our release naming to keep this a nice consistent structure

In [5]:
def strip_off_release(browser_download_url):
    filename = browser_download_url.split('/')[-1]
    basename = filename.split('.')[0]
    system = basename.split('-')[1:]
    return "-".join(system)
In [6]:
releases = [
  {
    'version': x['tag_name'], 
    'counts': { strip_off_release(y['browser_download_url']): y['download_count'] for y in x['assets'] }
  } 
    for x in data
]
releases
Out[6]:
[{'version': 'v0.10.0',
  'counts': {'linux': 364, 'mac': 2286, '': 116, '0': 2, 'setup-0': 0}},
 {'version': 'v0.9.1',
  'counts': {'linux': 528, 'mac': 3390, '': 120, '0': 10, 'setup-0': 6}},
 {'version': 'v0.9.0',
  'counts': {'linux': 71, 'mac': 1300, '': 110, '0': 4, 'setup-0': 1}},
 {'version': 'v0.8.4',
  'counts': {'linux': 2466, 'mac': 14277, '': 335, '0': 61, 'setup-0': 16}},
 {'version': 'v0.8.3',
  'counts': {'linux': 159, 'mac': 1039, '': 106, '0': 3, 'setup-0': 1}},
 {'version': 'v0.8.0',
  'counts': {'linux': 40, 'mac': 239, '': 62, '0': 1, 'setup-0': 1}},
 {'version': 'v0.7.1',
  'counts': {'linux': 665, 'mac': 4531, '': 2, '0': 26, 'setup-0': 9}},
 {'version': 'v0.7.0',
  'counts': {'linux': 67, 'mac': 470, '': 2, '0': 1, 'setup-0': 1}},
 {'version': 'v0.6.2',
  'counts': {'linux': 328, 'mac': 1883, '': 6, '0': 8, 'setup-0': 7}},
 {'version': 'v0.6.1',
  'counts': {'linux': 1, 'mac': 3, '': 3, '0': 1, 'setup-0': 1}},
 {'version': 'v0.6.0',
  'counts': {'linux': 11, 'mac': 91, '': 1, '0': 1, 'setup-0': 2}},
 {'version': 'v0.5.5',
  'counts': {'linux': 422, 'mac': 2715, '': 3, '0': 7, 'setup-0': 5}},
 {'version': 'v0.5.4',
  'counts': {'linux': 60, 'mac': 401, '': 1, '0': 3, 'setup-0': 3}},
 {'version': 'v0.4.3',
  'counts': {'linux': 508, 'mac': 3443, '': 3, '0': 6, 'setup-0': 1680}},
 {'version': 'v0.4.2',
  'counts': {'linux': 94, 'mac': 240, '': 2, '0': 1, 'setup-0': 251}},
 {'version': 'v0.4.1',
  'counts': {'linux': 6, 'mac': 81, '': 1, '0': 1, 'setup-0': 69}},
 {'version': 'v0.4.0',
  'counts': {'linux': 89, 'mac': 565, '': 1, '0': 2, 'setup-0': 394}},
 {'version': 'v0.3.4',
  'counts': {'linux': 445, 'mac': 3376, '': 282, '0': 12, 'setup-0': 1472}},
 {'version': 'v0.3.3', 'counts': {'mac': 321, '': 33, '0': 3, 'setup-0': 253}},
 {'version': 'v0.3.2', 'counts': {'mac': 93, '': 7, '0': 1, 'setup-0': 116}},
 {'version': 'v0.3.1',
  'counts': {'mac': 272, '': 204, '0': 3, 'setup-0': 161}},
 {'version': 'v0.3.0', 'counts': {'mac': 9, '': 32, '0': 2, 'setup-0': 6}},
 {'version': 'v0.2.0', 'counts': {'mac': 9, '': 455, '0': 9}},
 {'version': 'v0.1.0', 'counts': {'0': 44, '': 1736}},
 {'version': 'v0.0.15', 'counts': {'0': 376}},
 {'version': 'v0.0.14', 'counts': {'0': 264, '': 339}},
 {'version': 'v0.0.13',
  'counts': {'darwin-x64': 168, 'linux-x64': 228, 'win32-x64': 106}},
 {'version': 'v0.0.12', 'counts': {'darwin-x64': 118}},
 {'version': 'v0.0.11', 'counts': {'darwin-x64': 8}},
 {'version': 'v0.0.10', 'counts': {'darwin-x64': 17, 'linux-x64': 13}}]
In [7]:
versions = []
frames = []

for release in releases:
    versions.append(release['version'])
    frames.append(pd.DataFrame.from_dict(release['counts'], orient='index'))

df = pd.concat(frames, keys=versions).reset_index()
df.columns = ['version', 'os', 'count']
df['os'] = df.os.replace('os-x', 'darwin-x64')
df
Out[7]:
version os count
0 v0.10.0 linux 364
1 v0.10.0 mac 2286
2 v0.10.0 116
3 v0.10.0 0 2
4 v0.10.0 setup-0 0
5 v0.9.1 linux 528
6 v0.9.1 mac 3390
7 v0.9.1 120
8 v0.9.1 0 10
9 v0.9.1 setup-0 6
10 v0.9.0 linux 71
11 v0.9.0 mac 1300
12 v0.9.0 110
13 v0.9.0 0 4
14 v0.9.0 setup-0 1
15 v0.8.4 linux 2466
16 v0.8.4 mac 14277
17 v0.8.4 335
18 v0.8.4 0 61
19 v0.8.4 setup-0 16
20 v0.8.3 linux 159
21 v0.8.3 mac 1039
22 v0.8.3 106
23 v0.8.3 0 3
24 v0.8.3 setup-0 1
25 v0.8.0 linux 40
26 v0.8.0 mac 239
27 v0.8.0 62
28 v0.8.0 0 1
29 v0.8.0 setup-0 1
... ... ... ...
91 v0.3.3 33
92 v0.3.3 0 3
93 v0.3.3 setup-0 253
94 v0.3.2 mac 93
95 v0.3.2 7
96 v0.3.2 0 1
97 v0.3.2 setup-0 116
98 v0.3.1 mac 272
99 v0.3.1 204
100 v0.3.1 0 3
101 v0.3.1 setup-0 161
102 v0.3.0 mac 9
103 v0.3.0 32
104 v0.3.0 0 2
105 v0.3.0 setup-0 6
106 v0.2.0 mac 9
107 v0.2.0 455
108 v0.2.0 0 9
109 v0.1.0 0 44
110 v0.1.0 1736
111 v0.0.15 0 376
112 v0.0.14 0 264
113 v0.0.14 339
114 v0.0.13 darwin-x64 168
115 v0.0.13 linux-x64 228
116 v0.0.13 win32-x64 106
117 v0.0.12 darwin-x64 118
118 v0.0.11 darwin-x64 8
119 v0.0.10 darwin-x64 17
120 v0.0.10 linux-x64 13

121 rows × 3 columns

It would be really interesting to know how these counts change over time.

In [8]:
from distutils.version import LooseVersion

versions = set(df.version.values.tolist())
versions = sorted(versions, key=LooseVersion)
In [9]:
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
%config InlineBackend.figure_format = 'retina'

with sns.color_palette("colorblind", len(versions)):
    fig = plt.figure(figsize=(10, 6))
    ax = fig.add_subplot(1, 1, 1)
    ax = sns.barplot(x='version', y="count", hue="os", data=df, order=versions)
    ax.set_xticklabels(versions, rotation=30)
    ax.set(xlabel='Version', ylabel='Count')
    plt.legend(bbox_to_anchor=(1, 1), loc=2, borderaxespad=0)
    plt.show()