{"id":645,"date":"2021-08-20T07:00:55","date_gmt":"2021-08-20T12:00:55","guid":{"rendered":"https:\/\/wollen.org\/blog\/?p=645"},"modified":"2024-08-17T11:44:42","modified_gmt":"2024-08-17T16:44:42","slug":"ryan-crouser-is-the-best-shot-putter-ever","status":"publish","type":"post","link":"https:\/\/wollen.org\/blog\/2021\/08\/ryan-crouser-is-the-best-shot-putter-ever\/","title":{"rendered":"Ryan Crouser is the best shot putter ever"},"content":{"rendered":"<p>As curtains close on the 2020 Tokyo Olympics I thought I&#8217;d take a look at one of my favorite athletes: Ryan Crouser.<\/p>\n<p>After breaking the 31-year-old world record earlier this year (below), Crouser traveled to Tokyo and easily won Olympic Gold. In fact, his first attempt would have been more than enough to beat the field. Few people, at this point, would disagree that he has separated himself from other great shot putters in history. Let&#8217;s plot the data and put Crouser&#8217;s career in historical context.<\/p>\n<p style=\"text-align: center;\"><iframe loading=\"lazy\" title=\"YouTube video player\" src=\"https:\/\/www.youtube.com\/embed\/42VolB3Z3AU\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<hr \/>\n<p>We&#8217;ll visualize Crouser&#8217;s career in two ways:<\/p>\n<ol>\n<li>Create a stacked bar chart that displays Crouser&#8217;s share of 22.00+ meter performances.<\/li>\n<li>Using histograms, compare Crouser to Randy Barnes, the previous world record holder.<\/li>\n<\/ol>\n<hr \/>\n<h4>1. Ryan Crouser&#8217;s share of 22.00+ meter throws<\/h4>\n<p>Fortunately the folks at <a href=\"http:\/\/www.alltime-athletics.com\/mshotok.htm\" target=\"_blank\" rel=\"noopener\">Alltime Athletics<\/a> have been tracking the event for many years. They provide a convenient list of all performances exceeding 21.00 meters. I&#8217;ll link the dataset at the end of this post.<\/p>\n<p>First let&#8217;s read the CSV file with <em>pandas<\/em> and parse its date column.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df = pd.read_csv(\"shotput_alltime_8-5-2021.csv\", parse_dates=[\"date\"])<\/pre>\n<p>Since the x-axis will be divided into yearly units, we can simplify the work by treating dates as integers. Create a <code>year<\/code> column:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df.loc[:, \"year\"] = df[\"date\"].dt.strftime(\"%Y\").astype(int)<\/pre>\n<p>Before narrowing the dataframe to Crouser&#8217;s performances we should look at all athletes together. Create a view restricted to 22.00+ performances and use the <code>value_counts<\/code> method to find the number of throws per year. Storing this information as a dictionary will make it easy to plot later.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df = df[df.mark &gt;= 22.00]\r\n\r\nyearly_all = df.year.value_counts().to_dict()<\/pre>\n<p>The <code>yearly_all<\/code> dictionary should look like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">{1974: 1, 1975: 3, 1976: 2, 1978: 1, ...<\/pre>\n<p>Now simply restrict the view to rows that include &#8220;Ryan Crouser&#8221; and repeat the process. Create a second dictionary called <code>yearly_crouser<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df = df[df.name == \"Ryan Crouser\"]\r\n\r\nyearly_crouser = df.year.value_counts().to_dict()<\/pre>\n<p>With these two dictionaries we can easily plot a stacked bar chart and visualize Crouser&#8217;s contribution of 22.00+ meter throws. On the x-axis will be dictionary keys\u2014years\u2014and the y-axis will display dictionary values\u2014number of throws per year.<\/p>\n<p>We don&#8217;t need to worry about manually <em>stacking<\/em> the bars because Crouser&#8217;s throws are a subset of overall throws. Both bars can start at zero. I&#8217;ll use two of the five Olympic ring colors to stay on theme.<\/p>\n<p>A couple quick notes about the plot:<\/p>\n<ul>\n<li>I use the built-in <code>ggplot<\/code> style but change its font using <code>rcParams<\/code>.<\/li>\n<li><code>tick_params<\/code> is a good way to adjust both axes&#8217; tick labels with a single line.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">plt.style.use(\"ggplot\")\r\nplt.rcParams.update({\"font.family\": \"Ubuntu Condensed\"})\r\n\r\nfig, ax = plt.subplots(figsize=(12, 6.5))\r\nfig.subplots_adjust(left=0.046, right=0.985, top=0.952, bottom=0.085)\r\n\r\nax.bar(yearly_all.keys(), yearly_all.values(), color=\"#0286C3\", label=\"Other\")\r\nax.bar(yearly_crouser.keys(), yearly_crouser.values(), color=\"#FBB22E\", label=\"Crouser\")\r\n\r\nax.set_xticks(range(1972, 2028, 4))\r\nax.set_xlim(1971, 2025)\r\nax.set_xlabel(\"Season (Indoor &amp; Outdoor Combined)\", size=12, labelpad=6)\r\n\r\nax.set_ylim(0, 36)\r\nax.set_ylabel(\"Count\", size=12, labelpad=6)\r\n\r\nax.tick_params(axis=\"both\", labelsize=12)\r\n\r\nax.set_title(\"IAAF Men's Shot Put  |  22.00m+\", size=14)\r\n\r\nplt.legend(loc=\"upper center\", fontsize=11, facecolor=\"#FFF\")\r\n\r\nplt.show()<\/pre>\n<p>The output:<\/p>\n<p><a href=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/shotput_22m.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1771 size-full\" src=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/shotput_22m.png\" alt=\"\" width=\"1200\" height=\"650\" srcset=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/shotput_22m.png 1200w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/shotput_22m-300x163.png 300w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/shotput_22m-1024x555.png 1024w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/shotput_22m-768x416.png 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/p>\n<p>For readers who aren&#8217;t die-hard shot put fanatics, which I would estimate is nearly everyone reading this post, the sport fell off a metaphorical cliff in the early 1990&#8217;s with advancements in drug testing. Only in the past few years has it finally surpassed that era. Crouser and several other great athletes\u2014Joe Kovacs and Tom Walsh especially\u2014deserve credit for pushing the sport forward.<\/p>\n<hr \/>\n<h4>2. Ryan Crouser and Randy Barnes<\/h4>\n<p>Now let&#8217;s create histograms of performances by Crouser and the previous world record holder, Randy Barnes, who threw 23.12 meters in 1990.<\/p>\n<p>Let&#8217;s start fresh and create a new dataframe from the CSV file.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df = pd.read_csv(\"shotput_alltime_8-5-2021.csv\")<\/pre>\n<p>We&#8217;ll use <code>pandas.cut<\/code> to bin the data. This method groups all values within a given range. For example, because we specified a 10 centimeter bin size, all distances from 22.10 to 22.19 will be grouped together and labeled 22.15. We can then count how many values are in each bin.<\/p>\n<p>Put these labels, e.g. 22.15, into a new column called <code>bin<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">bins = arange(20.995, 23.495, 0.1)\r\nlabels = arange(21.05, 23.45, 0.1)\r\ndf.loc[:, \"bin\"] = pd.cut(df.mark, bins=bins, labels=labels)<\/pre>\n<p>Before counting the bins we need to separate Crouser and Barnes from the rest of the athletes. Create two separate dataframe views.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df_crouser = df[df.name == \"Ryan Crouser\"]\r\ndf_barnes = df[df.name == \"Randy Barnes\"]<\/pre>\n<p>At this point <code>df_crouser.head()<\/code> and <code>df_barnes.head()<\/code> should look like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">    mark          name        date    bin\r\n0  23.37  Ryan Crouser  2021-06-18  23.35\r\n1  23.30  Ryan Crouser  2021-05-08  23.35\r\n5  23.01  Ryan Crouser  2021-05-22  23.05\r\n6  22.92  Ryan Crouser  2021-06-18  22.95\r\n9  22.91  Ryan Crouser  2020-07-18  22.95\r\n\r\n     mark          name        date    bin\r\n2   23.12  Randy Barnes  1990-05-20  23.15\r\n3   23.10  Randy Barnes  1990-05-26  23.15\r\n25  22.66  Randy Barnes  1989-01-20  22.65\r\n66  22.42  Randy Barnes  1988-08-17  22.45\r\n69  22.40  Randy Barnes  1996-07-13  22.45<\/pre>\n<p>You can see how each mark is designated a bin.<\/p>\n<p>Now we&#8217;ll use <code>pandas.groupby<\/code> to collect all rows according to their bin labels. Set <code>as_index=False<\/code> because without it, <code>bin<\/code> would become the new dataframe&#8217;s index column.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df_crouser_hist = df_crouser.groupby(\"bin\", as_index=False)[\"mark\"].count()\r\ndf_barnes_hist = df_barnes.groupby(\"bin\", as_index=False)[\"mark\"].count()<\/pre>\n<p>Note that the <code>count<\/code> aggregate function could also be written this way:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df_crouser_hist = df_crouser.groupby(\"bin\", as_index=False)[\"mark\"].agg(\"count\")<\/pre>\n<p>These are equivalent lines of code.<\/p>\n<p><code>df_crouser_hist.head()<\/code> is shown below. It means Crouser has had:<\/p>\n<ul>\n<li>1 throw between 21.00 and 21.09.<\/li>\n<li>4 throws between 21.10 and 21.19.<\/li>\n<li>And so on.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">     bin  mark\r\n0  21.05     1\r\n1  21.15     4\r\n2  21.25     7\r\n3  21.35     2\r\n4  21.45     1<\/pre>\n<p>At this point we&#8217;re ready to plot the two histograms and compare.<\/p>\n<p>A few notes about the code:<\/p>\n<ul>\n<li>It uses the built-in <code>seaborn<\/code> style with a couple <code>rcParam<\/code> changes:\n<ul style=\"margin-bottom: 0px;\">\n<li>Font is changed to <em>Ubuntu Condensed<\/em>.<\/li>\n<li>x-ticks are excluded by default in <code>seaborn<\/code> style, so they&#8217;re brought back.<\/li>\n<\/ul>\n<\/li>\n<li>The figure has a 2&#215;1 subplot layout\u20142 rows, 1 column.\n<ul style=\"margin-bottom: 0px;\">\n<li>A vertical orientation makes it easy to compare the two distributions.<\/li>\n<\/ul>\n<\/li>\n<li>The two axes, <code>ax[0]<\/code> and <code>ax[1]<\/code>, are renamed for readability.<\/li>\n<li><code>matplotlib.ticker<\/code> is used to format the x-axis tick labels to have 2 decimal places.<\/li>\n<li>Vertical grid lines are hidden. I think this often looks cleaner on histograms.<\/li>\n<li>It uses the athletes&#8217; college colors\u2014Texas and Texas A&amp;M respectively.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">plt.style.use(\"seaborn\")\r\nplt.rcParams.update({\"font.family\": \"Ubuntu Condensed\",\r\n                     \"xtick.major.size\": 4.0})\r\n\r\nfig, axs = plt.subplots(2, 1, figsize=(10, 10))\r\nfig.subplots_adjust(hspace=0.18, left=0.047, right=0.983, bottom=0.075, top=0.968)\r\n\r\nax_crouser, ax_barnes = axs\r\n\r\nax_crouser.bar(df_crouser_hist.bin, df_crouser_hist.mark,\r\n               width=0.075, color=\"#bf5700\")\r\nax_crouser.set(yticks=range(8), ylim=(0, 7.2),\r\n               xticks=arange(21.0, 24.0, 0.5), xlim=(20.9, 23.6))\r\nax_crouser.set_ylabel(\"Count\", size=12, labelpad=6)\r\nax_crouser.set_title(\"Ryan Crouser  |  Distance\", size=13)\r\nax_crouser.xaxis.set_major_formatter(ticker.StrMethodFormatter(\"{x:.2f}\"))\r\nax_crouser.xaxis.grid(b=True, linewidth=0.1)\r\nax_crouser.tick_params(axis=\"both\", labelsize=12)\r\n\r\nax_barnes.bar(df_barnes_hist.bin, df_barnes_hist.mark,\r\n              width=0.075, color=\"#500000\")\r\nax_barnes.set(yticks=range(8), ylim=(0, 7.2),\r\n              xticks=arange(21.0, 24.0, 0.5), xlim=(20.9, 23.6))\r\nax_barnes.set_ylabel(\"Count\", size=12, labelpad=6)\r\nax_barnes.set_xlabel(\"Distance (m)\", size=12, labelpad=6)\r\nax_barnes.set_title(\"Randy Barnes  |  Distance\", size=13)\r\nax_barnes.xaxis.set_major_formatter(ticker.StrMethodFormatter(\"{x:.2f}\"))\r\nax_barnes.xaxis.grid(b=True, linewidth=0.1)\r\nax_barnes.tick_params(axis=\"both\", labelsize=12)\r\n\r\nsource_message = \"Through August 5, 2021. Outdoor &amp; Indoor combined.\\nData:  http:\/\/www.alltime-athletics.com.\"\r\nax_barnes.text(23.7, -1.15, source_message, ha=\"right\", size=8)\r\n\r\nplt.show()<\/pre>\n<p>The output:<\/p>\n<p><a href=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/crouser_barnes_hist.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1754 size-full\" src=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/crouser_barnes_hist.png\" alt=\"\" width=\"1000\" height=\"1000\" srcset=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/crouser_barnes_hist.png 1000w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/crouser_barnes_hist-300x300.png 300w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/crouser_barnes_hist-150x150.png 150w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/crouser_barnes_hist-768x768.png 768w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2021\/08\/crouser_barnes_hist-800x800.png 800w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/a>You can see the peak of Barnes&#8217; distribution is somewhere in the mid-21-meter range, while Crouser&#8217;s distribution is centered well above 22 meters.<\/p>\n<p>I don&#8217;t mean to take anything away from Randy Barnes. The man had an incredible career, including Olympic Gold in Atlanta, and he held the world record for over 30 years. I only want to show that Ryan Crouser stands head and shoulders above his peers\u2014including the former world record holder.<\/p>\n<hr \/>\n<p><a href=\"https:\/\/wollen.org\/misc\/shotput_data_8-2021.zip\"><strong>Download the data.<\/strong><\/a><\/p>\n<p><strong>Full code:<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pandas as pd\r\nfrom numpy import arange\r\nimport matplotlib.pyplot as plt\r\nimport matplotlib.ticker as ticker\r\n\r\n\r\ndf = pd.read_csv(\"shotput_alltime_8-5-2021.csv\", parse_dates=[\"date\"])\r\n\r\ndf.loc[:, \"year\"] = df[\"date\"].dt.strftime(\"%Y\").astype(int)\r\n\r\ndf = df[df.mark &gt;= 22.00]\r\n\r\nyearly_all = df.year.value_counts().to_dict()\r\n\r\ndf = df[df.name == \"Ryan Crouser\"]\r\n\r\nyearly_crouser = df.year.value_counts().to_dict()\r\n\r\nplt.style.use(\"ggplot\")\r\nplt.rcParams.update({\"font.family\": \"Ubuntu Condensed\"})\r\n\r\nfig, ax = plt.subplots(figsize=(12, 6.5))\r\nfig.subplots_adjust(left=0.046, right=0.985, top=0.952, bottom=0.085)\r\n\r\nax.bar(yearly_all.keys(), yearly_all.values(), color=\"#0286C3\", label=\"Other\")\r\nax.bar(yearly_crouser.keys(), yearly_crouser.values(), color=\"#FBB22E\", label=\"Crouser\")\r\n\r\nax.set_xticks(range(1972, 2028, 4))\r\nax.set_xlim(1971, 2025)\r\nax.set_xlabel(\"Season (Indoor &amp; Outdoor Combined)\", size=12, labelpad=6)\r\n\r\nax.set_ylim(0, 36)\r\nax.set_ylabel(\"Count\", size=12, labelpad=6)\r\n\r\nax.tick_params(axis=\"both\", labelsize=12)\r\n\r\nax.set_title(\"IAAF Men's Shot Put  |  22.00m+\", size=14)\r\n\r\nplt.legend(loc=\"upper center\", fontsize=11, facecolor=\"#FFF\")\r\n\r\nplt.savefig(\"shotput_22m.png\")\r\n\r\n# ############# Histogram plots #############\r\n\r\ndf = pd.read_csv(\"shotput_alltime_8-5-2021.csv\")\r\n\r\nbins = arange(20.995, 23.495, 0.1)\r\nlabels = arange(21.05, 23.45, 0.1)\r\ndf.loc[:, \"bin\"] = pd.cut(df.mark, bins=bins, labels=labels)\r\n\r\ndf_crouser = df[df.name == \"Ryan Crouser\"]\r\ndf_barnes = df[df.name == \"Randy Barnes\"]\r\n\r\ndf_crouser_hist = df_crouser.groupby(\"bin\", as_index=False)[\"mark\"].count()\r\ndf_barnes_hist = df_barnes.groupby(\"bin\", as_index=False)[\"mark\"].count()\r\n\r\nplt.style.use(\"seaborn\")\r\nplt.rcParams.update({\"font.family\": \"Ubuntu Condensed\", \"xtick.major.size\": 4.0})\r\n\r\nfig, axs = plt.subplots(2, 1, figsize=(10, 10))\r\nfig.subplots_adjust(hspace=0.18, left=0.047, right=0.983, bottom=0.075, top=0.968)\r\n\r\nax_crouser, ax_barnes = axs\r\n\r\nax_crouser.bar(df_crouser_hist.bin, df_crouser_hist.mark, width=0.075, color=\"#bf5700\")\r\nax_crouser.set(yticks=range(8), ylim=(0, 7.2), xticks=arange(21.0, 24.0, 0.5), xlim=(20.9, 23.6))\r\nax_crouser.set_ylabel(\"Count\", size=12, labelpad=6)\r\nax_crouser.set_title(\"Ryan Crouser  |  Distance\", size=13)\r\nax_crouser.xaxis.set_major_formatter(ticker.StrMethodFormatter(\"{x:.2f}\"))\r\nax_crouser.xaxis.grid(b=True, linewidth=0.1)\r\nax_crouser.tick_params(axis=\"both\", labelsize=12)\r\n\r\nax_barnes.bar(df_barnes_hist.bin, df_barnes_hist.mark, width=0.075, color=\"#500000\")\r\nax_barnes.set(yticks=range(8), ylim=(0, 7.2), xticks=arange(21.0, 24.0, 0.5), xlim=(20.9, 23.6))\r\nax_barnes.set_ylabel(\"Count\", size=12, labelpad=6)\r\nax_barnes.set_xlabel(\"Distance (m)\", size=12, labelpad=6)\r\nax_barnes.set_title(\"Randy Barnes  |  Distance\", size=13)\r\nax_barnes.xaxis.set_major_formatter(ticker.StrMethodFormatter(\"{x:.2f}\"))\r\nax_barnes.xaxis.grid(b=True, linewidth=0.1)\r\nax_barnes.tick_params(axis=\"both\", labelsize=12)\r\n\r\nsource_message = \"Through August 5, 2021. Outdoor &amp; Indoor combined.\\nData:  http:\/\/www.alltime-athletics.com.\"\r\nax_barnes.text(23.7, -1.15, source_message, ha=\"right\", size=8)\r\n\r\nplt.savefig(\"crouser_barnes_hist.png\")\r\n<\/pre>\n<hr \/>\n<p><em>Title image credit: <a href=\"https:\/\/simplifaster.com\/articles\/shot-put-development-jim-aikens\/\" target=\"_blank\" rel=\"noopener\">Simpli Faster<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As curtains close on the 2020 Tokyo Olympics I thought I&#8217;d take a look at one of my favorite athletes: Ryan Crouser. After breaking the 31-year-old world record earlier this year (below), Crouser traveled to Tokyo and easily won Olympic<\/p>\n","protected":false},"author":1,"featured_media":656,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59],"tags":[113,114,105,104,22,53,44,38,109,24,111,30,46,25,108,107,60,106,112,110,115],"class_list":["post-645","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sports","tag-113","tag-athletics","tag-bar-chart","tag-bar-plot","tag-data","tag-datetime","tag-games","tag-histogram","tag-joe-kovacs","tag-matplotlib","tag-olympics","tag-pandas","tag-plot","tag-python","tag-ryan-crouser","tag-shot-put","tag-sports","tag-stacked-bar-chart","tag-tokyo","tag-tom-walsh","tag-track-and-field"],"_links":{"self":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/645","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/comments?post=645"}],"version-history":[{"count":38,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/645\/revisions"}],"predecessor-version":[{"id":1772,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/645\/revisions\/1772"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/media\/656"}],"wp:attachment":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/media?parent=645"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/categories?post=645"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/tags?post=645"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}