Skip to content

Commit 6937639

Browse files
authored
Reorganize slides images to avoid GitHub raw issues (#55)
1 parent c0dbd3a commit 6937639

26 files changed

+100
-99
lines changed

.github/workflows/publish-slides.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ jobs:
3434
run: ./slides/generate_slides.sh regular
3535
- name: Package files
3636
run: |
37-
mkdir public && \
37+
mkdir -p public/media && \
38+
cp slides/media/* public/media/ && \
3839
cp slides/html/workshop.slides.html public/index.html;
3940
- name: Upload artifact
4041
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0

notebooks/1-getting_started_with_matplotlib.ipynb

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,7 +1596,7 @@
15961596
],
15971597
"source": [
15981598
"stackoverflow_monthly.matplotlib.plot(\n",
1599-
" figsize=(8, 2), xlabel='creation date', ylabel='total questions', \n",
1599+
" figsize=(8, 2), xlabel='creation date', ylabel='total questions',\n",
16001600
" title='Matplotlib Questions per Month\\n(since the creation of Stack Overflow)'\n",
16011601
")"
16021602
]
@@ -1729,7 +1729,7 @@
17291729
"The `Figure` object is the container for all components of our visualization. It contains one or more `Axes` objects, which can be thought of as the (sub)plots, as well as other [*Artists*](https://matplotlib.org/stable/tutorials/intermediate/artists.html), which draw on the plot canvas (x-axis, y-axis, legend, lines, etc.). The following image from the Matplotlib documentation illustrates the different components of a figure:\n",
17301730
"\n",
17311731
"<div style=\"text-align: center;\">\n",
1732-
" <img width=\"40%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/figure_anatomy.svg\" alt=\"Matplotlib figure anatomy\" style=\"min-width: 400px\">\n",
1732+
" <img width=\"40%\" src=\"../slides/media/figure_anatomy.svg\" alt=\"Matplotlib figure anatomy\" style=\"min-width: 400px\">\n",
17331733
" <div><small><em><a href=\"https://matplotlib.org/stable/tutorials/introductory/quick_start.html#parts-of-a-figure\">Source</a></em></small></div>\n",
17341734
"</div>"
17351735
]
@@ -5705,7 +5705,7 @@
57055705
],
57065706
"source": [
57075707
"ax = stackoverflow_monthly.matplotlib.plot(\n",
5708-
" figsize=(8, 2), xlabel='creation date', ylabel='total questions', \n",
5708+
" figsize=(8, 2), xlabel='creation date', ylabel='total questions',\n",
57095709
" title='Matplotlib Questions per Month\\n(since the creation of Stack Overflow)'\n",
57105710
")\n",
57115711
"ax.set_ylim(0, None) # this can also be done with pandas\n",
@@ -21035,7 +21035,7 @@
2103521035
"fig, ax = plt.subplots(figsize=(8, 2))\n",
2103621036
"ax.plot(avgs.index, avgs.matplotlib)\n",
2103721037
"ax.fill_between(\n",
21038-
" avgs.index, avgs.matplotlib - 2 * stds.matplotlib, \n",
21038+
" avgs.index, avgs.matplotlib - 2 * stds.matplotlib,\n",
2103921039
" avgs.matplotlib + 2 * stds.matplotlib, alpha=0.25\n",
2104021040
")"
2104121041
]
@@ -33816,7 +33816,7 @@
3381633816
"fig, ax = plt.subplots(figsize=(8, 2))\n",
3381733817
"ax.plot(avgs.index, avgs.matplotlib)\n",
3381833818
"ax.fill_between(\n",
33819-
" avgs.index, avgs.matplotlib - 2 * stds.matplotlib, \n",
33819+
" avgs.index, avgs.matplotlib - 2 * stds.matplotlib,\n",
3382033820
" avgs.matplotlib + 2 * stds.matplotlib, alpha=0.25\n",
3382133821
")\n",
3382233822
"\n",
@@ -34590,7 +34590,7 @@
3459034590
"fig, ax = plt.subplots(figsize=(9, 3))\n",
3459134591
"ax.plot(\n",
3459234592
" stackoverflow_monthly.index,\n",
34593-
" stackoverflow_monthly.matplotlib, \n",
34593+
" stackoverflow_monthly.matplotlib,\n",
3459434594
" 'ok', label=None, alpha=0.5\n",
3459534595
")"
3459634596
]
@@ -35395,7 +35395,7 @@
3539535395
"source": [
3539635396
"fig, ax = plt.subplots(figsize=(9, 3))\n",
3539735397
"ax.plot(\n",
35398-
" x_axis_dates, stackoverflow_monthly.matplotlib, \n",
35398+
" x_axis_dates, stackoverflow_monthly.matplotlib,\n",
3539935399
" 'ok', label=None, alpha=0.5\n",
3540035400
")"
3540135401
]
@@ -44476,7 +44476,7 @@
4447644476
"source": [
4447744477
"fig, ax = plt.subplots(figsize=(12, 3))\n",
4447844478
"ax.stackplot(\n",
44479-
" mdates.date2num(top_libraries_monthly.index), top_libraries_monthly.to_numpy().T, \n",
44479+
" mdates.date2num(top_libraries_monthly.index), top_libraries_monthly.to_numpy().T,\n",
4448044480
" labels=top_libraries_monthly.columns\n",
4448144481
")\n",
4448244482
"ax.set(xlabel='', ylabel='tagged questions', title='Stack Overflow Questions per Month')\n",
@@ -44509,7 +44509,7 @@
4450944509
" fig, ax = plt.subplots(figsize=(12, 3))\n",
4451044510
" ax.stackplot(\n",
4451144511
" mdates.date2num(data.index),\n",
44512-
" data.to_numpy().T, \n",
44512+
" data.to_numpy().T,\n",
4451344513
" labels=data.columns\n",
4451444514
" )\n",
4451544515
" ax.set(\n",
@@ -47195,7 +47195,7 @@
4719547195
" fig, ax = plt.subplots(figsize=(12, 3))\n",
4719647196
" ax.stackplot(\n",
4719747197
" mdates.date2num(data.index),\n",
47198-
" data.to_numpy().T, \n",
47198+
" data.to_numpy().T,\n",
4719947199
" labels=data.columns\n",
4720047200
" )\n",
4720147201
" ax.set(\n",
@@ -49833,7 +49833,7 @@
4983349833
"import datetime as dt\n",
4983449834
"\n",
4983549835
"ax = area_plot(top_libraries_monthly)\n",
49836-
" \n",
49836+
"\n",
4983749837
"# mark when seaborn was created\n",
4983849838
"seaborn_released = dt.date(2013, 10, 28)\n",
4983949839
"ax.axvline(seaborn_released, ymax=0.6, color='gray', linestyle='dashed')\n",
@@ -55159,8 +55159,8 @@
5515955159
")\n",
5516055160
"middle = (seaborn_released - first_seaborn_qs) / 2 + first_seaborn_qs\n",
5516155161
"ax.annotate(\n",
55162-
" 'posts retroactively\\ntagged \"seaborn\"', \n",
55163-
" xy=(mdates.date2num(middle), 3500), \n",
55162+
" 'posts retroactively\\ntagged \"seaborn\"',\n",
55163+
" xy=(mdates.date2num(middle), 3500),\n",
5516455164
" va='top', ha='center'\n",
5516555165
")"
5516655166
]
@@ -55210,7 +55210,7 @@
5521055210
" fig, ax = plt.subplots(figsize=(12, 3))\n",
5521155211
" ax.stackplot(\n",
5521255212
" mdates.date2num(data.index),\n",
55213-
" data.to_numpy().T, \n",
55213+
" data.to_numpy().T,\n",
5521455214
" labels=data.columns\n",
5521555215
" )\n",
5521655216
" ax.set(\n",
@@ -63637,7 +63637,7 @@
6363763637
"\n",
6363863638
"total_qs = top_libraries_monthly.sum()\n",
6363963639
"inset_ax.barh(\n",
63640-
" total_qs.index, total_qs.to_numpy(), \n",
63640+
" total_qs.index, total_qs.to_numpy(),\n",
6364163641
" color=[colors[label] for label in total_qs.index]\n",
6364263642
")\n",
6364363643
"inset_ax.yaxis.set_inverted(True)\n",
@@ -68368,7 +68368,7 @@
6836868368
" co_occurring_library = data[library]\n",
6836968369
" ax.barh(libraries, co_occurring_library, label=library, left=last)\n",
6837068370
" last += co_occurring_library\n",
68371-
" \n",
68371+
"\n",
6837268372
" ax.yaxis.set_inverted(True)\n",
6837368373
" return despine(ax)"
6837468374
]
@@ -73752,7 +73752,7 @@
7375273752
" co_occurring_library = data[library]\n",
7375373753
" ax.barh(libraries, co_occurring_library, label=library, left=last)\n",
7375473754
" last += co_occurring_library\n",
73755-
" \n",
73755+
"\n",
7375673756
" ax.yaxis.set_inverted(True)\n",
7375773757
" ax.legend(bbox_to_anchor=(1.35, 0.5), loc='center right', framealpha=0.5)\n",
7375873758
" ax.set(xlabel='percentage of questions with co-occurrences', xlim=(0, 1))\n",
@@ -76160,11 +76160,11 @@
7616076160
" for i, library in enumerate(libraries):\n",
7616176161
" co_occurring_library = data[library]\n",
7616276162
" ax.barh(\n",
76163-
" libraries, co_occurring_library, \n",
76163+
" libraries, co_occurring_library,\n",
7616476164
" label=library, left=last, color=cmap(i)\n",
7616576165
" )\n",
7616676166
" last += co_occurring_library\n",
76167-
" \n",
76167+
"\n",
7616876168
" ax.yaxis.set_inverted(True)\n",
7616976169
" ax.legend(bbox_to_anchor=(1.35, 0.5), loc='center right', framealpha=0.5)\n",
7617076170
" ax.set(xlabel='percentage of questions with co-occurrences', xlim=(0, 1))\n",
@@ -78628,7 +78628,7 @@
7862878628
],
7862978629
"source": [
7863078630
"subway = pd.read_csv(\n",
78631-
" '../data/NYC_subway_daily.csv', parse_dates=['Datetime'], \n",
78631+
" '../data/NYC_subway_daily.csv', parse_dates=['Datetime'],\n",
7863278632
" index_col=['Borough', 'Datetime']\n",
7863378633
")\n",
7863478634
"subway_daily = subway.unstack(0)\n",
@@ -84537,7 +84537,7 @@
8453784537
"\n",
8453884538
" axes[0].set_ylabel('Frequency')\n",
8453984539
" fig.suptitle('Histogram of Daily Subway Entries in Manhattan')\n",
84540-
" \n",
84540+
"\n",
8454184541
" return fig, axes"
8454284542
]
8454384543
},

notebooks/2-animations.ipynb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"We made a bar plot that captured the total number of questions per library, but it couldn't show us the growth in pandas questions over time (or how the growth rate changed over time):\n",
6161
"\n",
6262
"<div style=\"text-align: center;\">\n",
63-
" <img width=\"60%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/bar_plot.svg\" alt=\"bar plot\" style=\"min-width: 500px\">\n",
63+
" <img width=\"60%\" src=\"../slides/media/bar_plot.svg\" alt=\"bar plot\" style=\"min-width: 500px\">\n",
6464
"</div>"
6565
]
6666
},
@@ -77,7 +77,7 @@
7777
"We also made an area plot showing the number of questions per day over time for the top 4 libraries, but by limiting the libraries shown we lost some information:\n",
7878
"\n",
7979
"<div style=\"text-align: center;\">\n",
80-
" <img width=\"90%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/area_plot.svg\" alt=\"area plot\" style=\"min-width: 600px\">\n",
80+
" <img width=\"90%\" src=\"../slides/media/area_plot.svg\" alt=\"area plot\" style=\"min-width: 600px\">\n",
8181
"</div>"
8282
]
8383
},
@@ -373,7 +373,7 @@
373373
" fig, ax = plt.subplots(figsize=(6, 4), layout='constrained')\n",
374374
" sort_order = data.loc[data.index.max()].sort_values().index\n",
375375
" bars = ax.barh(sort_order, [0] * data.shape[1], label=sort_order)\n",
376-
" \n",
376+
"\n",
377377
" ax.set_xlabel('total questions', fontweight='bold')\n",
378378
" ax.set_xlim(0, 250_000)\n",
379379
" ax.xaxis.set_major_formatter(ticker.EngFormatter())\n",
@@ -1797,7 +1797,7 @@
17971797
"source": [
17981798
"def update(frame, *, ax, df, annotations, time_text):\n",
17991799
" data = df.loc[frame, :]\n",
1800-
" \n",
1800+
"\n",
18011801
" # update bars\n",
18021802
" for rect, text in zip(ax.patches, annotations):\n",
18031803
" col = rect.get_label()\n",
@@ -1883,7 +1883,7 @@
18831883
" fig, update_func, frames=questions_per_library.index, repeat=False\n",
18841884
")\n",
18851885
"ani.save(\n",
1886-
" '../media/stackoverflow_questions.mp4', \n",
1886+
" '../media/stackoverflow_questions.mp4',\n",
18871887
" writer='ffmpeg', fps=10, bitrate=100, dpi=300\n",
18881888
")\n",
18891889
"plt.close()"
@@ -1957,7 +1957,7 @@
19571957
"As with the previous example, the histograms of daily Manhattan subway entries in 2018 (from the first section of the workshop) don't tell the whole story of the dataset because the distributions changed drastically in 2020 and 2021:\n",
19581958
"\n",
19591959
"<div style=\"text-align: center;\">\n",
1960-
" <img width=\"70%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/2018_subway_entries_histogram.svg\" alt=\"Histograms of daily Manhattan subway entries in 2018\" style=\"min-width: 500px\">\n",
1960+
" <img width=\"70%\" src=\"../slides/media/2018_subway_entries_histogram.svg\" alt=\"Histograms of daily Manhattan subway entries in 2018\" style=\"min-width: 500px\">\n",
19611961
"</div>"
19621962
]
19631963
},
@@ -2153,7 +2153,7 @@
21532153
],
21542154
"source": [
21552155
"subway = pd.read_csv(\n",
2156-
" '../data/NYC_subway_daily.csv', parse_dates=['Datetime'], \n",
2156+
" '../data/NYC_subway_daily.csv', parse_dates=['Datetime'],\n",
21572157
" index_col=['Borough', 'Datetime']\n",
21582158
")\n",
21592159
"subway_daily = subway.unstack(0)\n",
@@ -2249,7 +2249,7 @@
22492249
" {'label': 'Weekend', 'mask': ~weekday_mask, 'ymax': 60},\n",
22502250
" {'label': 'Weekday', 'mask': weekday_mask, 'ymax': 120}\n",
22512251
" ]\n",
2252-
" \n",
2252+
"\n",
22532253
" fig, axes = plt.subplots(1, 2, figsize=(6, 3), sharex=True, layout='constrained')\n",
22542254
" for ax, config in zip(axes, configs):\n",
22552255
" _, _, config['hist'] = ax.hist(\n",
@@ -4396,7 +4396,7 @@
43964396
"metadata": {},
43974397
"outputs": [],
43984398
"source": [
4399-
"# "
4399+
"#"
44004400
]
44014401
},
44024402
{

notebooks/3-interactivity.ipynb

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@
12401240
"<p>The interactivity works best in a notebook environment &ndash; here's an example of the slider, tooltips, and zoom/pan functionality in action:</p>\n",
12411241
"\n",
12421242
"<div style=\"text-align: center;\">\n",
1243-
" <img width=\"50%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/interactive_map.gif\" style=\"border: 5px solid #555; min-width: 600px;\">\n",
1243+
" <img width=\"50%\" src=\"../slides/media/interactive_map.gif\" style=\"border: 5px solid #555; min-width: 600px;\">\n",
12441244
"</div>"
12451245
]
12461246
},
@@ -2227,7 +2227,7 @@
22272227
"<p>The result can be interacted with after displaying it, but this kind of interactivity only works in the notebook. Here's an example:</p>\n",
22282228
"\n",
22292229
"<div style=\"text-align: center;\">\n",
2230-
" <img width=\"60%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/linked_plots.gif\" style=\"border: 5px solid #555; min-width: 800px; margin: 0px auto;\">\n",
2230+
" <img width=\"60%\" src=\"../slides/media/linked_plots.gif\" style=\"border: 5px solid #555; min-width: 800px; margin: 0px auto;\">\n",
22312231
" <br/>\n",
22322232
" <small><em>This example uses tabs to display the layout rather than side by side like we did. Tabs are a little buggy in this version, so we didn't use them.</em></small>\n",
22332233
"</div>"
@@ -2412,7 +2412,7 @@
24122412
},
24132413
"source": [
24142414
"<div style=\"text-align: center;\">\n",
2415-
" <img width=\"75%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/sankey_and_chord.png\" style=\"min-width: 750px\">\n",
2415+
" <img width=\"75%\" src=\"../slides/media/sankey_and_chord.png\" style=\"min-width: 750px\">\n",
24162416
"</div>"
24172417
]
24182418
},
@@ -2443,12 +2443,12 @@
24432443
"flight_stats = pd.read_csv(\n",
24442444
" '../data/T100_MARKET_ALL_CARRIER.zip',\n",
24452445
" usecols=[\n",
2446-
" 'CLASS', 'REGION', 'UNIQUE_CARRIER_NAME', 'ORIGIN_CITY_NAME', 'ORIGIN', \n",
2446+
" 'CLASS', 'REGION', 'UNIQUE_CARRIER_NAME', 'ORIGIN_CITY_NAME', 'ORIGIN',\n",
24472447
" 'DEST_CITY_NAME', 'DEST', 'PASSENGERS', 'FREIGHT', 'MAIL'\n",
24482448
" ]\n",
24492449
").rename(lambda x: x.lower(), axis=1).assign(\n",
24502450
" region=lambda x: x.region.replace({\n",
2451-
" 'D': 'Domestic', 'I': 'International', 'A': 'Atlantic', \n",
2451+
" 'D': 'Domestic', 'I': 'International', 'A': 'Atlantic',\n",
24522452
" 'L': 'Latin America', 'P': 'Pacific', 'S': 'System'\n",
24532453
" }),\n",
24542454
" route=lambda x: np.where(\n",
@@ -2653,7 +2653,7 @@
26532653
"source": [
26542654
"cities = [\n",
26552655
" 'Atlanta, GA', 'Chicago, IL', 'New York, NY', 'Los Angeles, CA',\n",
2656-
" 'Dallas/Fort Worth, TX', 'Denver, CO', 'Houston, TX', \n",
2656+
" 'Dallas/Fort Worth, TX', 'Denver, CO', 'Houston, TX',\n",
26572657
" 'San Francisco, CA', 'Seattle, WA', 'Orlando, FL'\n",
26582658
"]\n",
26592659
"\n",
@@ -2678,7 +2678,7 @@
26782678
"A **chord diagram** is a way of showing many-to-many relationships between a set of entities called **nodes**: the nodes are arranged in a circle, and chords (which can be thought of as **edges**) are drawn between those that are connected, with the width of the chord encoding the strength of the connection. In this section, we will be making a chord diagram for total passenger service travel between the top 10 cities in 2019:\n",
26792679
"\n",
26802680
"<div style=\"text-align: center;\">\n",
2681-
" <img width=\"35%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/chord.png\" style=\"border: 5px solid #555; min-width: 350px\">\n",
2681+
" <img width=\"35%\" src=\"../slides/media/chord.png\" style=\"border: 5px solid #555; min-width: 350px\">\n",
26822682
"</div>"
26832683
]
26842684
},
@@ -2948,7 +2948,7 @@
29482948
"source": [
29492949
"chord = hv.Chord(\n",
29502950
" total_flight_stats,\n",
2951-
" kdims=['origin', 'dest'], \n",
2951+
" kdims=['origin', 'dest'],\n",
29522952
" vdims=['passengers', 'origin_city_name', 'dest_city_name', 'mail', 'freight']\n",
29532953
")"
29542954
]
@@ -3162,7 +3162,7 @@
31623162
"<p>The result can be interacted with after displaying it, but it works best in the notebook &ndash; the GIF below shows some example interactions. Note that for this visualization the interactivity is what makes it useful:</p>\n",
31633163
"\n",
31643164
"<div style=\"text-align: center;\">\n",
3165-
" <img width=\"50%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/chord.gif\" style=\"border: 5px solid #555; min-width: 500px;\">\n",
3165+
" <img width=\"50%\" src=\"../slides/media/chord.gif\" style=\"border: 5px solid #555; min-width: 500px;\">\n",
31663166
"</div>"
31673167
]
31683168
},
@@ -3181,7 +3181,7 @@
31813181
"For our final visualization, we will create a **Sankey plot**, which is a way to visualize flow as edges between nodes. Here, we will use it to analyze airline market share for passenger service flights between the top 5 US cities:\n",
31823182
"\n",
31833183
"<div style=\"text-align: center;\">\n",
3184-
" <img width=\"50%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/sankey.png\" style=\"border: 5px solid #555; min-width: 600px;\">\n",
3184+
" <img width=\"50%\" src=\"../slides/media/sankey.png\" style=\"border: 5px solid #555; min-width: 600px;\">\n",
31853185
"</div>"
31863186
]
31873187
},
@@ -3605,7 +3605,7 @@
36053605
],
36063606
"source": [
36073607
"carrier_edges = get_edges(\n",
3608-
" domestic_passenger_travel, \n",
3608+
" domestic_passenger_travel,\n",
36093609
" source_col='region',\n",
36103610
" target_col='unique_carrier_name'\n",
36113611
").replace('^Domestic$', 'Top Routes', regex=True)\n",
@@ -3806,11 +3806,11 @@
38063806
"outputs": [],
38073807
"source": [
38083808
"sankey = hv.Sankey(\n",
3809-
" all_edges, \n",
3809+
" all_edges,\n",
38103810
" kdims=['source', 'target'],\n",
38113811
" vdims=hv.Dimension('passengers', unit='M')\n",
38123812
").opts(\n",
3813-
" labels='index', label_position='right', cmap='Set1', # node config \n",
3813+
" labels='index', label_position='right', cmap='Set1', # node config\n",
38143814
" edge_color='lightgray', # edge config\n",
38153815
" width=750, height=600, # plot size config\n",
38163816
" title='Travel Between the Top 5 Cities in 2019'\n",
@@ -3951,7 +3951,7 @@
39513951
"<p>The resulting visualization can be interacted with after displaying it, but it works best in the notebook. Here's an example:</p>\n",
39523952
"\n",
39533953
"<div style=\"text-align: center;\">\n",
3954-
" <img width=\"50%\" src=\"https://raw.githubusercontent.com/stefmolin/python-data-viz-workshop/main/media/sankey.gif\" style=\"border: 5px solid #555; min-width: 700px;\">\n",
3954+
" <img width=\"50%\" src=\"../slides/media/sankey.gif\" style=\"border: 5px solid #555; min-width: 700px;\">\n",
39553955
"</div>"
39563956
]
39573957
},

0 commit comments

Comments
 (0)