<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Football Market Review]]></title><description><![CDATA[Data-driven deep dives into transfers and player valuations.

Built for fans and professionals interested in the business of football.]]></description><link>https://www.footballmarketreview.com</link><image><url>https://substackcdn.com/image/fetch/$s_!2wY2!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1106425-03e8-4005-845d-93c4df129830_1044x1044.png</url><title>Football Market Review</title><link>https://www.footballmarketreview.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 10 Apr 2026 18:48:29 GMT</lastBuildDate><atom:link href="https://www.footballmarketreview.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Football Market Review]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[footballmarketreview@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[footballmarketreview@substack.com]]></itunes:email><itunes:name><![CDATA[MartinOnData]]></itunes:name></itunes:owner><itunes:author><![CDATA[MartinOnData]]></itunes:author><googleplay:owner><![CDATA[footballmarketreview@substack.com]]></googleplay:owner><googleplay:email><![CDATA[footballmarketreview@substack.com]]></googleplay:email><googleplay:author><![CDATA[MartinOnData]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[The Future of the Python Football Review]]></title><description><![CDATA[Hi friends,]]></description><link>https://www.footballmarketreview.com/p/the-future-of-the-python-football</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/the-future-of-the-python-football</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Wed, 08 Apr 2026 11:03:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vrnm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friends,</p><p>Here&#8217;s a quick update on what&#8217;s been happening behind the scenes and where this newsletter is heading.</p><p>For the past five months, I&#8217;ve been reading and working on valuation models for football transfers. What was initially planned as a simple newsletter edition has grown into something much deeper than expected.</p><p>Going forward, the newsletter will move away from the &#8220;teaching Python&#8221; format and toward market-focused analysis. Think Swiss Ramble, but for player valuations, salaries, and performance. This includes:</p><ul><li><p>Player transfer and wage evaluations (obviously)</p></li><li><p>Assessing how well teams perform in the transfer market&#8212;and how players perform at the negotiation table</p></li><li><p>Transfer window reviews</p></li><li><p>Case studies (e.g. what Kevin De Bruyne&#8217;s data scientists might have said to Man City during negotiations for his &#8364;80 million contract extension in 2021)</p></li></ul><p>The previous articles won&#8217;t disappear&#8212;only the name of the newsletter and my handle will change.</p><p>So the <em><strong>Python Football Review</strong> </em>is evolving into the <em><strong>Football Market Review</strong></em> (hopefully I won&#8217;t change the name again before the first new post is out).</p><p>If this isn&#8217;t something you&#8217;re interested in, please feel free to unsubscribe.</p><p>If it is, I&#8217;m glad to have you here.</p><p>Also&#8212;if there&#8217;s something within these topics you&#8217;d like to learn more about or read regularly, drop your ideas in the comments or just hit reply. I&#8217;d genuinely love your feedback.</p><p>Cheers,<br>Martin</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vrnm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vrnm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!vrnm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!vrnm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!vrnm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vrnm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:68775,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/193561877?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vrnm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!vrnm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!vrnm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!vrnm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F986ddc0b-a950-4abd-8d05-e75f4db51b0b_1280x720.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div>]]></content:encoded></item><item><title><![CDATA[How Good Really Was FiveThirtyEight’s Soccer Power Index?]]></title><description><![CDATA[A Seven-Season Reality Check Against Pinnacle&#8217;s Closing Odds]]></description><link>https://www.footballmarketreview.com/p/how-good-really-was-fivethirtyeights</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/how-good-really-was-fivethirtyeights</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 11 Dec 2025 09:01:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!yUV6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>FiveThirtyEight has always had a kind of mythic status in the football world. Their <a href="https://fivethirtyeight.com/methodology/how-our-club-soccer-predictions-work/">Soccer Power Index</a> (SPI) was one of the first &#8220;super-model&#8221; rating systems I stumbled upon when I began my own analytics journey. And for years &#8212; before it was shut down &#8212; SPI became a reference point for pre-game probabilities and end-of-season title chances across football Twitter.</p><p>Last week, I came across a historical dataset that included SPI&#8217;s match-by-match outcome probabilities. Naturally, the first question that came to my mind was:</p><p><em><strong>&#8220;If someone blindly trusted SPI for years&#8230; would they have made money?&#8221;</strong></em></p><p>And that curiosity brings us to today&#8217;s issue.</p><p>Welcome to<em> <strong>The Python Football Review #019</strong>.</em></p><p>In this edition, we&#8217;ll explore how much one would have won (or lost) over seven seasons by betting strictly according to SPI&#8217;s implied probabilities &#8212; and we&#8217;ll compare those numbers to <em>the sharpest odds in world football</em>: Pinnacle&#8217;s closing line.</p><p>As always, the Python notebook is included at the end so you can replicate everything yourself from scratch (and mock my results).</p><p>Let&#8217;s get into it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v4wD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v4wD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg 424w, https://substackcdn.com/image/fetch/$s_!v4wD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg 848w, https://substackcdn.com/image/fetch/$s_!v4wD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!v4wD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v4wD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg" width="1456" height="564" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:564,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105364,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/181040224?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!v4wD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg 424w, https://substackcdn.com/image/fetch/$s_!v4wD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg 848w, https://substackcdn.com/image/fetch/$s_!v4wD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!v4wD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1d7d7fe-bee5-4219-9c10-d2a789a77b96_1690x655.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://fromthebyline.substack.com/p/fivethirtyeight-is-dead-long-live">FiveThirtyEight is Dead; Long Live Public Soccer Projection Models</a></figcaption></figure></div><div><hr></div><h1><em><strong>A Few Words About the Data</strong></em></h1><p>The historical SPI dataset &#8212; available on <a href="https://www.kaggle.com/datasets/thedevastator/club-soccer-predictions-spi-ratings-and-forecast">Kaggle</a> &#8212; includes <strong>40 leagues</strong> (male and female, national and international) covering the <strong>2016/17 to 2022/23</strong> seasons. For every match, we have SPI&#8217;s estimated probability of home win, draw and away win as illustrated below.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eXNA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eXNA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png 424w, https://substackcdn.com/image/fetch/$s_!eXNA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png 848w, https://substackcdn.com/image/fetch/$s_!eXNA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png 1272w, https://substackcdn.com/image/fetch/$s_!eXNA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eXNA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png" width="800" height="208" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:208,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:20488,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/181040224?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!eXNA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png 424w, https://substackcdn.com/image/fetch/$s_!eXNA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png 848w, https://substackcdn.com/image/fetch/$s_!eXNA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png 1272w, https://substackcdn.com/image/fetch/$s_!eXNA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48ca9932-e781-4481-8878-e6d93f03ffd7_800x208.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>From these probabilities we&#8217;ll compute <em>fair odds</em> simply by taking the inverse. For example, SPI gave <strong>Bastia a 4.63% chance</strong> of beating PSG in the opening match of 2016/17. The corresponding odds according to FiveThirtyEight are therefore <strong>1 / 0.0463 = 21.6</strong> which means that if you bet 1&#8364; on that outcome, you would have won a total of 21.6&#8364; back (in case if a winning wager of course).</p><p>To analyse <em>profitability</em>, I then needed the market odds for each match. Based on <em>ease</em> of downloading, I downloaded the market odds for 18 of those 40 leagues (my newsletter, my rules), which is still a very healthy sample.</p><p>The odds data comes from <strong><a href="https://x.com/12Xpert">Joseph Buchdahl</a>&#8217;s </strong><a href="https://www.football-data.co.uk/downloadm.php">football-data.co.uk</a>, as usual. For market prices, we take <strong>Pinnacle closing odds</strong>, because: <em>If your system consistently beats Pinnacle&#8217;s closing price, you almost certainly have an edge.</em></p><p>After matching team names across the two datasets, we end up with <strong>36,335 matches</strong>. And here is what the final analysis table looks like:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DPyZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DPyZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png 424w, https://substackcdn.com/image/fetch/$s_!DPyZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png 848w, https://substackcdn.com/image/fetch/$s_!DPyZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png 1272w, https://substackcdn.com/image/fetch/$s_!DPyZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DPyZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png" width="1456" height="246" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:246,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85419,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/181040224?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DPyZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png 424w, https://substackcdn.com/image/fetch/$s_!DPyZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png 848w, https://substackcdn.com/image/fetch/$s_!DPyZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png 1272w, https://substackcdn.com/image/fetch/$s_!DPyZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59cc97d1-a475-4571-8d53-31f85a76236e_1986x336.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ul><li><p><code>fair_home</code>, <code>fair_draw</code>, <code>fair_away</code> &#8594; from SPI</p></li><li><p><code>home_odds</code>, <code>draw_odds</code>, <code>away_odds</code> &#8594; Pinnacle closing odds</p></li></ul><p>Here&#8217;s the overall coverage.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wv7j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wv7j!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png 424w, https://substackcdn.com/image/fetch/$s_!wv7j!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png 848w, https://substackcdn.com/image/fetch/$s_!wv7j!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png 1272w, https://substackcdn.com/image/fetch/$s_!wv7j!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wv7j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png" width="603" height="577.875" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1012,&quot;width&quot;:1056,&quot;resizeWidth&quot;:603,&quot;bytes&quot;:153423,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/181040224?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wv7j!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png 424w, https://substackcdn.com/image/fetch/$s_!wv7j!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png 848w, https://substackcdn.com/image/fetch/$s_!wv7j!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png 1272w, https://substackcdn.com/image/fetch/$s_!wv7j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcc62606-97fb-496f-a24d-36d9ef214ceb_1056x1012.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h1><em><strong>The Betting Simulation</strong></em></h1><p>For each match, we look for <strong>value</strong>. A value bet exists when <em><strong>Market odds &gt; Fair odds.</strong></em></p><p>Simple example: In Bastia vs PSG, SPI assigns PSG fair odds of <strong>1.19</strong>, while Pinnacle offers <strong>1.34</strong>. That&#8217;s a <strong>12.6% value edge ((1.34/1.19) -1)</strong>, which means &#8212; in theory &#8212; we&#8217;d place a bet on PSG. To avoid over-exposure, we place <strong>only one bet per match</strong>, even if multiple outcomes show theoretical value. For each bet we will place a single unit wager.</p><p>So to recap: we&#8217;re about to test <strong>36,335 matches</strong> across <strong>7 seasons</strong> and <strong>18 leagues</strong>. We&#8217;ll compare SPI&#8217;s fair odds to Pinnacle&#8217;s closing odds and look for value. Whenever value appears, we place a <strong>single 1-unit bet</strong> on the outcome with the <strong>highest positive edge</strong>.</p><p>And the question is: <em><strong>What would the profitability look like? Would SPI beat the market? Or would it behave like a very polite random walk?</strong></em></p><p>Let&#8217;s find out.</p><div><hr></div><h1><em><strong>Simulation Results</strong></em></h1><p>Over the full period, the model would have generated <strong>33,929 bets</strong>, each taken when the SPI-implied probability appeared higher than Pinnacle&#8217;s market probability.<br>Across these bets, the <strong>average perceived value was around +18.2% </strong>(that&#8217;s a lot), and the system achieved a <strong>31% win rate</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WBcM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WBcM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png 424w, https://substackcdn.com/image/fetch/$s_!WBcM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png 848w, https://substackcdn.com/image/fetch/$s_!WBcM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png 1272w, https://substackcdn.com/image/fetch/$s_!WBcM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WBcM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png" width="824" height="162" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:162,&quot;width&quot;:824,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24156,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/181040224?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WBcM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png 424w, https://substackcdn.com/image/fetch/$s_!WBcM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png 848w, https://substackcdn.com/image/fetch/$s_!WBcM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png 1272w, https://substackcdn.com/image/fetch/$s_!WBcM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3694b787-b414-442c-ad7b-37ec7651f34a_824x162.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>However, despite the perceived positive expected value, the long-term outcome was a <strong>net loss of about 2,114 points</strong>, corresponding to a <em><strong>&#8211;6.2% rate of return</strong></em>. In practical terms:</p><blockquote><p><em><strong>For every &#8364;100 placed, you&#8217;d expect to lose about &#8364;6.</strong></em></p></blockquote><p>Can the results be improved? Of course. There are dozens of <s>data mining</s> filtering techniques we could explore, such as:</p><ul><li><p>restricting to lower odds (more likely events)</p></li><li><p>betting only when value exceeds certain thresholds &#8212; or avoiding extreme value outliers (model/market mistakes)</p></li><li><p>focusing on home-only strategies (or excluding draws)</p></li><li><p>applying Kelly-criterion staking</p></li></ul><p>These could change the curve and potentially improve performance.</p><p>But the <em>general conclusion</em> is :</p><blockquote><p><em><strong>A na&#239;ve, blind strategy that follows SPI as a pricing model would lose money against Pinnacle.</strong></em></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yUV6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yUV6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png 424w, https://substackcdn.com/image/fetch/$s_!yUV6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png 848w, https://substackcdn.com/image/fetch/$s_!yUV6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png 1272w, https://substackcdn.com/image/fetch/$s_!yUV6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yUV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png" width="889" height="540" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/deab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:540,&quot;width&quot;:889,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:33631,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/181040224?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yUV6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png 424w, https://substackcdn.com/image/fetch/$s_!yUV6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png 848w, https://substackcdn.com/image/fetch/$s_!yUV6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png 1272w, https://substackcdn.com/image/fetch/$s_!yUV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdeab0caa-6ae4-4c2c-bfb1-95630641c821_889x540.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><em><strong>Is this surprising? Not really.</strong></em></h2><p>No one ever claimed SPI was designed for betting. And importantly, we used Pinnacle <em><strong>closing </strong></em>odds, widely considered the sharpest lines in the world.</p><p>And SPI&#8212;at its core&#8212;is:</p><ul><li><p>a <em><strong>static</strong></em> <em><strong>pre-game</strong></em> index</p></li><li><p>ignoring late team news &amp; therefore blind to injuries, squad rotation, fatigue, travel, and line-up announcements</p></li><li><p>accessible to everyone well in advance.</p></li></ul><p>Meanwhile, Pinnacle&#8217;s <em><strong>closing </strong></em>line:</p><ul><li><p>reflects the aggregated knowledge of the sharpest bettors</p></li><li><p><em><strong>adjusts dynamically</strong></em> until the final seconds before kickoff</p></li><li><p>incorporates global betting pressure</p></li><li><p>reacts instantly to breaking news</p></li></ul><p>So would it be surprising if a <strong>static</strong>, pre-game, publicly available rating system consistently beat the closing line of the sharpest bookmaker in the world?</p><blockquote><p><em><strong>No &#8212; exatly the opposite would be suprising.</strong></em></p></blockquote><p>Having said that, here&#8217;s how SPI&#8217;s predicted probabilities fared against the actual results. In the chart below, we compare <strong>SPI&#8217;s probabilities</strong> to those implied by <strong>Pinnacle&#8217;s closing odds</strong>, and we check how well each aligns with reality. </p><p>A perfectly calibrated model would sit right on the dashed 45&#176; line &#8212; meaning that events predicted at 30% really happen 30% of the time, 60% events happen 60% of the time, and so on.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zZ_R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zZ_R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png 424w, https://substackcdn.com/image/fetch/$s_!zZ_R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png 848w, https://substackcdn.com/image/fetch/$s_!zZ_R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png 1272w, https://substackcdn.com/image/fetch/$s_!zZ_R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zZ_R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png" width="619" height="427.38994974874373" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc404b5e-100a-47db-bac5-f901035e30ff_995x687.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:687,&quot;width&quot;:995,&quot;resizeWidth&quot;:619,&quot;bytes&quot;:60699,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/181040224?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zZ_R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png 424w, https://substackcdn.com/image/fetch/$s_!zZ_R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png 848w, https://substackcdn.com/image/fetch/$s_!zZ_R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png 1272w, https://substackcdn.com/image/fetch/$s_!zZ_R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc404b5e-100a-47db-bac5-f901035e30ff_995x687.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Pinnacle (blue)</strong> is (for the most part) almost glued to that line. This is exactly what you&#8217;d expect from the sharpest bookmaker in the world. Their odds, once binned at 2.5% intervals, map extremely closely to actual match outcomes. When Pinnacle says something is 70% likely, it really <em>is</em> about 70% likely.</p><p><strong>SPI (orange)</strong>, however, shows consistent patterns of miscalibration:</p><ul><li><p><strong>At low probabilities</strong>, SPI <em>underestimates</em> the probabilities&#8212; for example events it predicted at 5% happened around 9% of the time.</p></li><li><p><strong>Across most of the range (10&#8211;90%)</strong>, SPI systematically <em>overestimates</em> true frequencies &#8212; for example, matches it rated at 50% actually occurred only 41% of the time.</p></li><li><p><strong>At high probabilities (90&#8211;100%)</strong>, SPI becomes too conservative again, assigning lower win chances than what actually happened on the pitch.</p></li></ul><p>In simple terms: <em><strong>SPI gets the direction right, but the confidence wrong.</strong></em></p><p>It knows which team is stronger, but it consistently misjudges <em>by how much</em>. And this miscalibration is exactly why betting strictly on SPI&#8217;s probabilities &#8212; without adjustments &#8212; fails to beat Pinnacle. Pinnacle isn&#8217;t just predicting winners; it&#8217;s capturing the <em>true likelihood</em> with remarkable precision.</p><div><hr></div><h2><em><strong>A broader reminder</strong></em></h2><p>This little experiment highlights an important point: even well-constructed &#8220;super-computer&#8221; models have limits. FiveThirtyEight&#8217;s SPI was analytically strong, but that doesn&#8217;t automatically translate into beating the sharpest sports betting markets on a match-by-match basis &#8212; and it was never designed to.</p><p>End-of-season simulations, title probabilities, and playoff chances were always where SPI shined. These tools are incredibly valuable for understanding long-term dynamics, but they are still just simulations. They don&#8217;t replace real-time information, market pressure, or closing-line pricing.</p><p>And to be clear: SPI <em>was</em> useful &#8212; very much so.<br>It consistently captured <strong>directional team strength</strong>, meaning it generally understood who the stronger and weaker sides were based on recent performance. It was also <strong>transparent</strong> in how it was built (combining xG and non-shot xG), which allowed you to adjust ratings yourself. If you felt a team was over- or under-performing those metrics you could mentally nudge the probabilities up or down.</p><p>So no, SPI couldn&#8217;t beat Pinnacle&#8217;s game-by-game closing odds. But that&#8217;s an unrealistic benchmark for any static pre-game public model.</p><p>What SPI <em>did</em> provide was a solid, interpretable foundation &#8212; a starting point for reasoning about team quality, season trajectories, and long-term probabilities. And for most fans, analysts, and hobbyist forecasters, that is already incredibly powerful.</p><div><hr></div><p>Boom &#8212; that was FiveThirtyEight vs Pinncle.</p><p>This was a fun exercise, even if I&#8217;m a little disappointed the curve ends well below zero. I honestly expected something slightly closer to breakeven. </p><p>But maybe that&#8217;s the next step &#8212; building a more refined, bottom-up forecasting model that incorporates last-minute news and seeing whether that can close the gap.</p><p>If you want to reproduce the results yourself, the code is available below.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/PythonFootball/PythonFootballReview/tree/main/pfr_019&quot;,&quot;text&quot;:&quot;Download Python Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/PythonFootball/PythonFootballReview/tree/main/pfr_019"><span>Download Python Code</span></a></p><div><hr></div><p>Thanks for reading all the way to the end.</p><p>See you next week,<br><strong>Martin</strong></p>]]></content:encoded></item><item><title><![CDATA[The Death of the Long-Range Screamer]]></title><description><![CDATA[A myth or reality?]]></description><link>https://www.footballmarketreview.com/p/the-death-of-the-long-range-screamer</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/the-death-of-the-long-range-screamer</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 04 Dec 2025 14:09:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uIL6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Ever since the xG revolution took place, everyone loves saying that <em>xG killed long-range screamers</em>. Well &#8230; that sounds like the perfect topic for this little newsletter. </p><p>Welcome to <em>The Python Football Review #018.</em></p><p>In this issue, you&#8217;ll learn:</p><ul><li><p>how much the average shot distance has dropped over the last 11 seasons</p></li><li><p>whether this shift actually affected conversion rates</p></li><li><p>and whether the &#8220;death of the screamer&#8221; is a myth or a real trend</p></li></ul><p>As always, the full code is available at the end so you can reproduce the analysis from scratch, check the numbers, and mock my conclusions if you want.</p><p>Let&#8217;s get into it.</p><div><hr></div><h2><em>A few words on the data</em></h2><p>For this study, we&#8217;ll use <strong>11 seasons of data (2014/15 to 2024/25)</strong> from Europe&#8217;s top five leagues, courtesy of <strong>Understat</strong> (via <code>soccerdata</code>). The dataset includes roughly <strong>half a million shots</strong>. We focus solely on <strong>open-play shots</strong>.</p><p>The data is already clean. We just need to add three features:</p><ol><li><p><strong>shot distance in meters</strong>, calculated from the pitch coordinates of each shot</p></li><li><p>a <strong>dummy variable (1/0) for shots outside the box</strong></p></li><li><p>a <strong>dummy variable for shots taken from 25+ meters</strong> (our definition of a long-range shot)</p></li></ol><div><hr></div><h1><em><strong>1 &#8212; How did shot volume evolve?</strong></em></h1><p>Across Europe&#8217;s top five leagues, the average number of open-play shots per match has been remarkably stable. In 2014/15 we recorded <strong>16.6 shots per match</strong>, and in 2024/25&#8230; also <strong>16.6</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DnyJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DnyJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png 424w, https://substackcdn.com/image/fetch/$s_!DnyJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png 848w, https://substackcdn.com/image/fetch/$s_!DnyJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!DnyJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DnyJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:566711,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!DnyJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png 424w, https://substackcdn.com/image/fetch/$s_!DnyJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png 848w, https://substackcdn.com/image/fetch/$s_!DnyJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!DnyJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f51b710-b1c7-4f92-b40f-f7db09eb6bd5_2418x1382.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There&#8217;s some negligible year-to-year variance, but nothing that suggests a structural change. So no, teams are not shooting less overall.</p><p>What about the shots from outside the box? Now it gets interesting. Outside-the-box shots fell from <strong>8.6 to 6.9 per match</strong> &#8212; a <strong>20% decline</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8Pmp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8Pmp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png 424w, https://substackcdn.com/image/fetch/$s_!8Pmp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png 848w, https://substackcdn.com/image/fetch/$s_!8Pmp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png 1272w, https://substackcdn.com/image/fetch/$s_!8Pmp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8Pmp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png" width="1456" height="828" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:828,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:566703,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!8Pmp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png 424w, https://substackcdn.com/image/fetch/$s_!8Pmp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png 848w, https://substackcdn.com/image/fetch/$s_!8Pmp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png 1272w, https://substackcdn.com/image/fetch/$s_!8Pmp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79566c53-55d0-426f-a970-ffd78dd7eb26_2394x1362.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And what about the shots from 25 meters or more (i.e. the &#8220;screamer zone&#8221;) ? These shots dropped from <strong>5.4 to 3.7 per match</strong> &#8212; a <strong>31% drop</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!80_p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!80_p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png 424w, https://substackcdn.com/image/fetch/$s_!80_p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png 848w, https://substackcdn.com/image/fetch/$s_!80_p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png 1272w, https://substackcdn.com/image/fetch/$s_!80_p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!80_p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png" width="1456" height="837" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:837,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:568342,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!80_p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png 424w, https://substackcdn.com/image/fetch/$s_!80_p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png 848w, https://substackcdn.com/image/fetch/$s_!80_p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png 1272w, https://substackcdn.com/image/fetch/$s_!80_p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a3f6bc9-20da-4bbb-afd8-a3429830a9b7_2418x1390.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is the trend people usually talk about when they say &#8220;xG killed long-range shots,&#8221; and to be fair, the decline <em>is</em> real and observable across all leagues. </p><div><hr></div><h1><em><strong>2 &#8212; What about shot distance?</strong></em></h1><p>Across all open-play shots, the <strong>average shot distance</strong> dropped from <strong>20.8m to 19.1m</strong> &#8212; an <strong>8% decrease</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uIL6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uIL6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png 424w, https://substackcdn.com/image/fetch/$s_!uIL6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png 848w, https://substackcdn.com/image/fetch/$s_!uIL6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!uIL6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uIL6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png" width="1456" height="827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:827,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:616779,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!uIL6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png 424w, https://substackcdn.com/image/fetch/$s_!uIL6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png 848w, https://substackcdn.com/image/fetch/$s_!uIL6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!uIL6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401a6811-3e91-4438-b4ca-d8e632de4140_2430x1380.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Outside-the-box shots distance dropped from <strong>27m to around 26m</strong> &#8212; roughly <strong>4% down</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1dTw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1dTw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png 424w, https://substackcdn.com/image/fetch/$s_!1dTw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png 848w, https://substackcdn.com/image/fetch/$s_!1dTw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!1dTw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1dTw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png" width="1456" height="837" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:837,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:613242,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!1dTw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png 424w, https://substackcdn.com/image/fetch/$s_!1dTw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png 848w, https://substackcdn.com/image/fetch/$s_!1dTw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png 1272w, https://substackcdn.com/image/fetch/$s_!1dTw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8eda64f8-1260-402d-b59b-14298577fe9e_2404x1382.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As for true long-range efforts (25m+), the average distance basically stayed the same. Don&#8217;t be misled by the upward-sloping line in the chart &#8212; yes, it&#8217;s increasing, but the Y-axis range is only 1.6 meters. Technically, between 2014/15 and 2024/25, the average distance rose by just <strong>0.8%</strong>, from <strong>29.93m to 30.17m</strong>. In other words, not significant.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1a7x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1a7x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png 424w, https://substackcdn.com/image/fetch/$s_!1a7x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png 848w, https://substackcdn.com/image/fetch/$s_!1a7x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png 1272w, https://substackcdn.com/image/fetch/$s_!1a7x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1a7x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png" width="1456" height="825" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:825,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:720827,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!1a7x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png 424w, https://substackcdn.com/image/fetch/$s_!1a7x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png 848w, https://substackcdn.com/image/fetch/$s_!1a7x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png 1272w, https://substackcdn.com/image/fetch/$s_!1a7x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6d1a732-7c8a-45a1-ace6-1bbb237f12a3_2420x1372.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Taken together, this section paints a clear picture:</p><blockquote><p><em><strong>Teams take the same number of shots as before &#8212; but they take far fewer from long range. </strong></em></p></blockquote><p>Thank you, Captain Obvious. Now that we confirmed what everobody talked about, let&#8217;s get into the conversion rates.</p><div><hr></div><h1><em><strong>3 &#8212; Conversion rates</strong></em></h1><p>Now comes the fun part: Has this shift actually hurt long-range scoring?</p><p>Across all open-play shots, conversion increased from <strong>9.3% to 10.8%</strong> &#8212; a <strong>1.5 percentage point increase</strong>. Should not come as a surprise since shots are being taken from closer positions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!utjv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!utjv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png 424w, https://substackcdn.com/image/fetch/$s_!utjv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png 848w, https://substackcdn.com/image/fetch/$s_!utjv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png 1272w, https://substackcdn.com/image/fetch/$s_!utjv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!utjv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png" width="1456" height="844" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:844,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:674668,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!utjv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png 424w, https://substackcdn.com/image/fetch/$s_!utjv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png 848w, https://substackcdn.com/image/fetch/$s_!utjv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png 1272w, https://substackcdn.com/image/fetch/$s_!utjv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F552f52f2-ac68-4e3e-a77d-6b67b5ea4948_2412x1398.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Outside-the-box conversion rose from <strong>3.3% to 4.6%</strong> &#8212; up <strong>1.3 percentage points</strong>, which is meaningful at that low baseline.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CtLK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CtLK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png 424w, https://substackcdn.com/image/fetch/$s_!CtLK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png 848w, https://substackcdn.com/image/fetch/$s_!CtLK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png 1272w, https://substackcdn.com/image/fetch/$s_!CtLK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CtLK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png" width="1456" height="844" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:844,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:681592,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!CtLK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png 424w, https://substackcdn.com/image/fetch/$s_!CtLK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png 848w, https://substackcdn.com/image/fetch/$s_!CtLK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png 1272w, https://substackcdn.com/image/fetch/$s_!CtLK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ff5a27-b89c-41d8-ae08-f7540b3ef536_2422x1404.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As for the long-range shots, conversion increased from <strong>1.7% to 2.8%</strong> &#8212; a <strong>1.1 pp increase</strong>, the <strong>largest relative jump</strong> of all.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8ktD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8ktD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png 424w, https://substackcdn.com/image/fetch/$s_!8ktD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png 848w, https://substackcdn.com/image/fetch/$s_!8ktD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png 1272w, https://substackcdn.com/image/fetch/$s_!8ktD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8ktD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png" width="1456" height="844" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:844,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:712284,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!8ktD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png 424w, https://substackcdn.com/image/fetch/$s_!8ktD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png 848w, https://substackcdn.com/image/fetch/$s_!8ktD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png 1272w, https://substackcdn.com/image/fetch/$s_!8ktD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa936b23a-3dae-48ea-af11-7065a40c8a55_2406x1394.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>What appears to be happening is teams <em>keeping </em>the risky long shots out of the game.</p><p>Long-range shots are clearly on the decline. On average, you&#8217;ll only see <strong>1.7 true long-range attempts per match</strong> today. But when teams <em>do</em> shoot from distance, the chances of observing a goal as a spectator are <strong>65% higher than a decade ago</strong>.</p><p>Why? Because only the right players are allowed to try. The long-range &#8220;permission&#8221; has shifted from <em>everyone</em> to <em>only the players who can actually hit them</em>.</p><div><hr></div><h1><em><strong>So did xG kill the long-range screamers?</strong></em></h1><p>Yes, the average shot distance dropped. Yes, the volume of long-range shots dropped &#8212; dramatically. But the idea that screamers are &#8220;dead&#8221; is&#8230; incomplete.</p><p>If you care about <strong>volume</strong>, then yes, long-range shooting is fading.</p><p>If you care about <strong>expected reward</strong>, then screamers are alive and well &#8212; in fact, they&#8217;re converting at the highest rates we&#8217;ve seen in more than a decade.</p><p>Modern footballers haven&#8217;t stopped shooting from range &#8212; they&#8217;ve simply stopped shooting <strong>bad</strong> long-range shots.</p><p>So the next time your Granit Xhaka (or your Declan Rice, or your Enzo Fern&#225;ndez) winds up from 25 yards&#8230; well, the numbers say it&#8217;s a <em>better</em> shot today than it was back in 2014.</p><p>And before I leave you, here&#8217;s the scatter plot of every player who attempted at least 30 shots across the dataset. Dotted lines are the medians.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jstb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jstb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png 424w, https://substackcdn.com/image/fetch/$s_!jstb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png 848w, https://substackcdn.com/image/fetch/$s_!jstb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png 1272w, https://substackcdn.com/image/fetch/$s_!jstb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jstb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png" width="1456" height="986" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:986,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:697281,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/180443025?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!jstb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png 424w, https://substackcdn.com/image/fetch/$s_!jstb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png 848w, https://substackcdn.com/image/fetch/$s_!jstb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png 1272w, https://substackcdn.com/image/fetch/$s_!jstb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F103642cf-9c2c-44d5-9f07-444a5525b5d7_2008x1360.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There&#8217;s one dot sitting right above the <strong>9% conversion from 31 meters</strong>. That&#8217;s <strong>Xabi Alonso</strong> &#8212; as if you needed reminding of how outrageous he was from range.</p><div><hr></div><p>Boom &#8212; and that&#8217;s the story behind the supposed death of the long-range screamer.</p><p>If you&#8217;re interested in replicating all the figures from scratch, you can download the full code below.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/PythonFootball/PythonFootballReview/blob/main/PFR_018_long_range_shots.ipynb&quot;,&quot;text&quot;:&quot;Download the Python Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/PythonFootball/PythonFootballReview/blob/main/PFR_018_long_range_shots.ipynb"><span>Download the Python Code</span></a></p><p>As always, thank you for reading all the way to the end.</p><p>See you next week,</p><p><em>Martin</em></p>]]></content:encoded></item><item><title><![CDATA[Which xG Data Should You Trust?]]></title><description><![CDATA[Opta, StatsBomb, Wyscout and Understat &#8212; the head-to-head comparison nobody shows you.]]></description><link>https://www.footballmarketreview.com/p/which-xg-data-should-you-trust</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/which-xg-data-should-you-trust</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 20 Nov 2025 09:01:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!kJPR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>StatsBomb loves reminding us that <em><strong>&#8220;not all xG is created equal.&#8221;</strong></em></p><p>So I decided to put that to the test.</p><p>Welcome to <em><strong>The Python Football Review #017</strong></em> &#8212; an edition where we compare xG from four of the most widely used sources in football analytics: <strong>Opta, StatsBomb, Wyscout and Understat</strong>.</p><p>By the end of it, you&#8217;ll learn:</p><ul><li><p>How closely the four providers agree on the same matches</p></li><li><p>How quickly their xG trends converge as the season unfolds</p></li><li><p>Which models consistently diverge</p></li><li><p>And how different your league table would look depending on which xG provider you trust</p></li></ul><p>Let&#8217;s dive in.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kJPR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kJPR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!kJPR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!kJPR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!kJPR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kJPR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2534612,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kJPR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!kJPR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!kJPR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!kJPR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcfec9a9-8091-46aa-b2f8-43adcd281527_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h1>1 &#8212; The Data</h1><p>For this edition, we&#8217;re working with five full seasons of matches (2017/18 to 2021/22) across the Premier League, Bundesliga, Serie A, La Liga and Ligue 1. </p><p>For every game, the dataset includes the <em><strong>full-time xG scoreline</strong></em> from four sources: <a href="https://theanalyst.com/">Opta</a>, <a href="https://www.hudl.com/en_gb/products/statsbomb">StatsBomb</a>, <a href="https://www.hudl.com/en_gb/products/wyscout">Wyscout</a> and <a href="https://understat.com/">Understat</a>. Here&#8217;s a quick look at the structure of the dataset:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2Utb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2Utb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png 424w, https://substackcdn.com/image/fetch/$s_!2Utb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png 848w, https://substackcdn.com/image/fetch/$s_!2Utb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png 1272w, https://substackcdn.com/image/fetch/$s_!2Utb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2Utb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png" width="1456" height="477" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:477,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:157507,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2Utb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png 424w, https://substackcdn.com/image/fetch/$s_!2Utb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png 848w, https://substackcdn.com/image/fetch/$s_!2Utb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png 1272w, https://substackcdn.com/image/fetch/$s_!2Utb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a49ac8f-00bd-41aa-b92e-b542fb85b4fa_1986x650.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Two quick disclaimers before we go further: </em></p><ul><li><p><em>For obvious reasons, I can&#8217;t share the full dataset &#8212; which also makes sharing the Python code somewhat pointless, since you wouldn&#8217;t be able to reproduce the tables without the underlying data. (So no Python template for this edition.)</em></p></li><li><p><em>The four sources were extracted at different points in time: <strong>StatsBomb</strong> &#8594; May 2022, <strong>Wyscout</strong> &#8594; October 2022, <strong>Opta</strong> &#8594; May 2023, <strong>Understat</strong> &#8594; November 2025. I mention this because some providers occasionally retro-update past xG values (more on that in the end). If any discrepancies show up, timing could be part of the explanation.</em></p></li></ul><div><hr></div><h2><strong>How complete is the dataset?</strong></h2><p>Across the five leagues and five seasons, we&#8217;re very close to full coverage. A handful of matches are missing because <strong>at least one provider had no xG values</strong> for that game. The 2019/20 Ligue 1 season was interrupted due to Covid, hence the 279 games.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0GD8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0GD8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png 424w, https://substackcdn.com/image/fetch/$s_!0GD8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png 848w, https://substackcdn.com/image/fetch/$s_!0GD8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png 1272w, https://substackcdn.com/image/fetch/$s_!0GD8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0GD8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png" width="456" height="194.59872611464968" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b4835af-d1c8-4728-af39-31f970c34293_942x402.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:402,&quot;width&quot;:942,&quot;resizeWidth&quot;:456,&quot;bytes&quot;:55316,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0GD8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png 424w, https://substackcdn.com/image/fetch/$s_!0GD8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png 848w, https://substackcdn.com/image/fetch/$s_!0GD8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png 1272w, https://substackcdn.com/image/fetch/$s_!0GD8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b4835af-d1c8-4728-af39-31f970c34293_942x402.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Overall, it&#8217;s a very healthy sample.</p><div><hr></div><h2><strong>Basic descriptive statistics</strong></h2><p>Before diving deeper, let&#8217;s look at some classic descriptive stats &#8212; the mean, median, standard deviation and maximum xG values across all teams, all games and all providers.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UJu7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UJu7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png 424w, https://substackcdn.com/image/fetch/$s_!UJu7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png 848w, https://substackcdn.com/image/fetch/$s_!UJu7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png 1272w, https://substackcdn.com/image/fetch/$s_!UJu7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UJu7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png" width="308" height="160.93693693693695" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:348,&quot;width&quot;:666,&quot;resizeWidth&quot;:308,&quot;bytes&quot;:42139,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!UJu7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png 424w, https://substackcdn.com/image/fetch/$s_!UJu7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png 848w, https://substackcdn.com/image/fetch/$s_!UJu7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png 1272w, https://substackcdn.com/image/fetch/$s_!UJu7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49f37709-c18c-4a17-a1b2-38eef7350016_666x348.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>A few quick observations:</p><ul><li><p><strong>StatsBomb and Opta</strong> are similar across every summary metric.</p></li><li><p><strong>Understat</strong> runs slightly higher on average (mean team xG = 1.38) and just about the same median-wise (1.22).</p></li><li><p><strong>Wyscout</strong> is the most generous model in this sample &#8212; highest mean (1.44), highest variance and the highest maximum single-team xG per match.</p></li></ul><p>But this is just basic summary stuff. Let&#8217;s now look at the <strong>full distributions</strong>.</p><div><hr></div><h1>2 &#8212; Comparing xG distributions across providers</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!09bg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!09bg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png 424w, https://substackcdn.com/image/fetch/$s_!09bg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png 848w, https://substackcdn.com/image/fetch/$s_!09bg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png 1272w, https://substackcdn.com/image/fetch/$s_!09bg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!09bg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png" width="1456" height="701" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:701,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:286107,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!09bg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png 424w, https://substackcdn.com/image/fetch/$s_!09bg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png 848w, https://substackcdn.com/image/fetch/$s_!09bg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png 1272w, https://substackcdn.com/image/fetch/$s_!09bg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc1af10c-b630-4303-b948-7f1a21d029ec_1990x958.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>How to read this figure</strong></h3><p>This is a smoothed distribution (a <a href="https://mathisonian.github.io/kde/">KDE curve</a>) of all xG values assigned per team per match. It shows how often each xG level occurs across thousands of matches.</p><p>The <strong>x-axis</strong> is the xG a team had in a match (0 &#8594; 7). The <strong>y-axis</strong> is a relative frequency: higher peaks mean &#8220;this xG value happens more often.&#8221;</p><ul><li><p>Where the curves sit <em>higher</em>, that provider gives those xG values more frequently.</p></li><li><p>Where the curves tail off <em>more slowly</em>, that provider gives more high-xG games.</p></li></ul><p>The exact height doesn&#8217;t matter &#8212; it&#8217;s the <em><strong>shape </strong></em>and <em><strong>position </strong></em>of each curve relative to the others.</p><h2><strong>What we learn from it</strong></h2><ul><li><p><em><strong>Opta and StatsBomb are nearly identical.</strong></em> Their curves overlap almost perfectly, which tells us the two models likely behave very similarly on a match-by-match basis.</p></li><li><p><em>Understat</em> runs a bit higher at the very low end (below ~0.4 xG) and again at the higher end (above ~2.3 xG), while sitting slightly lower in the middle. A subtle but noticeable difference.</p></li><li><p><em>Wyscout</em> assigns the lowest xG values up to around 1.5, and then consistently shifts furthest to the right with the heaviest tail. In other words, <em><strong>Wyscout hands out higher xG more often and produces the most extreme single-match xG values</strong></em>.</p></li></ul><h2><strong>Match-level agreement between providers</strong></h2><p>To complement the distribution plots, here&#8217;s a simple correlation matrix comparing each provider&#8217;s <strong>match-level xG values</strong>. Each number is a Pearson correlation: <strong>1.00 means identical behaviour</strong>, lower values mean more disagreement.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d0OH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d0OH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png 424w, https://substackcdn.com/image/fetch/$s_!d0OH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png 848w, https://substackcdn.com/image/fetch/$s_!d0OH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png 1272w, https://substackcdn.com/image/fetch/$s_!d0OH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d0OH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png" width="494" height="330.1865284974093" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:774,&quot;width&quot;:1158,&quot;resizeWidth&quot;:494,&quot;bytes&quot;:152782,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!d0OH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png 424w, https://substackcdn.com/image/fetch/$s_!d0OH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png 848w, https://substackcdn.com/image/fetch/$s_!d0OH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png 1272w, https://substackcdn.com/image/fetch/$s_!d0OH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96f4ab0e-ec21-4ae5-8b50-8b79418f4775_1158x774.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>What this tells us:</h3><ul><li><p><strong>Opta &#215; Understat</strong> show the strongest alignment at match level (0.96).</p></li><li><p><strong>Opta &#215; StatsBomb</strong> and <strong>StatsBomb &#215; Understat</strong> are also very tight (&#8776;0.92&#8211;0.93).</p></li><li><p><strong>Wyscout is an outlier</strong> &#8212; its match-level xG correlates the least with everybody else (0.86&#8211;0.88 range).</p></li></ul><p>Here are a few scatterplot (with linear fits on top) before we zoom out ask a bigger question: <em><strong>How quickly do these (small?) differences disappear once we look at season-long trends instead of single matches?</strong></em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CkvV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CkvV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png 424w, https://substackcdn.com/image/fetch/$s_!CkvV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png 848w, https://substackcdn.com/image/fetch/$s_!CkvV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png 1272w, https://substackcdn.com/image/fetch/$s_!CkvV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CkvV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png" width="1456" height="633" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:633,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:655836,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CkvV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png 424w, https://substackcdn.com/image/fetch/$s_!CkvV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png 848w, https://substackcdn.com/image/fetch/$s_!CkvV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png 1272w, https://substackcdn.com/image/fetch/$s_!CkvV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed493864-9aeb-49db-bb3a-5290d0a12493_2384x1036.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!V7pZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!V7pZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png 424w, https://substackcdn.com/image/fetch/$s_!V7pZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png 848w, https://substackcdn.com/image/fetch/$s_!V7pZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png 1272w, https://substackcdn.com/image/fetch/$s_!V7pZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!V7pZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png" width="1456" height="622" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:622,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:609404,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!V7pZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png 424w, https://substackcdn.com/image/fetch/$s_!V7pZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png 848w, https://substackcdn.com/image/fetch/$s_!V7pZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png 1272w, https://substackcdn.com/image/fetch/$s_!V7pZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faba6cd9f-7a48-4a7e-b1e3-93e1926c80a2_2384x1018.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Iy9x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Iy9x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png 424w, https://substackcdn.com/image/fetch/$s_!Iy9x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png 848w, https://substackcdn.com/image/fetch/$s_!Iy9x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png 1272w, https://substackcdn.com/image/fetch/$s_!Iy9x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Iy9x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png" width="1456" height="626" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:626,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:669062,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Iy9x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png 424w, https://substackcdn.com/image/fetch/$s_!Iy9x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png 848w, https://substackcdn.com/image/fetch/$s_!Iy9x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png 1272w, https://substackcdn.com/image/fetch/$s_!Iy9x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea70e349-cf1c-40f2-a2bc-f9152cc3adaa_2376x1022.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h1>3 &#8212; How quickly do providers <em>agree</em> as the season unfolds?</h1><p>So far, we&#8217;ve looked at <em>individual</em> xG values. But single matches only get you so far.</p><p>To really understand how similar the providers are, we need to zoom out and look at what happens <strong>as the season progresses</strong>. Instead of comparing isolated xG values, we compare <strong>each team&#8217;s cumulative xG difference</strong> &#8212; the running total of <em>xG</em> <em>for</em> minus <em>xG against</em> &#8212; and check how closely the providers track each other over time.</p><p>In other words: <em><strong>As teams pile up more matches, how quickly do the providers&#8217; season-long xG trends start agreeing with one another?</strong></em></p><p>That&#8217;s exactly what the chart below shows.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lJ6K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lJ6K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png 424w, https://substackcdn.com/image/fetch/$s_!lJ6K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png 848w, https://substackcdn.com/image/fetch/$s_!lJ6K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png 1272w, https://substackcdn.com/image/fetch/$s_!lJ6K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lJ6K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png" width="530" height="321.0576923076923" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:882,&quot;width&quot;:1456,&quot;resizeWidth&quot;:530,&quot;bytes&quot;:309014,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!lJ6K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png 424w, https://substackcdn.com/image/fetch/$s_!lJ6K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png 848w, https://substackcdn.com/image/fetch/$s_!lJ6K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png 1272w, https://substackcdn.com/image/fetch/$s_!lJ6K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72a8e060-4d5e-4b00-b113-48149800a279_1584x960.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>What you&#8217;re looking at</strong></h3><p>Each line shows (once more) the <strong>Pearson correlation</strong> (the one you first learned at school) between two providers&#8217; <strong>cumulative xG differences</strong> at each match week. A value of <strong>1.0</strong> means the two providers generate <em>identical</em> season-long curves. A value of <strong>0</strong> means the curves have nothing in common. Put simply: <strong>the higher the line, the stronger the agreement.</strong></p><h2><strong>What we learn from this</strong></h2><p>First, notice that <strong>all provider pairs start fairly high</strong> &#8212; even the least aligned pair begins around <strong>0.87</strong>, which is already strong. </p><p>But some pairs converge faster and more tightly than others. Three clear clusters emerge:</p><ol><li><p><em><strong>Opta x Understat:</strong></em><strong> the fastest and strongest agreement. </strong>After just a few matches, they&#8217;re already above <strong>0.97</strong>, and by the end of the season they&#8217;re sitting at <strong>0.99</strong>. These two tell virtually the same season-long story.</p></li><li><p><em><strong>Opta x StatsBomb</strong></em><strong> and </strong><em><strong>StatsBomb x Understat</strong></em><strong>: the middle cluster. </strong>By the 15-game mark, both pairs push past <strong>0.98</strong>. Consistent, tight, and very stable.</p></li><li><p><em><strong>Anything involving Wyscout: the outlier. </strong></em>Pairs with Wyscout start lower (<strong>0.88&#8211;0.90</strong>) and take longer to catch up. Even late in the season they peak slightly below the others. Wyscout &#8220;thinks differently,&#8221; but still gets close in the long run.</p></li></ol><p>By season&#8217;s end, every pair reaches very strong agreement (&gt;0.97). <em><strong>That tells us that while providers may disagree on individual matches, their season-long signals eventually converge &#8212; even for Wyscout.</strong></em></p><div><hr></div><h1>4 &#8212; Biggest differences</h1><p>Now that we understand <em>how</em> the providers move together, let&#8217;s look at something a bit more fun (and perhaps more intuitive): <em><strong>How often do providers disagree on who &#8220;won&#8221; the xG battle in a match?</strong></em></p><p>For every game, we&#8217;ll assign a winner based on which team created more xG (according to each provider). That gives us three possible scenarios:</p><p><strong>Scenario 1 &#8212; All four providers agree</strong></p><p>Example: <strong>Tottenham vs Arsenal (20/21) &#8212; </strong>Even though Spurs won on the scoreboard, all four models agree Arsenal created the better chances. (Why this happens is a newsletter of its own&#8230;)</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!q9Z5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q9Z5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png 424w, https://substackcdn.com/image/fetch/$s_!q9Z5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png 848w, https://substackcdn.com/image/fetch/$s_!q9Z5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png 1272w, https://substackcdn.com/image/fetch/$s_!q9Z5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q9Z5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png" width="1456" height="275" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:275,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:87821,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!q9Z5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png 424w, https://substackcdn.com/image/fetch/$s_!q9Z5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png 848w, https://substackcdn.com/image/fetch/$s_!q9Z5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png 1272w, https://substackcdn.com/image/fetch/$s_!q9Z5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc78222-cbc8-4bc5-8315-0abe9b0e134d_1960x370.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Scenario 2 &#8212; One provider disagrees</strong></p><p>Example: <strong>Everton vs Brighton &#8212; </strong>Three models choose the same xG winner. The fourth &#8212; <em>Wyscout in this case</em> &#8212; goes the other way.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Eerx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Eerx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png 424w, https://substackcdn.com/image/fetch/$s_!Eerx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png 848w, https://substackcdn.com/image/fetch/$s_!Eerx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png 1272w, https://substackcdn.com/image/fetch/$s_!Eerx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Eerx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png" width="1456" height="263" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:263,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85603,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Eerx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png 424w, https://substackcdn.com/image/fetch/$s_!Eerx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png 848w, https://substackcdn.com/image/fetch/$s_!Eerx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png 1272w, https://substackcdn.com/image/fetch/$s_!Eerx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04d61dbe-dac6-4ac7-90b1-ba3830c690b8_1968x356.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Scenario 3 &#8212; A 2-vs-2 split</strong></p><p>Example: <strong>Liverpool vs Leeds &#8212; </strong>Opta + Understat (in this case) on one side, StatsBomb + Wyscout on the other.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-3HV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-3HV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png 424w, https://substackcdn.com/image/fetch/$s_!-3HV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png 848w, https://substackcdn.com/image/fetch/$s_!-3HV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png 1272w, https://substackcdn.com/image/fetch/$s_!-3HV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-3HV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png" width="1456" height="273" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:273,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85821,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-3HV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png 424w, https://substackcdn.com/image/fetch/$s_!-3HV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png 848w, https://substackcdn.com/image/fetch/$s_!-3HV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png 1272w, https://substackcdn.com/image/fetch/$s_!-3HV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd563abd-2021-4585-a6ca-7b06fffc4312_1966x368.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2><strong>How often does each scenario occur?</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9_7N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9_7N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png 424w, https://substackcdn.com/image/fetch/$s_!9_7N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png 848w, https://substackcdn.com/image/fetch/$s_!9_7N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png 1272w, https://substackcdn.com/image/fetch/$s_!9_7N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9_7N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png" width="422" height="132.1735849056604" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:166,&quot;width&quot;:530,&quot;resizeWidth&quot;:422,&quot;bytes&quot;:30520,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9_7N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png 424w, https://substackcdn.com/image/fetch/$s_!9_7N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png 848w, https://substackcdn.com/image/fetch/$s_!9_7N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png 1272w, https://substackcdn.com/image/fetch/$s_!9_7N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33ce1057-99b6-4382-80d2-1c21ca7f357d_530x166.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Across all five seasons and all five leagues, here&#8217;s the breakdown:</p><ul><li><p><strong>76.1%</strong> of games &#8594; <em>all four providers agree</em></p></li><li><p><strong>15.9%</strong> &#8594; <em>exactly one provider disagrees</em></p></li><li><p><strong>8.0%</strong> &#8594; <em>a 2&#8211;2 split</em></p></li></ul><p>I don&#8217;t know if this surprises you, but next time you&#8217;re unhappy with <em><a href="https://x.com/xGPhilosophy">xGPhilosophy</a>&#8217;s</em> scoreline on X, remember this: in roughly <strong>1 out of 4 games</strong>, you can turn to another provider and find a different xG storyline to defend your team&#8217;s dignity &#8212; or to complain that xG is &#8220;broken.&#8221;</p><p><em>(That was irony for the xG haters out there.)</em></p><p>Moving on&#8230;</p><div><hr></div><h2><strong>Who is the lone dissenter?</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!o7mz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!o7mz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png 424w, https://substackcdn.com/image/fetch/$s_!o7mz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png 848w, https://substackcdn.com/image/fetch/$s_!o7mz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png 1272w, https://substackcdn.com/image/fetch/$s_!o7mz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!o7mz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png" width="250" height="200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:200,&quot;width&quot;:250,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:21325,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!o7mz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png 424w, https://substackcdn.com/image/fetch/$s_!o7mz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png 848w, https://substackcdn.com/image/fetch/$s_!o7mz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png 1272w, https://substackcdn.com/image/fetch/$s_!o7mz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1d5faf4d-a7b4-4a94-9729-21972b93b030_250x200.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>When <em>exactly one</em> model goes its own way, it&#8217;s overwhelmingly <strong>Wyscout with 45% of all 1-dissenter games. </strong>StatsBomb follows with 23% and then come Understat and Opta with 16%. No shock here &#8212; at this point in the newsletter, Wyscout consistently emerges as the &#8220;free spirit&#8221; of the group.</p><div><hr></div><h2><strong>Which pairs disagree together in 2-vs-2 splits?</strong></h2><p>When we get a split vote, here&#8217;s how it breaks down:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!t7lT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!t7lT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png 424w, https://substackcdn.com/image/fetch/$s_!t7lT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png 848w, https://substackcdn.com/image/fetch/$s_!t7lT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png 1272w, https://substackcdn.com/image/fetch/$s_!t7lT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!t7lT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png" width="298" height="228.73513513513512" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:284,&quot;width&quot;:370,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:44787,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!t7lT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png 424w, https://substackcdn.com/image/fetch/$s_!t7lT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png 848w, https://substackcdn.com/image/fetch/$s_!t7lT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png 1272w, https://substackcdn.com/image/fetch/$s_!t7lT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d2f0120-b3ed-411d-a9b1-f1ff4f9c5bc8_370x284.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The way to read this table is simple: among all <strong>2-vs-2 split</strong> games, <strong>38.6%</strong> of the time it&#8217;s <strong>StatsBomb + Wyscout</strong> teaming up. In <strong>21.5%</strong> of cases it&#8217;s <strong>Understat + Wyscout</strong>, and in <strong>15.4%</strong> of cases it&#8217;s <strong>StatsBomb + Understat</strong>.</p><p>Once again, Wyscout is the model that most often breaks away from the others. (And I promise I&#8217;m <em>not</em> trying to make this newsletter about Wyscout &#8212; the numbers are doing it for me.)</p><div><hr></div><h1><strong>5 &#8212; Who Ranks Teams the Most Differently?</strong></h1><p>Let&#8217;s now move from match-level disagreements to something even more practical: <em><strong>How much do the providers diverge when ranking teams over a full season?</strong></em></p><p>For this section, we rank every team in every league-season based on their <strong>season-long xG difference</strong> (xG for &#8211; xG against) according to each provider. Then we look at the <strong>largest gaps</strong> between those rankings &#8212; the cases where the four models disagree the most about how good (or bad) a team really was.</p><p>Here are the 10 biggest &#8220;disagreements&#8221;:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GTt7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GTt7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png 424w, https://substackcdn.com/image/fetch/$s_!GTt7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png 848w, https://substackcdn.com/image/fetch/$s_!GTt7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png 1272w, https://substackcdn.com/image/fetch/$s_!GTt7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GTt7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png" width="1456" height="466" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b086efba-38e7-4408-b035-892670efd285_2186x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:466,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:147412,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GTt7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png 424w, https://substackcdn.com/image/fetch/$s_!GTt7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png 848w, https://substackcdn.com/image/fetch/$s_!GTt7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png 1272w, https://substackcdn.com/image/fetch/$s_!GTt7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb086efba-38e7-4408-b035-892670efd285_2186x700.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The standout case is <strong>Bologna (2020/21)</strong>. Wyscout ranked them <strong>18th</strong>, Opta and Understat both had them <strong>11th</strong>, and StatsBomb put them <strong>14th</strong> &#8212; a spread of <strong>7 places</strong>, the biggest in the entire dataset.</p><p>And as you&#8217;ll see across the top 10 cases, Wyscout tends to offer either the <strong>best</strong> or the <strong>worst</strong> ranking in these big-disagreement seasons.</p><p>Even if we ignore Wyscout for a moment, there are still interesting differences. For instance:</p><ul><li><p><strong>Werder Bremen (2019/20)</strong> &#8594; StatsBomb had them <strong>10th</strong>, Opta had them <strong>15th</strong></p></li><li><p><strong>N&#238;mes (2019/20)</strong> &#8594; StatsBomb would have relegated them (<strong>20th</strong>), while Opta had them at <strong>16th</strong>, safely above the drop</p></li></ul><p>Now, keep in mind these are the <strong>most extreme</strong> ranking spreads. I&#8217;m not sure what I expected, but given the earlier convergence results &#8212; showing that all four models eventually align over the long run (just at different speeds) &#8212; this shouldn&#8217;t really shock us. A range of 5&#8211;6 places feels&#8230; reasonable. (Does it shock you?)</p><p>That said, the key takeaway is this: <em><strong>If you really want to criticise xG, here&#8217;s your ammunition: depending on the provider you choose, a team can be &#8220;relegated&#8221; or &#8220;saved.&#8221;</strong></em></p><p>(That&#8217;s another joke &#8212; but the numbers do make the point.)</p><div><hr></div><h1><strong>6 &#8212; Which model gets you closest to reality?</strong></h1><p>So far we&#8217;ve compared the providers <em>to each other</em>. But the really important question is: <em><strong>does it matter which xG source you use when you compare it to actual results? </strong></em></p><p>Surprisingly&#8230; much less than you&#8217;d think.</p><h2><strong>Actual Points vs Expected Points (xPoints)</strong></h2><p>The chart below shows how well each provider&#8217;s <strong>cumulative expected points (xPoints)</strong> tracks <strong>actual points won</strong>, week by week.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GpLG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GpLG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png 424w, https://substackcdn.com/image/fetch/$s_!GpLG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png 848w, https://substackcdn.com/image/fetch/$s_!GpLG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png 1272w, https://substackcdn.com/image/fetch/$s_!GpLG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GpLG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png" width="620" height="378.9835164835165" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:890,&quot;width&quot;:1456,&quot;resizeWidth&quot;:620,&quot;bytes&quot;:255424,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!GpLG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png 424w, https://substackcdn.com/image/fetch/$s_!GpLG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png 848w, https://substackcdn.com/image/fetch/$s_!GpLG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png 1272w, https://substackcdn.com/image/fetch/$s_!GpLG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F405deeff-bc4a-4e51-9132-f4019af3a30f_1596x976.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you&#8217;re new to xPoints: it&#8217;s simply the probability of a team winning/drawing/losing based on its xG, typically modelled with a Poisson distribution (McKay Johns has a great beginner-friendly explanation of this <a href="https://mckayjohns.substack.com/p/how-to-calculate-expected-points">here</a>).</p><p>What the chart shows is that all four providers <strong>track reality in a similar way</strong>. One model does lag a bit behind the others (no need to name it &#8212; you already know). </p><p><strong>Understat performs best</strong>, but the margin vs Opta/StatsBomb is small. Understat is also the first to cross <strong>80% correlation</strong> with real points &#8212; around <strong>matchweek 10</strong>. StatsBomb follows at <strong>matchweek 14</strong>. Opta around <strong>matchweek 15</strong>. And our usual outlier joins later (matchweek 17).</p><p>This means that <em><strong>Understat&#8217;s xG model aligns with real results the fastest</strong></em>, despite being the only source here that isn&#8217;t a traditional data provider. Funny how this works.</p><div><hr></div><h2><strong>Goal Difference vs xG Difference</strong></h2><p>This second chart compares <em><strong>actual</strong></em><strong> goal difference</strong> with <em><strong>xG </strong></em><strong>difference</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EKEu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EKEu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png 424w, https://substackcdn.com/image/fetch/$s_!EKEu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png 848w, https://substackcdn.com/image/fetch/$s_!EKEu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png 1272w, https://substackcdn.com/image/fetch/$s_!EKEu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EKEu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png" width="614" height="376.15934065934067" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:892,&quot;width&quot;:1456,&quot;resizeWidth&quot;:614,&quot;bytes&quot;:276669,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!EKEu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png 424w, https://substackcdn.com/image/fetch/$s_!EKEu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png 848w, https://substackcdn.com/image/fetch/$s_!EKEu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png 1272w, https://substackcdn.com/image/fetch/$s_!EKEu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0981596-f9ee-4862-9199-bfa2452a0f56_1594x976.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here the story is similar &#8212; but the gaps widen slightly: Understat again leads the pack. Opta and StatsBomb stay close together. Wyscout drifts below the others more noticeably. No model collapses completely, but some definitely require more match weeks before their xGD stabilises toward reality.</p><div><hr></div><h2><strong>League Table Positions vs xPoints Table</strong></h2><p>Finally, this third chart compares <strong>real league table positions</strong> with those created using <strong>xPoints-based rankings</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nK7u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nK7u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png 424w, https://substackcdn.com/image/fetch/$s_!nK7u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png 848w, https://substackcdn.com/image/fetch/$s_!nK7u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png 1272w, https://substackcdn.com/image/fetch/$s_!nK7u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nK7u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png" width="572" height="333.92857142857144" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:850,&quot;width&quot;:1456,&quot;resizeWidth&quot;:572,&quot;bytes&quot;:385149,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!nK7u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png 424w, https://substackcdn.com/image/fetch/$s_!nK7u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png 848w, https://substackcdn.com/image/fetch/$s_!nK7u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png 1272w, https://substackcdn.com/image/fetch/$s_!nK7u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28501a49-22f4-4572-ae18-403a5ff9a1aa_1998x1166.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is a stricter, more volatile test &#8212; ranking stability takes longer to emerge. Here&#8217;s when each model crosses <strong>80% Spearman correlation</strong> with actual league tables:</p><ul><li><p><em>Understat</em> &#8594; matchweek 16</p></li><li><p><em>Opta</em> &#8594; matchweek 19</p></li><li><p><em>StatsBomb</em> &#8594; matchweek 19</p></li><li><p><em>Wyscout</em> &#8594; matchweek 22</p></li></ul><p>Again, the theme repeats: <strong>all four models converge</strong>, but <em>at different speeds</em>, and <em>one model</em> consistently needs a few extra weeks to fall in line.</p><p>So does xG data choice provider matters? <em><strong>It does &#8230;but far less than the xG evangelists (or the xG haters) would have you believe.</strong></em></p><div><hr></div><h1>7 &#8212; Wrapping up</h1><p>Boom &#8212; that was &#8216;<em>Not All xG Is Created Equal&#8216; <strong>Python Football Review </strong></em>style.</p><p>I guess that despite StatsBomb&#8217;s claims that it is the best xG provider in the industry (notably because they consider things like shot height, nearby players, and goalkeeper position), it turns out they&#8217;re not that different from Opta after all.</p><p>And while we&#8217;re on this topic, it&#8217;s worth adding another small disclaimer. While preparing this newsletter, I was genuinely baffled by how close Opta and StatsBomb were. All the marketing talk around StatsBomb&#8217;s superiority must have gotten into my head. So, to make sure there wasn&#8217;t an error in my data, I tried to double-check whether my StatsBomb values were accurate.</p><p>I had a hard time finding another source of StatsBomb match-level data, so I scoured the internet and eventually stumbled upon a YouTube video dating back to April 2020 reviewing Statsbomb data (which at the time was hosted on Fbref) for Dortmund&#8217;s 2019/20 season.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Wq_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Wq_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png 424w, https://substackcdn.com/image/fetch/$s_!0Wq_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png 848w, https://substackcdn.com/image/fetch/$s_!0Wq_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png 1272w, https://substackcdn.com/image/fetch/$s_!0Wq_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Wq_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png" width="570" height="301.4423076923077" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:770,&quot;width&quot;:1456,&quot;resizeWidth&quot;:570,&quot;bytes&quot;:894200,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0Wq_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png 424w, https://substackcdn.com/image/fetch/$s_!0Wq_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png 848w, https://substackcdn.com/image/fetch/$s_!0Wq_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png 1272w, https://substackcdn.com/image/fetch/$s_!0Wq_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61243b10-e6a0-4d09-9a01-4ff3f11eb23c_1472x778.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: <a href="https://www.youtube.com/watch?v=RoA7KcOqvhc&amp;t=87s">Youtube</a></figcaption></figure></div><p>Comparing those numbers to mine revealed some differences:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kso2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kso2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png 424w, https://substackcdn.com/image/fetch/$s_!kso2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png 848w, https://substackcdn.com/image/fetch/$s_!kso2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png 1272w, https://substackcdn.com/image/fetch/$s_!kso2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kso2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png" width="1416" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:406,&quot;width&quot;:1416,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:71010,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178995609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!kso2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png 424w, https://substackcdn.com/image/fetch/$s_!kso2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png 848w, https://substackcdn.com/image/fetch/$s_!kso2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png 1272w, https://substackcdn.com/image/fetch/$s_!kso2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa690a3d9-9de8-4990-bc02-c1f03a984421_1416x406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>Match 1 (vs Augsburg): </p><ul><li><p>My data &#8594; <strong>2.7 vs 0.7</strong></p></li><li><p>Statsbomb (as of 2020) &#8594; <strong>2.4 vs 0.7</strong></p></li></ul></li><li><p>Match 2 (vs K&#246;ln): </p><ul><li><p>My data &#8594; <strong>1.4 vs 0.7</strong></p></li><li><p>Statsbomb (as of 2020)  &#8594; <strong>1.7 vs 0.8</strong></p></li></ul></li><li><p>Match 3 (vs Union Berlin): </p><ul><li><p>My data &#8594; <strong>1.9 vs 1.9</strong></p></li><li><p>Statsbomb (as of 2020)  &#8594; <strong>1.8 vs 2.1</strong></p></li></ul></li></ul><p>This makes me think that <strong>StatsBomb retro-updated their xG model</strong> (all providers revise historic values occasionally), which means that my data captured an earlier version of their feed.</p><p>Having said that &#8230; here are a few personal takeaways:</p><h4><strong>1. I was surprised by how close Opta and Understat are</strong></h4><p>Understat isn&#8217;t really a &#8220;provider&#8221; in the formal sense, and I still have no idea where they source their raw data. So either they rely on Opta (somewhat), or they built a very similar model &#8212; which seems like the more plausible explanation. Either way, Understat remains a great free resource that&#8217;s reliable enough for most purposes.</p><h4><strong>2. Wyscout&#8217;s reliability (or lack thereof)</strong></h4><p>Wyscout never had a reputation for best data in the industry. Still, I always interpreted that to mean they might struggle with <em>less popular leagues</em> &#8212; lower coverage, lower interest, fewer people checking and validating data, etc. </p><p>What surprised me, though, is how differently they behave in the five biggest and most well-covered leagues. I expected their model to track much more closely with Opta and StatsBomb.</p><p>As we saw in the cumulative plots, they eventually converge &#8212; but along the way they produce more outliers than the others. If you&#8217;re using this for predictive modelling, that variance could change a few odds that your model produces.</p><h4><strong>3. xG models converge over the season &#8212; but match-to-match variance can be big</strong></h4><p>Over the long run, the models tell almost the same story. But game-by-game? In <strong>25% of matches</strong>, at least one provider disagrees with the others about who &#8220;won&#8221; the xG battle (based on my simple xG-winner classification). This looks like a big diasgreement to me.</p><h4><strong>4. Understat data correlates best with actual team performance</strong></h4><p>I was genuinely surprised to find that Understat consistently leads the pack when it comes to convergence to actual team performance &#8212; whether you look at points, rankings, or xG differences. It&#8217;s almost ironic: the only source in the comparison that <em>isn&#8217;t</em> a formal data provider ends up aligning with reality the fastest.</p><div><hr></div><h4><strong>What was your biggest takeaway?</strong></h4><p>I&#8217;d genuinely love to hear it.</p><p>The natural follow-up is obvious: <strong>shot-by-shot analysis</strong>. Instead of comparing match-level aggregates, compare each provider&#8217;s probability for each individual shot. If that&#8217;s something you&#8217;d like to see in a future edition, drop a comment &#8212; I&#8217;d be happy to expand this series.</p><p>Thank you for reading until the end.</p><p>See you next week,</p><p><em>Martin</em></p>]]></content:encoded></item><item><title><![CDATA[How Soon Can You Trust the League Table?]]></title><description><![CDATA[And what 10 seasons of data reveal about when standings converge.]]></description><link>https://www.footballmarketreview.com/p/how-soon-can-you-trust-the-league</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/how-soon-can-you-trust-the-league</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 13 Nov 2025 15:06:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5F3J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend, </p><p>A few weeks back, <a href="https://substack.com/@aurelnazmiu">Aurel Nazmiu</a> shared a great visual showing when the Premier League table stabilises during the season.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sGdP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sGdP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png 424w, https://substackcdn.com/image/fetch/$s_!sGdP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png 848w, https://substackcdn.com/image/fetch/$s_!sGdP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png 1272w, https://substackcdn.com/image/fetch/$s_!sGdP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sGdP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png" width="450" height="602.6627218934912" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1358,&quot;width&quot;:1014,&quot;resizeWidth&quot;:450,&quot;bytes&quot;:337455,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35ccf866-88f1-4284-baef-8f9645c1b09e_1014x1358.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!sGdP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png 424w, https://substackcdn.com/image/fetch/$s_!sGdP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png 848w, https://substackcdn.com/image/fetch/$s_!sGdP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png 1272w, https://substackcdn.com/image/fetch/$s_!sGdP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20262003-91a9-4f79-b35d-acb3d65fef34_1014x1358.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Source: <a href="https://www.linkedin.com/posts/activity-7378349427503173632-KoXv?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAA1HkSMBcGVBEKGPvcsl-Uy62YaHAOp9Qtc">Linkedin</a></figcaption></figure></div><p>I loved it for three reasons:</p><ol><li><p>It shows you don&#8217;t need fancy, complicated charts to do good analytics.</p></li><li><p>This seemingly simple graph hides a surprising (to a beginner) amount of data wrangling beneath the surface.</p></li><li><p>And when you try to recreate it yourself, you naturally start asking deeper questions you never considered when you first saw the figure &#8212; like <em>what type of correlation should I use, and why does that matter?</em> (more on that below).</p></li></ol><p>Welcome to <em><strong>The Python Football Review #016</strong></em>.</p><p>In today&#8217;s edition, we&#8217;ll <strong>replicate that figure</strong>, then <strong>extend it to Europe&#8217;s top five leagues</strong> to see which ones settle earlier than others. </p><p>And along the way, you&#8217;ll see that a huge chunk of visualisation actually happens <em>before</em> you ever touch <code>matplotlib</code> &#8212; and why the classic (Pearson) correlation doesn&#8217;t work well with ranks (so we&#8217;ll use Spearman instead).</p><p>Let&#8217;s dive in.</p><div><hr></div><h2><em>So, what&#8217;s the plan, Martin?</em></h2><p>We&#8217;ll start by <em><strong>collecting</strong></em> 10 seasons of Premier League results data. Then we&#8217;ll <em><strong>wrangle</strong></em> it into a dataset that contains each team&#8217;s league position at every matchweek, along with a variable for each team&#8217;s final-season position. Once we have that, we&#8217;ll calculate the <em><strong>Spearman correlation</strong></em> and finally <em><strong>plot</strong></em> the results.</p><p>Without further ado, let&#8217;s collect some data.</p><div><hr></div><h1>1 &#8212; Collecting the Data</h1><p>First, we import the libraries we&#8217;ll use. <code>Polars </code>for fast, readable wrangling. <code>NumPy </code>for small numeric utilities. <code>Matplotlib </code>for plotting. And SciPy&#8217;s <code>spearmanr </code>to compute the Spearman rank correlations between interim and final league positions.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uKQk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uKQk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png 424w, https://substackcdn.com/image/fetch/$s_!uKQk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png 848w, https://substackcdn.com/image/fetch/$s_!uKQk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png 1272w, https://substackcdn.com/image/fetch/$s_!uKQk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uKQk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png" width="404" height="225.30769230769232" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:348,&quot;width&quot;:624,&quot;resizeWidth&quot;:404,&quot;bytes&quot;:58387,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uKQk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png 424w, https://substackcdn.com/image/fetch/$s_!uKQk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png 848w, https://substackcdn.com/image/fetch/$s_!uKQk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png 1272w, https://substackcdn.com/image/fetch/$s_!uKQk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbb478f06-a3c9-4398-8860-6f72f2b05211_624x348.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>We&#8217;ll collect <strong>10 seasons of Premier League results</strong> from <a href="https://x.com/12Xpert">Joseph Buchdahl</a>&#8217;s <a href="http://football-data.co.uk/">Football-Data.co.uk</a> &#8212; a fantastic open resource with historical match CSVs. With Polars&#8217; <code>read_csv</code>, we can load them directly.</p><p>Here&#8217;s what the following snippet does:</p><ul><li><p>Defines the list of the 10 seasons we want.</p></li><li><p>Creates an empty list to store each season&#8217;s table.</p></li><li><p>Loops over each season and loads the corresponding CSV.</p></li><li><p>Keeps only the relevant columns: date, home team, away team, full-time result, full-time goals.</p></li><li><p>Adds a <code>season</code> column so we can track each row back to its year.</p></li><li><p>Appends each cleaned table to our list.</p></li><li><p>Concatenates everything into one big DataFrame.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4djK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4djK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png 424w, https://substackcdn.com/image/fetch/$s_!4djK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png 848w, https://substackcdn.com/image/fetch/$s_!4djK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png 1272w, https://substackcdn.com/image/fetch/$s_!4djK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4djK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png" width="508" height="319.1858407079646" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:852,&quot;width&quot;:1356,&quot;resizeWidth&quot;:508,&quot;bytes&quot;:164845,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4djK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png 424w, https://substackcdn.com/image/fetch/$s_!4djK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png 848w, https://substackcdn.com/image/fetch/$s_!4djK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png 1272w, https://substackcdn.com/image/fetch/$s_!4djK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bd5590e-2983-4b0c-adb2-df69ca39da1d_1356x852.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The result is a clean Polars table with <strong>one row per match</strong>, ready for wrangling.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nzUI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nzUI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png 424w, https://substackcdn.com/image/fetch/$s_!nzUI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png 848w, https://substackcdn.com/image/fetch/$s_!nzUI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png 1272w, https://substackcdn.com/image/fetch/$s_!nzUI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nzUI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png" width="430" height="335.0242718446602" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c3255502-87f7-4fb3-a7f4-947503049464_824x642.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:642,&quot;width&quot;:824,&quot;resizeWidth&quot;:430,&quot;bytes&quot;:91119,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nzUI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png 424w, https://substackcdn.com/image/fetch/$s_!nzUI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png 848w, https://substackcdn.com/image/fetch/$s_!nzUI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png 1272w, https://substackcdn.com/image/fetch/$s_!nzUI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3255502-87f7-4fb3-a7f4-947503049464_824x642.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>2 &#8212; Wrangling</h1><p>We start by renaming all columns to lowercase.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lmDv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lmDv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png 424w, https://substackcdn.com/image/fetch/$s_!lmDv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png 848w, https://substackcdn.com/image/fetch/$s_!lmDv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png 1272w, https://substackcdn.com/image/fetch/$s_!lmDv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lmDv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png" width="650" height="101.47275405007363" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:212,&quot;width&quot;:1358,&quot;resizeWidth&quot;:650,&quot;bytes&quot;:42536,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lmDv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png 424w, https://substackcdn.com/image/fetch/$s_!lmDv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png 848w, https://substackcdn.com/image/fetch/$s_!lmDv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png 1272w, https://substackcdn.com/image/fetch/$s_!lmDv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37c70692-0742-438c-aa12-3f5f50aa9407_1358x212.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Next, we build the team-level data. For each <strong>home team</strong>, we calculate their goals for, goals against, points won, and goal difference.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3iMe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3iMe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png 424w, https://substackcdn.com/image/fetch/$s_!3iMe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png 848w, https://substackcdn.com/image/fetch/$s_!3iMe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png 1272w, https://substackcdn.com/image/fetch/$s_!3iMe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3iMe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png" width="486" height="546.75" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:972,&quot;width&quot;:864,&quot;resizeWidth&quot;:486,&quot;bytes&quot;:144737,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3iMe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png 424w, https://substackcdn.com/image/fetch/$s_!3iMe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png 848w, https://substackcdn.com/image/fetch/$s_!3iMe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png 1272w, https://substackcdn.com/image/fetch/$s_!3iMe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31f37efb-5137-420e-9d87-db2f4f8f1983_864x972.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We repeat the same for each <strong>away team</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!I05g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!I05g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png 424w, https://substackcdn.com/image/fetch/$s_!I05g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png 848w, https://substackcdn.com/image/fetch/$s_!I05g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png 1272w, https://substackcdn.com/image/fetch/$s_!I05g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!I05g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png" width="474" height="528.3577981651376" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:972,&quot;width&quot;:872,&quot;resizeWidth&quot;:474,&quot;bytes&quot;:146547,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!I05g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png 424w, https://substackcdn.com/image/fetch/$s_!I05g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png 848w, https://substackcdn.com/image/fetch/$s_!I05g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png 1272w, https://substackcdn.com/image/fetch/$s_!I05g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd47f239d-699f-4cff-bb74-ccebb8e264f0_872x972.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Then we stack the two together using a concatenation.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!o9qf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!o9qf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png 424w, https://substackcdn.com/image/fetch/$s_!o9qf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png 848w, https://substackcdn.com/image/fetch/$s_!o9qf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png 1272w, https://substackcdn.com/image/fetch/$s_!o9qf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!o9qf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png" width="594" height="160.01162790697674" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:278,&quot;width&quot;:1032,&quot;resizeWidth&quot;:594,&quot;bytes&quot;:55041,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!o9qf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png 424w, https://substackcdn.com/image/fetch/$s_!o9qf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png 848w, https://substackcdn.com/image/fetch/$s_!o9qf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png 1272w, https://substackcdn.com/image/fetch/$s_!o9qf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa404cdb5-bea2-4025-b57e-44b063f1f63f_1032x278.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>And now we have <strong>one row per team per match</strong>, containing that team&#8217;s goals for, goals against, points earned, and goal difference.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ESEA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ESEA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png 424w, https://substackcdn.com/image/fetch/$s_!ESEA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png 848w, https://substackcdn.com/image/fetch/$s_!ESEA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png 1272w, https://substackcdn.com/image/fetch/$s_!ESEA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ESEA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png" width="532" height="492.9265536723164" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c673b65a-9106-4300-bd5d-197900134062_708x656.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:656,&quot;width&quot;:708,&quot;resizeWidth&quot;:532,&quot;bytes&quot;:77476,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ESEA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png 424w, https://substackcdn.com/image/fetch/$s_!ESEA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png 848w, https://substackcdn.com/image/fetch/$s_!ESEA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png 1272w, https://substackcdn.com/image/fetch/$s_!ESEA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc673b65a-9106-4300-bd5d-197900134062_708x656.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Since our data is ordered by date, we create a <strong>matchweek number</strong>. Yes &#8212; this is a simplification because not all teams play on the exact same day, but over 10 seasons this should not meaningfully impact the results.</p><p>In addition to matchweek, we compute: cumulative points, cumulative goals for, cumulative goals against, cumulative goal difference.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0oLT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0oLT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png 424w, https://substackcdn.com/image/fetch/$s_!0oLT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png 848w, https://substackcdn.com/image/fetch/$s_!0oLT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png 1272w, https://substackcdn.com/image/fetch/$s_!0oLT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0oLT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png" width="1356" height="740" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:740,&quot;width&quot;:1356,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:157958,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0oLT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png 424w, https://substackcdn.com/image/fetch/$s_!0oLT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png 848w, https://substackcdn.com/image/fetch/$s_!0oLT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png 1272w, https://substackcdn.com/image/fetch/$s_!0oLT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4ca332-74b4-4ce0-88d0-8468c1e266c2_1356x740.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This produces a tidy table showing, for every team in every season, how their totals evolve <em><strong>after each matchweek</strong></em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fVp6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fVp6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png 424w, https://substackcdn.com/image/fetch/$s_!fVp6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png 848w, https://substackcdn.com/image/fetch/$s_!fVp6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png 1272w, https://substackcdn.com/image/fetch/$s_!fVp6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fVp6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png" width="508" height="334.56161616161614" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c64cb425-be78-4190-893c-51d89c4fff67_990x652.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:652,&quot;width&quot;:990,&quot;resizeWidth&quot;:508,&quot;bytes&quot;:88892,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fVp6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png 424w, https://substackcdn.com/image/fetch/$s_!fVp6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png 848w, https://substackcdn.com/image/fetch/$s_!fVp6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png 1272w, https://substackcdn.com/image/fetch/$s_!fVp6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc64cb425-be78-4190-893c-51d89c4fff67_990x652.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Ranking the teams each week</strong></h2><p>Based on the interim values for points accumulated, goals for, goals against, and goal difference, we create each team&#8217;s position for every matchweek. We do this by sorting first by <em><strong>points</strong></em>, then by <em><strong>goal difference</strong></em>, and finally by <em><strong>goals for</strong></em>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Cwg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Cwg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png 424w, https://substackcdn.com/image/fetch/$s_!0Cwg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png 848w, https://substackcdn.com/image/fetch/$s_!0Cwg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png 1272w, https://substackcdn.com/image/fetch/$s_!0Cwg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Cwg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png" width="751" height="250" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de623566-12ff-4b30-9c73-02f09b369303_751x250.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:250,&quot;width&quot;:751,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:37668,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0Cwg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png 424w, https://substackcdn.com/image/fetch/$s_!0Cwg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png 848w, https://substackcdn.com/image/fetch/$s_!0Cwg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png 1272w, https://substackcdn.com/image/fetch/$s_!0Cwg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde623566-12ff-4b30-9c73-02f09b369303_751x250.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This new <code>cum_pos</code> column is what we care about.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LEqs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LEqs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png 424w, https://substackcdn.com/image/fetch/$s_!LEqs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png 848w, https://substackcdn.com/image/fetch/$s_!LEqs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png 1272w, https://substackcdn.com/image/fetch/$s_!LEqs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LEqs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png" width="746" height="269" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:269,&quot;width&quot;:746,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:18335,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!LEqs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png 424w, https://substackcdn.com/image/fetch/$s_!LEqs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png 848w, https://substackcdn.com/image/fetch/$s_!LEqs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png 1272w, https://substackcdn.com/image/fetch/$s_!LEqs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5f1653b-c253-4141-bb8a-09fdc50b7bba_746x269.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With our clean data ready, we move into the analytical phase. First, we select only the columns we need for the correlation exercise.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ztss!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ztss!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png 424w, https://substackcdn.com/image/fetch/$s_!Ztss!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png 848w, https://substackcdn.com/image/fetch/$s_!Ztss!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png 1272w, https://substackcdn.com/image/fetch/$s_!Ztss!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ztss!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png" width="670" height="101" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:101,&quot;width&quot;:670,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12336,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ztss!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png 424w, https://substackcdn.com/image/fetch/$s_!Ztss!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png 848w, https://substackcdn.com/image/fetch/$s_!Ztss!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png 1272w, https://substackcdn.com/image/fetch/$s_!Ztss!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd666912f-2da2-4d51-a1e5-c54358d5d1af_670x101.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GbL2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GbL2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png 424w, https://substackcdn.com/image/fetch/$s_!GbL2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png 848w, https://substackcdn.com/image/fetch/$s_!GbL2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png 1272w, https://substackcdn.com/image/fetch/$s_!GbL2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GbL2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png" width="390" height="247" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9119497d-44e8-40d4-8006-2848606d95b4_390x247.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:247,&quot;width&quot;:390,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11628,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GbL2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png 424w, https://substackcdn.com/image/fetch/$s_!GbL2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png 848w, https://substackcdn.com/image/fetch/$s_!GbL2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png 1272w, https://substackcdn.com/image/fetch/$s_!GbL2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9119497d-44e8-40d4-8006-2848606d95b4_390x247.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Then we create a <strong>final positions table</strong> by keeping only the <strong>last matchweek of each season</strong> &#8212; these are the official final ranks.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uDhF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uDhF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png 424w, https://substackcdn.com/image/fetch/$s_!uDhF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png 848w, https://substackcdn.com/image/fetch/$s_!uDhF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png 1272w, https://substackcdn.com/image/fetch/$s_!uDhF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uDhF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png" width="495" height="172" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:172,&quot;width&quot;:495,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:20394,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uDhF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png 424w, https://substackcdn.com/image/fetch/$s_!uDhF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png 848w, https://substackcdn.com/image/fetch/$s_!uDhF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png 1272w, https://substackcdn.com/image/fetch/$s_!uDhF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa6519d-fe7c-4ad3-a548-19ed062459df_495x172.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y3pB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y3pB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png 424w, https://substackcdn.com/image/fetch/$s_!Y3pB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png 848w, https://substackcdn.com/image/fetch/$s_!Y3pB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png 1272w, https://substackcdn.com/image/fetch/$s_!Y3pB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y3pB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png" width="305" height="269" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:269,&quot;width&quot;:305,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:10376,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y3pB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png 424w, https://substackcdn.com/image/fetch/$s_!Y3pB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png 848w, https://substackcdn.com/image/fetch/$s_!Y3pB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png 1272w, https://substackcdn.com/image/fetch/$s_!Y3pB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F590c8f40-f25f-4752-b2ba-d62b4745d496_305x269.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Finally, we join the final positions back to <strong>all</strong> matchweeks, so for any given matchweek, we can compare a team&#8217;s <strong>current position</strong> vs its <strong>final position</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Tkdv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Tkdv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png 424w, https://substackcdn.com/image/fetch/$s_!Tkdv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png 848w, https://substackcdn.com/image/fetch/$s_!Tkdv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png 1272w, https://substackcdn.com/image/fetch/$s_!Tkdv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Tkdv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png" width="522" height="96" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:96,&quot;width&quot;:522,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:10524,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Tkdv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png 424w, https://substackcdn.com/image/fetch/$s_!Tkdv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png 848w, https://substackcdn.com/image/fetch/$s_!Tkdv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png 1272w, https://substackcdn.com/image/fetch/$s_!Tkdv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c8784dc-9397-46e0-921a-63b020129d7e_522x96.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tedq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tedq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png 424w, https://substackcdn.com/image/fetch/$s_!tedq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png 848w, https://substackcdn.com/image/fetch/$s_!tedq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png 1272w, https://substackcdn.com/image/fetch/$s_!tedq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tedq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png" width="465" height="275" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:275,&quot;width&quot;:465,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:13057,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tedq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png 424w, https://substackcdn.com/image/fetch/$s_!tedq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png 848w, https://substackcdn.com/image/fetch/$s_!tedq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png 1272w, https://substackcdn.com/image/fetch/$s_!tedq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03c47af3-b81c-4beb-a598-bed4028b12ee_465x275.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Correlation over time</strong></h2><p>Next, we compute the correlation for each matchweek. The loop:</p><ul><li><p>takes matchweek <em>k</em></p></li><li><p>extracts all team positions at that point</p></li><li><p>compares them to the final table</p></li><li><p>computes<em><strong> Spearman&#8217;s &#961;</strong></em></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!H5cJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!H5cJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png 424w, https://substackcdn.com/image/fetch/$s_!H5cJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png 848w, https://substackcdn.com/image/fetch/$s_!H5cJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png 1272w, https://substackcdn.com/image/fetch/$s_!H5cJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!H5cJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png" width="605" height="295" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/237391e8-4d54-464f-a810-7985f7bb8253_605x295.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:295,&quot;width&quot;:605,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:35153,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!H5cJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png 424w, https://substackcdn.com/image/fetch/$s_!H5cJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png 848w, https://substackcdn.com/image/fetch/$s_!H5cJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png 1272w, https://substackcdn.com/image/fetch/$s_!H5cJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F237391e8-4d54-464f-a810-7985f7bb8253_605x295.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Why <em><strong>Spearman</strong></em> and not <em><strong>Pearson</strong></em> (the classic correlation you first learn at school)?</p><ul><li><p><strong>Pearson</strong> works on raw numeric distances &#8212; it assumes linear relationships, not ranks.</p></li><li><p><strong>Spearman</strong> works on <strong>ranks</strong>, which fits league tables perfectly. League positions are ordinal, not numerical &#8212; finishing 1st vs 2nd is not the same &#8220;distance&#8221; as finishing 10th vs 11th.</p></li></ul><p>So Spearman is the right choice for football standings.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XoMZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XoMZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png 424w, https://substackcdn.com/image/fetch/$s_!XoMZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png 848w, https://substackcdn.com/image/fetch/$s_!XoMZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png 1272w, https://substackcdn.com/image/fetch/$s_!XoMZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XoMZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png" width="193" height="428" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:428,&quot;width&quot;:193,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11734,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XoMZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png 424w, https://substackcdn.com/image/fetch/$s_!XoMZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png 848w, https://substackcdn.com/image/fetch/$s_!XoMZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png 1272w, https://substackcdn.com/image/fetch/$s_!XoMZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a111a7b-6ac0-4f7d-9c34-5ddae5d270cb_193x428.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>3 &#8212; Plotting</h1><p>Once correlations are computed for all weeks, we plot them.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g56l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g56l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png 424w, https://substackcdn.com/image/fetch/$s_!g56l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png 848w, https://substackcdn.com/image/fetch/$s_!g56l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png 1272w, https://substackcdn.com/image/fetch/$s_!g56l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g56l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png" width="738" height="473" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:473,&quot;width&quot;:738,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65745,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!g56l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png 424w, https://substackcdn.com/image/fetch/$s_!g56l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png 848w, https://substackcdn.com/image/fetch/$s_!g56l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png 1272w, https://substackcdn.com/image/fetch/$s_!g56l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d8df938-d233-4507-91d6-2b65d4d20a0f_738x473.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In competition economics (my day job), an 80% threshold is often used as a way to summarise a relatively strong effect or a reliable sample. I think it also links loosely to the Pareto idea &#8212; the 20% of factors that deliver 80% of the results. Regardless, for the purposes of this small article, we&#8217;ll treat 80% as the level where things start to &#8220;stabilise&#8221; (my newsletter, my rules).</p><p>So the natural question is:</p><blockquote><p><em><strong>At which matchweek does the Premier League&#8217;s correlation exceed 80%?</strong></em></p></blockquote><p>Answer: <em><strong>Around Matchweek 10.</strong></em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CvXt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CvXt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png 424w, https://substackcdn.com/image/fetch/$s_!CvXt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png 848w, https://substackcdn.com/image/fetch/$s_!CvXt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png 1272w, https://substackcdn.com/image/fetch/$s_!CvXt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CvXt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png" width="800" height="490" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:490,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42799,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!CvXt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png 424w, https://substackcdn.com/image/fetch/$s_!CvXt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png 848w, https://substackcdn.com/image/fetch/$s_!CvXt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png 1272w, https://substackcdn.com/image/fetch/$s_!CvXt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07dc6402-5f1a-4e76-9fd9-fdde3efd4480_800x490.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>By that point, the table already starts to resemble its final shape to a meaningful degree. A few observations stand out:</p><ul><li><p>The <strong>70% threshold</strong> is crossed as early as Matchweek 6.</p></li><li><p>But it&#8217;s only around <strong>Matchweek 10</strong> that the league passes the <strong>80%</strong> mark &#8212; our &#8220;stability&#8221; line.</p></li><li><p>And interestingly, crossing from <strong>80% to 90%</strong> takes quite a bit longer. It&#8217;s only after roughly <strong>Matchweek 20</strong> that the Premier League reaches the 90% correlation level.</p></li><li><p>The final 10% &#8212; from 90% to 100% &#8212; takes about <strong>18 additional matchweeks</strong>, almost half the season.</p></li></ul><p>Early structure forms quickly. True stability takes time.</p><h2><em><strong>And what about the other Big 5 leagues?</strong></em></h2><h2>It turns out:</h2><ul><li><p><strong>Ligue 1</strong> crosses the 80% threshold only after Matchweek 15, and reaches the 90% mark around Matchweek 25 &#8212; a bit late.</p></li><li><p><strong>Serie A</strong> and the <strong>Bundesliga</strong> are the earliest to stabilise among the Big 5, passing the 0.8 threshold at Matchweek 9 &#8212; though La Liga and the Premier League aren&#8217;t far behind.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5F3J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5F3J!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png 424w, https://substackcdn.com/image/fetch/$s_!5F3J!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png 848w, https://substackcdn.com/image/fetch/$s_!5F3J!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png 1272w, https://substackcdn.com/image/fetch/$s_!5F3J!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5F3J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png" width="995" height="588" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:588,&quot;width&quot;:995,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83390,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/178409648?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5F3J!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png 424w, https://substackcdn.com/image/fetch/$s_!5F3J!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png 848w, https://substackcdn.com/image/fetch/$s_!5F3J!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png 1272w, https://substackcdn.com/image/fetch/$s_!5F3J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F864e866c-c8ca-4edd-a2e6-e228321afcd1_995x588.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><p>Boom &#8212; that was the behind-the-scenes look at <strong>when league standings actually settle</strong>.</p><p>You&#8217;ve now seen the amount of wrangling required to produce a graph that looks deceptively simple. You&#8217;ve seen the kinds of questions you end up asking only once you start working with the data (you&#8217;ve probably heard of correlation &#8212; but maybe not the difference between Pearson and Spearman). And you&#8217;ve learned that Ligue 1 takes its time to stabilise, while Serie A is the quickest of the Big 5.</p><p>This whole exercise reminded me of one of my favourite truths about (football) analytics: <em><strong>the best insights show up only once you&#8217;re deep in the weeds doing the work.</strong></em></p><p>On paper, this looked like a trivial problem: <em>&#8220;Compare matchweek positions to final positions. Plot the correlation.&#8221;</em> Easy.</p><p>But once I started building the table &#8212; lining up matchweeks, ranking teams, joining final positions &#8212; a bigger question surfaced:</p><p><em><strong>&#8220;Wait&#8230; what exactly is being correlated here? Do distances between positions even mean anything? No. So why am I reaching for Pearson? This is a ranking problem &#8212; of course Spearman is the right tool.&#8221;</strong></em></p><p>You only see the true shape of a problem once you&#8217;re inside it.</p><p>Thanks for reading until the end.</p><p>See you next week,<br><em><strong>Martin</strong></em></p><div><hr></div><p>As usual, you can grab the code below. The part that downloads all five leagues and plots the figure is included inside.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/PythonFootball/PythonFootballReview/blob/main/PFR_016_position_correlation.ipynb&quot;,&quot;text&quot;:&quot;Grab the Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/PythonFootball/PythonFootballReview/blob/main/PFR_016_position_correlation.ipynb"><span>Grab the Code</span></a></p><p>Simply download it, open a <a href="https://colab.research.google.com/">Google Colab</a> session (if you don&#8217;t have Python installed), and run it line by line to replicate the analysis. And if you&#8217;re feeling adventurous, try switching the leagues and exploring beyond the Big 5.</p><p>Hint: you can use keys like <strong>E1</strong> (Championship), <strong>E2</strong> (League One), <strong>E3</strong> (League Two), <strong>I2</strong> (Serie B), <strong>SP2</strong> (Segunda Divisi&#243;n), <strong>D2</strong> (2. Bundesliga), <strong>F2</strong> (Ligue 2), <strong>B1</strong> (Belgium), <strong>P1</strong> (Portugal), <strong>T1</strong> (Turkey)&#8230; just to name a few.</p><p>Cheers!</p>]]></content:encoded></item><item><title><![CDATA[3 Reasons Why Football Fans Are Best Placed to Learn Python for Analytics]]></title><description><![CDATA[And why you can do it too]]></description><link>https://www.footballmarketreview.com/p/3-reasons-why-football-fans-are-best</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/3-reasons-why-football-fans-are-best</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Fri, 07 Nov 2025 08:54:54 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a15f7ddb-50a8-4219-8648-4215bdb43853_571x503.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review</em> #015.</p><p>When it comes to learning Python for analytics, football fans are the best-suited group out there.</p><p>Yes &#8212; that&#8217;s the claim we&#8217;re exploring today.</p><p>Let&#8217;s not waste time and jump straight into it.</p><div><hr></div><h3><strong>Reason #1: Football is the perfect sandbox for the entire data science workflow.</strong></h3><p>After 10 years in consulting, I can safely say that most business problems only cover two or three parts of the data science workflow (<em>collect</em> &#8594; <em>wrangle</em> &#8594; <em>visualise</em> &#8594; <em>model</em> &#8594; <em>deploy</em>). But only rarely,  the full spectrum.</p><p>Football covers all of them.</p><blockquote><p><em><strong>It&#8217;s rich enough to challenge you, familiar enough to stay fun, and concrete enough to show progress fast.</strong></em></p></blockquote><p>Every key stage of the workflow appears naturally:</p><p><em><strong>Collection </strong></em>&#8212; If you stick around long enough, you&#8217;ll eventually touch all the main methods &#8212; using community-built wrappers (where most of us start), web scraping, and calling APIs from data providers. It&#8217;s a natural progression: from hobby projects to more serious analytical work. Football lets you go all the way &#8212; from analyst to data engineer.</p><p><em><strong>Wrangling</strong> </em>&#8212; Football data is gloriously messy &#8212; and that&#8217;s a good thing. Even early on, you&#8217;ll run into challenges like merging sources where <em>&#8220;Man Utd&#8221;</em> in one dataset needs to match <em>&#8220;Manchester United&#8221;</em> in another. This is the unglamorous middle of every real project &#8212; and football gives you plenty of practice.</p><p><em><strong>Visualisation </strong></em>&#8212; Few domains offer better opportunities to visualise data. From simple scatter plots and line charts to more advanced visuals &#8212; xG flow charts, player radars, passing networks, pass sonars &#8212; football has it all. In analytics, visuals are often the final product &#8212; and football gives you endless ways to master the craft.</p><p><em><strong>Modelling </strong></em>&#8212; When it comes to modelling, we can safely say that <strong>machine learning is the name of the game in football analytics. </strong>Think of the buzzword <em>expected goals</em> &#8212; behind it often sits a simple but powerful model: <strong>logistic regression. </strong>How do teams find replacements for departing players? They could turn to <strong>clustering and dimensionality reduction</strong> &#8212; algorithms that combine dozens of metrics into just a few, then group players by similarity. How do platforms project a team&#8217;s chances of winning the title &#8212; or even the next game? That&#8217;s <strong>regression analysis</strong> at work.</p><p>My point is this: the four main pillars of machine learning &#8212; <strong>prediction, classification, clustering, and dimensionality reduction</strong> &#8212; are the same questions fans, scouts, and journalists ask every week.</p><p><strong>Deployment</strong> &#8212; Finally, football pushes you to share your insights &#8212; from hobby dashboards to professional tools. Whether it&#8217;s tracking trends, explaining tactics, or previewing matches, football gives you a reason to build and publish your work.</p><p>When you learn Python through football analytics, you naturally learn to wear all three hats:</p><ul><li><p>Engineer &#8594; collecting and structuring data</p></li><li><p>Analyst &#8594; finding and visualising insights</p></li><li><p>Scientist &#8594; building and testing models</p></li></ul><p>That&#8217;s what makes football the perfect playground for learning analytics end to end.</p><div><hr></div><h3><strong>Reason #2: The easiest way to learn something? Start with what you love.</strong></h3><p>I learned that the hard way.</p><p>I improved my French through <em>Football Manager.</em> Back when I was a junior economics consultant trying to break into the Paris consulting world, that game became my tutor.</p><p>You might think knowing the difference between a <em>Meneur de jeu en retrait</em> (Deep-Lying Playmaker) and a <em>Milieu r&#233;cup&#233;rateur</em> (Ball-Winning Midfielder) wouldn&#8217;t help me professionally &#8212; and you&#8217;d be right.</p><p>But beyond the tactics and jargon, I was absorbing grammar, vocabulary, and sentence structures without even realising it. The learning stuck because <em><strong>it felt like play.</strong></em></p><p>The same pattern repeated in my career.</p><p>I perfected my <strong>R skills</strong> not through formal training, but by combining client projects with late-night forecasting experiments. There&#8217;s no better way to master <em>dplyr</em> than trying to fuzzy-match messy data sources full of special characters. Sure, I used R at work &#8212; but the real progress came from side projects that didn&#8217;t feel like work.</p><p>Now, I sharpen my <strong>Python</strong> through <em>The Python Football Review. </em>At work, it&#8217;s only the third tool I use (not my choice!). But I knew one truth: if you don&#8217;t use a language &#8212; any language &#8212; you lose it. The newsletter gave me a reason to keep learning: exploring football questions that genuinely interested me, while staying sharp with new libraries and trends.</p><blockquote><p><em><strong>Same lesson every time: When you learn through something you already love, the learning sticks.</strong></em></p></blockquote><p>That&#8217;s why <strong>football fans have a real head start</strong> when learning Python for analytics. You already understand the context and the meaning behind the numbers.</p><p>Picking your favourite team as your &#8220;dataset&#8221; is what most data learners dream of.</p><p>Imagine collecting Arsenal&#8217;s data from this season. Modelling Arsenal&#8217;s title chances using their average xG difference &#8212; that&#8217;s <strong>linear regression</strong> in action. Predicting their next match result based on their 6-game rolling form &#8212; that&#8217;s <strong>logistic regression. </strong>Grouping &#216;degaard, Rice, and N&#248;rgaard by playing style &#8212; that&#8217;s <strong>K-Means clustering.</strong></p><p>Suddenly, abstract algorithms become intuitive. When you start with football, the learning never feels forced. It&#8217;s relevant, motivating, and &#8212; most importantly &#8212; sustainable.</p><p><strong>As a fan, you already have the perfect excuse to get into Python. </strong>The subject you love is the best teacher you&#8217;ll ever have.</p><div><hr></div><h3><strong>Reason #3: The Feedback loop is fast (and addictive)</strong></h3><p>The best kind of learning is the kind that gives you <strong>instant feedback.</strong></p><p>In football, that feedback comes naturally. The data changes every week &#8212; new matches, new patterns, new stories. You can test your code, tweak it, rerun it after the next round, and instantly see how things evolve.</p><p>That sense of progress keeps you motivated far longer than any textbook ever could.</p><p>And then there&#8217;s the <strong>community.</strong></p><p>Football has one of the most active, passionate data communities anywhere online &#8212; fans and analysts sharing visuals, models, and insights for every league, every team.</p><p>Imagine posting your own shot map after the weekend&#8217;s game and joining the discussion around what it means. You&#8217;ll get instant feedback &#8212; on your visual style, your code, your interpretation &#8212; from people who genuinely care about the same questions you do.</p><p>That kind of feedback is priceless. It&#8217;s fast, constructive, and it helps you improve without feeling like work.</p><p>With quick feedback loops and a supportive community, <strong>learning Python through football starts to feel like play. </strong>You don&#8217;t think of it as &#8220;practicing coding&#8221; &#8212; you&#8217;re just exploring, visualising, modelling, sharing. And without noticing, you get better every single week.</p><div><hr></div><p>Boom &#8212; those were the 3 reasons football fans are perfectly suited to learn Python for analytics.</p><p>Thanks for reading,</p><p><em><strong>Martin</strong></em></p>]]></content:encoded></item><item><title><![CDATA[5 Mistakes Beginners Make When Learning Python for Football (and How to Solve Them)]]></title><description><![CDATA[Hi friend,]]></description><link>https://www.footballmarketreview.com/p/5-mistakes-beginners-make-when-learning</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/5-mistakes-beginners-make-when-learning</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Wed, 05 Nov 2025 08:30:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1T1n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review</em> #014.</p><p>Today, we&#8217;re tackling a question I&#8217;ve been thinking about a lot lately: <em><strong>What are the biggest mistakes beginners make when they start learning Python for football?</strong></em></p><p>Let&#8217;s dive into five of them and see how beginners can move past them.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1T1n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1T1n!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png 424w, https://substackcdn.com/image/fetch/$s_!1T1n!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png 848w, https://substackcdn.com/image/fetch/$s_!1T1n!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png 1272w, https://substackcdn.com/image/fetch/$s_!1T1n!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1T1n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png" width="1038" height="1033" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1033,&quot;width&quot;:1038,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1925088,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177910393?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1T1n!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png 424w, https://substackcdn.com/image/fetch/$s_!1T1n!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png 848w, https://substackcdn.com/image/fetch/$s_!1T1n!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png 1272w, https://substackcdn.com/image/fetch/$s_!1T1n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc20a2c17-8097-4948-8e7a-ba4021e4e197_1038x1033.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3><strong>Mistake #1 &#8212; </strong><em><strong>Starting without a roadmap</strong></em></h3><p>Python is everywhere &#8212; websites, apps, machine learning, and of course, football analytics. The good news: there are thousands of tutorials. The bad news: <strong>that&#8217;s the problem.</strong></p><p>You search online and you&#8217;re hit with two extremes: a 5-hour<strong> Python bootcamps</strong> made for software engineers or overly<strong> technical research papers / GitHub projects</strong> written by data scientists for other data scientists. And on rare occasions, you&#8217;ll find <strong>a single video showing one cool football visualisation or model</strong> &#8212; but nothing structured, nothing that takes you from start to finish.</p><p>Both are valuable. Neither are designed for a beginner who just wants to answer a simple football question like:</p><blockquote><p>&#8220;How many points is my team projected to win based on their current form?&#8221;</p></blockquote><p>So you bounce from tutorial to tutorial, learning random bits of Python without ever completing a project. The overwhelm quickly turns into paralysis:</p><blockquote><p>&#8220;Am I supposed to learn <em>all</em> of Python before I start analysing football?&#8221;</p></blockquote><p>No.</p><p>In the beginning, you don&#8217;t need <em>all</em> of Python &#8212; you need the <strong>minimum viable skills</strong> that let you move through the four phases of a project: <em><strong>Collect</strong></em><strong> &#8212;&gt; </strong><em><strong>Wrangle </strong></em><strong>&#8212;&gt; </strong><em><strong>Visualise</strong></em><strong> &#8212;&gt; </strong><em><strong>Model</strong></em><strong>.</strong></p><p>Just enough to complete something real &#8212; fast. </p><p>Once you understand the framework and have a tiny toolkit for each phase, you stop wandering and start building. And that brings us to the next mistakes &#8212; one per phase &#8212; starting with:</p><div><hr></div><h3><strong>Mistake #2 &#8212; </strong><em><strong>Getting stuck at data collection</strong></em></h3><p>Few things derail a beginner faster than getting stuck at step one &#8212; <strong>finding usable data.</strong></p><p>Many YouTube tutorials gloss over this stage because collecting data can be a pain, but in real projects you have to source it yourself. The bottleneck usually looks like one of two things:</p><ul><li><p>you lose days trying to build scrapers (often with ChatGPT&#8217;s help), or</p></li><li><p>you simply don&#8217;t know where to find analysis-ready data.</p></li></ul><p>So you copy someone&#8217;s code&#8230; and it breaks. Now you&#8217;re left wondering: <em>Did the website change? Is my environment broken? Did the site upgrade its bot protection?</em></p><p>You have no idea where the problem is, and the frustration kills your momentum.</p><p>The easier path &#8212; especially when starting out &#8212; is to use <strong>reliable shortcuts. </strong>In football analytics, those shortcuts are community-built wrappers like <strong><a href="https://soccerdata.readthedocs.io/en/latest/">soccerdata</a></strong> and <strong><a href="https://scraperfc.readthedocs.io/en/latest/">scraperfc</a></strong>.</p><p>These packages exist because people in the analytics community created them so <em>you don&#8217;t have to build scrapers yourself.</em> They let you load team, match, and event data across multiple leagues in minutes, using simple one-liners.</p><p>Spend your time analysing football &#8212; not fighting HTML (at least not in the beginning).</p><div><hr></div><h3><strong>Mistake #3 &#8212; </strong><em><strong>Letting pandas slow you down</strong></em></h3><p>You&#8217;ve finally collected your football data. Naturally, you want to jump straight to the fun part &#8212; plotting visuals, building models, proving your point.</p><p>Not so fast.</p><p>In real projects, the bottleneck isn&#8217;t the chart or the model. It&#8217;s getting your data into a shape where those things <em>even work.</em></p><p>That stage is called <strong>wrangling</strong> &#8212; cleaning, transforming, structuring &#8212; and seasoned analysts joke that it eats <strong>80% of every project. </strong>It&#8217;s funny only because it&#8217;s true.</p><p>Sure, some paid feeds or public repos give you neat, tidy tables. But the moment you combine sources or scrape data yourself, chaos appears: missing values, inconsistent team names, wrong data types, tables shaped like abstract art.</p><p>Every tiny issue compounds. This is where frustration spikes.</p><p>For years, the default tool was <em><strong><a href="https://pandas.pydata.org/">pandas</a> </strong></em>&#8212; every tutorial on Earth seemed to start with: <code>import pandas as pd</code>.</p><p>And soon you&#8217;re staring at code like:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l11r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l11r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png 424w, https://substackcdn.com/image/fetch/$s_!l11r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png 848w, https://substackcdn.com/image/fetch/$s_!l11r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png 1272w, https://substackcdn.com/image/fetch/$s_!l11r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l11r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png" width="1064" height="256" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:256,&quot;width&quot;:1064,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!l11r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png 424w, https://substackcdn.com/image/fetch/$s_!l11r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png 848w, https://substackcdn.com/image/fetch/$s_!l11r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png 1272w, https://substackcdn.com/image/fetch/$s_!l11r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44275fe8-7702-4f55-bb58-a24c03bc3ee6_1064x256.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>And thinking:<em> &#8220;How am I supposed to remember this?&#8221;</em> Welcome to <strong>pandas bracket soup</strong>.</p><p>The Fix? Use <em><strong><a href="https://pola.rs/">Polars</a></strong></em> &#8211; a modern, readable and fast library. Instead of nested brackets and constant index resets, <em><strong>Polars reads like plain English</strong></em>:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xrQI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xrQI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png 424w, https://substackcdn.com/image/fetch/$s_!xrQI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png 848w, https://substackcdn.com/image/fetch/$s_!xrQI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png 1272w, https://substackcdn.com/image/fetch/$s_!xrQI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xrQI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png" width="946" height="224" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:224,&quot;width&quot;:946,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xrQI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png 424w, https://substackcdn.com/image/fetch/$s_!xrQI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png 848w, https://substackcdn.com/image/fetch/$s_!xrQI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png 1272w, https://substackcdn.com/image/fetch/$s_!xrQI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd9c7a1f-43a6-4152-bae5-1f91f5c3a84b_946x224.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>If your wrangling code is readable, <strong>you learn faster. </strong></p><p>Instead of wrestling with syntax, you stay focused on the football question.</p><div><hr></div><h3><strong>Mistake #4 &#8212; </strong><em><strong>Jumping into advanced visuals without mastering the basics</strong></em></h3><p>You&#8217;ve collected your data. You&#8217;ve wrangled it into shape. Now comes the part that feels the most rewarding: <strong>turning numbers into visuals.</strong></p><p>But this is where many beginners hit a wall.</p><p>You search GitHub, find someone&#8217;s beautiful shot map or radar chart, copy the template &#8230; and then spend two hours tweaking fonts, colours, and layout. You&#8217;re focussed on styling instead of learning fundamentals.</p><p>The real bottleneck isn&#8217;t Python syntax. Most visuals take just a few lines of code. The bottleneck is <strong>not knowing what to plot, or why. </strong><em>&#8220;Is this a scatter? A bar? A line? A radar?&#8221;</em> So you jump into advanced football charts without first learning the basics.</p><p>Here&#8217;s the thing nobody explains: A shot map is just a <strong>scatter plot</strong> on a pitch. An xG flow is just a <strong>line chart</strong> over time. A radar is just a <strong>bar chart</strong>, arranged differently.</p><p>If you understand the fundamentals (scatter, line, bar etc.) &#8212; you can build the football-specific visuals later with (greater) confidence.</p><p>So focus on the fundamentals first, templates later.</p><p>Start with <em><strong><a href="https://matplotlib.org/">Matplotlib</a></strong></em> to learn the core chart types and how to shape data for them. Then add <em><strong><a href="https://mplsoccer.readthedocs.io/en/latest/">mplsoccer</a></strong></em> to place those charts on a football pitch when you&#8217;re ready. </p><div><hr></div><h3><strong>Mistake #5 &#8212; </strong><em><strong>Treating modelling like black-box magic</strong></em></h3><p>You&#8217;ve gathered your data, wrangled the mess, and even sketched a few charts. Now every football guru on Twitter is going to ask, <em>&#8220;Great&#8212;so what does this mean for the next match? The next season? The next transfer?&#8221;</em>.</p><p>Welcome to data modelling: the stage where history turns into actionable predictions &#8230; and the stage every beginner thinks <em>is</em> the whole show.</p><p>Newcomers often picture this step as black-box AI magic&#8212;machine learning this, neural networks that. In reality, most useful models boil down to a few clear ideas and a single line of code that does the heavy lifting. The hard part isn&#8217;t running a model; it&#8217;s <strong>framing the question</strong>, <strong>choosing the right tool</strong>, and <strong>interpreting results without fooling yourself</strong>.</p><p>The biggest trap beginners fall into is <strong>jumping straight to complex algorithms</strong> without understanding the mechanics or the &#8220;why&#8221; behind them.</p><p>The truth is, if you focus on just <strong>one algorithm per key machine learning task</strong>, you&#8217;ll cover 80% of what you&#8217;ll ever need.</p><p>In practice, that means mastering:</p><ul><li><p>Two <strong>supervised</strong> algorithms &#8212; <em>Linear Regression</em> (for predictions) and <em>Logistic Regression</em> (for classifications).</p></li><li><p>Two <strong>unsupervised</strong> algorithms &#8212; <em>K-Means Clustering</em> (for grouping) and <em>PCA</em> (for dimensionality reduction).</p></li></ul><p>Those four alone will prepare you for the vast majority of real-world problems you&#8217;ll face. Once you understand the mechanics &#8212; how to run them, how to read results, and how to apply them &#8212; then you can move on to the fancier stuff like ensemble models or XGBoost.</p><p>With <em><strong><a href="https://scikit-learn.org/stable/">scikit-learn</a></strong></em>, most of these take a single line of code. The real work lies in <strong>framing the question</strong> and <strong>interpreting the output</strong>.</p><p>And speaking from experience &#8212; you&#8217;d be surprised how often, even in the business world, a simple linear regression delivers great results. </p><p>Just remember: <em>simple is smooth, and smooth is fast.</em></p><p>You don&#8217;t need neural networks to start. You need a <strong>question &#8594; a simple model &#8594; an insight</strong>.</p><div><hr></div><p>Boom &#8212; those were the 5 biggest traps beginners fall into when learning Python for football.</p><p>Thanks for reading,</p><p><em>Martin</em></p>]]></content:encoded></item><item><title><![CDATA[Elliot Anderson and the Art of Showing Just Enough Data]]></title><description><![CDATA[So Josh Williams just tweeted this &#8212; a great little bit of football analytics on Sky Sports.]]></description><link>https://www.footballmarketreview.com/p/elliott-anderson-and-the-art-of-showing</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/elliott-anderson-and-the-art-of-showing</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Mon, 03 Nov 2025 23:57:21 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/cca2990c-c5e2-4987-a263-675dba1e7989_1366x1228.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So <a href="https://substack.com/@distancecovered">Josh Williams</a> just tweeted this &#8212; a great little bit of football analytics on Sky Sports.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://x.com/DistanceCovered/status/1985435841104396422" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EKKy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png 424w, https://substackcdn.com/image/fetch/$s_!EKKy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png 848w, https://substackcdn.com/image/fetch/$s_!EKKy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png 1272w, https://substackcdn.com/image/fetch/$s_!EKKy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EKKy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png" width="520" height="467.30897009966776" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1082,&quot;width&quot;:1204,&quot;resizeWidth&quot;:520,&quot;bytes&quot;:919196,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://x.com/DistanceCovered/status/1985435841104396422&quot;,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EKKy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png 424w, https://substackcdn.com/image/fetch/$s_!EKKy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png 848w, https://substackcdn.com/image/fetch/$s_!EKKy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png 1272w, https://substackcdn.com/image/fetch/$s_!EKKy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd579f0b0-2aea-490d-8798-96001fd70a49_1204x1082.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And it&#8217;s not the first time I&#8217;ve stumbled across Elliot Anderson&#8217;s name this season either.</p><p>So, since I&#8217;m officially <em>back</em> (after a long summer break), I thought &#8212; why not do a quick, improvised <strong>Python Football Review</strong>?</p><p>Welcome to <em><strong>The Python Football Review</strong></em><strong> #013</strong>, where we&#8217;ll recreate Sky Sports&#8217; figure in just a few minutes using Python.</p><div><hr></div><h3>Step 1 &#8212; Collecting the Data</h3><p>We&#8217;ll start with the basics. Install <code>soccerdata</code> to scrape data from Opta via <strong>FBref</strong>, and import it alongside <code>polars</code> (for easy wrangling) and <code>matplotlib</code> (for plotting).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0iWT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0iWT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png 424w, https://substackcdn.com/image/fetch/$s_!0iWT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png 848w, https://substackcdn.com/image/fetch/$s_!0iWT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png 1272w, https://substackcdn.com/image/fetch/$s_!0iWT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0iWT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png" width="350" height="204.2622950819672" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:356,&quot;width&quot;:610,&quot;resizeWidth&quot;:350,&quot;bytes&quot;:60934,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0iWT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png 424w, https://substackcdn.com/image/fetch/$s_!0iWT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png 848w, https://substackcdn.com/image/fetch/$s_!0iWT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png 1272w, https://substackcdn.com/image/fetch/$s_!0iWT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b910fdf-0ecb-4575-9d3b-98c5a94c9c3c_610x356.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>From FBref, <em><strong>tackles</strong></em> live in the defensive stats, while <em><strong>progressive passes</strong></em> come from the standard stats. No, FBref doesn&#8217;t have <em><strong>line-breaking passes</strong></em>, but progressive passes are the closest we can get &#8212; so we&#8217;ll take them and move on.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yrmI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yrmI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png 424w, https://substackcdn.com/image/fetch/$s_!yrmI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png 848w, https://substackcdn.com/image/fetch/$s_!yrmI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png 1272w, https://substackcdn.com/image/fetch/$s_!yrmI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yrmI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png" width="544" height="156.3116883116883" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:354,&quot;width&quot;:1232,&quot;resizeWidth&quot;:544,&quot;bytes&quot;:82130,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yrmI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png 424w, https://substackcdn.com/image/fetch/$s_!yrmI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png 848w, https://substackcdn.com/image/fetch/$s_!yrmI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png 1272w, https://substackcdn.com/image/fetch/$s_!yrmI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1aa123e9-ffd1-4dc8-b3e2-401365fa0b9a_1232x354.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>Step 2 &#8212; Wrangling the Data</h3><p><code>soccerdata</code> returns pandas DataFrames, but I prefer working in <strong>Polars</strong> for its clarity. So, we convert everything to Polars, rename our columns of interest, and keep only what we need.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uyi2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uyi2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png 424w, https://substackcdn.com/image/fetch/$s_!Uyi2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png 848w, https://substackcdn.com/image/fetch/$s_!Uyi2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png 1272w, https://substackcdn.com/image/fetch/$s_!Uyi2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uyi2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png" width="510" height="279.72727272727275" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:724,&quot;width&quot;:1320,&quot;resizeWidth&quot;:510,&quot;bytes&quot;:155334,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Uyi2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png 424w, https://substackcdn.com/image/fetch/$s_!Uyi2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png 848w, https://substackcdn.com/image/fetch/$s_!Uyi2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png 1272w, https://substackcdn.com/image/fetch/$s_!Uyi2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4327f6cc-a5db-47d8-81d6-d7a4c6ad6c77_1320x724.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Next, we join the two datasets, create <em>tackles per 90</em> and <em>progressive passes per 90</em>, and filter for midfielders only. </p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tBRy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tBRy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png 424w, https://substackcdn.com/image/fetch/$s_!tBRy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png 848w, https://substackcdn.com/image/fetch/$s_!tBRy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png 1272w, https://substackcdn.com/image/fetch/$s_!tBRy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tBRy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png" width="606" height="224.33653846153845" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:539,&quot;width&quot;:1456,&quot;resizeWidth&quot;:606,&quot;bytes&quot;:114418,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tBRy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png 424w, https://substackcdn.com/image/fetch/$s_!tBRy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png 848w, https://substackcdn.com/image/fetch/$s_!tBRy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png 1272w, https://substackcdn.com/image/fetch/$s_!tBRy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F120b55c9-45dd-4cd7-b4c6-875823cbe45a_1524x564.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>After this step, we&#8217;re left with a clean DataFrame of <strong>102 midfielders</strong> &#8212; ready to visualize.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PDRW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PDRW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png 424w, https://substackcdn.com/image/fetch/$s_!PDRW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png 848w, https://substackcdn.com/image/fetch/$s_!PDRW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png 1272w, https://substackcdn.com/image/fetch/$s_!PDRW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PDRW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png" width="1456" height="574" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:574,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:142133,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PDRW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png 424w, https://substackcdn.com/image/fetch/$s_!PDRW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png 848w, https://substackcdn.com/image/fetch/$s_!PDRW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png 1272w, https://substackcdn.com/image/fetch/$s_!PDRW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff52a6d70-0638-40a6-83a2-fc046597dc5f_1644x648.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Step 3 &#8212; Visualizing</h3><p>Now that we&#8217;ve got our cleaned dataset, it&#8217;s time for making the visual. </p><p>We&#8217;ll create a simple scatter plot, where each dot represents a player &#8212; progressive passes on the x-axis, tackles on the y-axis.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!29zl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!29zl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png 424w, https://substackcdn.com/image/fetch/$s_!29zl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png 848w, https://substackcdn.com/image/fetch/$s_!29zl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png 1272w, https://substackcdn.com/image/fetch/$s_!29zl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!29zl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png" width="550" height="477.6957163958641" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1176,&quot;width&quot;:1354,&quot;resizeWidth&quot;:550,&quot;bytes&quot;:241219,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!29zl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png 424w, https://substackcdn.com/image/fetch/$s_!29zl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png 848w, https://substackcdn.com/image/fetch/$s_!29zl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png 1272w, https://substackcdn.com/image/fetch/$s_!29zl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F137cbabf-7335-4208-95ec-0fd78171f0c2_1354x1176.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And here is our scatter plot. </p><p>Right away, <strong>Nottingham Forest&#8217;s </strong><em><strong>Elliot Anderson</strong></em> jumps off the chart &#8212; an aggressive ball-winner (26 tackles) <em>and</em> an exceptional progressive passer (89 progressive passes).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iEVl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iEVl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png 424w, https://substackcdn.com/image/fetch/$s_!iEVl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png 848w, https://substackcdn.com/image/fetch/$s_!iEVl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png 1272w, https://substackcdn.com/image/fetch/$s_!iEVl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iEVl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png" width="1456" height="857" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:857,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!iEVl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png 424w, https://substackcdn.com/image/fetch/$s_!iEVl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png 848w, https://substackcdn.com/image/fetch/$s_!iEVl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png 1272w, https://substackcdn.com/image/fetch/$s_!iEVl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59ce489f-5fcd-4b75-88b8-0a570f25b298_1498x882.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you look closely at Sky Sports&#8217; version, you&#8217;ll see their metrics are per 90 minutes.<br>So, let&#8217;s replicate that too. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7yiZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7yiZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png 424w, https://substackcdn.com/image/fetch/$s_!7yiZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png 848w, https://substackcdn.com/image/fetch/$s_!7yiZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png 1272w, https://substackcdn.com/image/fetch/$s_!7yiZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7yiZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png" width="522" height="462.1628959276018" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1174,&quot;width&quot;:1326,&quot;resizeWidth&quot;:522,&quot;bytes&quot;:253941,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7yiZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png 424w, https://substackcdn.com/image/fetch/$s_!7yiZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png 848w, https://substackcdn.com/image/fetch/$s_!7yiZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png 1272w, https://substackcdn.com/image/fetch/$s_!7yiZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dddb6b5-e7ad-42fe-b523-5c97dcc7ef05_1326x1174.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Once we adjust for minutes played, <em><strong>Anderson</strong></em> still stands out &#8212; averaging <strong>8.9 progressive passes</strong> and <strong>2.6 tackles per 90 minutes</strong>. But he&#8217;s no longer quite the outlier he appeared to be in the first figure. </p><p>What happened? Well, some players in the dataset likely have played far fewer games than he has &#8212; which naturally inflates their per-game averages.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!koSt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!koSt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png 424w, https://substackcdn.com/image/fetch/$s_!koSt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png 848w, https://substackcdn.com/image/fetch/$s_!koSt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png 1272w, https://substackcdn.com/image/fetch/$s_!koSt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!koSt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png" width="1456" height="868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:868,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:157256,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!koSt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png 424w, https://substackcdn.com/image/fetch/$s_!koSt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png 848w, https://substackcdn.com/image/fetch/$s_!koSt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png 1272w, https://substackcdn.com/image/fetch/$s_!koSt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84bbe7d8-ae46-4319-ab50-958904cf130c_1496x892.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So, once we account for that (for example, by keeping only players who&#8217;ve played at least <strong>six matches</strong>), we end up right where we expected to be from the start.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_d5z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_d5z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png 424w, https://substackcdn.com/image/fetch/$s_!_d5z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png 848w, https://substackcdn.com/image/fetch/$s_!_d5z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png 1272w, https://substackcdn.com/image/fetch/$s_!_d5z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_d5z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png" width="1456" height="879" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:879,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:145845,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_d5z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png 424w, https://substackcdn.com/image/fetch/$s_!_d5z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png 848w, https://substackcdn.com/image/fetch/$s_!_d5z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png 1272w, https://substackcdn.com/image/fetch/$s_!_d5z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4fc90f-b599-4681-b974-bf64c30d4c01_1464x884.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This small exercise is a great reminder of what matters when visualizing data.<br>It&#8217;s not just about plotting numbers &#8212; it&#8217;s about making sure the sample is <em>representative</em>. Because if you include everyone without context, outliers can easily distort the message.</p><p>It&#8217;s also a reminder that with the right filters, you can subtly shape which stories (and which players) stand out (I am not saying that&#8217;s the case here). That&#8217;s why even Sky&#8217;s version says <em>&#8220;selected midfielders.&#8221;</em> Filtering matters. (And kudos to them for making that clear).</p><p>Anderson is an exceptional player. Sky Sports are a trusted source. This little project simply serves as a reminder of the dos and don&#8217;ts in data visualization. Here, everything is perfectly valid &#8212; but it also shows how, depending on the filters you use, the picture can shift.</p><p>Here&#8217;s the same figure again, this time keeping only players who&#8217;ve played at least <strong>three full matches</strong> &#8212; which is still a fair cut-off (roughly 30% of the season so far).</p><p>So Curtis Jones for Player of the Season? Maybe not (yet?) &#8230; but you get the point.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fHRx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fHRx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png 424w, https://substackcdn.com/image/fetch/$s_!fHRx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png 848w, https://substackcdn.com/image/fetch/$s_!fHRx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png 1272w, https://substackcdn.com/image/fetch/$s_!fHRx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fHRx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png" width="652" height="384.2142857142857" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:858,&quot;width&quot;:1456,&quot;resizeWidth&quot;:652,&quot;bytes&quot;:157161,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/177934508?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fHRx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png 424w, https://substackcdn.com/image/fetch/$s_!fHRx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png 848w, https://substackcdn.com/image/fetch/$s_!fHRx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png 1272w, https://substackcdn.com/image/fetch/$s_!fHRx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802f98c-8f45-40bc-9520-79b6499cff96_1466x864.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Wrapping Up</h3><p>This was a small but fun reminder of two things:</p><ol><li><p>With Python, you can recreate Sky Sports-worthy analytics visuals in minutes (even if the Matplotlib aesthetics we used here still lag a bit behind).</p></li><li><p>Data always needs context &#8212; even the cleanest chart can mislead if you forget to filter carefully. (Not that I&#8217;m saying there&#8217;s one &#8220;proper&#8221; filter here &#8212; but you see what I mean)</p></li></ol><p>And with that, we wrap up this short, improvised edition of the <em><strong>Python Football Review</strong></em>.</p><p>Ah &#8212; it feels <em>so good</em> to be back.</p><p>Thanks for reading,</p><p><em><strong>Martin</strong></em></p><p><em>P.S. As usual, you can grab the code below.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/odnrongb273utop/PFR_013.ipynb/file&quot;,&quot;text&quot;:&quot;Grab the Python code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/odnrongb273utop/PFR_013.ipynb/file"><span>Grab the Python code</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Why Visuals Matter More Than You Think ]]></title><description><![CDATA[The beginner&#8217;s guide to avoiding visualisation traps &#8212; and how to fix them fast]]></description><link>https://www.footballmarketreview.com/p/why-visuals-matter-more-than-you</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/why-visuals-matter-more-than-you</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 07 Aug 2025 08:01:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!kz2V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #012</em> &#8212; and to our ongoing <strong>&#8220;in plain English&#8221;</strong> series.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kz2V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kz2V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!kz2V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!kz2V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!kz2V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kz2V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png" width="488" height="488" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:488,&quot;bytes&quot;:1965905,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/170258228?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kz2V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!kz2V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!kz2V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!kz2V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F261dd25b-1449-47f8-8348-9594b6a119b9_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Today, we&#8217;re zooming in on <strong>data visualisation</strong> &#8212; what it is, why it matters, and how it fits into a typical football analytics workflow. Even though the term <em>kind of</em> explains itself, there's more nuance than you might think.</p><p>There&#8217;ll be <strong>no Python code</strong> in this one &#8212; just ideas, insights, and some visuals to help you build intuition.</p><div><hr></div><h3>Quick heads-up</h3><p>I&#8217;m working on a <em><strong>Fast-Track</strong></em><strong> Guide to Football Analytics with Python</strong> &#8212; designed to cut through the fluff and get you building your first football data project <em>fast</em>.</p><p>If templates and walkthroughs sound like your thing, join the waitlist below. It&#8217;s launching in early September.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.pythonfootball.com/survey/3897364?token=&quot;,&quot;text&quot;:&quot;Join the Wait List&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.pythonfootball.com/survey/3897364?token="><span>Join the Wait List</span></a></p><p>Alright, let&#8217;s get into it.</p><div><hr></div><h1>A (good) graph is worth a thousand words?</h1><p>Why do we make graphs?</p><p>Seems obvious, right? To visually represent our analysis.</p><p>But here&#8217;s the catch: in the rush to produce slick-looking visuals, we often forget the <strong>actual point</strong> of a graph &#8212; <strong>to reveal patterns and problems that numbers alone </strong><em><strong>can&#8217;t</strong></em><strong> show</strong>.</p><p>Allow me to introduce you to...</p><h1>Anscombe&#8217;s Quartet: When Statistics Lie</h1><p>In 1973, statistician Francis Anscombe made a powerful point.</p><p>He created four datasets &#8212; now known as <strong>Anscombe&#8217;s Quartet</strong> &#8212; that all had <strong>nearly identical statistical summaries</strong>: same mean, same variance, same correlation, same regression line.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Hzt7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Hzt7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png 424w, https://substackcdn.com/image/fetch/$s_!Hzt7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png 848w, https://substackcdn.com/image/fetch/$s_!Hzt7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png 1272w, https://substackcdn.com/image/fetch/$s_!Hzt7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Hzt7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png" width="631" height="405.64285714285717" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:765,&quot;width&quot;:1190,&quot;resizeWidth&quot;:631,&quot;bytes&quot;:958075,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/170258228?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Hzt7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png 424w, https://substackcdn.com/image/fetch/$s_!Hzt7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png 848w, https://substackcdn.com/image/fetch/$s_!Hzt7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png 1272w, https://substackcdn.com/image/fetch/$s_!Hzt7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc6140d9e-5a54-400d-8e3f-db3a29420feb_1190x765.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>But when plotted, they looked radically different.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-SXF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-SXF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-SXF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-SXF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-SXF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-SXF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg" width="607" height="449.72480948348857" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:875,&quot;width&quot;:1181,&quot;resizeWidth&quot;:607,&quot;bytes&quot;:53873,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/170258228?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-SXF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-SXF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-SXF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-SXF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52447bd6-f9cc-45c9-a094-9b2ca3281a71_1181x875.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Each quadrant tells a different story:</p><ul><li><p><strong>Top Left: Linear Relationship</strong></p><p>What you&#8217;d expect. A clean trend. Visuals and stats agree.</p></li><li><p><strong>Top Right: Non-Linear Relationship</strong></p><p>The correlation exists, but it&#8217;s not linear. A regression line would mislead.</p></li><li><p><strong>Bottom Left: Outlier Distortion</strong></p><p>One rogue point skews the analysis. You&#8217;d miss this without a plot.</p></li><li><p><strong>Bottom Right: High-Leverage Point</strong></p><p>A single point creates the illusion of a relationship. Remove it, and it vanishes.</p></li></ul><p><strong>Lesson:</strong> Always visualise your data. Don&#8217;t trust the stats alone.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1>So what <em>is</em> data visualisation, really?</h1><p>In theory, data visualisation is the use of graphs and figures to communicate the insights hidden in your data.</p><p>In practice, it serves <strong>two different purposes</strong> (especially in a football analytics workflow):</p><ol><li><p>Visuals <em>before</em> modeling &#8212; to <strong>explore</strong> and clean your data.</p></li><li><p>Visuals <em>after</em> modeling&#8212;to <strong>communicate</strong> your findings to others.</p></li></ol><p>Let&#8217;s unpack both.</p><div><hr></div><h1>Data Visualisation <em>Before</em> Modeling</h1><p>Before you train any model &#8212; or even start building one &#8212; you should always look at your data visually.</p><p>Why?</p><ul><li><p>To <strong>spot outliers</strong></p></li><li><p>To <strong>see patterns</strong> that stats might hide</p></li><li><p>To <strong>double-check</strong> missing values, or duplicates</p></li><li><p>To <strong>rethink aggregations</strong> (maybe total annual wage makes more sense than average?)</p></li></ul><p>This &#8220;visual inspection&#8221; often sends you back to the wrangling phase to fix or reshape your dataset &#8212; and that&#8217;s a good thing.</p><h3>Most-used graphs at this stage:</h3><ul><li><p><strong>Scatter plots</strong> &#8211; Show relationships between two numeric variables</p></li><li><p><strong>Histograms</strong> &#8211; Show the distribution of a single variable</p></li><li><p><strong>Box plots</strong> &#8211; Highlight outliers and spread of a variable</p></li><li><p><strong>Line plots</strong> &#8211; Track a variable over time</p></li><li><p><strong>Bar charts</strong> &#8211; Compare categorical groups</p></li></ul><p>These are your <strong>exploratory workhorses</strong> &#8212; the ones you&#8217;ll return to over and over.</p><blockquote><p>The Python Toolstack? Usually just <code>matplotlib</code> or <code>seaborn</code>&#8212; one line of code gets you 80% of the way there.</p></blockquote><div><hr></div><h1>Data Visualisation <em>After</em> Modeling</h1><p>This is where data visualization becomes <strong>the final product</strong>.</p><p>You&#8217;ve done the heavy lifting. Now it&#8217;s time to <em>show</em> your insights &#8212; clearly and convincingly.</p><p>And football has its own set of specialized visuals for this:</p><ul><li><p><strong>Radar charts / Pizza plots</strong> &#8211; Compare player profiles across attributes</p></li><li><p><strong>Pass maps</strong> &#8211; Show passing patterns or clusters</p></li><li><p><strong>Pass networks</strong> &#8211; Visualize team structure and ball movement</p></li><li><p><strong>Heat maps</strong> &#8211; Show player or team activity zones</p></li><li><p><strong>Shot maps</strong> &#8211; Reveal shooting tendencies and goal threats</p></li><li><p><strong>xG Flow charts</strong> &#8211; Track expected goals across match time</p></li></ul><blockquote><p>The Python Toolstack? Usually <code>matplotlib</code> and <code>seaborn</code> again, combined with <code>mplsoccer</code>, a library tailored to football analytics.</p></blockquote><div><hr></div><h2>A Few Rules of Thumb From 10 Years in Consulting</h2><p>Rendering a simple figure is, in most cases, a one-liner. The real challenge is almost never the plotting itself &#8212; it&#8217;s getting your data into the right format and shape.</p><p>I told you wrangling was important (if you missed the football data wrangling issue, grab it <a href="https://www.pythonfootball.com/p/football-data-wrangling-in-plain?r=5mroiq">here</a>).</p><p>Of course, you still need to get familiar with different visualisation libraries and functions. But that&#8217;s generally the <em>easier</em> part.</p><h2>The Real Bottlenecks</h2><p>There are two major hurdles that beginners face when visualising data:</p><ul><li><p><strong>Not knowing what you want to show.</strong></p></li></ul><p>This is the hardest part. Especially early on, it's easy to feel lost &#8212; you have the data, but you don&#8217;t know what story to tell or what figure would best show it. </p><p>Here is a thought-starter:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Nr4R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nr4R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png 424w, https://substackcdn.com/image/fetch/$s_!Nr4R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png 848w, https://substackcdn.com/image/fetch/$s_!Nr4R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png 1272w, https://substackcdn.com/image/fetch/$s_!Nr4R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nr4R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png" width="1061" height="795" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:795,&quot;width&quot;:1061,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:218170,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/170258228?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Nr4R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png 424w, https://substackcdn.com/image/fetch/$s_!Nr4R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png 848w, https://substackcdn.com/image/fetch/$s_!Nr4R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png 1272w, https://substackcdn.com/image/fetch/$s_!Nr4R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d645a3e-5025-472a-9410-dc96746ff7b4_1061x795.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Not knowing how to wrangle the data into shape.</strong></p></li></ul><p>You might have an idea (&#8220;I want a scatter plot showing Shooting Goals Added/90 vs xG/90 per player&#8221;), but you can&#8217;t quite get the DataFrame to that point. Wrangling data is a fundamental skill that will follow you everywhere.</p><p>For beginners, the easiest way to get started is with <code>polars</code> &#8212; lightning fast, simpler syntax (the code reads like a recipe), and easy to revisit after a break.</p><p>If you get past these two &#8212; that is, you know what to graph <strong>and</strong> you can wrangle your way into the right shape &#8212; you&#8217;ve done <strong>80%</strong> of the visualisation work.</p><h2>The Last 20%: Branding and Beautifying</h2><p>As with most things in life, going from 80% to 100% takes <strong>disproportionate effort</strong>. It&#8217;s where diminishing returns kick in. But let&#8217;s not kid ourselves &#8212; a <strong>beautiful</strong> figure often stands out because of:</p><ul><li><p>Clean <strong>labels</strong> and <strong>titles</strong></p></li><li><p>Thoughtful <strong>color palettes</strong></p></li><li><p>Well-placed <strong>annotations</strong></p></li><li><p>Consistent <strong>fonts and styling</strong></p></li></ul><p>Take a look at the most popular football analytics accounts on Twitter: they have a recognisable aesthetic. That&#8217;s their visual branding &#8212; a consistent combination of font choices, color themes, and annotation styles.</p><p>As a beginner though, your job is <em>not</em> to perfect every tiny detail. Your job is to <strong>get the fundamentals right</strong> &#8212; and trust that polish will come with time.</p><p>The good news? Once you design your own visualisation template (or adapt an existing one), you rarely need to touch it again. That&#8217;s the power of templating.</p><div><hr></div><p><strong>Boom &#8212; that was data visualisation fundamentals in plain English.</strong></p><p>Data visualisation isn&#8217;t just about making pretty charts.</p><p>It&#8217;s about <strong>thinking clearly</strong>, <strong>communicating honestly</strong>, and <strong>seeing what&#8217;s really there</strong> &#8212; even when the stats try to tell a different story.</p><p>If you enjoyed this post, consider sharing it with someone who might find it useful.</p><p>If you&#8217;d like access to Python football templates, stick around &#8212; or join the waitlist for the upcoming <em>Fast-Track Guide to Football Analytics with Python</em>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.pythonfootball.com/survey/3897364?token=&quot;,&quot;text&quot;:&quot;Join the Wait List&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.pythonfootball.com/survey/3897364?token="><span>Join the Wait List</span></a></p><p>Either way, deep dives are coming.</p><p>Comments and shares are always appreciated.</p><p>Thanks for reading&#8212;see you next Thursday!</p><p><em><strong>Martin</strong></em></p><p><em>The Python Football Review</em></p>]]></content:encoded></item><item><title><![CDATA[Football Data Wrangling (in plain English)]]></title><description><![CDATA[Why 80 % of data science is about wrangling&#8212;and the Python shortcut that makes it painless]]></description><link>https://www.footballmarketreview.com/p/football-data-wrangling-in-plain</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/football-data-wrangling-in-plain</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 31 Jul 2025 08:01:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0Yr7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #011.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Yr7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Yr7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!0Yr7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!0Yr7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!0Yr7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Yr7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png" width="438" height="438" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:438,&quot;bytes&quot;:1789181,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/169327855?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0Yr7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!0Yr7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!0Yr7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!0Yr7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9b178bd-a6a4-443d-a0e1-d8c395481617_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Seasoned analysts will tell you that <strong>80 % of any football data project is spent on one thing: wrangling</strong>. If the term is new to you, think of it as the combined art of <em>cleaning</em> and <em>transforming</em> raw tables so your analysis doesn&#8217;t fall apart later.</p><p>In this issue you&#8217;ll learn:</p><ul><li><p>what data wrangling <em>really</em> means,</p></li><li><p>why even &#8220;clean&#8221; datasets still trip people up,</p></li><li><p>the common bottlenecks that beginners face, and</p></li><li><p>the one Python library that makes wrangling faster&#8212;and far less painful.</p></li></ul><p>Enjoy!</p><div><hr></div><p>Before we dive in &#8212; quick heads-up.</p><p>I&#8217;m working on a <em><strong>Fast-Track</strong></em><strong> Guide to Football Analytics with Python</strong> &#8212; designed to cut through the usual beginner roadblocks and get you hands-on, fast.</p><p>It&#8217;s packed with ready-to-use templates and practical case studies, so you can skip the fluff and start exploring football data with confidence.</p><p><strong>Interested?</strong> Join the waitlist below:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.pythonfootball.com/survey/3897364?token=&quot;,&quot;text&quot;:&quot;Join the Waitlist&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.pythonfootball.com/survey/3897364?token="><span>Join the Waitlist</span></a></p><p>Okay, let&#8217;s dive in.</p><div><hr></div><h1><strong>1 &#8211; Cleaning</strong></h1><p>Last week, you learned the four ways to collect football data. If you missed that issue, you can catch up <a href="https://www.pythonfootball.com/p/football-data-collection-in-plain?r=5mroiq&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=false">here</a>. Once you&#8217;ve collected the data, your next move is to clean it.</p><h4><em><strong>But wait, Martin&#8212;isn&#8217;t the data I just downloaded already clean?</strong></em></h4><p>It&#8217;s tempting to think so. If your feed comes from an internal pipeline, a paid JSON API, or a trusted public hub like FBref, the tables usually <strong>look</strong> pristine. Yet they almost always hide little traps:</p><ul><li><p>A handful of xG values are missing&#8212;models choke on blank rows.</p></li><li><p>Brighton appear as &#8220;Brighton&#8221;, &#8220;Brighton &amp; Hove Albion&#8221; and &#8220;BHAFC&#8221; across seasons. Pick one or your merges will explode.</p></li><li><p>Dates sneak in as plain text; numeric columns arrive as strings. Try plotting those and see what happens.</p></li></ul><p>Long story short: <strong>&#8220;collected&#8221; does not equal &#8220;analysis&#8209;ready.&#8221;</strong> The safest mindset is to assume every dataset is dirty until proven clean.</p><p>Once you&#8217;ve fixed the nulls, unified names, and straightened data types, you can move on to the fun part: transforming.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1><strong>2 &#8211; Transforming</strong></h1><p>Cleaning makes the data <em>safe</em>; transforming makes it <em>useful</em>.</p><p>Here&#8217;s what usually happens in this stage:</p><ul><li><p><strong>Zoom in</strong> &#8211; Slice the universe down to what matters: maybe just Premier League matches since 2014/15, or only Arsenal home fixtures, or every shot taken after the 75&#8209;minute mark.</p></li><li><p><strong>Create new metrics</strong> &#8211; Raw columns rarely answer football questions on their own. You might turn <code>xG</code> and <code>minutes</code> into <em>xG per 90 min,</em> combine passes into a <em>possession percentage</em>, or compute <em>contributions</em> as goals plus assists.</p></li><li><p><strong>Summarise up a level</strong> &#8211; Event data might be often <em>too</em> granular for the question you&#8217;re asking. Aggregate it until each row matches the decision-making level you care about: turn <em>individual shots</em> into <strong>total xG per match</strong> or combine <em>match records</em> into <strong>team-season aggregates.</strong></p></li><li><p><strong>Reshape the table</strong> &#8211; Statistical models prefer &#8220;one <em>row</em> = one observation.&#8221; That could mean pivoting <em>long</em> (each team a separate row). A graph may require &#171; one <em>column</em> = one observation &#187; and that could mean pivoting wide (each team in its own column). Switching formats is routine.</p></li><li><p><strong>Stitch multiple sources together</strong> &#8211; Want to add betting odds or other non-performance data? You&#8217;ll merge tables on date, match ID, or team name; uniform naming from the <em>cleaning</em> step is what keeps these joins from exploding.</p></li><li><p><strong>Scale where needed</strong> &#8211; Some algorithms behave better when inputs sit on a common scale. Simple min&#8209;max scaling is often enough.</p></li></ul><p>A single project may loop through these tasks several times: aggregate, spot an outlier, go back, filter differently, aggregate again. The end&#8209;product is one tidy, logically structured DataFrame you can feed straight into a model or visual.</p><p>The goal is simple: produce a single, well&#8209;structured DataFrame your model, chart, or dashboard can consume without complaint.</p><p><strong>Cleaning + transforming = wrangling</strong>&#8212;and that&#8217;s where 80 % of real project time goes.</p><p>Told you it was important.</p><div><hr></div><h1>3 &#8211; How do you actually wrangle data in Python?</h1><p>For years the default answer was <code>pandas</code>.</p><p>Pandas gives Python a DataFrame object (Python itself has none), and every tutorial on Earth seems to start with <code>import pandas as pd</code>.</p><p>But here&#8217;s the trouble: the API is showing its age.</p><p>You juggle <code>as_index=False</code>, fight the dreaded <em>SettingWithCopyWarning</em>, and chain methods that read nothing like plain English. Great library&#8212;just (dare I say it) not beginner&#8209;friendly.</p><p>A newer option, <code>polars</code>, fixes all three pain&#8209;points:</p><ul><li><p><strong>Faster</strong> &#8211; Under the hood it&#8217;s Rust, so large tables fly.</p></li><li><p><strong>Cleaner syntax</strong> &#8211; Verbs like <code>select</code>, <code>filter</code>, <code>with_columns</code> read like a recipe.</p></li><li><p><strong>Short learning curve</strong> &#8211; Fewer edge&#8209;case arguments, no copy&#8209;view headaches.</p></li></ul><h4>If someone offered you <em>standard</em> vs. <em>faster, clearer, easier to remember</em>, which would you pick?</h4><p>Exactly.</p><p>Here&#8217;s a sample <code>Polars</code> code. For this exercise, we&#8217;ll use a <strong>2023/24 Fantasy Premier League</strong> dataset available on Github that contains ~ 30,000 rows, where each row records a single player&#8217;s stats for one Premier League gameweek. The data contains <strong>41 columns</strong> covering everything from goals and assists to minutes played, xG, xA, and more.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eL_V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eL_V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png 424w, https://substackcdn.com/image/fetch/$s_!eL_V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png 848w, https://substackcdn.com/image/fetch/$s_!eL_V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png 1272w, https://substackcdn.com/image/fetch/$s_!eL_V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eL_V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png" width="1456" height="407" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:407,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:110802,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/169327855?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eL_V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png 424w, https://substackcdn.com/image/fetch/$s_!eL_V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png 848w, https://substackcdn.com/image/fetch/$s_!eL_V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png 1272w, https://substackcdn.com/image/fetch/$s_!eL_V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16a61e64-620c-4233-b843-ffa877a2eee0_1830x512.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wYHq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wYHq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png 424w, https://substackcdn.com/image/fetch/$s_!wYHq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png 848w, https://substackcdn.com/image/fetch/$s_!wYHq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png 1272w, https://substackcdn.com/image/fetch/$s_!wYHq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wYHq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png" width="1456" height="553" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:553,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92337,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/169327855?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wYHq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png 424w, https://substackcdn.com/image/fetch/$s_!wYHq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png 848w, https://substackcdn.com/image/fetch/$s_!wYHq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png 1272w, https://substackcdn.com/image/fetch/$s_!wYHq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff26399ce-3c9f-403d-8b56-a837b87f9c22_1470x558.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If we want to wrangle the data to discover <strong>Arsenal&#8217;s top contributors in goals and assists</strong>, here&#8217;s how we could do it with Polars:</p><h3>A quick Polars demo</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!I2Gi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!I2Gi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png 424w, https://substackcdn.com/image/fetch/$s_!I2Gi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png 848w, https://substackcdn.com/image/fetch/$s_!I2Gi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png 1272w, https://substackcdn.com/image/fetch/$s_!I2Gi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!I2Gi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png" width="1046" height="694" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:694,&quot;width&quot;:1046,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:143289,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/169327855?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!I2Gi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png 424w, https://substackcdn.com/image/fetch/$s_!I2Gi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png 848w, https://substackcdn.com/image/fetch/$s_!I2Gi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png 1272w, https://substackcdn.com/image/fetch/$s_!I2Gi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba1761f5-2c15-4f35-abe5-9a164d0f4a6c_1046x694.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Try reading that line by line:</p><ol><li><p><code>read_csv</code> &#8211; load the file (using its <a href="https://raw.githubusercontent.com/vaastav/Fantasy-Premier-League/refs/heads/master/data/2023-24/gws/merged_gw.csv">URL</a>).</p></li><li><p><code>select</code> &#8211; keep only the columns we need.</p></li><li><p><code>filter</code> &#8211; keep only the Arsenal rows only.</p></li><li><p><code>with_columns</code> &#8211; add <code>assists + goals_scored</code> as <em>contributions</em>.</p></li><li><p><code>group_by</code><strong> / </strong><code>agg</code> &#8211; group by each player and aggregate his total contributions.</p></li><li><p><code>sort</code>  &#8211; rank the players by their contributions and show the top five.</p></li><li><p><code>head</code> - show the top 5 performers.</p></li></ol><p>That&#8217;s the entire story&#8212;no temporary variables, no <code>lambdas</code>, no warnings. Swap <code>select</code> for <code>merge</code> or <code>pivot</code> and you&#8217;ve covered 80 % of day&#8209;to&#8209;day wrangling.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EExb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EExb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png 424w, https://substackcdn.com/image/fetch/$s_!EExb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png 848w, https://substackcdn.com/image/fetch/$s_!EExb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png 1272w, https://substackcdn.com/image/fetch/$s_!EExb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EExb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png" width="254" height="226.70093457943926" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:382,&quot;width&quot;:428,&quot;resizeWidth&quot;:254,&quot;bytes&quot;:33183,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/169327855?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EExb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png 424w, https://substackcdn.com/image/fetch/$s_!EExb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png 848w, https://substackcdn.com/image/fetch/$s_!EExb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png 1272w, https://substackcdn.com/image/fetch/$s_!EExb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b608c32-6172-43a6-92cf-94b1eff3b387_428x382.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The point of this demo is to show that <strong>Polars reads like a recipe</strong> (it has tons of other advantages but that&#8217;s a story for another time). Even if you&#8217;ve never written a line of Python in your life, you&#8217;ll have no trouble following it. Better still, once you type it out, the syntax sticks&#8212;because you use clear, verb-style commands. </p><p>Next time you need to wrangle data, the steps will come right back to you, streamlining your workflow like nothing else. Speaking from experience here.</p><p>Now, <code>polars</code> won&#8217;t make every wrinkle disappear, but it removes a lot of the boilerplate that trips newcomers. Learn a dozen <em>verbs</em> and you&#8217;ll slice through datasets while everyone else is still Googling &#8220;Pandas groupby keeps index true/false?&#8221;</p><p>(And yes, Pandas is still the industry standard; we&#8217;ll look at bridging the two in a future issue.)</p><div><hr></div><h1><strong>4 &#8211; Rules of thumb from a decade in data consulting</strong></h1><ol><li><p><strong>Choose a library you can walk away from and still remember.</strong></p><p>If you might take a few weeks off, Polars&#8217; verb&#8209;style API is far easier to pick up again than Pandas&#8217; bracket soup.</p></li><li><p><strong>Assume every dataset is messy.</strong></p><p>Even &#8220;premium&#8221; feeds hide quirks&#8212;extra spaces in names, dashes instead of <code>NaN</code>, silent duplicates. Treat cleanliness as a hypothesis you must test, not a fact.</p></li><li><p><strong>Verify first, trust later.</strong></p><p>Quick descriptive stats (min, max, unique counts) expose impossible values before they poison your model.</p></li><li><p><strong>Name things clearly and consistently.</strong></p><p>Lower&#8209;case, snake_case, no spaces: <code>team_id</code>, <code>match_date</code>, <code>xg_total</code>. Future&#8209;you&#8212;and your join keys&#8212;will thank you.</p></li><li><p><strong>Interrogate every column.</strong></p><p>A header can lie. Ask &#8220;What exactly does <em>possession</em> mean here?&#8221; before you publish a chart based on it.</p></li><li><p><strong>Debug on a snack&#8209;size sample.</strong></p><p>Pivot won&#8217;t run on 100 k rows? Slice ten rows, fix the issue, then scale back up. Small chunks reveal problems fast.</p></li></ol><p>Stick to these habits and wrangling becomes routine rather than a recurring nightmare.</p><div><hr></div><p><strong>Boom&#8212;that&#8217;s data wrangling in plain English for absolute beginners.</strong></p><p>If this issue helped, feel free to pass it on. You now understand why most people stall at the wrangling stage&#8212;and how to jump ahead of 90 % of them.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/football-data-wrangling-in-plain?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/football-data-wrangling-in-plain?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>I&#8217;m still tweaking the format, so hit reply and tell me what you&#8217;d like more (or less) of: shorter bites, deeper dives, extra Python snippets, or broader football concepts? </p><p>My goal is to build this newsletter <em>with</em> you, not just <em>for</em> you.</p><p>See you next Thursday,</p><p><strong>Martin</strong></p><p><em>The Python Football Review</em></p>]]></content:encoded></item><item><title><![CDATA[Football Data Collection (in plain English)]]></title><description><![CDATA[The 4 Ways to Collect Football Data&#8212;and the Best Starting Point for Beginners]]></description><link>https://www.footballmarketreview.com/p/football-data-collection-in-plain</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/football-data-collection-in-plain</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 24 Jul 2025 08:00:51 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/34793e12-2626-4796-ba78-e9decf4d72d6_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #010.</em></p><p>Today we&#8217;re tackling the unglamorous but absolutely critical first step in any football analytics project: <strong>collecting the data</strong>.</p><p>By the end of this issue you&#8217;ll know the <strong>4 main ways to source football data</strong>&#8212;and <strong>how to start pulling it with only a few lines of Python</strong>, all explained in <em>plain English</em>.</p><div><hr></div><p>Before we get started, just a quick heads-up.</p><p>I&#8217;ve started working on a beginner-friendly <em><strong>Fast-Track</strong></em><strong> Guide to Football Analytics with Python</strong>.</p><p>It will be packed with useful templates, practical case studies, and easy-to-follow explanations.</p><p>If you&#8217;d like to be the first to know when it launches (and maybe even grab an early-bird bonus), you can join the waitlist below:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.pythonfootball.com/survey/3897364?token=&quot;,&quot;text&quot;:&quot;Join the Waitlist&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.pythonfootball.com/survey/3897364?token="><span>Join the Waitlist</span></a></p><p>Okay, so grab a coffee, and let&#8217;s dive in.</p><div><hr></div><h1>What <em>Data Collection</em> Really Means</h1><p>Most coding courses hand you spotless CSVs. Real life doesn&#8217;t.</p><p>Unless you work somewhere that pipes cleaned match feeds straight to your desk, <strong>you are the data engineer</strong>. Your job is to move raw numbers&#8212;from a website, an API, or a database&#8212;onto your machine in a format you can actually use.</p><p>Ian Graham, Liverpool&#8217;s former Director of Research and the brains behind the first in-house analytics department in the Premier League, recalls sprinting into the office the morning after their 4-0 comeback against Barcelona just to open an analysis-ready match file. Lovely&#8212;if you have a dedicated data engineering team.</p><p>Most of us don&#8217;t.</p><p>So here&#8217;s how to do it yourself.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!68qI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!68qI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!68qI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!68qI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!68qI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!68qI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png" width="618" height="618" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:618,&quot;bytes&quot;:1874110,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168967691?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!68qI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!68qI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!68qI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!68qI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe097a112-18ae-4d12-b42e-44bcff9b7e4d_1024x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h1>1&#8212;Manual Copy</h1><p>Sometimes the fastest route is staring you in the face: open Understat or FBref, copy-paste the table into Excel, job done.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cCSM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cCSM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png 424w, https://substackcdn.com/image/fetch/$s_!cCSM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png 848w, https://substackcdn.com/image/fetch/$s_!cCSM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png 1272w, https://substackcdn.com/image/fetch/$s_!cCSM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cCSM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png" width="1456" height="585" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/db2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:585,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:344225,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168967691?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cCSM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png 424w, https://substackcdn.com/image/fetch/$s_!cCSM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png 848w, https://substackcdn.com/image/fetch/$s_!cCSM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png 1272w, https://substackcdn.com/image/fetch/$s_!cCSM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb2d049a-dacb-4b4f-813d-0e48723ef781_2172x872.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There&#8217;s nothing technically tricky here&#8212;other than finding exactly what you need.</p><p>But manual work can&#8217;t be automated, and it doesn&#8217;t scale.</p><p><em>Thank you, Captain Obvious.</em></p><p>Still, for a quick sanity check or a one-off chart, copy-paste is quicker than spinning up a full scraper.</p><p>You can do even better: <strong>never start copying until you&#8217;ve checked GitHub or Kaggle.</strong></p><p>Chances are someone has already posted the dataset you need. If you can <code>read_csv()</code> or <code>read_html() </code>a clean file in a single line, take the gift and run.</p><div><hr></div><h1>2&#8212;Web Scraping</h1><p>The data you need isn&#8217;t always gift-wrapped. It may sit behind dynamic tables, dropdown menus, or JavaScript calls that no public wrapper touches. <strong>Web scraping</strong> is the art of writing a script that visits a page, finds the right pieces of the markup, and copies the numbers to your machine.</p><p>In practice you:</p><ol><li><p><strong>Request</strong> the page&#8217;s HTML.</p></li><li><p><strong>Parse</strong> its <em>nodes</em> (individual tags such as <code>&lt;tr&gt;</code> or <code>&lt;td&gt;</code> that hold text).</p></li><li><p><strong>Extract</strong> what you need and save it to a DataFrame.</p></li></ol><p><em>Expect a learning curve though.</em></p><p>You&#8217;ll juggle <strong>CSS selectors</strong> (mini-queries like <code>.table-row &gt; td:nth-child(3)</code> that tell Python &#8220;grab the 3rd cell in each row&#8221;), deal with cookies and CAPTCHAs, and respect <code>robots.txt</code> so you don&#8217;t hammer the host server.</p><p><strong>Typical Python toolkit</strong></p><ul><li><p><code>requests</code> + <code>BeautifulSoup</code> for quick and clean for static pages and simple tables.</p></li><li><p><code>Selenium</code> for spinning up a headless browser so you can click buttons, open dropdowns, and wait for JavaScript to load.</p></li><li><p><code>pandas.read_html()</code> &#8211; a one-liner that sometimes grabs simple tables without extra code (You can check out <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;McKay Johns&quot;,&quot;id&quot;:15691582,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/152becb8-787f-4f56-992b-5ddf614750b6_4000x4000.jpeg&quot;,&quot;uuid&quot;:&quot;56928a26-355a-4e3e-9d71-ae2acdf72b44&quot;}" data-component-name="MentionToDOM"></span>&#8217;s brilliant explanation on <a href="https://www.youtube.com/watch?v=I0TB9m_hyCo">YouTube</a>).</p></li></ul><p>Scraping could fill a course by itself, but even basic skills pay off: once you automate a tricky site, the data updates are yours forever.</p><div><hr></div><p>Now, if you&#8217;d rather skip copy-pasting (too basic, not scalable) <strong>and</strong> avoid the overhead of building custom scrapers (steep learning curve, time-consuming upkeep), you have two smoother routes:</p><ol><li><p><strong>Pay for polished feeds</strong>&#8212;exactly what most pro clubs do. Providers like Opta, StatsBomb, or Wyscout deliver match files that are already cleaned and documented.</p></li><li><p><strong>Lean on community wrappers</strong>&#8212;open-source libraries that pull multiple seasons of advanced metrics with a single line of Python.</p></li></ol><p>We&#8217;ll look at the paid option first, then wrap up with the beginner-friendly community wrappers that most hobby analysts start with.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1>3&#8212;Paid APIs</h1><p>Professional setups lean on <strong>APIs</strong>&#8212;stable web endpoints that deliver data in a clean, documented format. (API = <strong>Application Programming Interface</strong>: a contract that lets your code request specific data from a provider&#8217;s server.)</p><p>Think of it as web-scraping&#8217;s legal, high-speed, fully supported cousin&#8212;just one that usually comes with a price tag.</p><p><strong>Typical workflow</strong></p><ol><li><p>Create an account and grab your personal API key.</p></li><li><p>Read the docs for the endpoint you need&#8212;<code>/matches</code>, <code>/shots</code>, <code>/players</code>, etc.</p></li><li><p>Hit the URL, pass your key, and pull back a JSON payload (basically one giant nested dictionary you&#8217;ll flatten during wrangling).</p></li></ol><p><strong>Pros</strong></p><ul><li><p>Clean, consistent schema&#8212;no guessing which table cell holds the xG.</p></li><li><p>Historical depth and live feeds.</p></li><li><p>Official support; if something breaks, you have a help desk.</p></li></ul><p><strong>Cons</strong></p><ul><li><p>Cost (sometimes eye-watering).</p></li><li><p>You still have to wrangle the JSON into tidy columns&#8212;just a smaller headache than messy HTML.</p></li></ul><p>Pricing varies. Wyscout is usually cheaper; StatsBomb is the gold-standard and priced accordingly.</p><p>If you&#8217;re working on a hobby project and don&#8217;t need live updates, take advantage of <strong>StatsBomb&#8217;s free datasets</strong>&#8212;entire seasons (e.g., Europe&#8217;s top-five leagues 2015/16), Arsenal&#8217;s 2003/04 Invincibles, Bayer Leverkusen&#8217;s 2023/24 unbeaten run, even Lionel Messi&#8217;s whole career. Grab them here: <a href="https://statsbomb.com/what-we-do/hub/free-data/">https://statsbomb.com/what-we-do/hub/free-data/</a> or use their Python library <code>statsbombpy</code><strong>.</strong></p><p><em>Ready for the easiest path of all?</em></p><p>Enter community wrappers that fetch those same metrics in a single line of Python.</p><div><hr></div><h1>4&#8212;Community wrappers</h1><p>The football analytics community has blessed us with Python <em>wrappers</em>&#8212;packages that hide 97 % of the scraping grunt work.</p><p>Instead of copy-pasting from FBref, building a custom crawler, or paying StatsBomb money you don&#8217;t have, you can often import a library and fetch the data in a single line.</p><p><strong>Flagship wrapper: </strong><code>soccerdata</code> by <a href="https://x.com/p_robberechts">Pieter Robberechts</a>. Behind the scenes it scrapes several public sources and returns tidy (pandas) DataFrames. With the same package you can tap into</p><ul><li><p><strong>FBref &amp; Understat:</strong> xG, xGOT, xA, xGChain, xGFlow, shot locations, and other advanced team/player stats</p></li><li><p><strong>SofaScore, WhoScored, FotMob:</strong> line-ups and player ratings</p></li><li><p><strong>ClubElo:</strong> historical team strength</p></li><li><p><strong>SoFIFA:</strong> FIFA/FC player attributes</p></li></ul><p>&#8230;and more (full documentation <a href="https://soccerdata.readthedocs.io/en/latest/">here</a>).</p><p>Usually it&#8217;s one line to set parameters, one line to pull clean data. Simple as that.</p><p><strong>Why beginners love wrappers</strong></p><ul><li><p>Zero scraping headaches&#8212;instant gratification</p></li><li><p>Perfect sandbox to practise Polars/Pandas before wrestling with raw HTML</p></li></ul><p><strong>Caveats</strong></p><ul><li><p>Community projects can go stale; endpoints change and packages break&#8212;be ready to fork or patch</p></li><li><p>Documentation still matters&#8212;read it so you hit the right methods and parameters</p></li><li><p>Coverage is uneven: plenty of x-metrics for Europe&#8217;s top five leagues, far less for lower tiers or niche competitions</p></li></ul><p><strong>Bottom line:</strong> start with wrappers. If they cover your use-case, you&#8217;re already analysing. If not, fall back on the other three roads: manual copy, web scraping, or APIs.</p><div><hr></div><h1>5&#8212;The Python Corner</h1><p>And finally &#8212; here&#8217;s the <strong>Python code of the day</strong>. </p><p>It illustrates why starting with wrappers is the <strong>fastest and most efficient way</strong> for beginners to begin collecting advanced, up-to-date football data.</p><p><em><strong>So, how do you get xG data for Europe&#8217;s top five leagues for the past eight seasons?</strong></em></p><p>Easy.</p><p>First, install <code>soccerdata</code> (if you haven&#8217;t already), and load the library along with a data-wrangling tool &#8212; in this case, <strong>Polars</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8YPl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8YPl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png 424w, https://substackcdn.com/image/fetch/$s_!8YPl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png 848w, https://substackcdn.com/image/fetch/$s_!8YPl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png 1272w, https://substackcdn.com/image/fetch/$s_!8YPl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8YPl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png" width="378" height="295.82608695652175" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:468,&quot;width&quot;:598,&quot;resizeWidth&quot;:378,&quot;bytes&quot;:223052,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168967691?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8YPl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png 424w, https://substackcdn.com/image/fetch/$s_!8YPl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png 848w, https://substackcdn.com/image/fetch/$s_!8YPl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png 1272w, https://substackcdn.com/image/fetch/$s_!8YPl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a9264d3-0f1d-41e1-9d1f-501d00636bae_598x468.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Then, define the scope of your data. You simply call <code>sd.FBref()</code>, set the league to <code>"Big 5 European Leagues Combined"</code>, and select the seasons from 2017&#8211;18 through the current 2024&#8211;25 season. After that, use <code>.read_schedule()</code> &#8212; and voil&#224;, the data is yours.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NVhH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NVhH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png 424w, https://substackcdn.com/image/fetch/$s_!NVhH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png 848w, https://substackcdn.com/image/fetch/$s_!NVhH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png 1272w, https://substackcdn.com/image/fetch/$s_!NVhH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NVhH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png" width="1256" height="756" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:756,&quot;width&quot;:1256,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:430072,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168967691?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NVhH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png 424w, https://substackcdn.com/image/fetch/$s_!NVhH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png 848w, https://substackcdn.com/image/fetch/$s_!NVhH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png 1272w, https://substackcdn.com/image/fetch/$s_!NVhH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5653106f-1c16-443b-9c99-b2ddbd8e11ef_1256x756.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lFxs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lFxs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png 424w, https://substackcdn.com/image/fetch/$s_!lFxs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png 848w, https://substackcdn.com/image/fetch/$s_!lFxs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png 1272w, https://substackcdn.com/image/fetch/$s_!lFxs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lFxs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png" width="1320" height="688" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:688,&quot;width&quot;:1320,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:143866,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168967691?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lFxs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png 424w, https://substackcdn.com/image/fetch/$s_!lFxs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png 848w, https://substackcdn.com/image/fetch/$s_!lFxs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png 1272w, https://substackcdn.com/image/fetch/$s_!lFxs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b892112-be82-44a5-aee8-71241c654ec5_1320x688.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In the code example, we also convert the resulting DataFrame to a <strong>Polars DataFrame</strong> to take advantage of its friendly, high-performance syntax. </p><p>And that&#8217;s it &#8212; <strong>quick and easy</strong>, just as promised.</p><div><hr></div><p>Boom&#8212;that was data collection in plain English.</p><p>If you found this newsletter helpful, please spread the word! You now know the 4 ways you can get started collecting football data.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/football-data-collection-in-plain?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/football-data-collection-in-plain?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>I&#8217;m still experimenting with the format of the newsletter, so your feedback is super welcome&#8212;would you prefer shorter content, longer deep dives, more Python, or more football concepts? Or does this format hit the mark?</p><p>My aim is to build a truly practical newsletter <em>together</em> with you.</p><p>Until next week,</p><p><em><strong>Martin</strong></em></p><p><em><strong>The Python Football Review</strong></em></p>]]></content:encoded></item><item><title><![CDATA[How Wrong Are Football Pundits?]]></title><description><![CDATA[16 Years &#183; 5,582 Lawro & Sutton Picks &#8212; What Would Your Bankroll Look Like if You&#8217;d Followed Every Single One?]]></description><link>https://www.footballmarketreview.com/p/how-wrong-are-football-pundits</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/how-wrong-are-football-pundits</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 17 Jul 2025 08:01:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ttsi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #009.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ttsi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ttsi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ttsi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ttsi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ttsi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ttsi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92119,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ttsi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ttsi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ttsi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ttsi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f4c734c-6d6f-4690-a192-b5ae4d19bbc1_1280x720.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Youtube</figcaption></figure></div><p>For as long as I&#8217;ve watched football, I&#8217;ve been fascinated by the pundits who sit in match&#8209;day studios and announce exactly how the weekend will unfold.</p><p>But are they actually any good&#8212;or are we all just blindly trusting their reputation?</p><p>It&#8217;s time to find out.</p><p>This week I crunched every Premier League prediction that BBC (and Liverpool) legend <strong>Mark Lawrenson</strong> made between <strong>2009/10&#8211;2021/22</strong>, along with those of his successor <strong>Chris Sutton</strong> (2022/23&#8211;2024/25), and stacked them against the market&#8217;s odds. My questions were simple:</p><ul><li><p>How many matches did they call correctly?</p></li><li><p>What would your bankroll look like if you&#8217;d followed them with flat&#8209;stake bets?</p></li><li><p>Was Lawrenson really biased against Tottenham, West Ham, and Southampton?</p></li></ul><p>And&#8212;because this <em>is</em> the Python Football Review&#8212;I&#8217;m sharing the code at the end so that you can replicate the analysis yourself.</p><p>Enjoy!</p><div><hr></div><h1>1&#8239;&#8212;&#8239;The Data</h1><p>I scraped <a href="https://www.myfootballfacts.com/premier-league/all-time-premier-league/predictions/">MyFootballFacts</a> for Lawrenson&#8217;s and Sutton&#8217;s predictions over 16 seasons. In theory, 16&#8239;&#215;&#8239;380 = 6,080 games; I collected <strong>5,582</strong> predictions&#8212;covering 92&#8239;% of all fixtures (a few predictions were missing, nothing crucial).</p><p>Actual results and average market odds came from <a href="http://football-data.co.uk/">Football&#8209;Data.co.uk</a>.</p><p>For each match I have:</p><ul><li><p>the pundit&#8217;s <em>predicted</em> scoreline and full-time forecast</p></li><li><p>the <em>real</em> scoreline and outcome</p></li><li><p>market&#8209;average odds for home win, draw and away win</p></li></ul><p>That&#8217;s enough to run a profit&#8209;and&#8209;loss simulation with a simple 1&#8209;unit flat&#8209;stake strategy.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PkX2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PkX2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png 424w, https://substackcdn.com/image/fetch/$s_!PkX2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png 848w, https://substackcdn.com/image/fetch/$s_!PkX2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png 1272w, https://substackcdn.com/image/fetch/$s_!PkX2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PkX2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png" width="1456" height="330" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:330,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:89734,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PkX2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png 424w, https://substackcdn.com/image/fetch/$s_!PkX2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png 848w, https://substackcdn.com/image/fetch/$s_!PkX2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png 1272w, https://substackcdn.com/image/fetch/$s_!PkX2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcee2dc02-7769-4185-8788-7c59ea1d83c7_1608x364.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h1>2&#8239;&#8212;&#8239;Simulation Results</h1><p>So what would have happened if we placed a single&#8209;unit bet on all 5,582 forecasts?</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cveB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cveB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png 424w, https://substackcdn.com/image/fetch/$s_!cveB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png 848w, https://substackcdn.com/image/fetch/$s_!cveB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png 1272w, https://substackcdn.com/image/fetch/$s_!cveB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cveB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png" width="288" height="93" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aadf7522-9419-4064-bec7-5a586e039326_288x93.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:93,&quot;width&quot;:288,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4176,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cveB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png 424w, https://substackcdn.com/image/fetch/$s_!cveB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png 848w, https://substackcdn.com/image/fetch/$s_!cveB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png 1272w, https://substackcdn.com/image/fetch/$s_!cveB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faadf7522-9419-4064-bec7-5a586e039326_288x93.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The pundits called <strong>2,862</strong> matches correctly (<strong>51&#8239;% win rate</strong>), resulting in a <strong>+14.5&#8209;unit profit</strong> on a 1&#8209;unit stake per game&#8212;an overall rate of return (ROR) of <strong>+0.3&#8239;%</strong> (14.5/5582) across the 16&#8209;season sample.</p><p>Now that&#8217;s a surprise. Honestly, I expected a loss.</p><p>No disrespect, but making money in betting is about <em>value</em>, not simply picking winners, and punditry is (mostly) about predicting winners.</p><p>Having said that, a 0.3% ROR over 16 seasons is nothing to brag about. I mean the pundits were basically treading water&#8212;just about breaking even.</p><p>Nothing more, nothing less.</p><h3>Individual performance</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bjdc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bjdc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png 424w, https://substackcdn.com/image/fetch/$s_!bjdc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png 848w, https://substackcdn.com/image/fetch/$s_!bjdc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png 1272w, https://substackcdn.com/image/fetch/$s_!bjdc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bjdc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png" width="419" height="134" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:134,&quot;width&quot;:419,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8582,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bjdc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png 424w, https://substackcdn.com/image/fetch/$s_!bjdc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png 848w, https://substackcdn.com/image/fetch/$s_!bjdc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png 1272w, https://substackcdn.com/image/fetch/$s_!bjdc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f1c5a75-968f-44ef-bfb5-17a6c8c94fe3_419x134.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ul><li><p><strong>Mark Lawrenson</strong>: 4,450 forecasts &#8594; 2,289 correct predictions (<strong>51&#8239;% win rate</strong>) &#8594; <strong>+47.6 units</strong> (<strong>+1.0&#8239;% ROR</strong>). He started strong, dipped to &#8211;60 units, then clawed his way back and spent most of the time above zero.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qHOd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qHOd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png 424w, https://substackcdn.com/image/fetch/$s_!qHOd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png 848w, https://substackcdn.com/image/fetch/$s_!qHOd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png 1272w, https://substackcdn.com/image/fetch/$s_!qHOd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qHOd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png" width="587" height="467" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:467,&quot;width&quot;:587,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:38343,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qHOd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png 424w, https://substackcdn.com/image/fetch/$s_!qHOd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png 848w, https://substackcdn.com/image/fetch/$s_!qHOd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png 1272w, https://substackcdn.com/image/fetch/$s_!qHOd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c4a37c7-e3f5-4590-96c0-fd9f25207b15_587x467.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Chris Sutton</strong>: 1,132 forecasts &#8594; 573 wins (<strong>51&#8239;% win rate</strong>) &#8594; <strong>&#8211;33 units</strong> (<strong>&#8211;3&#8239;% ROR</strong>).</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uoRE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uoRE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png 424w, https://substackcdn.com/image/fetch/$s_!uoRE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png 848w, https://substackcdn.com/image/fetch/$s_!uoRE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png 1272w, https://substackcdn.com/image/fetch/$s_!uoRE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uoRE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png" width="592" height="462" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:462,&quot;width&quot;:592,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40623,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uoRE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png 424w, https://substackcdn.com/image/fetch/$s_!uoRE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png 848w, https://substackcdn.com/image/fetch/$s_!uoRE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png 1272w, https://substackcdn.com/image/fetch/$s_!uoRE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ff83904-73da-4a3f-b785-601e6d399d67_592x462.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Sutton hasn&#8217;t found the same luck (yet?). After 1,000 forecasts he&#8217;s 33 units down. For context, at the same stage Lawro was &#8211;60, so don&#8217;t write him off just yet.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1>3&#8239;&#8212;&#8239;Should We Be Impressed with Lawro&#8217;s Record?</h1><p>Let&#8217;s be real: <strong>a 1&#8239;% ROI over 13 seasons is nothing to brag about.</strong> You&#8217;d have earned more interest parking the cash in a half&#8209;decent savings account.</p><p>Remember, this is <em>after</em> decades of insider contacts, professional playing experience, and BBC resources.</p><p>Lawro&#8217;s Predictions began as a TV segment and became a BBC Sport website staple, regularly generating <em>hundreds of thousands</em> of page impressions each week&#8212;peaking at 1.2&#8239;million when Rick Astley guested over Christmas&#8239;2020 (<a href="https://www.bbc.com/sport/football/61493783">BBC</a>).</p><p>Now, that&#8217;s a lot of interest for a 1&#8239;% return over 13 years of predictions, wouldn&#8217;t you agree?</p><p>It&#8217;s not really about betting, of course, but many fans still treat the column as a tipping service.</p><p>Any experienced bettor will tell you:</p><ul><li><p>Profitable betting is about <strong>value</strong>, not just calling winners.</p></li><li><p><strong>Blindly following</strong> tipsters (or pundits?) won&#8217;t get you far. If they&#8217;re right, odds adjust and the edge disappears; if they&#8217;re wrong, your bankroll suffers.</p></li><li><p><em>If betting were easy money, it wouldn&#8217;t be legal.</em> Harsh but true. As Lawro himself once <a href="https://www.bbc.com/sport/football/61493783">joked</a>:</p></li></ul><blockquote><p><em>&#8220;If I honestly thought I could accurately predict the results of football matches, I wouldn't be here, freezing my backside off. I would be in Barbados, in Sandy Lane hotel.&#8221;</em></p></blockquote><div><hr></div><h1>4&#8239;&#8212;&#8239;Did Lawro Have Biases?</h1><p>Before we get to the Python corner, let&#8217;s tackle a complaint Lawro heared a lot. Fans of Tottenham, Southampton, and especially West Ham have long <a href="https://www.bbc.com/sport/football/61493783">claimed</a> he&#8217;s biased against them.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!M6k3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!M6k3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png 424w, https://substackcdn.com/image/fetch/$s_!M6k3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png 848w, https://substackcdn.com/image/fetch/$s_!M6k3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png 1272w, https://substackcdn.com/image/fetch/$s_!M6k3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!M6k3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png" width="595" height="227" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:227,&quot;width&quot;:595,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19789,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!M6k3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png 424w, https://substackcdn.com/image/fetch/$s_!M6k3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png 848w, https://substackcdn.com/image/fetch/$s_!M6k3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png 1272w, https://substackcdn.com/image/fetch/$s_!M6k3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F170382e3-c794-491b-ad19-8ecd17be51e1_595x227.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><a href="https://x.com/WestHam/status/687023879072550914?ref_src=twsrc%5Etfw">West Ham United on X: "88: 'Lawro, what's the score?' sing the travelling Hammers fans! He predicted we'd lose 2-1 tonight, by the way... [1-3] #WHUFC #BOUWHU" / X</a></figcaption></figure></div><p>So here&#8217;s a small analysis we can run: grade only Lawrenson&#8217;s for/against calls at average odds. </p><ul><li><p>If his picks beat the market (i.e., show a positive ROR), you could argue his forecasts were broadly justified. </p></li><li><p>If they fail to beat the market, critics have a case that he under-performed&#8212;wilfully or not&#8212;on certain teams. </p></li></ul><p>Yes, this is a simplification. A positive ROR might just reflect a few mis-priced games, while a negative one could be the product of small samples, long-shot variance, or statistically insignificant results. The goal here is insight and a bit of fun.</p><p>So how did his predictions fare for those clubs?</p><p>The table below shows the simulation results for matches involving any of those three teams in which Lawrenson picked a side (draws are excluded).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Sge5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Sge5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png 424w, https://substackcdn.com/image/fetch/$s_!Sge5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png 848w, https://substackcdn.com/image/fetch/$s_!Sge5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png 1272w, https://substackcdn.com/image/fetch/$s_!Sge5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Sge5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png" width="596" height="163" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:163,&quot;width&quot;:596,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16176,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Sge5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png 424w, https://substackcdn.com/image/fetch/$s_!Sge5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png 848w, https://substackcdn.com/image/fetch/$s_!Sge5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png 1272w, https://substackcdn.com/image/fetch/$s_!Sge5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf523900-5450-4c9e-9f5d-acb6c78a58c0_596x163.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><ul><li><p><strong>Spurs supporters can relax</strong>&#8212;Lawro was actually <em>better than average</em> on Tottenham fixtures, both in accuracy (60% win rate) and profit (2% ROR)</p></li><li><p><strong>Hammers fans:</strong> his 53&#8239;% hit&#8209;rate and +1&#8239;% ROR are almost exactly his long&#8209;run baseline. No real bias either way.</p></li><li><p><strong>Saints die&#8209;hards do have a case.</strong> He undershot on Southampton, paying out only 46&#8239;% of the time and reaching a negative 8&#8239;% of returns meaning that over the long term for any 100&#163; wagered, you&#8217;d be expected to lose 8&#163;.</p></li></ul><p>Looking wider, the best teams in his for/against prediction portfolio were Reading (+22% ROR), Watford (20%) and Cardiff (19%).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Gfxj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Gfxj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png 424w, https://substackcdn.com/image/fetch/$s_!Gfxj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png 848w, https://substackcdn.com/image/fetch/$s_!Gfxj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png 1272w, https://substackcdn.com/image/fetch/$s_!Gfxj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Gfxj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png" width="485" height="351.566985645933" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:606,&quot;width&quot;:836,&quot;resizeWidth&quot;:485,&quot;bytes&quot;:101418,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Gfxj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png 424w, https://substackcdn.com/image/fetch/$s_!Gfxj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png 848w, https://substackcdn.com/image/fetch/$s_!Gfxj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png 1272w, https://substackcdn.com/image/fetch/$s_!Gfxj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca0a95cf-9cca-4137-8daf-b6f6e07bd63d_836x606.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Blackpool were Lawro&#8217;s Trojan horse: only 43&#8239;% win rate and a &#8211;31&#8239;% ROR, followed by Brighton (-16%) and Wigan (-14%).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FhER!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FhER!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png 424w, https://substackcdn.com/image/fetch/$s_!FhER!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png 848w, https://substackcdn.com/image/fetch/$s_!FhER!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png 1272w, https://substackcdn.com/image/fetch/$s_!FhER!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FhER!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png" width="519" height="383.6626794258373" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:618,&quot;width&quot;:836,&quot;resizeWidth&quot;:519,&quot;bytes&quot;:107706,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/168451957?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FhER!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png 424w, https://substackcdn.com/image/fetch/$s_!FhER!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png 848w, https://substackcdn.com/image/fetch/$s_!FhER!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png 1272w, https://substackcdn.com/image/fetch/$s_!FhER!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2be14c5f-8c3b-4ef1-bbcf-e7d5f3aa0204_836x618.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Bottom line:</strong> the &#8220;Lawro hates my team&#8221; meme is mostly myth&#8212;unless you&#8217;re a <strong>Southampton</strong> fan. (And even then, there are <em>five</em> clubs he performed worse against).</p><div><hr></div><h1>5 &#8212; The Code</h1><p>Finally, here&#8217;s the Python notebook so you can replicate the analysis yourself.</p><p>About 80&#8239;% of the work went into scraping the data; I&#8217;ll spare you that mess so you can jump straight into the clean, analysis&#8209;ready dataset and do some wrangling. <em>You&#8217;re welcome. </em>(We&#8217;ll tackle web&#8209;scraping another day.)</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/folder/vcx3hcrw71p9e/PFR-009&quot;,&quot;text&quot;:&quot;Download the notebook and data&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/folder/vcx3hcrw71p9e/PFR-009"><span>Download the notebook and data</span></a></p><p>If you&#8217;re new to Python, a Gmail account is all you need: open a <strong>Google Colab</strong> session, import the notebook you just downloaded, and run the cells in order. At the second cell you&#8217;ll be prompted to upload the data file&#8212;select the one you grabbed from the link above&#8212;then continue executing cell by cell.</p><p>The notebook loads the pre-cleaned data and walks through every step needed to produce the simulation tables.</p><p><strong>Credits:</strong> Predictions from <a href="https://www.myfootballfacts.com/premier-league/all-time-premier-league/predictions/">MyFootballFacts</a> and results/odds from <a href="http://football-data.co.uk/">Football&#8209;Data.co.uk</a> (maintained by <a href="https://x.com/12xpert">Joseph&#8239;Buchdahl</a>).</p><div><hr></div><p>Boom&#8212;that was <em>football</em> <em>pundits uncovered</em>.</p><p>If you enjoyed this edition, please share it with a friend.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/how-wrong-are-football-pundits?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/how-wrong-are-football-pundits?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>You now know how accurate football pundits really are, why their tips deserve a pinch of salt, and how to wrangle a dataset to test a pundit&#8217;s track record.</p><p>Thanks for reading&#8212;see you next Thursday!</p><p>Martin</p><p><em><strong>The Python Football Review</strong></em></p><p><em>P.S. Did the results surprise you? Reply below or drop your favourite pundit clich&#233; and I&#8217;ll test it in a future issue.</em></p>]]></content:encoded></item><item><title><![CDATA[You Shall Not Pass]]></title><description><![CDATA[Ranking elite shot-stoppers with xGOT&#8212;plus the World Cup & Euro champions who quietly sit among the worst.]]></description><link>https://www.footballmarketreview.com/p/you-shall-not-pass</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/you-shall-not-pass</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 10 Jul 2025 08:01:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!xYsg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #008!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xYsg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xYsg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!xYsg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!xYsg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!xYsg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xYsg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2108176,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167891603?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xYsg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!xYsg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!xYsg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!xYsg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a19905b-a39c-4873-a21e-3f336f2b1d37_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Last week we crowned football&#8217;s <a href="https://www.pythonfootball.com/p/the-myth-of-the-clinical-striker?r=5mroiq">greatest finishers</a>. Today we turn the spotlight on goalkeepers and ask:</p><blockquote><p><em><strong>Who are the elite shot-stoppers?</strong></em></p></blockquote><p>To find out, I&#8217;ll dive into Opta&#8217;s post-shot data and examine:</p><ul><li><p>whether the clean-sheet leaders are truly world-class shot-stoppers</p></li><li><p>which names quietly top the <strong>Goals Prevented</strong> leaderboard</p></li><li><p>which fan favourites <em>leak</em> more than they should (brace yourself, we&#8217;ve got a World Cup and Euro champions in the list)</p></li></ul><p>A step-by-step Python template is included so you can rerun (and roast) my numbers.</p><p>Enjoy!</p><div><hr></div><h2>Quick refresher / disclaimer</h2><p>If xGOT (expected goals on target) is new to you, start with my 101 primer <a href="https://www.pythonfootball.com/p/expected-goals-on-target-xgot-101?r=5mroiq">here</a>. In one sentence:</p><ul><li><p><strong>xGOT</strong> = the probability that a <em>shot on target</em> becomes a goal&#8212;ball flight, pace, and placement included.</p></li></ul><p>From there we can build two related keeper metrics:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fEDf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fEDf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png 424w, https://substackcdn.com/image/fetch/$s_!fEDf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png 848w, https://substackcdn.com/image/fetch/$s_!fEDf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png 1272w, https://substackcdn.com/image/fetch/$s_!fEDf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fEDf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png" width="537" height="258" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:258,&quot;width&quot;:537,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19628,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167891603?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fEDf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png 424w, https://substackcdn.com/image/fetch/$s_!fEDf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png 848w, https://substackcdn.com/image/fetch/$s_!fEDf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png 1272w, https://substackcdn.com/image/fetch/$s_!fEDf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73eccac5-883d-49d2-9884-1352bcd07e7e_537x258.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Example</strong></p><p>A keeper faces 105 xGOT and concedes 100 goals.</p><ul><li><p><strong>GPR</strong> = 105 &#247; 100 = <strong>1.05</strong> &#8594; he saved 5 % more than the average goalie would.</p></li><li><p><strong>GP</strong> = 105 &#8722; 100 = <strong>+5</strong> &#8594; over the sample he <em>prevented</em> five goals than the average keeper would.</p></li></ul><p>Of course, shot-stopping is only one pillar of goalkeeping. Distribution, aerial command, and sweeping all matter too&#8212;ranking low here doesn&#8217;t automatically make anyone a poor keeper, just one who saves fewer shots than the model predicts.</p><p>Thank you, Captain Obvios.</p><p>Enough talk; let&#8217;s see the data.</p><div><hr></div><h1>1 &#8212; Scope of the study</h1><p>For this review we pull eight seasons of Opta post-shot data via Fbref (2017/18 &#8211; 2024/25) from Europe&#8217;s big-five leagues&#8212;Premier League, La Liga, Serie A, Bundesliga, and Ligue 1.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cOO2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cOO2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png 424w, https://substackcdn.com/image/fetch/$s_!cOO2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png 848w, https://substackcdn.com/image/fetch/$s_!cOO2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png 1272w, https://substackcdn.com/image/fetch/$s_!cOO2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cOO2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png" width="566" height="82" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92f7e510-c182-4403-831c-07f2359500ad_566x82.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:82,&quot;width&quot;:566,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5719,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167891603?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cOO2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png 424w, https://substackcdn.com/image/fetch/$s_!cOO2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png 848w, https://substackcdn.com/image/fetch/$s_!cOO2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png 1272w, https://substackcdn.com/image/fetch/$s_!cOO2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92f7e510-c182-4403-831c-07f2359500ad_566x82.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Across the sample we see:</p><ul><li><p><strong>122,732</strong> shots on target that yielded <strong>38,877</strong> goals (excluding own goals)</p></li><li><p>Those shots carried <strong>37,986 xGOT</strong>, so sample-wide <strong>Goals Prevented Rate of 0.98</strong>&#8212;keepers prevented about 2**% less** than the model expected.</p></li><li><p>The average shot on target weighed in at <strong>0.31 xGOT</strong>, and goalkeepers logged roughly <strong>0.26 clean sheets per 90 minutes</strong>.</p></li></ul><p>In plain English: over eight seasons the &#8220;typical&#8221; big-five keeper is a hair below par&#8212;about two extra goals allowed every hundred matches. That gives us a baseline: anyone posting a <strong>positive GPR comfortably above 1.00</strong> is bending probability in their team&#8217;s favour.</p><p>Let&#8217;s find out who.</p><div><hr></div><h1>2 &#8212; Are clean-sheet leaders world-class shot-stoppers, too?</h1><p>Okay, over the eight seasons studied, here are the top 10 keepers (minimum 160 games) ranked by clean sheets per 90 minutes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Lsme!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Lsme!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png 424w, https://substackcdn.com/image/fetch/$s_!Lsme!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png 848w, https://substackcdn.com/image/fetch/$s_!Lsme!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png 1272w, https://substackcdn.com/image/fetch/$s_!Lsme!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Lsme!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png" width="647" height="305" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:305,&quot;width&quot;:647,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:26692,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167891603?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Lsme!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png 424w, https://substackcdn.com/image/fetch/$s_!Lsme!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png 848w, https://substackcdn.com/image/fetch/$s_!Lsme!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png 1272w, https://substackcdn.com/image/fetch/$s_!Lsme!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2dcf60e4-8449-4fb2-bc4e-5c6a6ff27de6_647x305.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>No surprises here&#8212;we see the usual suspects: first-choice keepers at elite clubs.</p><p>Across the period, <strong>Marc-Andr&#233; ter Stegen</strong> tops the list with 113 clean sheets in 247 full matches, or <strong>0.46 clean sheets per 90</strong>. He conceded 210 goals from 225 xGOT, giving him a <strong>Goals Prevented ratio of 1.07</strong>. In plain English, he allowed roughly <strong>7 % fewer goals</strong> than the average keeper would have from the same shots&#8212;fine margins.</p><p><strong>Ederson</strong> and <strong>Jan Oblak</strong> sit second and third at 0.45 and 0.44 clean sheets per 90, while <strong>Alisson</strong> and <strong>Courtois</strong> round out the top five. If I&#8217;d closed my eyes and guessed, these five names would still have made the cut (though perhaps in a different order).</p><p>What really stands out is Oblak&#8217;s <strong>Goals Prevented ratio of 1.14</strong>: his shot-stopping erased roughly <strong>14 % of the goals</strong> an average keeper would have conceded. That&#8217;s truly elite&#8212;though you hardly needed the stat to remember how dominant he&#8217;s been. Alisson isn&#8217;t far behind at 1.13.</p><p>Then come the interesting cases: <strong>Ederson</strong> at 1.03 and <strong>Neuer</strong> at 1.02. Both are still <em>above</em> par, yet only marginally so.</p><p><em><strong>Does that make two world-class keepers merely average shot-stoppers?</strong></em></p><p>Rhetorical question&#8212;over long samples goals and xGOT tend to converge. More likely, their strengths lie elsewhere: Ederson&#8217;s distribution powers Manchester City&#8217;s build-up, and Neuer practically invented the modern sweeper-keeper role.</p><p>Another working hypothesis &#8212; playing behind dominant sides means they face fewer truly testing shots, giving them fewer opportunities to accumulate xGOT (as is also the case for Alisson and Courtois though, so the jury is still out on this one).</p><p>The point stands, though: <strong>Goals Prevented reframes the conversation by isolating pure shot-stopping, stripping out the protection provided by an elite defence.</strong></p><p>So what happens if we flip the question and rank keepers solely by Goals Prevented Rate? Can anyone top Oblak&#8217;s +14 %?</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1>3 &#8212; Elite shot-stoppers</h1><p>Over the eight-season window, 29 goalkeepers posted a <strong>Goals Prevented Rate</strong> above 1.0. Here are the top performers:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MghG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MghG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png 424w, https://substackcdn.com/image/fetch/$s_!MghG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png 848w, https://substackcdn.com/image/fetch/$s_!MghG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png 1272w, https://substackcdn.com/image/fetch/$s_!MghG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MghG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png" width="640" height="377" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:377,&quot;width&quot;:640,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:33340,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167891603?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MghG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png 424w, https://substackcdn.com/image/fetch/$s_!MghG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png 848w, https://substackcdn.com/image/fetch/$s_!MghG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png 1272w, https://substackcdn.com/image/fetch/$s_!MghG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1732d95d-64c5-4272-b910-704fb4c32d91_640x377.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Surprise, surprise: former Nice and PSV guardian <strong>Walter Ben&#237;tez</strong> tops the table with an eye-catching <strong>1.15</strong> Goals Prevented Rate. Put differently, he kept out 15 extra goals for every 100 he conceded&#8212;across 164 matches. Wow.</p><p>Unless you&#8217;re a Football Manager addict, this might be the first time you&#8217;ve heard his name. Ben&#237;tez has just moved to Crystal Palace on a free; if he beats Dean Henderson to the No. 1 shirt, he could be a savvy FPL pick.</p><p>The metric highlights elite shot-stoppers who don&#8217;t enjoy elite defences. Because Ben&#237;tez faced far more shots than keepers at super-clubs, his clean-sheet rate is a modest <strong>0.30 per 90</strong>&#8212;still above average, but nothing to headline.</p><p>Goals Prevented cuts through that noise.</p><p>Rounding out the list are the familiar faces: <strong>Oblak</strong> (1.14), <strong>Alisson</strong> (1.13) and <strong>Courtois</strong> (1.10). Ben&#237;tez has roughly 100 fewer games than this trio, so a little regression is possible in the future, but topping the chart at all is impressive.</p><p><em><strong>Why it matters?</strong></em></p><p>Scouts can use Goals Prevented to scan global databases for keepers at mid-table sides who are already &#8220;adding&#8221; goals&#8212;spotting the next Oblak (or dare I say Benitez) before everyone else.</p><p>Okay, now to the biggest under-performers.</p><div><hr></div><h1>4 &#8212; Elite under-performers</h1><p>Twenty-six goalkeepers in the data set posted a <strong>Goals Prevented</strong> rate below 1.0. Here are the biggest under-performers:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fvMQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fvMQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png 424w, https://substackcdn.com/image/fetch/$s_!fvMQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png 848w, https://substackcdn.com/image/fetch/$s_!fvMQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png 1272w, https://substackcdn.com/image/fetch/$s_!fvMQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fvMQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png" width="625" height="348" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:348,&quot;width&quot;:625,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31487,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167891603?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fvMQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png 424w, https://substackcdn.com/image/fetch/$s_!fvMQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png 848w, https://substackcdn.com/image/fetch/$s_!fvMQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png 1272w, https://substackcdn.com/image/fetch/$s_!fvMQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6b8e8a5-1f0d-4195-b5fb-8242aeb3df8e_625x348.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Lorenzo Montip&#242;</strong> (Verona) anchors the table at <strong>0.86</strong>, meaning that for every <strong>100 goals</strong> he conceded, the average keeper would have conceded only <strong>86</strong>. In other words, he handed opponents <strong>14 &#8220;free&#8221; goals</strong> per 100 allowed. Ouch.</p><p>Next come journeyman Frenchman <strong>Beno&#238;t Costil,</strong> Union Berlin&#8217;s <strong>Alexander Schwolow</strong> and Sassuolo&#8217;s <strong>Andrea Consigli</strong> all with 0.88.</p><p>So far, so ordinary&#8212;until you scroll and spot <strong>World-Cup winner Steve Mandanda</strong> and <strong>European-championship hero Rui Patr&#237;cio</strong>, both at <strong>0.94</strong>.</p><p>You might argue that Mandanda was rarely France&#8217;s first-choice and that both keepers are deep into their thirties, so age drag is real. You could also shrug and say &#8220;four percentage points off the mean&#8212;maybe it&#8217;s noise.&#8221;</p><p>Still, you certaintly didn&#8217;t expect national-team players from heavyweight nations to flirt with this list, did you?</p><p>I certaintly didn't.</p><p>And finally, let&#8217;s fast-forward to 2024/25 for a fresh snapshot.</p><div><hr></div><h1>5 &#8212; What happened last year?</h1><p>During the 2024/25 season, 49 goalkeepers logged at least 20 league appearances <strong>and</strong> finished with a Goals Prevented ratio above 1.0. The chart above shows the top ten.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7KQu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7KQu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png 424w, https://substackcdn.com/image/fetch/$s_!7KQu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png 848w, https://substackcdn.com/image/fetch/$s_!7KQu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png 1272w, https://substackcdn.com/image/fetch/$s_!7KQu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7KQu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png" width="729" height="303" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:303,&quot;width&quot;:729,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:28921,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167891603?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7KQu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png 424w, https://substackcdn.com/image/fetch/$s_!7KQu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png 848w, https://substackcdn.com/image/fetch/$s_!7KQu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png 1272w, https://substackcdn.com/image/fetch/$s_!7KQu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6376e3b-7241-4fca-b8ba-288c2d9670c4_729x303.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Yehvann Diouf</strong> (Reims) sets the pace at <strong>1.31</strong>&#8212;Opta&#8217;s model says an average keeper would have conceded <strong>31 % more</strong> goals from the same shots. Put differently, Diouf erased roughly one goal out of every three the model expected. That&#8217;s a hefty spike in form.</p><p>Next comes a distinctly Balkan quartet &#8212; three Serbs and one Bosnian &#8212; <strong>Vanja Milinkovi&#263;-Savi&#263;</strong> (1.29), <strong>&#272;or&#273;e Petrovi&#263;</strong> (1.27), <strong>Nikola Vasilj</strong> (1.25), and <strong>Mile Svilar</strong> (1.25).</p><p>If Yugoslavia still existed, its national-team coach would have a pleasant selection headache. Well, I guess Serbia&#8217;s coach certainly does now.</p><p>At the other end of the table, <strong>31</strong> keepers fell below the break-even line. The headline shock sits in the bottom ten: PSG&#8217;s undisputed No. 1 <strong>Gianluigi Donnarumma</strong> slumped to <strong>0.87</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Llbz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Llbz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png 424w, https://substackcdn.com/image/fetch/$s_!Llbz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png 848w, https://substackcdn.com/image/fetch/$s_!Llbz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png 1272w, https://substackcdn.com/image/fetch/$s_!Llbz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Llbz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png" width="719" height="297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:297,&quot;width&quot;:719,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29118,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167891603?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Llbz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png 424w, https://substackcdn.com/image/fetch/$s_!Llbz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png 848w, https://substackcdn.com/image/fetch/$s_!Llbz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png 1272w, https://substackcdn.com/image/fetch/$s_!Llbz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7edaf1b7-43ca-44dd-86dc-a769e016d8af_719x297.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em><strong>Wait, what?</strong></em></p><p>Despite starring in PSG&#8217;s late-stage Champions League run, Donnarumma cost his side roughly <strong>13 % more goals than xGOT predicted</strong> over the league season. Maybe supporters forgive that as long as he delivers on the nights that truly matter, but the domestic data is hard to ignore.</p><p>And finally, below you&#8217;ll find a Python template to reproduce every step of the analysis from scratch.</p><div><hr></div><h1>6 &#8212; The Python Corner</h1><p>Here&#8217;s how to replicate everything we just did in Python.</p><p>Are you new to Python and programming? Head to <a href="https://colab.research.google.com/">Google Colab</a> and open a Python session&#8212; all you need is a Gmail account.</p><p>Next, grab the notebook I used for this issue by clicking the button below. Inside, you&#8217;ll find step-by-step instructions on how to</p><ul><li><p>pull eight seasons of Opta data from FBref with <code>soccerdata</code>;</p></li><li><p>wrangle it with <code>polars</code>; and</p></li><li><p>reproduce every insight we&#8217;ve just covered.</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/sowqvzc9gxfdy24/PFR_008_YouShallNotPass.ipynb/file&quot;,&quot;text&quot;:&quot;Download Python Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/sowqvzc9gxfdy24/PFR_008_YouShallNotPass.ipynb/file"><span>Download Python Code</span></a></p><p>Once downloaded, simply import the notebook, launch the code and enjoy.</p><div><hr></div><p>And there you have it&#8212;elite shot-stoppers in a nutshell.</p><p>If this issue helped you, please pass it along!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/you-shall-not-pass?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/you-shall-not-pass?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>You now know how to rank elite shot-stoppers with xGOT, quantify how much they save their teams, identify the biggest under-achievers, and pull eight seasons of data with Python to analyse all of it yourself.</p><p>Until next week,</p><p><strong>Martin</strong></p><p><em>The Python Football Review</em></p>]]></content:encoded></item><item><title><![CDATA[Shooting Royalty]]></title><description><![CDATA[Ranking elite ball-strikers with xGOT: how much they outshoot the average finisher and which big names fall short]]></description><link>https://www.footballmarketreview.com/p/shooting-royalty</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/shooting-royalty</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 03 Jul 2025 08:01:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rohg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #007!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rohg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rohg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!rohg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!rohg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!rohg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rohg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:248318,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167370520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rohg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!rohg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!rohg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!rohg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0225e7a-ee4d-4099-bdd9-dffe04239ccc_1536x1024.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Last week we busted the <em><a href="https://www.pythonfootball.com/p/the-myth-of-the-clinical-striker?r=5mroiq">myth of the clinical striker</a></em>&#8212;why even superstars rarely beat their xG by much, and why that&#8217;s perfectly fine. The big lesson: only a few players finish well above expectation, and the word &#8220;clinical&#8221; is messy because xG mixes team service, movement, and finishing into one number.</p><p>To study <em>pure finishing</em> we need a sharper tool: <strong>xGOT (Expected Goals on Target)</strong>. xGOT looks at what happens <em>after</em> the ball leaves the boot, so it isolates a striker&#8217;s shot placement.</p><p>So, in this issue we&#8217;ll:</p><ul><li><p>reveal <strong>who</strong> the best strikers of the ball are,</p></li><li><p>see <strong>how far</strong> they outshine the average shooter,</p></li><li><p>call out the big names who &#8216;<em>under-perform&#8217;</em> xGOT yet still top the scoring charts (spoiler: two Ballon d&#8217;Or winners make the list),</p></li><li><p>and give you the full step-by-step Python code to run the analysis yourself.</p></li></ul><p>Enjoy!</p><div><hr></div><h3><strong>Before we dive in, a quick refresher / disclaimer</strong></h3><p>If xG or xGOT are new concepts for you, you can grab a primer <a href="https://www.pythonfootball.com/p/expected-goals-xg-101?r=5mroiq">here</a> and <a href="https://www.pythonfootball.com/p/expected-goals-on-target-xgot-101?r=5mroiq">here</a>. In short:</p><ul><li><p><strong>xG (Expected Goals)</strong> gauges <em>chance quality</em>&#8212;how promising the opportunity was <em>before</em> the shot.</p></li><li><p><strong>xGOT (Expected Goals on Target)</strong> gauges <em>shot execution</em>&#8212;what the striker actually did with the ball <em>after</em> contact.</p></li></ul><p>To isolate pure finishing skill professionals compare <strong>xGOT to xG</strong>:</p><ul><li><p><strong>Over-performing xG</strong> &#8594; the player beats the &#8220;average&#8221; shooter on identical chances.</p></li><li><p><strong>Under-performing xG</strong> &#8594; could signal below-par finishing <em>or</em> contextual factors we&#8217;ll unpack later.</p></li></ul><p>So, for this issue we&#8217;ll treat xGOT strictly as a proxy for striking technique. It goes without saying that an elite forward offers far more than goals&#8212;target men and pressing forwards change games without scoring&#8212;but today we&#8217;re zooming in on finishing alone.</p><p>Alright, let&#8217;s roll out the data.</p><div><hr></div><h1><strong>1 &#8212; Scope of the study</strong></h1><p>For this review we&#8217;ll pull Opta&#8217;s <strong>xGOT</strong> dataset&#8212;Opta calls it <em>Post-Shot Expected Goals (PSxG)</em>&#8212;via FBref. It covers <strong>eight seasons</strong> of shot-level data from Europe&#8217;s top-five leagues (2017/18 &#8211; 2024/25) and totals <strong>360,430 shots</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OZun!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OZun!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png 424w, https://substackcdn.com/image/fetch/$s_!OZun!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png 848w, https://substackcdn.com/image/fetch/$s_!OZun!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png 1272w, https://substackcdn.com/image/fetch/$s_!OZun!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OZun!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png" width="728" height="90.56459330143541" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:78,&quot;width&quot;:627,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:6843,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167370520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OZun!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png 424w, https://substackcdn.com/image/fetch/$s_!OZun!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png 848w, https://substackcdn.com/image/fetch/$s_!OZun!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png 1272w, https://substackcdn.com/image/fetch/$s_!OZun!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6fd6558-459e-4ab5-8443-66a3dd69f63d_627x78.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Across those attemps, 5,724 players accumulated a total of 38,883 goals from 39,998 xG and 38,759 xGOT. This means that the:</p><ul><li><p><strong>Goals : xG = 0.97</strong></p></li></ul><p>Players scored about 3 % fewer goals than the pre-shot model predicted. That near-one ratio is the sanity check we want: over a huge sample, hot and cold streaks cancel out, so xG should line up with reality. The small shortfall suggests that, overall, goalkeepers and imperfect finishing trimmed the total slightly. Or perhaps it&#8217;s simply a bit of noise &#8212; right in the range where statistical error tends to lie.</p><ul><li><p><strong>xGOT : xG = 0.97</strong></p></li></ul><p>Post-shot expected goals are at the same 0.97 ratio. Even after accounting for shot placement, the picture barely changes: strikers are still expected to finish just below the pre-shot expectation. This should not surprise you. If xGOT had drifted far from xG, we&#8217;d worry about model noise &#8212; because over the long term, the two should converge.</p><ul><li><p><strong>xG / shot &#8776; xGOT / shot &#8776; 0.11</strong></p></li></ul><p>The typical open-play attempt in the big five leagues offers roughly an <strong>11 % chance of becoming a goal</strong>, whether judged before the strike (xG) or after you know its placement (xGOT).</p><p>These results echo last week&#8217;s findings: over large samples, goals converge toward xG, and the average non-penalty shot in the big five leagues sits around <strong>0.11 expected goals</strong>. Numbers differ slightly from last week because that issue used Understat data over an 11-season window.</p><p>With the baseline set, let&#8217;s see which players top the charts in <strong>xGOT &#247; xG</strong>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1><strong>2 &#8212; The best strikers of the ball</strong></h1><p>Over the 8 seasons studied, <strong>38 players</strong> reached 80+ league goals. Exactly <strong>20</strong> finished with an <strong>xGOT : xG ratio above 1.00</strong>&#8212;meaning their shot placement <em>added</em> value on top of chance quality. The stand-outs:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3MTU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3MTU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png 424w, https://substackcdn.com/image/fetch/$s_!3MTU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png 848w, https://substackcdn.com/image/fetch/$s_!3MTU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png 1272w, https://substackcdn.com/image/fetch/$s_!3MTU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3MTU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png" width="509" height="391.1399491094148" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:302,&quot;width&quot;:393,&quot;resizeWidth&quot;:509,&quot;bytes&quot;:22630,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167370520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3MTU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png 424w, https://substackcdn.com/image/fetch/$s_!3MTU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png 848w, https://substackcdn.com/image/fetch/$s_!3MTU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png 1272w, https://substackcdn.com/image/fetch/$s_!3MTU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F537272aa-2b95-4adb-bead-22e04b5ed7f0_393x302.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em><strong>Messi</strong></em> tops yet another finishing table. His shot-placement-to-chance ratio is <strong>1.29</strong>, meaning his finishing adds <strong>29 %</strong> to the conversion probability of every shot compared with the average player in the same positions. <em>World-class</em>&#8212;as if you needed reminding.</p><p>Close behind is <strong>Heung-min Son</strong> at <strong>1.25</strong> (+25 %). Yes, Spurs really did have a world-class finisher&#8212;and that isn&#8217;t even Harry Kane. (Though Kane still makes the list at No. 8 with +10 %.)</p><p>After those two, the gap widens:</p><ul><li><p><strong>Memphis Depay</strong> closes out the top three at <strong>+17 %</strong>&#8212;proof that a Premier-League-only lens can miss La Liga/Ligue 1 excellence (I mean he did flop at United).</p></li><li><p><strong>Paulo Dybala</strong> (+14%), <strong>Iago Aspas</strong> (+12%), and <strong>Ciro Immobile</strong> (+12%) complete the top six. I knew Immobile was banging in goals in Serie A, but come on &#8212; ranking him (and Aspas, another Premier League flop) among the most efficient shooters? I wouldn&#8217;t have guessed that.</p></li><li><p>Only then do we see the usual suspects: <strong>Luis Su&#225;rez</strong> and <strong>Harry Kane</strong> (both +10 %).</p></li><li><p><strong>Serge Gnabry</strong> also posts +10 %, while <strong>Jonathan David</strong> from Lille adds +8 %. (Sneaky good&#8212;how hadn&#8217;t I noticed him sooner?)</p></li></ul><h3>Value added per shot</h3><p>Another way to look at this is through the value added per shot. The table below presents the average xGOT per shot, the average xG per shot, and the absolute difference between the two.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XhXq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XhXq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png 424w, https://substackcdn.com/image/fetch/$s_!XhXq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png 848w, https://substackcdn.com/image/fetch/$s_!XhXq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png 1272w, https://substackcdn.com/image/fetch/$s_!XhXq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XhXq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png" width="541" height="367.4944320712695" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/febd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:305,&quot;width&quot;:449,&quot;resizeWidth&quot;:541,&quot;bytes&quot;:23612,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167370520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XhXq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png 424w, https://substackcdn.com/image/fetch/$s_!XhXq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png 848w, https://substackcdn.com/image/fetch/$s_!XhXq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png 1272w, https://substackcdn.com/image/fetch/$s_!XhXq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffebd3f2f-4df0-4b83-b337-d46606a50f88_449x305.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Looking at xGOT &#8722; xG per shot highlights who squeezes the most extra value out of <em>each and every</em> attempt.</p><p>Messi&#8217;s average chance is already 13%, but his placement bumps it up to 17% &#8212; a 4-point boost per shot. <strong>Put differently, the best shooter in the world adds just 4 percentage points per attempt.</strong> Talk about fine margins. Of course, once you add up multiple shots, the difference becomes more noticeable.</p><p>Son adds 3 points; Memphis, Aspas, and Immobile sit around 2.</p><p>Okay, so now that we&#8217;ve covered the best shooters, let&#8217;s take a look at the underperformers.</p><div><hr></div><h1><strong>3 &#8212; The &#8216;underperformers&#8217;</strong></h1><p>At the opposite end of the spectrum, <strong>18 of the 38 high-volume scorers</strong> posted an xGOT-to-xG ratio below 1.00.</p><p>The ten lowest (who still scored more than 80 goals) appear in the table below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CKmw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CKmw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png 424w, https://substackcdn.com/image/fetch/$s_!CKmw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png 848w, https://substackcdn.com/image/fetch/$s_!CKmw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png 1272w, https://substackcdn.com/image/fetch/$s_!CKmw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CKmw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png" width="589" height="380" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:300,&quot;width&quot;:465,&quot;resizeWidth&quot;:589,&quot;bytes&quot;:24058,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167370520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CKmw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png 424w, https://substackcdn.com/image/fetch/$s_!CKmw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png 848w, https://substackcdn.com/image/fetch/$s_!CKmw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png 1272w, https://substackcdn.com/image/fetch/$s_!CKmw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a8ebba-d75b-4dac-ba7e-2a4fbad23502_465x300.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Lautaro Mart&#237;nez tops the list with an xGOT:xG ratio of <strong>0.86</strong>. In other words, compared with an average player shooting from the same locations, his finishing <em>reduces</em> the likelihood of a goal by about 14 %.</p><h3><em><strong>How can that be, given his reputation as one of the world&#8217;s best strikers?</strong></em></h3><p>First, note that Mart&#237;nez still <strong>out-scores raw xG and xGOT</strong>: he has 115 goals from 110 xG (a figure that includes team supply, movement and shot volume but still). He beats his 96 xGOT (115 goals), so something beyond sheer shot placement is helping him.</p><p>Why, then, does his xGOT/xG lag? Three plausible explanations:</p><ol><li><p><strong>Shot mix.</strong> Many of his attempts may be missing the target. Off-target shots keep their full xG but add zero to xGOT, pulling the ratio down.</p></li><li><p><strong>Goalkeeping.</strong> Even when his placement is mediocre, the goalkeepers he faces may under-perform, conceding shots that average keepers would save.</p></li><li><p><strong>Starting quality.</strong> He shoots frequently from close range, where xG is already high. Close-range strikes leave less room to <em>add</em> value through pinpoint placement&#8212;unlike, say, Messi-style curlers from distance that can boost conversion probability by double digit percentage points.</p></li></ol><p>A surface-level read would label Mart&#237;nez &#8220;wasteful,&#8221; but context matters.</p><p>Next comes <strong>Timo Werner</strong>, whose finishing is roughly 10 % below average&#8212;no surprise given his (bad) reputation at Chelsea and Tottenham. The same trio of factors (shot mix, goalkeeping, starting shot quality) could explain his shortfall if poor ball-striking ability does not satisfy you.</p><p>Most of the remaining group cluster around 0.95, near the overall mean of 0.97.</p><p>Again, at first glance, <strong>Karim Benzema</strong> (0.95) and <strong>Cristiano Ronaldo</strong> (0.97) might look like poor finishers (purely data-wise!).</p><p>They&#8217;re not. Thank you, Captain Obvious.</p><p>They win through <strong>where and how often they shoot</strong>, not by squeezing every last drop out of each strike: execution roughly average, shot selection elite. Blend in ageing curves&#8212;our sample spans Ronaldo&#8217;s final Madrid season and his time at Juve and Man United&#8212;and any modest xGOT surplus gets diluted.</p><p>Okay so what can we make from this?</p><div><hr></div><h1>4&#8212; Implications</h1><p><strong>1. </strong><em><strong>True elite ball-strikers are unicorns</strong></em></p><p>Across 5,724 players who took 360,430 shots in eight seasons, only 20 high-volume scorers&#8212;about <strong>0.3 % of the sample</strong>&#8212;consistently <em>added</em> value with placement.</p><p>Even the very best (Messi) raise an average chance from roughly 13 % to just 17 %. Margins are razor-thin, which is why random variance can hide&#8212;or exaggerate&#8212;a short-term &#8220;hot streak.&#8221;</p><p><em><strong>2. Placement gains disappear without volume</strong></em></p><p>Because the per-shot edge is tiny, a striker needs a large sample before placement skill shows up through the noise.</p><p>Most forwards take fewer than 100 shots a season, so judging finishing quality after &#8220;a couple of matches&#8221; is wishful thinking.</p><p><em><strong>3. Under-performance &#8800; poor finisher</strong></em></p><p>Lautaro Mart&#237;nez, Benzema, and Ronaldo prove that xGOT &lt; xG can coexist with world-class goal totals.</p><p>High-frequency shooters who find <em>better</em> positions&#8212;or face shaky keepers&#8212;can still beat raw xG. Shot selection, movement, and team context remain decisive.</p><p><em><strong>4. Convergence creates edges</strong></em></p><p>Because league-wide xG and xGOT trend toward 1 over time, <em>temporary</em> gaps are where analysts may strike (so to speak):</p><ul><li><p><strong>Recruitment:</strong> Spot undervalued youngsters whose placement already outperforms xG, even if their volume is low?</p></li><li><p><strong>Risk management:</strong> Flag veterans riding unsustainable hot streaks before the market prices correction in?</p></li></ul><p>Now let&#8217;s see who the top xGOT/xG performers were during the 2024/25 season.</p><div><hr></div><h1><strong>5 &#8212; Top 24/25 Finishers</strong></h1><p>One last stop before we share the Python notebook: who actually topped the <strong>xGOT &#247; xG</strong> leaderboard in Europe&#8217;s big-five leagues last season?</p><p>I filtered for players with <strong>at least 10 league goals</strong> and then ranked them by the ratio of post-shot to pre-shot expected goals.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!y9fY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!y9fY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png 424w, https://substackcdn.com/image/fetch/$s_!y9fY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png 848w, https://substackcdn.com/image/fetch/$s_!y9fY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png 1272w, https://substackcdn.com/image/fetch/$s_!y9fY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!y9fY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png" width="935" height="376" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:376,&quot;width&quot;:935,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:51044,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/167370520?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!y9fY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png 424w, https://substackcdn.com/image/fetch/$s_!y9fY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png 848w, https://substackcdn.com/image/fetch/$s_!y9fY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png 1272w, https://substackcdn.com/image/fetch/$s_!y9fY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1409a72-36ef-4572-a5f9-a4ffaba0c8ca_935x376.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Shuto Machino</strong> comes out of nowhere (and newly promoted Holstein Kiel) to top the table with 1.43 xGOT to xG ratio. His shot-placement turned a typical 12.7 % conversion chance into roughly a 18.2 % one. Over the whole season, he added nearly 3 extra goals if we use the Shooting Goals Added (SGA) metric of xGOT &#8722; xG (the extra goals a player&#8217;s ball-striking contributed relative to an average finisher on the same shots).</p><p><strong>Bryan Mbeumo</strong> is right behind at 1.42 xGOT to xG, with a league-best +5.2 SGA &#8212; no wonder Manchester United are googling his name.</p><p><strong>Marcus Thuram</strong> finally gives Inter a striker who <em>over-performs</em> the models (sorry, Lautaro), while <strong>Strand Larsen</strong> (Wolves) validates the &#8220;one-to-watch&#8221; tag from our earlier <a href="https://www.pythonfootball.com/p/expected-goals-on-target-xgot-101?r=5mroiq">xGOT</a> primer.</p><p>And yes, that really is <strong>Scott McTominay</strong> sneaking into the top ten. Quite the season he&#8217;s had.</p><h3><strong>Why this matters</strong></h3><p>Across roughly one-third of Messi&#8217;s career, he adds +29 % per shot. Yet in a single season we already see ten players beating that mark. The lesson of course isn&#8217;t that Shuto Machino is a better finisher than Messi. It&#8217;s that <strong>one-year leaderboards are noisy</strong>.</p><p>Treat seasonal xGOT surpluses as flags, not verdicts, until the sample size grows.</p><p>And finally, here&#8217;s how to replicate this analysis in Python.</p><div><hr></div><h1><strong>6 &#8212; The Python Corner</strong></h1><p>Interested in recreating the analysis? All you need is a Python session and the accompanying notebook.</p><p>If you&#8217;re brand-new to Python, the quickest on-ramp is <strong>Google Colab</strong>: open a new notebook in your browser, sign in with your Gmail account, and you&#8217;re ready to code&#8212;no local setup required.</p><p>Next, grab the notebook I used for this issue by clicking the button below. Inside, you&#8217;ll find step-by-step instructions on how to:</p><ul><li><p>pull eight seasons of Opta data from FBref with <code>soccerdata</code></p></li><li><p>wrangle it with <code>polars</code></p></li><li><p>replicate every insight we&#8217;ve just covered</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/roft4p7vg87hr2i/PFR_007_Shooting_Royalty.ipynb/file&quot;,&quot;text&quot;:&quot;Download Python Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/roft4p7vg87hr2i/PFR_007_Shooting_Royalty.ipynb/file"><span>Download Python Code</span></a></p><div><hr></div><p>And there you have it&#8212;football&#8217;s shooting royalty, TL;DR style.</p><p>If this issue helped you, please pass it along!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/shooting-royalty?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/shooting-royalty?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>You now know how to rank elite finishers with xGOT, quantify how much they out-shoot the average striker, spot the big names who fall short, and see what eight seasons of data reveal about over- and under-performance in front of goal.</p><p>Until next week,</p><p><strong>Martin</strong><br><em>The Python Football Review</em></p>]]></content:encoded></item><item><title><![CDATA[The Myth of the Clinical Striker]]></title><description><![CDATA[Why even Robert Lewandowski does not beat his xG, why that doesn&#8217;t make him wasteful, and what 11 seasons of data reveal about true finishing outliers.]]></description><link>https://www.footballmarketreview.com/p/the-myth-of-the-clinical-striker</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/the-myth-of-the-clinical-striker</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 26 Jun 2025 07:00:55 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0789890a-bc32-4c85-a1c0-024c0224efa3_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #006!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qd5q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qd5q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Qd5q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Qd5q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Qd5q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qd5q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2780074,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166589014?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Qd5q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Qd5q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Qd5q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Qd5q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa94d6511-a528-4603-aa4e-a00aee562ab7_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>While reading <strong>James Tippett&#8217;s <a href="https://www.amazon.co.uk/xGenius-Expected-Science-Winning-Football/dp/1399411551">xGenius</a></strong> (a brilliant book, by the way) one idea kept bugging me:</p><blockquote><p>Over the long term, only a handful of attackers outperform their expected goals (xG) tally&#8212;and when they do, it&#8217;s not by a lot.</p></blockquote><p>Wait&#8212;<em>what?</em></p><p>Aren&#8217;t elite forwards <em>supposed</em> to bury chances above expectation?</p><p>Fans, pundits, and highlight reels love the &#8220;clinical finisher&#8221; label whenever a hot streak pops up.</p><p>So I dug in.</p><p>I pulled <strong>every shot logged by Understat in Europe&#8217;s top-five leagues from 2014/15 through 2024/25</strong> (that&#8217;s 11 full seasons) and asked three simple questions:</p><ol><li><p><strong>How many high-volume scorers genuinely beat their xG?</strong></p></li><li><p><strong>By how much?</strong></p></li><li><p><strong>What&#8217;s their average xG per shot?</strong> (Are they relying on tap-ins or scoring from outside the box?)</p></li></ol><p>Join me for the answers&#8212;served, as always, in easy-to-follow steps with Python templates you can copy-paste.</p><p>Enjoy!</p><div><hr></div><h3><strong>Quick Disclaimer</strong></h3><p>Now, before we dive in, here&#8217;s a quick disclaimer. If you haven&#8217;t read my 101 posts on <strong><a href="https://www.pythonfootball.com/p/expected-goals-xg-101?r=5mroiq">xG</a></strong> and <strong><a href="https://www.pythonfootball.com/p/expected-goals-on-target-xgot-101?r=5mroiq">xGOT</a></strong>, you can catch up <strong><a href="https://www.pythonfootball.com/p/expected-goals-xg-101?r=5mroiq">here</a></strong> and <strong><a href="https://www.pythonfootball.com/p/expected-goals-on-target-xgot-101?r=5mroiq">here</a></strong>. If you have, you would probably know that:</p><ul><li><p><strong>xG</strong> measures <em>chance creation</em>&#8212;how good the opportunity was <em>before</em> the shot.</p></li><li><p><strong>xGOT</strong> measures <em>shot execution</em>&#8212;what the striker actually did with the ball <em>after</em> contact.</p></li></ul><p>So, if you want to judge a striker&#8217;s pure finishing skill, you should really compare <strong>xGOT to xG</strong>.</p><p>However, the football world is obsessed with &#8220;strikers beating their xG,&#8221; so for this Review we&#8217;ll focus on <strong>Goals vs xG</strong> instead. That comparison isn&#8217;t meaningless&#8212;it&#8217;s still a model trained on thousands of historical shots&#8212;but it blends <strong>team supply</strong>, <strong>striker movement</strong>, <em>and</em> <strong>finishing</strong> into one value.</p><p>Now to the caveats &#8230; (the Python code to replicate the analysis from scratch is at the end of this piece).</p><div><hr></div><h1><strong>1 &#8212; The Big picture</strong></h1><p>After crunching <strong>11 seasons of data</strong> (2014/15 &#8211; 2024/25) from Europe&#8217;s top-five leagues, we end up with <strong>498,324 shots</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ib3C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ib3C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png 424w, https://substackcdn.com/image/fetch/$s_!Ib3C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png 848w, https://substackcdn.com/image/fetch/$s_!Ib3C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png 1272w, https://substackcdn.com/image/fetch/$s_!Ib3C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ib3C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png" width="820" height="152" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:152,&quot;width&quot;:820,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24126,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166589014?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ib3C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png 424w, https://substackcdn.com/image/fetch/$s_!Ib3C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png 848w, https://substackcdn.com/image/fetch/$s_!Ib3C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png 1272w, https://substackcdn.com/image/fetch/$s_!Ib3C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8b0b0e1-a71d-4f51-b875-dacb3652db6e_820x152.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Those shots produced <strong>53,284 goals from 55,923 xG</strong>, which works out to:</p><ul><li><p><strong>Goals &#247; xG = 0.95</strong></p></li><li><p><strong>xG per shot = 0.11</strong></p></li></ul><p>So yes&#8212;over the long term goals and xG do converge, albeit with a slight <em>under-performance</em> relative to the model.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1><strong>2 &#8212; The High Scorers</strong></h1><p>Across those 11 seasons, <strong>39 players</strong> scored <strong>100+ goals</strong>. Below are the top ten, ordered by total goals</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cdGO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cdGO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png 424w, https://substackcdn.com/image/fetch/$s_!cdGO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png 848w, https://substackcdn.com/image/fetch/$s_!cdGO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png 1272w, https://substackcdn.com/image/fetch/$s_!cdGO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cdGO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png" width="1112" height="570" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:570,&quot;width&quot;:1112,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:114574,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166589014?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cdGO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png 424w, https://substackcdn.com/image/fetch/$s_!cdGO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png 848w, https://substackcdn.com/image/fetch/$s_!cdGO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png 1272w, https://substackcdn.com/image/fetch/$s_!cdGO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff09462e7-727d-4153-8ee8-c03aac4dadaa_1112x570.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Highlights</em>:</p><ul><li><p><strong>Lewandowski</strong> leads the raw count&#8212;307 goals from 312 xG (Goals &#247; xG = 0.98). Under the pundit logic of &#8220;must beat xG,&#8221; the Pole would be labelled an &#8216;<em>under-performer&#8217;</em>. Reality check: the metric and the man simply converge. And given his monstrous goals tally, the two percentage points are <em>roughly in line with the model.</em></p></li><li><p><strong>Kane</strong> posts the first big outlier: 272 goals from 239 xG (<strong>+13 %</strong>), hinting at a repeatable <strong>team supply</strong>, <strong>striker movement</strong>, <em>and</em> <strong>finishing</strong> edge.</p></li><li><p><strong>Messi</strong> goes one better (253 &#247; 219 xG = <strong>1.15</strong>).</p></li><li><p><strong>Ronaldo</strong> sits almost bang on expectation (1.02), while <strong>Mbapp&#233;</strong> mirrors Kane at 1.13 and <strong>Salah</strong> hovers just above par at 1.03.</p></li></ul><p>So, in the top six we have:</p><ul><li><p><strong>One &#8220;under-performer&#8221;</strong> (Lewandowski)</p></li><li><p><strong>Two basically on par</strong> (Ronaldo, Salah)</p></li><li><p><strong>Three genuine over-performers</strong> (Messi, Mbapp&#233;, Kane)</p></li></ul><p>Not quite the narrative you get from weekend sound-bites, right?</p><div><hr></div><h1><strong>3 &#8212; The Outliers</strong></h1><p>Among all 39 centurions, who <em>really</em> tops the Goals &#247; xG chart&#8212;and by how much?</p><p>Let&#8217;s sort the list by that Goals to xG ratio and see which names pop.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ShHt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ShHt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png 424w, https://substackcdn.com/image/fetch/$s_!ShHt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png 848w, https://substackcdn.com/image/fetch/$s_!ShHt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png 1272w, https://substackcdn.com/image/fetch/$s_!ShHt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ShHt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png" width="1038" height="566" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:566,&quot;width&quot;:1038,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:109314,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166589014?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ShHt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png 424w, https://substackcdn.com/image/fetch/$s_!ShHt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png 848w, https://substackcdn.com/image/fetch/$s_!ShHt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png 1272w, https://substackcdn.com/image/fetch/$s_!ShHt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6c1a271-f3d2-45cd-9a41-9ce1934be72d_1038x566.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Surprised? Which headline grabs you more:</p><ul><li><p><strong>Son Heung-min</strong> perched at No. 1 (elite was a given, but <em>this</em> screams world-class),</p></li><li><p><strong>Dries Mertens</strong> sliding into second, or</p></li><li><p>Liverpool &#8220;flop&#8221; <strong>Iago Aspas</strong> ranking as <em>more clinical</em> than Messi?</p></li></ul><p>So we can say that <strong>25 of 39</strong> hundred-plus goal scorers posted a Goals &#247; xG ratio <em>above</em> 1.00.</p><ul><li><p><strong>Son Heung-min</strong> leads the pack: <strong>138 goals from 105.3 xG</strong> across 791 shots. That&#8217;s a <strong>1.31 ratio</strong>&#8212;scoring <strong>31 % </strong>more <em>than an average player would from the same shots</em>. That&#8217;s ridiculous. As in ridiculously good.</p></li><li><p><strong>Mertens</strong> (+22 %) and <strong>Griezmann</strong> (+20 %) round out the podium.</p></li><li><p><strong>Aspas</strong> and <strong>Dybala</strong> sit at +16 %, with <strong>Messi</strong> just behind on +15 %.</p></li></ul><p>These are the rare finishers James Tippett had in mind: the tiny cohort who consistently bend the xG curve in their favour.</p><p>Notice how slim the margins are&#8212;outperforming by 9 % over a decade is enough to put you among the sport&#8217;s most efficient shooters (according to our initial definition, which of course is open to debate).</p><p>For everyone else, goals and xG converge exactly as the model expects.</p><p>Speaking of every else, what about the 14 players that scored 100+ goals but underperformed the xG?</p><div><hr></div><h1><strong>4 &#8212; The &#8216;Underperformers&#8217;</strong></h1><p>So who sits at the other end of the scale&#8212;the lads who score plenty but <em>should</em> have scored more, given the chances they had?</p><p>Among the 39 centurions, <strong>14</strong> finished below expectation. Here are the &#8220;bottom&#8221; ten:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!daqD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!daqD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png 424w, https://substackcdn.com/image/fetch/$s_!daqD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png 848w, https://substackcdn.com/image/fetch/$s_!daqD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png 1272w, https://substackcdn.com/image/fetch/$s_!daqD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!daqD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png" width="1112" height="568" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:568,&quot;width&quot;:1112,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:111567,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166589014?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!daqD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png 424w, https://substackcdn.com/image/fetch/$s_!daqD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png 848w, https://substackcdn.com/image/fetch/$s_!daqD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png 1272w, https://substackcdn.com/image/fetch/$s_!daqD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24c0fd5a-0459-479b-a364-fe73f2b9d912_1112x568.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em>Highlights</em>:</p><ul><li><p><strong>Edin D&#382;eko</strong> is the starkest outlier: 111 goals from 145 xG (Goals &#247; xG = 0.77). That&#8217;s a 23 % shortfall (compared to what the average player would score from the same shots<em>)</em>&#8212;ouch.</p></li><li><p><strong>Lautaro Mart&#237;nez</strong> (0.96) and <strong>Aubameyang</strong> (0.94) under-shoot, but only by single-digits&#8212;well within normal noise.</p></li><li><p><strong>Timo Werner</strong>&#8217;s 0.91 fits the eye test from his Premier-League spell: excellent movement and supply, finishing not quite matching the volume of chances?</p></li></ul><div><hr></div><h1><strong>5 &#8212; What does it all mean?</strong></h1><ol><li><p><strong>Goals and xG converge</strong> over multi-season samples&#8212;even for superstars. That&#8217;s exactly what a well-trained (xG) model should do actually.</p></li><li><p><strong>Short-term spikes still matter.</strong> A player running hot (Goals &#8811; xG) is probably in form, but the burst may owe as much to team supply and a bit of luck as to pure finishing.</p></li><li><p><strong>For true clinical skill, use xGOT &#8722; xG.</strong></p><ul><li><p><strong>xG</strong> = opportunity quality.</p></li><li><p><strong>xGOT</strong> = execution quality.</p></li><li><p><strong>Shooting Goals Added (xGOT &#8722; xG)</strong> strips out the noise and isolates finishing talent. We&#8217;ll tackle that metric in a future deep dive.</p></li></ul></li></ol><p><em>xG isn&#8217;t about &#8220;clinicalness.&#8221;</em></p><p>It blends <strong>team service</strong>, <strong>striker movement</strong>, and <strong>finishing edge</strong> into a single probability.</p><p>Next time you hear &#8220;he&#8217;s so clinical&#8212;look at his goals versus xG,&#8221; reach for xGOT instead.</p><p>And finally here&#8217;s how to reproduce this analysis in Python.</p><div><hr></div><h1><strong>6 &#8212; The Python Corner</strong></h1><p>So, how do you reproduce this analysis?</p><p><strong>First things first.</strong> If you&#8217;re new to Python, head to <strong><a href="https://colab.research.google.com/">Google Colab</a></strong>&#8212;the quickest, zero-setup route (all you need is a Gmail account). Open a new notebook and you&#8217;re ready to roll.</p><p>You can download the code I&#8217;m about to detail here:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/5bbfy71hp64ezqy/PFR_006_Clinical_Strikers.ipynb/file&quot;,&quot;text&quot;:&quot;Download Python Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/5bbfy71hp64ezqy/PFR_006_Clinical_Strikers.ipynb/file"><span>Download Python Code</span></a></p><h3><strong>Install and import the packages</strong></h3><p>We&#8217;ll use <code>soccerdata</code> by <a href="https://x.com/p_robberechts">Pieter Robberechts</a> to pull <a href="https://understat.com/">Understat</a> data and <strong>Polars</strong> for lightning-fast data wrangling.</p><pre><code><code>!pip install soccerdata
import polars as pl
import soccerdata as sd</code></code></pre><h3><strong>Define the study scope</strong></h3><p>Create lists for the leagues and the seasons you want to cover.</p><pre><code><code>leagues = ['ENG-Premier League', 'ESP-La Liga', 'FRA-Ligue 1',
           'GER-Bundesliga', 'ITA-Serie A']

seasons = ['2014/2015', '2015/2016', '2016/2017', '2017/2018',
           '2018/2019', '2019/2020', '2020/2021', '2021/2022',
           '2022/2023', '2023/2024', '2024/2025']</code></code></pre><h3><strong>Collect the shot-level data</strong></h3><p><code>sd.Understat</code> and <code>understat.read_shot_events()</code> fetch every shot event for a given league-season pair. Eleven seasons across five leagues is roughly <strong>half a million shots</strong>, so expect the scrape to take up to an hour.</p><pre><code><code>dfs_shots = []
for season in seasons:
    for league in leagues:
        understat = sd.Understat(leagues=league, seasons=season)

        df_shots = understat.read_shot_events()

        df_shots = pl.from_pandas(df_shots, include_index=True)

        df_shots = df_shots.with_columns([
            pl.lit(league).alias("league"),
            pl.lit(season).alias("season")])

        dfs_shots.append(df_shots)</code></code></pre><h3><strong>Align columns and concatenate</strong></h3><p>Column sets can vary slightly from season to season, so we harmonise them before stitching everything together.</p><pre><code><code>col_order_shots = []
for df in dfs_shots:
    for c in df.columns:
        if c not in col_order_shots:
            col_order_shots.append(c)

aligned_shots = []
for df in dfs_shots:
    missing = [c for c in col_order_shots if c not in df.columns]
    if missing:
        df = df.with_columns([pl.lit(None).alias(c) for c in missing])
    aligned_shots.append(df.select(col_order_shots))

shot_events = pl.concat(aligned_shots, how="vertical")
</code></code></pre><h3><strong>Big-picture aggregates</strong></h3><p>Total goals, total xG, shots, plus the global ratios:</p><pre><code><code>(
    df_raw
    .with_columns(
        (pl.col("result") == "Goal").alias("goal"))
    .select(
        pl.col("xg").sum().alias("xg_total"),
        pl.col("goal").sum().alias("goals_total"),
        pl.col("shot_id").count().alias("shots_total"))
    .with_columns(
(pl.col("goals_total")/pl.col("xg_total")).alias("goals_to_xg"),        (pl.col("xg_total")/pl.col("shots_total")).alias("xg_per_shot"))

)</code></code></pre><h3><strong>Player-level summary</strong></h3><p>Aggregate by player and compute Goals &#247; xG and xG per shot.</p><pre><code><code>df_shots = (
    shot_events
    .with_columns(
        (pl.col("result") == "Goal").alias("goal"))
    .group_by(["player"])
    .agg(
        pl.col("xg").sum().alias("xg_total"),
        pl.col("goal").sum().alias("goals_total"),
        pl.col("shot_id").count().alias("shots_total"))
    .with_columns(
      (pl.col("goals_total")/pl.col("xg_total")).alias("goals_to_xg"),
      (pl.col("xg_total")/pl.col("shots_total")).alias("xg_per_shot"))
)</code></code></pre><h3><strong>Slice the interesting bits</strong></h3><p>Top scorers (&#8805; 100 goals):</p><pre><code><code>(
    df_shots
    .filter(pl.col("goals_total") &gt; 100)
    .sort("goals_total", descending=True)
    .head(10)
)</code></code></pre><p>Best Goal &#247; xG ratios among those centurions:</p><pre><code><code>(
    df_shots
    .filter(pl.col("goals_total") &gt; 100)
    .sort("goals_to_xg", descending=True)
    .head(10)
)</code></code></pre><p>Worst Goal &#247; xG ratios among those centurions:</p><pre><code><code>(
    df_shots
    .filter(pl.col("goals_total") &gt; 100)
    .sort("goals_to_xg")
    .head(10)
)</code></code></pre><p>Boom&#8212;that&#8217;s the myth of the &#8220;clinical&#8221; striker, reproduced in your own notebook.</p><p>If you found this issue useful, please share it!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/the-myth-of-the-clinical-striker?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/the-myth-of-the-clinical-striker?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p>You now know <strong>why even world-class forwards don&#8217;t always beat their xG, why that doesn&#8217;t make them wasteful, and what 11 seasons of data reveal about true finishing outliers.</strong></p><p>Until next week,</p><p><strong>Martin</strong></p><p><em>The Python Football Review</em></p>]]></content:encoded></item><item><title><![CDATA[xGChain & xGBuildup 101]]></title><description><![CDATA[What each metric measures, which gap they fill (left by xA and xAG), which players have posted the best build-up numbers this season, and how to pull xGChain/xGBuildup data with Python]]></description><link>https://www.footballmarketreview.com/p/xgchain-and-xgbuildup-101</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/xgchain-and-xgbuildup-101</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 19 Jun 2025 08:01:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe999ca69-23eb-48af-b52d-d971473dd907_325x325.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #005!</em></p><p>Today we add two more creativity metrics to our analyst&#8217;s tool belt: <strong>xGChain</strong> and <strong>xGBuildup</strong>.</p><p>By the end of this issue you&#8217;ll know</p><ul><li><p>what each metric measures</p></li><li><p>which gap they fill (left by <strong>xA</strong> and <strong>xAG</strong>)</p></li><li><p>which deep-lying playmakers have posted the best build-up numbers this season</p></li><li><p>which wing-backs top the charts for participation in attacking sequences</p></li><li><p>how to pull xGChain and xGBuildup in Python in seconds</p></li></ul><p>Enjoy!</p><div><hr></div><h2><em>But Martin, why do we need yet another way to judge creative talent?</em></h2><p>So far we&#8217;ve covered:</p><ul><li><p><strong><a href="https://www.pythonfootball.com/p/expected-assisted-goals-xag-101?r=5mroiq&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=false">xAG</a></strong> &#8212; gives the shot&#8217;s xG to the player who plays the <em>final</em> pass.</p></li><li><p><strong><a href="https://www.pythonfootball.com/p/expected-assists-xa-101?r=5mroiq">xA</a></strong> &#8212; assigns every completed pass a probability of <em>eventually</em> becoming an assist.</p></li></ul><p>Both reward the player closest to goal but overlook the <strong>initiators</strong>:</p><ul><li><p>deep pivots who progress play (the Rodris and Jorginhos)</p></li><li><p>centre-backs who split lines (the John Stones and Virgil van Dijks)</p></li><li><p>wing-backs who join the build-up (the Cafus and Kyle Walkers)</p></li></ul><p>Because these actions start far from goal, they accrue only modest xA and almost no xAG.</p><p>That&#8217;s the gap <strong>xGChain</strong> and <strong>xGBuildup</strong> are designed to close.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe for free to get these in your inbox every Thursday.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>1 &#8212; What are xGChain and xGBuildup?</h2><p><strong>xGChain</strong> gives every player who touches the ball in a possession the shot&#8217;s <strong><a href="https://www.pythonfootball.com/p/expected-goals-xg-101?r=5mroiq">xG</a></strong> if that possession ends in a shot.</p><p><em>Example:</em> a move ends with a 0.25-xG shot. Every participant&#8212;keeper to striker&#8212;adds <strong>0.25</strong> to their xGChain total.</p><p>Three details matter:</p><ol><li><p>The simplest touch and a forty-yard carry <em>count the same</em> if they&#8217;re in the same chain.</p></li><li><p>No shot &#8594; 0 xGChain for everyone in that possession.</p></li><li><p>Because credit is copied to each player, the squad&#8217;s summed xGChain will exceed the team&#8217;s match xG&#8212;so this is a <em>player</em> metric, not a team one (even though we can use it to analyse team structure, more on that below).</p></li></ol><p>Great for spotting who <strong>helps</strong> attacks reach the box: xAG credits <em>one</em> passer; xGChain credits <em>everyone</em> involved.</p><h3>Why xGBuildup then?</h3><p>Rank players by xGChain and advanced attackers still top the list&#8212;they finish and assist, so they appear in nearly every chain. To surface the early-phase contributors we use <strong>xGBuildup</strong>:</p><ul><li><p>Start with xGChain.</p></li><li><p><strong>Exclude</strong> the players who made the final two touches&#8212;the key pass and the shot.</p></li></ul><p>What remains is xGBuildup.</p><p>Some elite attackers still rank highly even after you strip away their shots and assists; that simply means they also contribute in the build-up&#8212;valuable context.</p><p>And yes, expect Lionel Messi to still pop up near the top (not that you needed yet another metric to remind you of this).</p><p>Okay, moving on&#8230;</p><div><hr></div><h2>2 &#8212; How analysts use xGChain &amp; xGBuildup</h2><p>There are two main applications:</p><ol><li><p><strong>Scouting and player evaluation</strong> &#8211; surfacing deep-lying contributors who rarely appear on assist charts.</p></li><li><p><strong>Tactical profiling</strong> &#8211; mapping where a team&#8217;s build-up flows without watching a single minute of video.</p></li></ol><p>Below are quick case studies from the 2024/25 season (Europe&#8217;s top five leagues). You&#8217;ll be able to reproduce the tables in Python later.</p><div><hr></div><h3>2.1 &#8212; Scouting &amp; evaluating players</h3><h3>Top xGBuildup/90, 2024-25</h3><p>Okay, so who were the players that topped the xGBuildup per 90 minutes rankings during the past season? Because xGBuildup strips out shots and key passes, the leaderboard is dominated by midfielders and defenders&#8212;exactly the roles we want to judge.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!J9kU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!J9kU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png 424w, https://substackcdn.com/image/fetch/$s_!J9kU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png 848w, https://substackcdn.com/image/fetch/$s_!J9kU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png 1272w, https://substackcdn.com/image/fetch/$s_!J9kU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!J9kU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png" width="1314" height="564" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:564,&quot;width&quot;:1314,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:147194,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!J9kU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png 424w, https://substackcdn.com/image/fetch/$s_!J9kU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png 848w, https://substackcdn.com/image/fetch/$s_!J9kU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png 1272w, https://substackcdn.com/image/fetch/$s_!J9kU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a825621-0088-4e9b-a8d4-d111bdd94f6d_1314x564.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Vitinha</strong> sits miles clear at <strong>1.18 xGBuildup/90</strong>&#8212;on average he takes part in attacking sequences worth 1.18 xG every match.</p></li><li><p>His midfield partner <strong>Fabi&#225;n Ruiz</strong> follows at <strong>0.97</strong>, underlining PSG&#8217;s central dominance.</p></li><li><p>Two full-backs&#8212;<strong>Nuno Mendes</strong> (0.91) and <strong>Achraf Hakimi</strong> (0.89)&#8212;both rank in the top four, suggesting PSG&#8217;s build-up is well balanced across flanks.</p></li><li><p>As expected, the list is almost entirely midfielders and defenders once key-pass credit is removed.</p></li></ul><h3>Top xGChain/90, 2024-25</h3><p>Including the shot and assist brings attackers back into view.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oviw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oviw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png 424w, https://substackcdn.com/image/fetch/$s_!oviw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png 848w, https://substackcdn.com/image/fetch/$s_!oviw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png 1272w, https://substackcdn.com/image/fetch/$s_!oviw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oviw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png" width="1340" height="568" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:568,&quot;width&quot;:1340,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:148228,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oviw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png 424w, https://substackcdn.com/image/fetch/$s_!oviw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png 848w, https://substackcdn.com/image/fetch/$s_!oviw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png 1272w, https://substackcdn.com/image/fetch/$s_!oviw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F571b7cb3-b07e-42d4-96ea-df8a2e44948d_1340x568.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Ousmane Demb&#233;l&#233;</strong> tops the table at <strong>1.65 xGChain/90</strong>&#8212;fitting for a player who re-invented the false-9 role in PSG&#8217;s historic season. No wonder he is now a Ballon d&#8217;Or favourite (hands up if you predicted that last August; I certainly didn&#8217;t).</p></li><li><p><strong>Gon&#231;alo Ramos</strong> makes the list despite limited starts; his touches keep showing up in scoring moves even when he isn&#8217;t the one shooting.</p></li><li><p><strong>Bradley Barcola</strong> and <strong>Khvicha Kvaratskhelia</strong> round out the top four, underlining just how balanced PSG&#8217;s attack (and, as we saw earlier, their build-up) has been.</p></li></ul><div><hr></div><h3>2.2 &#8212; Assessing team patterns</h3><p><em>But Martin, didn&#8217;t you say xGChain and xGBuildup are player metrics?</em></p><p>I did&#8212;yet comparing a few key players can still reveal where a team&#8217;s build-up flows.</p><p>Earlier we saw <strong>Achraf Hakimi</strong> (right) and <strong>Nuno Mendes</strong> (left) posting almost identical xGBuildup figures, suggesting PSG advance play down both flanks in roughly equal measure. Let&#8217;s apply the same lens to Arsenal.</p><h3>Arsenal wide balance, 2024-25</h3><p>This season Gabriel Martinelli often looked isolated on the left. The numbers agree.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CaA5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CaA5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png 424w, https://substackcdn.com/image/fetch/$s_!CaA5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png 848w, https://substackcdn.com/image/fetch/$s_!CaA5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png 1272w, https://substackcdn.com/image/fetch/$s_!CaA5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CaA5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png" width="1262" height="190" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:190,&quot;width&quot;:1262,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:47097,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CaA5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png 424w, https://substackcdn.com/image/fetch/$s_!CaA5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png 848w, https://substackcdn.com/image/fetch/$s_!CaA5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png 1272w, https://substackcdn.com/image/fetch/$s_!CaA5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06f5c423-372f-4de4-a47c-d1e2513b9e40_1262x190.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Saka is involved earlier and more often (0.31 vs 0.17 xGBuildup/90), pointing to a right-heavy build-up bias. The narrower gap in xGChain (0.84 vs 0.66 xGChain/90) shows Martinelli does contribute more in the final phases, but the attack tilts right from start to finish.</p><h3>Arsenal centre-backs</h3><p>Saliba and Gabriel drive progression from the back. When <strong>Jakub Kiwior</strong> steps in, Arsenal lose roughly 0.13 xGBuildup per 90 at centre-back&#8212;a reminder that depth matters if your system relies on ball-playing defenders to start attacks.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QHPJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QHPJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png 424w, https://substackcdn.com/image/fetch/$s_!QHPJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png 848w, https://substackcdn.com/image/fetch/$s_!QHPJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png 1272w, https://substackcdn.com/image/fetch/$s_!QHPJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QHPJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png" width="1242" height="240" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:240,&quot;width&quot;:1242,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56607,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QHPJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png 424w, https://substackcdn.com/image/fetch/$s_!QHPJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png 848w, https://substackcdn.com/image/fetch/$s_!QHPJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png 1272w, https://substackcdn.com/image/fetch/$s_!QHPJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c8e0406-00af-405c-9496-eb116e1c28a9_1242x240.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>2.3 &#8212; Things to watch out for</h3><ul><li><p><strong>Team style inflation</strong> &#8211; Possession-heavy sides naturally inflate xGBuildup (I am looking at you, Pep); always benchmark within league and pace context.</p></li><li><p><strong>Direct teams</strong> &#8211; A low xGBuildup doesn&#8217;t always mean a player is conservative; the ball might bypass midfield altogether (think Leicester&#8217;s title-winning 15/16 campaign).</p></li><li><p><strong>Double counting</strong> &#8211; Forwards with huge shot volumes can dominate xGChain leaderboards. Subtract the player&#8217;s own xG if you want non-shooting influence.</p></li><li><p><strong>Sample size</strong> &#8211; Use per-90 numbers and set a sensible minutes threshold (e.g., &gt;900 mins) to avoid noise.</p></li></ul><p>Great, now that we have covered those, let&#8217;s do some coding.</p><div><hr></div><h2><strong>3&#8212;How to Fetch xGChain and xGBuildup Data Using Python</strong></h2><p>Here&#8217;s how to pull xGChain and xGBuildup yourself.</p><p>If you&#8217;re new to Python, the quickest route is <strong>Google Colab</strong>&#8212;a free, browser-based notebook that needs zero local setup.</p><ol><li><p>Go to https://colab.research.google.com and sign in with your Google account.</p></li><li><p>In Colab, click <strong>File &#8594; New notebook</strong>.</p></li></ol><p>You can paste the snippets below or download the full notebook:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/j2ghhc4bxtsvvrq/PFR_005_xGChain_xGBuildup.ipynb/file&quot;,&quot;text&quot;:&quot;Download Python code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/j2ghhc4bxtsvvrq/PFR_005_xGChain_xGBuildup.ipynb/file"><span>Download Python code</span></a></p><p>We&#8217;ll use two libraries:</p><ul><li><p><code>soccerdata</code>, a community wrapper by <a href="https://x.com/p_robberechts">Pieter Robberechts</a> that scrapes Understat.</p></li><li><p><code>polars</code>, our preferred dataframe engine.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3ht_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3ht_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png 424w, https://substackcdn.com/image/fetch/$s_!3ht_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png 848w, https://substackcdn.com/image/fetch/$s_!3ht_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png 1272w, https://substackcdn.com/image/fetch/$s_!3ht_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3ht_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png" width="316" height="238.17910447761193" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:404,&quot;width&quot;:536,&quot;resizeWidth&quot;:316,&quot;bytes&quot;:75199,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3ht_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png 424w, https://substackcdn.com/image/fetch/$s_!3ht_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png 848w, https://substackcdn.com/image/fetch/$s_!3ht_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png 1272w, https://substackcdn.com/image/fetch/$s_!3ht_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5a7e04a-dada-4a13-86a8-facea38e2833_536x404.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In the example below we pull Europe&#8217;s top-five leagues for the 2024/25 season. You can add any season from <strong>2014/15</strong> onward by extending the list.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6igo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6igo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png 424w, https://substackcdn.com/image/fetch/$s_!6igo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png 848w, https://substackcdn.com/image/fetch/$s_!6igo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png 1272w, https://substackcdn.com/image/fetch/$s_!6igo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6igo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png" width="466" height="281.79059829059827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:566,&quot;width&quot;:936,&quot;resizeWidth&quot;:466,&quot;bytes&quot;:122166,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6igo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png 424w, https://substackcdn.com/image/fetch/$s_!6igo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png 848w, https://substackcdn.com/image/fetch/$s_!6igo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png 1272w, https://substackcdn.com/image/fetch/$s_!6igo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F29cbef7a-270a-4f0c-9d47-e40dda925ba5_936x566.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Next we run a simple <code>read_player_stats()</code> to pull the player stats for the season and then transform the resulting <code>pandas</code> dataframe into a <code>polars</code> one with <code>from_polars</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kOQl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kOQl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png 424w, https://substackcdn.com/image/fetch/$s_!kOQl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png 848w, https://substackcdn.com/image/fetch/$s_!kOQl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png 1272w, https://substackcdn.com/image/fetch/$s_!kOQl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kOQl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png" width="470" height="240.1711491442543" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:418,&quot;width&quot;:818,&quot;resizeWidth&quot;:470,&quot;bytes&quot;:87938,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kOQl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png 424w, https://substackcdn.com/image/fetch/$s_!kOQl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png 848w, https://substackcdn.com/image/fetch/$s_!kOQl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png 1272w, https://substackcdn.com/image/fetch/$s_!kOQl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc7a79a0-1845-4452-907f-cfcd5d17b839_818x418.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>At this point you&#8217;ll see a wide table with dozens of columns&#8212;one row per player &#215; season.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rD1V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rD1V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png 424w, https://substackcdn.com/image/fetch/$s_!rD1V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png 848w, https://substackcdn.com/image/fetch/$s_!rD1V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png 1272w, https://substackcdn.com/image/fetch/$s_!rD1V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rD1V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png" width="1456" height="253" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:253,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:161094,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rD1V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png 424w, https://substackcdn.com/image/fetch/$s_!rD1V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png 848w, https://substackcdn.com/image/fetch/$s_!rD1V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png 1272w, https://substackcdn.com/image/fetch/$s_!rD1V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff39aaf10-dac1-4545-ae54-c28f33c954af_2846x494.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Next, we&#8217;ll keep only the variables we care about&#8212;season, team, player, position, minutes played, and their xGBuildup and xGChain values&#8212;and then calculate the corresponding per-90 figures.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PQd9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PQd9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png 424w, https://substackcdn.com/image/fetch/$s_!PQd9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png 848w, https://substackcdn.com/image/fetch/$s_!PQd9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png 1272w, https://substackcdn.com/image/fetch/$s_!PQd9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PQd9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png" width="588" height="232.9353507565337" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:1454,&quot;resizeWidth&quot;:588,&quot;bytes&quot;:138383,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PQd9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png 424w, https://substackcdn.com/image/fetch/$s_!PQd9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png 848w, https://substackcdn.com/image/fetch/$s_!PQd9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png 1272w, https://substackcdn.com/image/fetch/$s_!PQd9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb48a6ba3-413f-4df6-a1ac-83abdfce2899_1454x576.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Vd0V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Vd0V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png 424w, https://substackcdn.com/image/fetch/$s_!Vd0V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png 848w, https://substackcdn.com/image/fetch/$s_!Vd0V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png 1272w, https://substackcdn.com/image/fetch/$s_!Vd0V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Vd0V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png" width="1252" height="380" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:380,&quot;width&quot;:1252,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85888,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Vd0V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png 424w, https://substackcdn.com/image/fetch/$s_!Vd0V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png 848w, https://substackcdn.com/image/fetch/$s_!Vd0V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png 1272w, https://substackcdn.com/image/fetch/$s_!Vd0V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76a57884-6b12-4b86-bd0a-e45079c04b9a_1252x380.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Next, we replicate the tables from the case studies. First, we filter for players who have appeared in at least 10 matches and return the top ten in xGBuildup per 90 minutes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PUPZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PUPZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png 424w, https://substackcdn.com/image/fetch/$s_!PUPZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png 848w, https://substackcdn.com/image/fetch/$s_!PUPZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png 1272w, https://substackcdn.com/image/fetch/$s_!PUPZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PUPZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png" width="446" height="269.52517985611513" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:504,&quot;width&quot;:834,&quot;resizeWidth&quot;:446,&quot;bytes&quot;:98973,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PUPZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png 424w, https://substackcdn.com/image/fetch/$s_!PUPZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png 848w, https://substackcdn.com/image/fetch/$s_!PUPZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png 1272w, https://substackcdn.com/image/fetch/$s_!PUPZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bda829b-3854-4a54-b6c2-b9a4f4b6d0c8_834x504.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And here we simply change the sorting parameter to <code>xg_chain_90</code> to order the players by that metric.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PpqA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PpqA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png 424w, https://substackcdn.com/image/fetch/$s_!PpqA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png 848w, https://substackcdn.com/image/fetch/$s_!PpqA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png 1272w, https://substackcdn.com/image/fetch/$s_!PpqA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PpqA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png" width="388" height="238.91169451073986" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:516,&quot;width&quot;:838,&quot;resizeWidth&quot;:388,&quot;bytes&quot;:104551,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PpqA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png 424w, https://substackcdn.com/image/fetch/$s_!PpqA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png 848w, https://substackcdn.com/image/fetch/$s_!PpqA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png 1272w, https://substackcdn.com/image/fetch/$s_!PpqA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76f19ee8-c3ad-4854-b9cf-f6a9cc40f7a8_838x516.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>And here&#8217;s the coding bit for focusing only on Saka and Martinelli</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!auqG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!auqG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png 424w, https://substackcdn.com/image/fetch/$s_!auqG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png 848w, https://substackcdn.com/image/fetch/$s_!auqG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png 1272w, https://substackcdn.com/image/fetch/$s_!auqG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!auqG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png" width="440" height="230.91603053435114" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:550,&quot;width&quot;:1048,&quot;resizeWidth&quot;:440,&quot;bytes&quot;:111053,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!auqG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png 424w, https://substackcdn.com/image/fetch/$s_!auqG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png 848w, https://substackcdn.com/image/fetch/$s_!auqG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png 1272w, https://substackcdn.com/image/fetch/$s_!auqG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e591422-9208-40c1-bfa0-8b643ea58c82_1048x550.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>And the bit for focusing on Arsenal&#8217;s three central defenders.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7t1z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7t1z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png 424w, https://substackcdn.com/image/fetch/$s_!7t1z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png 848w, https://substackcdn.com/image/fetch/$s_!7t1z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png 1272w, https://substackcdn.com/image/fetch/$s_!7t1z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7t1z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png" width="424" height="259.1111111111111" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:594,&quot;width&quot;:972,&quot;resizeWidth&quot;:424,&quot;bytes&quot;:117847,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/166300292?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7t1z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png 424w, https://substackcdn.com/image/fetch/$s_!7t1z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png 848w, https://substackcdn.com/image/fetch/$s_!7t1z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png 1272w, https://substackcdn.com/image/fetch/$s_!7t1z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F072ef155-89cb-4a7f-967f-4393ac09434a_972x594.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can now fire up Python and explore other seasons, teams, and players to see what the underlying data reveals.</p><div><hr></div><p>Boom&#8212;that was xGChain/xGBuildup 101.</p><p>If you found this issue useful, please spread the word! </p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/xgchain-and-xgbuildup-101?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/xgchain-and-xgbuildup-101?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/xgchain-and-xgbuildup-101?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p>You now know more about these two metrics than most football fans: what they measure, how to use them, why they shouldn&#8217;t be underestimated, and&#8212;crucially&#8212;how to pull extensive data with just a few lines of Python.</p><p>Until next week,</p><p><strong>Martin</strong></p><p><em>The Python Football Review</em></p>]]></content:encoded></item><item><title><![CDATA[Expected Assists (xA) 101]]></title><description><![CDATA[What xA measures, why people confuse it with xAG (and why you shouldn't), how to uncover hidden creative talent, and how to pull tons of xA data with a few lines of Python code]]></description><link>https://www.footballmarketreview.com/p/expected-assists-xa-101</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/expected-assists-xa-101</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 12 Jun 2025 08:00:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe999ca69-23eb-48af-b52d-d971473dd907_325x325.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The&#8239;Python Football Review&#8239;#004!</em></p><p>We previously dissected <strong>Expected&#8239;Assisted&#8239;Goals (<a href="https://www.pythonfootball.com/p/expected-assisted-goals-xag-101?r=5mroiq">xAG</a>)</strong>. If you missed that issue, catch up <a href="https://www.pythonfootball.com/p/expected-assisted-goals-xag-101?r=5mroiq">here</a>.</p><p>Today we explore its first cousin <strong>Expected&#8239;Assists (xA)</strong>&#8212;and, spoiler alert, they are <em>not</em> the same metric.</p><p>By the end of this issue, you&#8217;ll know:</p><ul><li><p>what xA stands for</p></li><li><p>how it patches two of xAG&#8217;s biggest blind spots</p></li><li><p>how analysts use it&#8212;and the traps you should avoid</p></li><li><p>how to profile different types of creators</p></li><li><p>how to scrape full seasons of xA with just a few lines of Python <em>(templates included)</em></p></li></ul><p>Enjoy!</p><div><hr></div><h2><em>Wait&#8230; aren&#8217;t xA and xAG the same thing?</em></h2><p>Be honest. How many of you thought they were interchangeable? &#9995;</p><p>I certainly did.</p><p>Turns out I was wrong.</p><p>Both stats aim to value creativity, but under the hood they are somewhat distant relatives.</p><h3>Quick refresher on xAG</h3><p>xAG assigns the <strong>xG of the next shot</strong> to the passer who supplied that shot.</p><ul><li><p><strong>Blind spot #1 &#8211; The dribble tax:</strong> if the receiver slaloms past five defenders before shooting, the original passer still gets credit for the inflated xG.</p></li><li><p><strong>Blind spot #2 &#8211; The pass&#8209;before&#8209;the&#8209;pass:</strong> if the receiver decides to pass rather than shoot, the original passer receives <strong>zero</strong> credit.</p></li></ul><p>xA removes both blind spots:</p><ul><li><p><strong>Freeze&#8209;frame at reception</strong> &#8211; The passer is scored <em>the moment the ball arrives</em>, before any solo heroics inflate xG (looking at you, Leo Messi).</p></li><li><p><strong>Every completed pass counts</strong> &#8211; Even if no shot follows, each pass receives a probability of becoming a goal.</p></li></ul><p>But let&#8217;s not get ahead of ourselves.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h1>1 &#8212; So What <em>is</em> xA?</h1><p>Every completed pass is graded from <strong>0.00</strong> to <strong>1.00</strong> according to how often <em>historically similar</em> passes became goals.</p><p>For example, a diagonal through&#8209;ball completed inside the box might score 0.25&#8239;xA&#8212;meaning one in four similar passes historically became goals.</p><p>Miss the receiver entirely? xA = <strong>0</strong>. You can&#8217;t assist phantom team&#8209;mates.</p><p><em>Thank you, Captain Obvious.</em></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!c0Vv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c0Vv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png 424w, https://substackcdn.com/image/fetch/$s_!c0Vv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png 848w, https://substackcdn.com/image/fetch/$s_!c0Vv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png 1272w, https://substackcdn.com/image/fetch/$s_!c0Vv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c0Vv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png" width="366" height="166.00714285714287" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:254,&quot;width&quot;:560,&quot;resizeWidth&quot;:366,&quot;bytes&quot;:34634,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165735006?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!c0Vv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png 424w, https://substackcdn.com/image/fetch/$s_!c0Vv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png 848w, https://substackcdn.com/image/fetch/$s_!c0Vv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png 1272w, https://substackcdn.com/image/fetch/$s_!c0Vv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ad7efc4-43bd-4354-be0c-23e7398df359_560x254.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>What goes into the model?</h3><ol><li><p><strong>Pass context</strong></p><p>&#8226; Start &amp; end coordinates</p><p>&#8226; Pass length &amp; angle</p><p>&#8226; Delivery type (through&#8209;ball, cross, set&#8209;piece, header&#8230;)</p><p>&#8226; Phase of play (open play, free&#8209;kick, corner&#8230;)</p></li><li><p><strong>Historical outcome</strong></p><p>&#8226; Frequency with which those passes became <em>official</em> assists</p></li></ol><p>Most providers run a logistic regression (or gradient&#8209;boosted tree) to spit out the probability.</p><p><strong>Important:</strong> xA stops counting at reception. The receiver can pass backwards or dribble sideways; the passer already has his probability.</p><p>xA therefore does <strong>not</strong> tell you how many assists a player <em>should</em> have. Instead it measures the <em><strong>quality</strong></em> and <em><strong>frequency</strong></em> of passes into dangerous areas.</p><div><hr></div><h1>2 &#8212; The classic analyst pitfall</h1><p>Because <em>every</em> successful pass enters the tally, high&#8209;possession teams will naturally pile up xA. Summing an individual&#8217;s season&#8209;long xA and comparing it one&#8209;for&#8209;one with his assist total is a category error:</p><ul><li><p>xA &#8800; &#8220;deserved assists&#8221;</p></li><li><p>xA &#8594; &#8220;volume&#8209;weighted danger injected by passes&#8221;</p></li></ul><p>Always look at <strong>per&#8209;90</strong> or <strong>possession&#8209;adjusted</strong> rates and compare roles, not raw totals.</p><p>And also, be mindful of how each data provider labels its statistics.</p><p>For instance, Opta data on FBref follows the definitions we&#8217;ve used here, whereas Understat calls &#8220;xA&#8221; what we&#8217;ve previously defined as xAG.</p><p>Confusing, I know.</p><p>Bottom line: always read a provider&#8217;s documentation before using any metric.</p><div><hr></div><h1>3 &#8212; How professionals use xA</h1><ul><li><p><strong>Scouting hidden creators</strong> &#8212; Deep&#8209;lying playmakers, wing&#8209;backs, even centre&#8209;backs with a quarterback switch can rack up xA long before they register a headline&#8209;making assist.</p></li><li><p><strong>Process vs outcome audits</strong> &#8212; A winger on a cold assist streak but steady xA is probably getting let down by finishing, not suddenly running out of ideas.</p></li><li><p><strong>Tactical fingerprints</strong> &#8212; Plotting xA by pitch zone highlights which channels a team repeatedly exploits.</p></li></ul><p>Most importantly, xA is often <em>paired with </em>xAG to refine the profile of a creator. A few rules of thumb:</p><ul><li><p><strong>High xA + high xAG</strong> &#8594; elite creator who delivers plenty of dangerous final balls.</p></li><li><p><strong>High xA, low xAG</strong> &#8594; volume distributor whose team&#8209;mates often fail to shoot.</p></li><li><p><strong>Low xA, high xAG</strong> &#8594; low&#8209;touch playmaker who saves his bullets for killer passes.</p></li></ul><h2><strong>Mini&#8209;case study: the Premier League&#8217;s top 10 creators</strong></h2><p>Below are the top 10 Premier League creators for the 2024/25 season (data up to 6&#8239;May 2025). For each player you&#8217;ll see total assists, xAG, xA, minutes played, their per&#8209;90 versions, and their ranks in terms of <code>xA_90</code> and <code>xAG_90</code>. Data is sorted by the players&#8217; xA_90 rank.</p><p><em>Don&#8217;t worry&#8212;full Python code to reproduce this table appears at the end.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L1wB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L1wB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png 424w, https://substackcdn.com/image/fetch/$s_!L1wB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png 848w, https://substackcdn.com/image/fetch/$s_!L1wB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png 1272w, https://substackcdn.com/image/fetch/$s_!L1wB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L1wB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png" width="1456" height="544" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:544,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:149337,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165735006?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L1wB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png 424w, https://substackcdn.com/image/fetch/$s_!L1wB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png 848w, https://substackcdn.com/image/fetch/$s_!L1wB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png 1272w, https://substackcdn.com/image/fetch/$s_!L1wB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa809820a-8528-4ea6-8331-f6bcb994e238_1520x568.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>So what do we see?</p><ol><li><p><strong>Bukayo Saka</strong> <em>(High xA + High xAG):</em> Arsenal&#8217;s right&#8209;sider is both <em>busy</em> and <em>deadly</em>. He supplies lots of balls into danger (highest xA) <strong>and</strong> those balls turn into big&#8209;value shots (xAG &#8776; xA). Classic elite creator.</p></li><li><p><strong>Kevin De Bruyne</strong> <em>(Low&#8209;volume sniper):</em> xAG&#8239;/&#8239;90 is actually <strong>higher</strong> than his xA&#8239;/&#8239;90. He doesn&#8217;t spam passes; instead he waits for the killer ball that becomes a huge chance.</p></li><li><p><strong>S&#225;vio</strong> <em>(Balanced creator):</em> Very active and the shot value is almost keeping up with the volume. A reliable supply line for City.</p></li><li><p><strong>James Maddison</strong> <em>(High xA, low xAG):</em> ****Maddison keeps finding advanced receivers, but Spurs either (a) take extra touches/dribbles before shooting or (b) fail to shoot at all. The pass is dangerous in principle, but the resulting shot&#8212;if any&#8212;carries far less xG.</p></li><li><p><strong>Dwight McNeil</strong> <em>(Above&#8209;average both):</em> ****Everton&#8217;s wide creator is fairly balanced; shot quality lags volume a bit but not dramatically.</p></li><li><p><strong>Trent Alexander&#8209;Arnold</strong> <em>(Volume distributor):</em> ****Lots of probing passes (high xA), yet Liverpool&#8217;s eventual shots from those balls are middling. Typical of a high&#8209;crossing full&#8209;back.</p></li><li><p><strong>Phil Foden</strong> <em>(Volume distributor):</em> Similar story to Trent, although from more central zones. A steady stream of chances that aren&#8217;t always huge.</p></li><li><p><strong>Martin &#216;degaard</strong> <em>(Table&#8209;setting 10):</em> Like Maddison, he racks up danger in the build&#8209;up, but Arsenal often recycle or shoot from trickier angles afterward, deflating xAG.</p></li><li><p><strong>Harvey Barnes</strong> <em>(Secondary creator):</em> ****Respectable volume; the shot value lags&#8212;perhaps because many of his passes are squared across the box rather than cut&#8209;backs.</p></li><li><p><strong>Cole Palmer</strong> <em>(Selective killer passes):</em> ****The inverse of Maddison/&#216;degaard: Palmer&#8217;s passes don&#8217;t flood the box (xA rank only 10th), yet when he does supply a key ball it tends to become a high&#8209;xG shot (ranked 7th). Chelsea lean on him for the decisive action rather than general ball circulation.</p></li></ol><p>Phew! I hope I haven&#8217;t lost you.</p><p>The xA&#8202;/&#8202;xAG combination quickly highlights under&#8209;achievers (hello, James&#8239;Maddison) and selective assassins like De&#8239;Bruyne or Palmer&#8212;though you probably knew that already.</p><p>Key takeaways:</p><ul><li><p>xA&#8202;/&#8202;xAG adds the nuance needed to spot under&#8209;achievers.</p></li><li><p>It can help you track how a player&#8217;s creative profile evolves over time.</p></li><li><p>Most importantly, by applying the same analysis to less&#8209;watched leagues and players, you can uncover the next global megastar. You&#8217;re welcome. &#128522;</p></li></ul><p>And finally here&#8217;s the Python template of the day.</p><div><hr></div><h1>4 &#8212; Getting xA Data with Python</h1><p>So how do we get our hands on xA data? If you&#8217;ve followed previous issues of <em>The&#8239;Python Football Review</em>, you know the drill: Opta data freely shared on FBref.</p><p>Rather than spend hours writing your own scraper, let <a href="https://x.com/p_robberechts">Pieter Robberechts</a>&#8217; <code>soccerdata</code> library handle the heavy lifting.</p><p>Before we begin, here&#8217;s a download link to the code you are about to read.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/vq1t1qqcgarxld4/PFR_004_xA.ipynb/file&quot;,&quot;text&quot;:&quot;Download code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/vq1t1qqcgarxld4/PFR_004_xA.ipynb/file"><span>Download code</span></a></p><p>So first we install <em>soccerdata</em> and import it alongside Polars.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k8aI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k8aI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png 424w, https://substackcdn.com/image/fetch/$s_!k8aI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png 848w, https://substackcdn.com/image/fetch/$s_!k8aI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png 1272w, https://substackcdn.com/image/fetch/$s_!k8aI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k8aI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png" width="348" height="265.20446096654274" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/33073cda-0590-4298-a72c-fc9b8110f371_538x410.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:410,&quot;width&quot;:538,&quot;resizeWidth&quot;:348,&quot;bytes&quot;:76605,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165735006?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!k8aI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png 424w, https://substackcdn.com/image/fetch/$s_!k8aI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png 848w, https://substackcdn.com/image/fetch/$s_!k8aI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png 1272w, https://substackcdn.com/image/fetch/$s_!k8aI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33073cda-0590-4298-a72c-fc9b8110f371_538x410.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Next we define the scope of our study by specifying the 2024/25 English Premier League season from FBref. We fetch the passing stats by calling <code>read_player_season_stats</code> with <code>stat_type="passing"</code> to capture both xA and xAG.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FaZM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FaZM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png 424w, https://substackcdn.com/image/fetch/$s_!FaZM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png 848w, https://substackcdn.com/image/fetch/$s_!FaZM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png 1272w, https://substackcdn.com/image/fetch/$s_!FaZM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FaZM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png" width="552" height="169.04499274310595" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:422,&quot;width&quot;:1378,&quot;resizeWidth&quot;:552,&quot;bytes&quot;:114546,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165735006?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FaZM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png 424w, https://substackcdn.com/image/fetch/$s_!FaZM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png 848w, https://substackcdn.com/image/fetch/$s_!FaZM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png 1272w, https://substackcdn.com/image/fetch/$s_!FaZM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00a688d1-b127-41b1-b793-b8e81ed1c03f_1378x422.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The returned DataFrame has 28 columns.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!emoV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!emoV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png 424w, https://substackcdn.com/image/fetch/$s_!emoV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png 848w, https://substackcdn.com/image/fetch/$s_!emoV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png 1272w, https://substackcdn.com/image/fetch/$s_!emoV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!emoV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png" width="1456" height="476" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:476,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:191959,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165735006?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!emoV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png 424w, https://substackcdn.com/image/fetch/$s_!emoV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png 848w, https://substackcdn.com/image/fetch/$s_!emoV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png 1272w, https://substackcdn.com/image/fetch/$s_!emoV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd722e50-8dc5-4695-8d0f-af30d3fa373e_2194x718.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That&#8217;s why we keep only what you need&#8212;<code>player</code>, <code>position</code>, <code>90s</code>, <code>assists</code>, <code>xAG</code>, and <code>xA</code>&#8212;then convert it to Polars for easier wrangling.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9r8Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9r8Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png 424w, https://substackcdn.com/image/fetch/$s_!9r8Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png 848w, https://substackcdn.com/image/fetch/$s_!9r8Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png 1272w, https://substackcdn.com/image/fetch/$s_!9r8Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9r8Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png" width="528" height="268.78068410462777" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:506,&quot;width&quot;:994,&quot;resizeWidth&quot;:528,&quot;bytes&quot;:109266,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165735006?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9r8Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png 424w, https://substackcdn.com/image/fetch/$s_!9r8Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png 848w, https://substackcdn.com/image/fetch/$s_!9r8Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png 1272w, https://substackcdn.com/image/fetch/$s_!9r8Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f02373e-2f11-450a-a099-17ec3ef07464_994x506.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>And finally we wrangle the data to</strong></p><ul><li><p>Filter out players with fewer than 10 matches.</p></li><li><p>Create the per&#8209;90 metrics.</p></li><li><p>Rank <code>xA_90</code> and <code>xAG_90</code>.</p></li><li><p>Sort by <code>xA_90</code> in descending order.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WKAf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WKAf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png 424w, https://substackcdn.com/image/fetch/$s_!WKAf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png 848w, https://substackcdn.com/image/fetch/$s_!WKAf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png 1272w, https://substackcdn.com/image/fetch/$s_!WKAf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WKAf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png" width="511" height="353.9148148148148" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:748,&quot;width&quot;:1080,&quot;resizeWidth&quot;:511,&quot;bytes&quot;:160897,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165735006?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WKAf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png 424w, https://substackcdn.com/image/fetch/$s_!WKAf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png 848w, https://substackcdn.com/image/fetch/$s_!WKAf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png 1272w, https://substackcdn.com/image/fetch/$s_!WKAf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea90cbc-3560-441c-b4b7-69d8884f9351_1080x748.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Et&#8239;voil&#224;&#8212;the table you just saw, ready for analysis.</p><div><hr></div><p>Boom&#8212;<strong>that&#8217;s xA 101</strong>.</p><p>If you found this issue useful, please spread the word! You now know what xA is, how it&#8217;s calculated, why so many people confuse it with xAG (and why <em>you</em> won&#8217;t), how to uncover hidden creative talent, and&#8212;most importantly&#8212;how to pull a season&#8217;s worth of data with just a few lines of Python.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/expected-assists-xa-101?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/expected-assists-xa-101?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/expected-assists-xa-101?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p>I&#8217;m still experimenting with the newsletter&#8217;s format, so your feedback is invaluable. Would you prefer shorter bites, longer deep dives, more Python, or more case-studies? Or does this mix hit the sweet spot?</p><p>My goal is to build this newsletter <em>with</em> you.</p><p>Until next week,</p><p><strong>Martin</strong></p><p><em>The&#8239;Python Football Review</em></p>]]></content:encoded></item><item><title><![CDATA[Expected Assisted Goals (xAG) 101]]></title><description><![CDATA[What xAG measures (and what it doesn&#8217;t), the key blindspots to watch out for, how it's different from expected assists (xA), and how to pull tons of xAG data with Python.]]></description><link>https://www.footballmarketreview.com/p/expected-assisted-goals-xag-101</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/expected-assisted-goals-xag-101</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 05 Jun 2025 08:01:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/582359ec-34de-47ba-80cb-75210bfd588d_325x325.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The&#8239;Python Football Review&#8239;#003!</em></p><p>We&#8217;ve already dissected <strong><a href="https://open.substack.com/pub/pythonfootballreview/p/expected-goals-xg-101?r=5mroiq&amp;utm_medium=ios">xG</a></strong> (chance creation) and <strong><a href="https://open.substack.com/pub/pythonfootballreview/p/expected-goals-on-target-xgot-101?r=5mroiq&amp;utm_medium=ios">xGOT</a></strong> (shot execution).</p><p>Today we slide one pass earlier in the move: <strong>Expected&#8239;Assisted&#8239;Goals (xAG)</strong>.</p><p>By the end of this issue, you&#8217;ll know:</p><ul><li><p>what xAG measures</p></li><li><p>the biggest blindspots to watch for</p></li><li><p>how it differs from expected assists (yes they are different)</p></li><li><p>how professionals uncover hidden creative talent using it</p></li><li><p>how to pull 8 seasons of xAG data with a few lines of Python code (templates included)</p></li></ul><p>Enjoy!</p><div><hr></div><h3>First things first&#8230; <em>&#8220;Aren&#8217;t assists good enough?&#8221;</em></h3><p>Raw assists <strong>matter</strong>, but they&#8217;re messy:</p><ul><li><p><strong>Finisher&#8209;dependent:</strong> A defence&#8209;splitting through&#8209;ball earns <em>zero</em> credit if the striker skies it.</p></li><li><p><strong>Team&#8209;dependent:</strong> Creators at goal&#8209;rich clubs stack assists; equally gifted players on low&#8209;scoring sides look anonymous.</p></li></ul><p>Analysts needed a way to rate the <strong>quality of the pass itself</strong>, independent of who finishes&#8212;or whether anyone finishes at all.</p><p>Enter <strong>Expected&#8239;Assisted&#8239;Goals (xAG).</strong></p><div><hr></div><h2>1&#8239;&#8212;&#8239;What is xAG?</h2><p>Think of xAG as <em>xG but for the passer.</em></p><p>xAG equals the <strong>xG of the shot</strong> that immediately follows a completed pass.</p><p>So it&#8217;s a probability between 0 and 1 that the shot resulting from the pass would transform into a goal.</p><ul><li><p><strong>0.00</strong>&#8239;&#8594; a pass that virtually never leads to a goal</p></li><li><p><strong>1.00</strong>&#8239;&#8594; a pass that would become an assist for a goal every single time</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!McVe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!McVe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png 424w, https://substackcdn.com/image/fetch/$s_!McVe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png 848w, https://substackcdn.com/image/fetch/$s_!McVe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png 1272w, https://substackcdn.com/image/fetch/$s_!McVe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!McVe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png" width="638" height="154.94285714285715" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:238,&quot;width&quot;:980,&quot;resizeWidth&quot;:638,&quot;bytes&quot;:97738,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!McVe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png 424w, https://substackcdn.com/image/fetch/$s_!McVe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png 848w, https://substackcdn.com/image/fetch/$s_!McVe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png 1272w, https://substackcdn.com/image/fetch/$s_!McVe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9d38b07-27fa-4b0e-bb68-63d67c7d0f16_980x238.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Add up every pass&#8217;s xAG and you get how many assists a player <strong>should</strong> have given the quality of chances he supplies&#8212;regardless of finishing luck.</p><p>In short, xAG adds <strong>quality</strong> to the raw <strong>quantity</strong> of passes leading to shots.</p><p>It removes finishing noise and levels the field across teams, turning raw pass counts into a <strong>continuous, chance&#8209;quality metric</strong>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>2&#8239;&#8212;xAG blind spots</h2><p>No stat is perfect&#8212;xAG included. Two common traps you should be aware of:</p><ol><li><p><strong>The Messi Dribble Tax</strong></p><p>A five&#8209;yard square ball to Messi in the middle of the pitch that he turns into a wonder&#8209;goal by dancing his way through 5 defenders still hands the passer the full xAG. Great for Busquets&#8217; r&#233;sum&#233;; not great for isolating creative genius.</p></li><li><p><strong>The Pre&#8209;assist Disappearing Act</strong></p><p>A deep-lying Pirlo laser that breaks the press, followed by one extra square pass of the receiver, earns 0 xAG for Pirlo. The metric only credits the final ball before the shot.</p></li></ol><p>Now there are other metrics such as xA (expected assists) and xT (expected threat) that can plug those gaps&#8212;but that&#8217;s a story for another issue.</p><p>Bottom line: <strong>use xAG, but never in isolation.</strong> It captures far more nuance than raw assists, yet still needs context from video, xA, or xT to tell the full creative story.</p><h3><em><strong>&#8220;But Martin, isn&#8217;t xAG just expected assists&#8212;xA?&#8221;</strong></em></h3><p>If only it were that simple, my friend. The two are related but <strong>not</strong> the same:</p><ul><li><p><strong>xAG</strong> gives the passer the <em>xG of the very next shot</em>. No shot, no xAG.</p></li><li><p><strong>xA</strong> values <strong>every</strong> completed pass, shot or no shot, so long as it historically leads to goals often enough.</p></li></ul><p>xA fixes the &#8220;no&#8209;shot, no credit&#8221; problem&#8212;but in doing so it introduces its own quirks (a story for another newsletter).</p><p>For now, just remember: <strong>xAG and xA measure the same creative impulse from two different angles. Don&#8217;t mix them up.</strong></p><p>All right&#8212;so how do the pros actually <em>use</em> xAG?</p><div><hr></div><h2>3&#8239;&#8212;&#8239;How professionals use xAG</h2><p>Just as xG separates luck from finishing skill, <strong>xAG tells a richer story than raw assists ever can.</strong></p><p>By rewarding pass quality, it has become the go&#8209;to metric for judging creative players&#8212;especially midfielders whose reputations hinge on the final ball.</p><h3>Rating creators over time</h3><p>Over large samples xAG drifts toward a player&#8217;s assist total, but the <strong>gap</strong> between the two is where the insight hides:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0XPN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0XPN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png 424w, https://substackcdn.com/image/fetch/$s_!0XPN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png 848w, https://substackcdn.com/image/fetch/$s_!0XPN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png 1272w, https://substackcdn.com/image/fetch/$s_!0XPN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0XPN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png" width="468" height="238.10526315789474" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:290,&quot;width&quot;:570,&quot;resizeWidth&quot;:468,&quot;bytes&quot;:92544,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0XPN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png 424w, https://substackcdn.com/image/fetch/$s_!0XPN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png 848w, https://substackcdn.com/image/fetch/$s_!0XPN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png 1272w, https://substackcdn.com/image/fetch/$s_!0XPN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1a5dd6c-7c5e-4f77-a3f3-0e6a705d35bb_570x290.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>A simple roll&#8209;up therefore is <strong>Assists&#8239;&#8722;&#8239;xAG</strong>.</p><ul><li><p>Negative across a season? Bad luck or blunt finishing.</p></li><li><p>Positive? Visionary passer or ruthless finishers.</p></li></ul><p>Let&#8217;s do a mini case study and uncover Europe&#8217;s top under&#8209;credited architects.</p><p><em>Who&#8217;s been most let down by team&#8209;mates since 2017&#8209;18?</em></p><p>Here are the top five &#8220;should&#8209;have&#8221; creators as of 2 May 2025 (you will get to replicate this analysis with our templates below):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fR3H!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fR3H!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png 424w, https://substackcdn.com/image/fetch/$s_!fR3H!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png 848w, https://substackcdn.com/image/fetch/$s_!fR3H!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png 1272w, https://substackcdn.com/image/fetch/$s_!fR3H!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fR3H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png" width="1222" height="328" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:328,&quot;width&quot;:1222,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:70469,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fR3H!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png 424w, https://substackcdn.com/image/fetch/$s_!fR3H!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png 848w, https://substackcdn.com/image/fetch/$s_!fR3H!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png 1272w, https://substackcdn.com/image/fetch/$s_!fR3H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83a19c9e-d5d4-402b-a112-af86b366119e_1222x328.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Serge Gnabry</strong>&#8217;s Bayern teammates hardly lack fire&#8209;power, yet he &#8220;deserved&#8221; roughly <strong>12 more assists (-11.9 xGA)</strong> on top of his 33 from 191 games. Further down we find creators at less glamorous clubs&#8212;<strong>Lorenzo</strong> <strong>Pellegrini</strong> (Roma) with -11.8 xGA, <strong>Junya</strong> <strong>Ito</strong> (Reims) with -11.4 xGA, <strong>Jesus Navas</strong> (Sevilla) with -11.2 xGA&#8212;whose teammates squandered double&#8209;digit chances.</p><p>Sort by <strong>Assists-xGA per 90 minutes</strong> and hidden gems pop even faster (if you can define a player playing for Europe&#8217;s top 5 leagues as &#8220;hidden&#8221;).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aseP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aseP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png 424w, https://substackcdn.com/image/fetch/$s_!aseP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png 848w, https://substackcdn.com/image/fetch/$s_!aseP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png 1272w, https://substackcdn.com/image/fetch/$s_!aseP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aseP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png" width="1258" height="328" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:328,&quot;width&quot;:1258,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:68315,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!aseP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png 424w, https://substackcdn.com/image/fetch/$s_!aseP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png 848w, https://substackcdn.com/image/fetch/$s_!aseP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png 1272w, https://substackcdn.com/image/fetch/$s_!aseP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56b84ea5-564d-4a09-ab7f-3900ba465670_1258x328.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Remi&#8239;Oudin</strong> (Lecce) &#8722;0.17&#8239;Assists&#8211;minus-xAG per 90 minutes &#8776; 7 &#8220;missing&#8221; assists per season (that&#8217;s 0.17x38)</p></li></ul><ul><li><p><strong>Lucas&#8239;P&#233;rez</strong> (Deportivo La Coruna) &#8776; 6 &#8220;missing&#8221; assists</p></li><li><p><strong>Angelo&#8239;Fulgini</strong> (Lens) &#8776; 6 &#8220;missing&#8221; assists</p></li></ul><p>Of course, those players hardly unknown&#8212;each plays in a top league&#8212;but the exercise shows how quickly a global database can surface creators whose numbers lag behind their service.</p><p>And that&#8217;s exactly what recruitment departments do. Filter your database for <strong>high&#8239; xAG/90, low&#8239;Assists/90</strong>. Swap their wasteful strikers for clinical finishers and the numbers explode.</p><h3>Hot&#8209;streak beneficiaries</h3><p>Now for the over&#8209;performers&#8212;usually stars on elite, clinical sides.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RaXC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RaXC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png 424w, https://substackcdn.com/image/fetch/$s_!RaXC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png 848w, https://substackcdn.com/image/fetch/$s_!RaXC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png 1272w, https://substackcdn.com/image/fetch/$s_!RaXC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RaXC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png" width="1302" height="332" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:332,&quot;width&quot;:1302,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:76511,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RaXC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png 424w, https://substackcdn.com/image/fetch/$s_!RaXC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png 848w, https://substackcdn.com/image/fetch/$s_!RaXC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png 1272w, https://substackcdn.com/image/fetch/$s_!RaXC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff55b00da-3359-495b-976a-bdaff1a1e387_1302x332.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Top of the pile is <strong>Thomas&#8239;M&#252;ller</strong>: Bayern&#8217;s finishers converted <strong>25.8 more goals</strong> than his xAG implied. He&#8217;s followed by a surprise name, <strong>Paul&#8239;Pogba</strong> (+16.4), then <strong>Jadon&#8239;Sancho</strong> in his Dortmund days (+14.9), <strong>Florian&#8239;Wirtz</strong> (+13.7) and <strong>Mohamed&#8239;Salah</strong> (+13.3).</p><div><hr></div><p>So to recap, xAG lets clubs spot two very different stories:</p><ol><li><p><strong>Underrated creators</strong>&#8212;high xAG, few assists&#8212;who might explode with better finishers.</p></li><li><p><strong>Hot&#8209;streak beneficiaries</strong>&#8212;assists far above xAG&#8212;whose numbers could cool when the shooting luck fades (or if paired with less skillful finishers).</p></li></ol><p>And finally, here&#8217;s how to get 8 seasons of data with a few lines of Python code.</p><div><hr></div><h2>4 &#8212;&#8239;Getting xAG data in Python</h2><p>If you&#8217;ve been reading <em>The Python Football Review</em> for a while, you know the drill: Opta&#8217;s advanced data&#8212;shared free on FBref&#8212;is the easiest starting point. </p><p>Rather than scraping it by hand, we&#8217;ll lean on Pieter&#8239;Robberechts&#8217; (<a href="https://x.com/p_robberechts">@p_robberechts</a>) community wrapper <code>soccerdata</code> and wrangle the results with <code>polars</code>.</p><p>Before we begin, here&#8217;s a download link to the code you are about to read.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/stk9dwlj2l5uhzp/PFR_003_xAG.ipynb/file&quot;,&quot;text&quot;:&quot;Download Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/stk9dwlj2l5uhzp/PFR_003_xAG.ipynb/file"><span>Download Code</span></a></p><p>To start coding, just go to <em><strong>Google&#8239;Colab</strong></em> (zero setup&#8212;just your Gmail) and open a new notebook. You can either import the code (that you just downloaded), or type it yourself by following the instructions you are about to read.</p><p>So the first thing you&#8217;ll need to do is to install <code>soccerdata</code>, then import it alongside <code>polars</code> (for data wrangling).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wytw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wytw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png 424w, https://substackcdn.com/image/fetch/$s_!wytw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png 848w, https://substackcdn.com/image/fetch/$s_!wytw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png 1272w, https://substackcdn.com/image/fetch/$s_!wytw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wytw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png" width="308" height="242.0811808118081" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:426,&quot;width&quot;:542,&quot;resizeWidth&quot;:308,&quot;bytes&quot;:81220,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wytw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png 424w, https://substackcdn.com/image/fetch/$s_!wytw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png 848w, https://substackcdn.com/image/fetch/$s_!wytw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png 1272w, https://substackcdn.com/image/fetch/$s_!wytw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74616982-dd51-4de6-b777-5d6e7b93d21e_542x426.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Next, define your study window with <code>sd.FBref</code>. For this demo we&#8217;ll pull the last eight seasons across Europe&#8217;s top&#8209;five leagues.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sdUS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sdUS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png 424w, https://substackcdn.com/image/fetch/$s_!sdUS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png 848w, https://substackcdn.com/image/fetch/$s_!sdUS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png 1272w, https://substackcdn.com/image/fetch/$s_!sdUS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sdUS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png" width="560" height="187.91318864774624" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:402,&quot;width&quot;:1198,&quot;resizeWidth&quot;:560,&quot;bytes&quot;:97729,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sdUS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png 424w, https://substackcdn.com/image/fetch/$s_!sdUS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png 848w, https://substackcdn.com/image/fetch/$s_!sdUS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png 1272w, https://substackcdn.com/image/fetch/$s_!sdUS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F671c708a-b479-4b6f-a370-857dba9ba92e_1198x402.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Next we call <code>read_player_season_stats(stat_type="standard")</code></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!B0T_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B0T_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png 424w, https://substackcdn.com/image/fetch/$s_!B0T_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png 848w, https://substackcdn.com/image/fetch/$s_!B0T_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png 1272w, https://substackcdn.com/image/fetch/$s_!B0T_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B0T_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png" width="609" height="157.60337552742615" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:368,&quot;width&quot;:1422,&quot;resizeWidth&quot;:609,&quot;bytes&quot;:96563,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!B0T_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png 424w, https://substackcdn.com/image/fetch/$s_!B0T_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png 848w, https://substackcdn.com/image/fetch/$s_!B0T_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png 1272w, https://substackcdn.com/image/fetch/$s_!B0T_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91b7b0ed-2b84-4dce-9a7b-d60a90699b9e_1422x368.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rNvM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rNvM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png 424w, https://substackcdn.com/image/fetch/$s_!rNvM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png 848w, https://substackcdn.com/image/fetch/$s_!rNvM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png 1272w, https://substackcdn.com/image/fetch/$s_!rNvM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rNvM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png" width="1456" height="273" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:273,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:115494,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rNvM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png 424w, https://substackcdn.com/image/fetch/$s_!rNvM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png 848w, https://substackcdn.com/image/fetch/$s_!rNvM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png 1272w, https://substackcdn.com/image/fetch/$s_!rNvM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff20f69c3-e92b-485e-8d97-6b82b0eda23e_2296x430.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The raw DataFrame arrives with 33 columns; we keep only the essentials&#8212;position, matches, minutes, assists, and xAG&#8212;rename them for sanity, and convert to Polars.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cz5x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cz5x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png 424w, https://substackcdn.com/image/fetch/$s_!cz5x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png 848w, https://substackcdn.com/image/fetch/$s_!cz5x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png 1272w, https://substackcdn.com/image/fetch/$s_!cz5x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cz5x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png" width="1136" height="530" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e632b94e-855a-4a02-901e-9310cf580cce_1136x530.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:530,&quot;width&quot;:1136,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117279,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!cz5x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png 424w, https://substackcdn.com/image/fetch/$s_!cz5x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png 848w, https://substackcdn.com/image/fetch/$s_!cz5x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png 1272w, https://substackcdn.com/image/fetch/$s_!cz5x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe632b94e-855a-4a02-901e-9310cf580cce_1136x530.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Et voil&#224;&#8212;we now have our clean analysis-ready data.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LhoE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LhoE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png 424w, https://substackcdn.com/image/fetch/$s_!LhoE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png 848w, https://substackcdn.com/image/fetch/$s_!LhoE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png 1272w, https://substackcdn.com/image/fetch/$s_!LhoE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LhoE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png" width="1264" height="338" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:338,&quot;width&quot;:1264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:75287,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LhoE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png 424w, https://substackcdn.com/image/fetch/$s_!LhoE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png 848w, https://substackcdn.com/image/fetch/$s_!LhoE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png 1272w, https://substackcdn.com/image/fetch/$s_!LhoE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68565e6d-0450-4cb7-8e1d-de419315760b_1264x338.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We continue the analysis by grouping by league&#8239;/&#8239;team&#8239;/&#8239;player, aggregating totals, and creating our key metrics:</p><ul><li><p><strong>Assists&#8239;&#8722;&#8239;xAG</strong></p></li><li><p><strong>Assists&#8239;&#8722;&#8239;xAG &#8239;per &#8239;90</strong> <strong>minutes</strong></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6QNc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6QNc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png 424w, https://substackcdn.com/image/fetch/$s_!6QNc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png 848w, https://substackcdn.com/image/fetch/$s_!6QNc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png 1272w, https://substackcdn.com/image/fetch/$s_!6QNc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6QNc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png" width="1456" height="781" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:781,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:188123,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6QNc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png 424w, https://substackcdn.com/image/fetch/$s_!6QNc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png 848w, https://substackcdn.com/image/fetch/$s_!6QNc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png 1272w, https://substackcdn.com/image/fetch/$s_!6QNc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b2bd6f5-7e5a-482a-b5a2-2f50a16acb53_1502x806.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8cCt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8cCt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png 424w, https://substackcdn.com/image/fetch/$s_!8cCt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png 848w, https://substackcdn.com/image/fetch/$s_!8cCt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png 1272w, https://substackcdn.com/image/fetch/$s_!8cCt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8cCt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png" width="1266" height="332" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:332,&quot;width&quot;:1266,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69113,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8cCt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png 424w, https://substackcdn.com/image/fetch/$s_!8cCt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png 848w, https://substackcdn.com/image/fetch/$s_!8cCt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png 1272w, https://substackcdn.com/image/fetch/$s_!8cCt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e0ba8b0-2add-44d6-a1c2-8632eadeaab3_1266x332.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Sort ascending <strong>Assists&#8239;&#8722;&#8239;xAG</strong> to spot <em>under&#8209;credited</em> creators.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UnSS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UnSS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png 424w, https://substackcdn.com/image/fetch/$s_!UnSS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png 848w, https://substackcdn.com/image/fetch/$s_!UnSS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png 1272w, https://substackcdn.com/image/fetch/$s_!UnSS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UnSS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png" width="280" height="243.74100719424462" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:484,&quot;width&quot;:556,&quot;resizeWidth&quot;:280,&quot;bytes&quot;:80846,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UnSS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png 424w, https://substackcdn.com/image/fetch/$s_!UnSS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png 848w, https://substackcdn.com/image/fetch/$s_!UnSS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png 1272w, https://substackcdn.com/image/fetch/$s_!UnSS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc066b97-d7fa-42ab-9250-ccd9b8d85c59_556x484.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Add a minimum&#8209;xAG filter (e.g., &#8805;&#8239;5) to avoid tiny&#8209;sample noise and sort ascending <strong>Assists&#8239;&#8722;&#8239;xAG &#8239;per&#8239;90</strong> <strong>minutes</strong> to spot <em>under&#8209;credited</em> creators.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nIsi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nIsi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png 424w, https://substackcdn.com/image/fetch/$s_!nIsi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png 848w, https://substackcdn.com/image/fetch/$s_!nIsi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png 1272w, https://substackcdn.com/image/fetch/$s_!nIsi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nIsi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png" width="322" height="263.1826625386997" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a774bcab-1c69-451f-9930-5a29fa738052_646x528.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:528,&quot;width&quot;:646,&quot;resizeWidth&quot;:322,&quot;bytes&quot;:96046,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nIsi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png 424w, https://substackcdn.com/image/fetch/$s_!nIsi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png 848w, https://substackcdn.com/image/fetch/$s_!nIsi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png 1272w, https://substackcdn.com/image/fetch/$s_!nIsi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa774bcab-1c69-451f-9930-5a29fa738052_646x528.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Sort descending <strong>Assists&#8239;&#8722;&#8239;xAG</strong> to see who&#8217;s thriving on clinical team&#8209;mates.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dnCd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dnCd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png 424w, https://substackcdn.com/image/fetch/$s_!dnCd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png 848w, https://substackcdn.com/image/fetch/$s_!dnCd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png 1272w, https://substackcdn.com/image/fetch/$s_!dnCd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dnCd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png" width="328" height="278.2046204620462" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:514,&quot;width&quot;:606,&quot;resizeWidth&quot;:328,&quot;bytes&quot;:85950,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/165094665?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dnCd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png 424w, https://substackcdn.com/image/fetch/$s_!dnCd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png 848w, https://substackcdn.com/image/fetch/$s_!dnCd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png 1272w, https://substackcdn.com/image/fetch/$s_!dnCd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a41114a-e932-4e6f-9412-c7048dda5da2_606x514.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Within minutes you&#8217;re staring at clean tables showing who deserved more assists and who benefited from red&#8209;hot finishers.</p><div><hr></div><p>Boom&#8212;that&#8217;s xAG 101.</p><p>If you found this issue useful, please spread the word! You now know more about xAG than most football fans: what it measures, how professionals use it, why it isn&#8217;t the same as xA, and&#8212;crucially&#8212;how to pull eight seasons of data with a handful of Python lines.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/expected-assisted-goals-xag-101?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/p/expected-assisted-goals-xag-101?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/p/expected-assisted-goals-xag-101?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><p>I&#8217;m still experimenting with the format of the newsletter, so your feedback is super welcome&#8212;would you prefer shorter content, longer deep dives, more Python, or more football concepts? Or does this format hit the mark?</p><p>My aim is to build a truly practical newsletter <em>together</em> with you.</p><p>Until next week,</p><p><em><strong>Martin</strong></em></p><p><em><strong>The Python Football Review</strong></em></p>]]></content:encoded></item><item><title><![CDATA[Expected Goals on Target (xGOT) 101]]></title><description><![CDATA[What xGOT measures, how it fixes xG&#8217;s blind spots, how analysts rely on it, and a Python shortcut to bulk-download xGOT data]]></description><link>https://www.footballmarketreview.com/p/expected-goals-on-target-xgot-101</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/expected-goals-on-target-xgot-101</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 29 May 2025 08:01:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe999ca69-23eb-48af-b52d-d971473dd907_325x325.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The Python Football Review #002!</em></p><p>We previously broke down <strong>xG</strong> (missed it? grab it <a href="https://www.pythonfootball.com/p/expected-goals-xg-101?r=5mroiq">here</a>).</p><p>Today we move one step closer to goal: <strong>Expected Goals on Target (xGOT)</strong>.</p><p>By the end of this issue, you&#8217;ll know:</p><ul><li><p>what xGOT <em>really</em> measures</p></li><li><p>how it patches xG&#8217;s two biggest blind spots</p></li><li><p>the two ways analysts rely on it (and why we should talk about Strand Larsen and Emiliano Martinez more)</p></li><li><p>how to pull seasons of xGOT with just a few lines of Python (templates included)</p></li></ul><p>Enjoy!</p><div><hr></div><h3>First things first&#8230; <em>but Martin didn&#8217;t you say xG is already the best forward-looking metric we&#8217;ve got?</em></h3><p>First, it was the data providers who said it.</p><p>And second, xG is indeed brilliant at describing <strong>chance creation</strong>, but it freezes the play <em>before</em> the ball leaves the boot.</p><p>xGOT presses &#8220;play&#8221; and tells us what happened <em>after</em> the strike.</p><p>And that small difference unlocks a lot.</p><h2>1 &#8212; Why xG needed an upgrade</h2><p>Even xG die-hards admit two stubborn flaws:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xJAx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xJAx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png 424w, https://substackcdn.com/image/fetch/$s_!xJAx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png 848w, https://substackcdn.com/image/fetch/$s_!xJAx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png 1272w, https://substackcdn.com/image/fetch/$s_!xJAx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xJAx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png" width="478" height="173.01840490797545" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:354,&quot;width&quot;:978,&quot;resizeWidth&quot;:478,&quot;bytes&quot;:68522,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xJAx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png 424w, https://substackcdn.com/image/fetch/$s_!xJAx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png 848w, https://substackcdn.com/image/fetch/$s_!xJAx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png 1272w, https://substackcdn.com/image/fetch/$s_!xJAx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ccb8a1-39ce-4f97-bc1f-7a84a089ec28_978x354.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Enter xGOT.</p><p>A more skillful striker will typically post a higher xGOT&#8212;striking the ball cleaner, placing it smarter, and adding extra pace or spin. In short, xGOT bakes a slice of <em>execution skill</em> into the goal probability, neatly answering both critiques.</p><p>Let&#8217;s define xGOT and then explore how professionals use it.</p><div><hr></div><h2>2 &#8212; So, what <em>is</em> xGOT?</h2><p><strong>Expected Goals on Target</strong> looks only at <strong>on-target</strong> attempts.</p><p>It begins with the shot&#8217;s original xG, then layers on post-contact detail:</p><ul><li><p>precise landing spot in the goal frame</p></li><li><p>height, velocity, even spin</p></li></ul><p>A postage-stamp rocket earns more credit than a daisy-cutter straight at the keeper.</p><p>In short, xGOT answers:</p><p><em>&#8220;Given how this ball was struck and where it finished, how often does a keeper still save it?&#8221;</em></p><div><hr></div><h3>Declan Rice&#8217;s second goal vs Real Madrid &#8212; textbook example</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0lCm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0lCm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png 424w, https://substackcdn.com/image/fetch/$s_!0lCm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png 848w, https://substackcdn.com/image/fetch/$s_!0lCm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png 1272w, https://substackcdn.com/image/fetch/$s_!0lCm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0lCm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png" width="518" height="162.56920077972708" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:322,&quot;width&quot;:1026,&quot;resizeWidth&quot;:518,&quot;bytes&quot;:49520,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0lCm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png 424w, https://substackcdn.com/image/fetch/$s_!0lCm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png 848w, https://substackcdn.com/image/fetch/$s_!0lCm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png 1272w, https://substackcdn.com/image/fetch/$s_!0lCm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e349ed9-ed0a-4c9c-9cf5-dd813591d0f1_1026x322.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Same attempt, two very different tales: the <em>chance</em> was mediocre, the <em>strike</em> was elite.</p><p>An xGOT of 0.97 means that if a player executed that exact strike 100 times&#8212;same speed, placement, and technique&#8212;97 would find the net, and the keeper would save only three of those attempts.</p><p>Miss the target or get your shot blocked? xGOT = 0. After all, you can&#8217;t score what you don&#8217;t put on frame.</p><p>A key takeaway is that&#8212;just as with xG&#8212;over large samples xGOT and actual goals <em>converge</em>.</p><p>That means you can choose a time window (a month, half-season, full campaign) and measure how much a team or player over- or under-performed during that span.</p><p><em>(Note that depending on the data provider, xGOT may also be called post-shot expected goals (PSxG) so be prepared).</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>3 &#8212; Two ways professionals use xGOT</h2><h3>Quantifying finishing quality</h3><p>Beginners often judge a striker by <strong>Goals vs. xG</strong>. That&#8217;s a start, but xG bundles two separate things:</p><ol><li><p><strong>Getting into position</strong> &#8211; the runs, passes, and off-ball movement that create the chance</p></li><li><p><strong>Estimating the shot&#8217;s chance to become a goal</strong> &#8211; without ever measuring <em>how</em> the ball was struck</p></li></ol><p>So Goals-minus-xG mixes chance creation and finishing outcomes, while overlooking the crucial nuance of execution (placement, power, spin).</p><p>To isolate pure finishing skill, compare <strong>xGOT to xG</strong> instead:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-ekA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-ekA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png 424w, https://substackcdn.com/image/fetch/$s_!-ekA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png 848w, https://substackcdn.com/image/fetch/$s_!-ekA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png 1272w, https://substackcdn.com/image/fetch/$s_!-ekA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-ekA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png" width="478" height="268.7957559681698" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:424,&quot;width&quot;:754,&quot;resizeWidth&quot;:478,&quot;bytes&quot;:63888,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-ekA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png 424w, https://substackcdn.com/image/fetch/$s_!-ekA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png 848w, https://substackcdn.com/image/fetch/$s_!-ekA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png 1272w, https://substackcdn.com/image/fetch/$s_!-ekA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F417bd4c7-c37e-4bc1-9912-c947c5d8d105_754x424.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A handy summary metric you may encounter is <strong>Shooting Goals Added (SGA), which is simply</strong> <code>SGA = xGOT &#8722; xG</code></p><ul><li><p>High SGA? A scout&#8217;s eyebrow should rise.</p></li><li><p>Low or negative? Either poor technique or a cold streak&#8212;check the sample size before you draw conclusions.</p></li></ul><p>This means that if a striker racks up <strong>20 xGOT</strong> in a season while registering <strong>15 xG</strong>, his <strong>Shooting Goals Added</strong> would be: 20&#8197;&#8202;&#8722;&#8197;&#8202;15&#8197;&#8202;=&#8197;&#8202;+5. In other words, his finishing skill would be expected to deliver <strong>five extra goals</strong> above expectation for his team over that period.</p><h3><em>&#8220;We need to talk more about Strand Larsen&#8221;</em></h3><p>Okay, let&#8217;s do a mini&#8211;case study. A couple of weeks ago, BBC Sport argued we should be talking more about Strand Larsen at Wolves.</p><p><em>Wait, Strand who?</em></p><p>Let&#8217;s see what <strong>SGA = xGOT&#8722;xG</strong> reveals about that striker&#8212;even if this is the first you&#8217;ve heard of him.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Wy-Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png 424w, https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png 848w, https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png 1272w, https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png" width="536" height="409.466275659824" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1042,&quot;width&quot;:1364,&quot;resizeWidth&quot;:536,&quot;bytes&quot;:1179621,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png 424w, https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png 848w, https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png 1272w, https://substackcdn.com/image/fetch/$s_!Wy-Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63e5b-09f2-48fe-878a-4445a204b761_1364x1042.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://www.bbc.com/sport/football/articles/cjdxyn75vpmo">caption...</a></figcaption></figure></div><p>As of May 2 (when I&#8217;m writing), here are the top six Premier League non-penalty goal scorers. Salah, Haaland, Isak. Nothing surprising here.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!W3J1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W3J1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png 424w, https://substackcdn.com/image/fetch/$s_!W3J1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png 848w, https://substackcdn.com/image/fetch/$s_!W3J1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png 1272w, https://substackcdn.com/image/fetch/$s_!W3J1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W3J1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png" width="344" height="236.43943661971832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:488,&quot;width&quot;:710,&quot;resizeWidth&quot;:344,&quot;bytes&quot;:109618,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!W3J1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png 424w, https://substackcdn.com/image/fetch/$s_!W3J1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png 848w, https://substackcdn.com/image/fetch/$s_!W3J1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png 1272w, https://substackcdn.com/image/fetch/$s_!W3J1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67140a0c-2c3e-47c8-acfb-33e95e7b0e6d_710x488.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Now, here are the top six players by <strong>SGA = xGOT &#8722; xG</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WeZj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WeZj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png 424w, https://substackcdn.com/image/fetch/$s_!WeZj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png 848w, https://substackcdn.com/image/fetch/$s_!WeZj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png 1272w, https://substackcdn.com/image/fetch/$s_!WeZj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WeZj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png" width="497" height="223.93563218390804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:392,&quot;width&quot;:870,&quot;resizeWidth&quot;:497,&quot;bytes&quot;:115830,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WeZj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png 424w, https://substackcdn.com/image/fetch/$s_!WeZj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png 848w, https://substackcdn.com/image/fetch/$s_!WeZj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png 1272w, https://substackcdn.com/image/fetch/$s_!WeZj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0186f119-d64d-4c03-8de3-b7a970c957b4_870x392.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Mo Salah</strong> still leads with +6.91 SGA&#8212;he has scored nearly seven extra goals purely through his finishing skill. Next comes <strong>Chris Wood</strong> (+6.02), then <strong>Bryan Mbeumo</strong> (+5.53).</p><p>And then there&#8217;s <strong>Strand Larsen</strong>, climbing into fifth with <strong>+4.23 SGA</strong>.</p><p>SGA offers a fresh lens. For established names like Salah or Haaland, it confirms what we already suspected. But Larsen&#8217;s place in the top five shows the Wolves hype has real merit.</p><p>I&#8217;m not claiming xGOT&#8212;or SGA&#8212;is flawless. Strikers contribute more than goals alone. But when it comes to pure shot execution, it adds the nuance we&#8217;ve been missing.</p><p>Maybe it is indeed time to talk about <strong><s>Strand Larsen</s></strong> xGOT more.</p><p>Moving on&#8230;</p><h3>Assessing shot-stopping</h3><p>The second major use of xGOT is to assess the shot-stopping quality of goalkeepers.</p><p>The logic is straightforward:</p><ul><li><p>if a keeper concedes <strong>more</strong> goals than xGOT would predict, he&#8217;s underperforming;</p></li><li><p>if he concedes <strong>fewer</strong>, he&#8217;s exceeding expectations.</p></li></ul><p>So for keepers we flip the script and talk about Goals Prevented = <strong>xGOT conceded &#8722; Goals conceded</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9ClN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9ClN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png 424w, https://substackcdn.com/image/fetch/$s_!9ClN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png 848w, https://substackcdn.com/image/fetch/$s_!9ClN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png 1272w, https://substackcdn.com/image/fetch/$s_!9ClN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9ClN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png" width="476" height="241.83870967741936" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:378,&quot;width&quot;:744,&quot;resizeWidth&quot;:476,&quot;bytes&quot;:54172,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9ClN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png 424w, https://substackcdn.com/image/fetch/$s_!9ClN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png 848w, https://substackcdn.com/image/fetch/$s_!9ClN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png 1272w, https://substackcdn.com/image/fetch/$s_!9ClN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9d96801-38f4-4676-b00c-0d2e0ff70d93_744x378.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Please note an important nuance:</strong></p><ul><li><p>For strikers, we compare <strong>xGOT to xG</strong>&#8212;that is, we measure how well the striker struck the ball versus the average shot from that position.</p></li><li><p>For goalkeepers, we compare <strong>xGOT conceded to goals conceded</strong>&#8212;that is, we assess, given the difficulty of the on-target shots they faced, whether keepers saved or allowed them.</p></li></ul><p><em>Calculation note: When comparing xGOT conceded to goals conceded, data providers typically drop own goals, since no xGOT value can be assigned to a strike that was unintended for the target.</em></p><p>This means that if a keeper conceded 40 goals in a season&#8212;4 of which were own goals&#8212;while facing 38 xGOT, then his <strong>Goals Prevented</strong> would be: 38&#8197;&#8202;&#8722;&#8197;&#8202;(40&#8722;4)&#8197;&#8202;=&#8197;&#8202;+2. In other words, his shot-stopping skill saved an extra 2 goals for his team over that period.</p><h3><em>&#8220;Emiliano Martinez is not a great goalkeeper&#8221;</em></h3><p>Okay, let&#8217;s do another mini&#8211;case study. Emiliano Mart&#237;nez often draws criticism&#8212;mainly for his outspoken personality (just remember that World Cup celebration).</p><p>Pundits routinely question his quality&#8212;<em>&#8221;he&#8217;s a good goalkeeper, just not a great goalkeeper&#8221;.</em> So, what does xGOT reveal?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ackn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ackn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png 424w, https://substackcdn.com/image/fetch/$s_!ackn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png 848w, https://substackcdn.com/image/fetch/$s_!ackn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png 1272w, https://substackcdn.com/image/fetch/$s_!ackn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ackn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png" width="480" height="449.6703296703297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1364,&quot;width&quot;:1456,&quot;resizeWidth&quot;:480,&quot;bytes&quot;:1846422,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ackn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png 424w, https://substackcdn.com/image/fetch/$s_!ackn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png 848w, https://substackcdn.com/image/fetch/$s_!ackn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png 1272w, https://substackcdn.com/image/fetch/$s_!ackn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b81db3-35dc-4338-ba6a-c858743ac18d_1612x1510.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://www.goal.com/en/lists/emi-martinez-savaged-psg-legend-aston-villa-stopper-annoying-provocations/bltf6805918b51f5f1d">caption...</a></figcaption></figure></div><p><strong>Since 2019/20</strong> (through May 2, as I write), Mart&#237;nez has racked up <strong>+10.5 Goals Prevented</strong> (that&#8217;s 233.5 xGOT faced &#8211; 223 goals conceded as per Opta via Fbref), which works out to <strong>+0.09 Goals Prevented per 90 minutes per season</strong>. Over a 38-game season, that&#8217;s <strong>+3.42 goals saved</strong>.</p><p>How does he compare to (the great) title-winning peers?</p><ul><li><p><strong>Ederson:</strong> +4.1 Goals Prevented (165.1 xGOT &#8211; 161 goals), or <strong>+0.03 per 90</strong> &#8594; <strong>+1.14 per 38 games</strong></p></li><li><p><strong>Alisson:</strong> +12.1 Goals Prevented (178.1 xGOT &#8211; 166 goals), or <strong>+0.05 per 90</strong> &#8594; <strong>+1.90 per 38 games</strong></p></li></ul><p>Mart&#237;nez&#8217;s <strong>+3.42</strong> dwarfs Ederson&#8217;s <strong>+1.14</strong> and edges out Alisson&#8217;s <strong>+1.90</strong>.</p><p>See why analysts rave about him now?</p><p>I&#8217;m not claiming xGOT is the sole arbiter of goalkeeping greatness&#8212;there&#8217;s distribution, command of the area, and so on&#8212;but in pure shot-stopping terms, Mart&#237;nez ranks among&#8212;and arguably leads&#8212;the Premier League (over the last six seasons).</p><p>And finally here&#8217;s the easiest way to get xGOT data with Python.</p><div><hr></div><h2>4 &#8212; Getting xGOT data in Python</h2><p>The easiest free route&#8212;no custom scraping, no manual copy-pasting, no pricey API key&#8212;is the <code>soccerdata</code> wrapper by Pieter Robberechts (<a href="https://x.com/p_robberechts">@p_robberechts</a>). In just a couple of lines, you&#8217;ll be swimming in post-shot metrics from Opta (called PSxG on FBref).</p><p>First, if you&#8217;re on Google Colab (the fastest way to start Python with zero setup), install and import <code>soccerdata</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!C2vY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C2vY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png 424w, https://substackcdn.com/image/fetch/$s_!C2vY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png 848w, https://substackcdn.com/image/fetch/$s_!C2vY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png 1272w, https://substackcdn.com/image/fetch/$s_!C2vY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!C2vY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png" width="356" height="251.22408026755852" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:422,&quot;width&quot;:598,&quot;resizeWidth&quot;:356,&quot;bytes&quot;:93845,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!C2vY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png 424w, https://substackcdn.com/image/fetch/$s_!C2vY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png 848w, https://substackcdn.com/image/fetch/$s_!C2vY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png 1272w, https://substackcdn.com/image/fetch/$s_!C2vY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a2352a3-97a4-41a4-a72b-f6c9941c9c48_598x422.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Then define your study parameters&#8212;for example, Premier League, 2024&#8211;25&#8212;and call <code>read_schedule()</code> to fetch that season&#8217;s fixture list.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0GJf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0GJf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png 424w, https://substackcdn.com/image/fetch/$s_!0GJf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png 848w, https://substackcdn.com/image/fetch/$s_!0GJf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png 1272w, https://substackcdn.com/image/fetch/$s_!0GJf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0GJf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png" width="512" height="273.59645232815967" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:482,&quot;width&quot;:902,&quot;resizeWidth&quot;:512,&quot;bytes&quot;:122183,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0GJf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png 424w, https://substackcdn.com/image/fetch/$s_!0GJf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png 848w, https://substackcdn.com/image/fetch/$s_!0GJf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png 1272w, https://substackcdn.com/image/fetch/$s_!0GJf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbc39eb3-0916-4539-bbad-f347c5994eb0_902x482.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IJ0p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IJ0p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png 424w, https://substackcdn.com/image/fetch/$s_!IJ0p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png 848w, https://substackcdn.com/image/fetch/$s_!IJ0p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png 1272w, https://substackcdn.com/image/fetch/$s_!IJ0p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IJ0p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png" width="1456" height="338" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:338,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:196845,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IJ0p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png 424w, https://substackcdn.com/image/fetch/$s_!IJ0p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png 848w, https://substackcdn.com/image/fetch/$s_!IJ0p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png 1272w, https://substackcdn.com/image/fetch/$s_!IJ0p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66891353-fb1d-4922-ae56-7650ff5ece36_2354x546.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Once you have the schedule, extract the <code>game_id</code> column into a list and pass it to <code>read_shot_events()</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RFxl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RFxl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png 424w, https://substackcdn.com/image/fetch/$s_!RFxl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png 848w, https://substackcdn.com/image/fetch/$s_!RFxl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png 1272w, https://substackcdn.com/image/fetch/$s_!RFxl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RFxl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png" width="631" height="291.2307692307692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:1040,&quot;resizeWidth&quot;:631,&quot;bytes&quot;:115454,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RFxl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png 424w, https://substackcdn.com/image/fetch/$s_!RFxl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png 848w, https://substackcdn.com/image/fetch/$s_!RFxl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png 1272w, https://substackcdn.com/image/fetch/$s_!RFxl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3246d0cb-bd1a-40df-a6b6-30193502f5de_1040x480.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The result is a pandas DataFrame where each row is a shot event: minute, player, xG, PSxG (xGOT), outcome (goal/off-target/saved/blocked), distance, body part, plus the two players who combined to create the chance.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!V7cS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!V7cS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png 424w, https://substackcdn.com/image/fetch/$s_!V7cS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png 848w, https://substackcdn.com/image/fetch/$s_!V7cS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png 1272w, https://substackcdn.com/image/fetch/$s_!V7cS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!V7cS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png" width="1456" height="338" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:338,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:196845,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!V7cS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png 424w, https://substackcdn.com/image/fetch/$s_!V7cS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png 848w, https://substackcdn.com/image/fetch/$s_!V7cS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png 1272w, https://substackcdn.com/image/fetch/$s_!V7cS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64a63ca-1e97-4604-99e6-6ec9eb5e2b15_2354x546.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>With eight lines of code you&#8217;ve built a detailed shot log. Note: pulling one game&#8217;s worth of shots takes about 7 seconds&#8212;so a full 380-game season is roughly 45 minutes.</p><p>For goalkeeper analysis, run a similar call to <code>read_player_match_stats(stat_type="keeper")</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ddJi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ddJi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png 424w, https://substackcdn.com/image/fetch/$s_!ddJi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png 848w, https://substackcdn.com/image/fetch/$s_!ddJi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png 1272w, https://substackcdn.com/image/fetch/$s_!ddJi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ddJi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png" width="1360" height="506" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:506,&quot;width&quot;:1360,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:118988,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ddJi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png 424w, https://substackcdn.com/image/fetch/$s_!ddJi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png 848w, https://substackcdn.com/image/fetch/$s_!ddJi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png 1272w, https://substackcdn.com/image/fetch/$s_!ddJi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3967073-84b8-4c53-acad-fa2b5f322578_1360x506.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You&#8217;ll get one row per keeper per match, with fields like saves, goals conceded, PSxG (xGOT) faced, and more&#8212;ready for your shot-stopping deep dive.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aYLy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aYLy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png 424w, https://substackcdn.com/image/fetch/$s_!aYLy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png 848w, https://substackcdn.com/image/fetch/$s_!aYLy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png 1272w, https://substackcdn.com/image/fetch/$s_!aYLy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aYLy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png" width="1456" height="640" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:281913,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163769384?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!aYLy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png 424w, https://substackcdn.com/image/fetch/$s_!aYLy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png 848w, https://substackcdn.com/image/fetch/$s_!aYLy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png 1272w, https://substackcdn.com/image/fetch/$s_!aYLy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25b041e3-5d75-45f9-b37f-c46b42a74192_2334x1026.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I did tell you it was going to be easy, didn&#8217;t I? &#128522;</p><p>Here&#8217;s a link to the code if you want to copy-and-paste it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/lic102b93di752u/PFR_002_xGOT.ipynb/file&quot;,&quot;text&quot;:&quot;Download Python Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/lic102b93di752u/PFR_002_xGOT.ipynb/file"><span>Download Python Code</span></a></p><div><hr></div><h3>Key takeaways</h3><ul><li><p>xG explains chance creation; <strong>xGOT shows what the shooter did with it.</strong></p></li><li><p>For strikers: <strong>xGOT vs. xG</strong> &#8594; finishing talent.</p></li><li><p>For goalkeepers: <strong>xGOT conceded vs. Goals conceded</strong> &#8594; shot-stopping grade.</p></li></ul><div><hr></div><p>Boom&#8212;that&#8217;s xGOT 101.</p><p>If you found this newsletter helpful, please spread the word! You now know how xGOT is calculated, what it measures, why it matters, the two ways professional analysts use it, and how to grab xGOT data in seconds.</p><p>I&#8217;m still experimenting with the format of the newsletter, so your feedback is super welcome&#8212;would you prefer shorter content, longer deep dives, more Python, or more football concepts? Or does this format hit the mark?</p><p>My aim is to build a truly practical newsletter <em>together</em> with you.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"><em>Thanks for reading! Subscribe for free (if you haven&#8217;t already) to receive new posts.</em></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Until next week,</p><p><strong>Martin</strong></p><p><em>The Python Football Review</em></p><div><hr></div><p><em>P.S. If you enjoyed this newsletter and want to support it (I spend around 8 hours writing these), please share it on Twitter or LinkedIn. I know it can feel like a chore&#8212;trust me, I often hesitate too&#8212;so to say thanks I&#8217;ll send you an extended Python notebook that automatically pulls eight seasons of xGOT data (shots and goalkeeper metrics) from Europe&#8217;s top five leagues, fully wrangled into one analysis-ready dataset. Just send me an email (</em><code>martin@pythonfootball.com</code><em>) once you&#8217;ve shared, and I&#8217;ll send it over. Cheers!</em></p>]]></content:encoded></item><item><title><![CDATA[Expected Goals (xG) 101]]></title><description><![CDATA[What xG really measures (and what it doesn&#8217;t), the key misconception that trips up even seasoned pros, why its loudest critics are mostly wrong, and how to pull tons of xG data with Python.]]></description><link>https://www.footballmarketreview.com/p/expected-goals-xg-101</link><guid isPermaLink="false">https://www.footballmarketreview.com/p/expected-goals-xg-101</guid><dc:creator><![CDATA[MartinOnData]]></dc:creator><pubDate>Thu, 22 May 2025 09:00:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tsD6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe999ca69-23eb-48af-b52d-d971473dd907_325x325.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend,</p><p>Welcome to <em>The&#8239;Python Football Review #001!</em> &#127881;</p><p>We&#8217;re kicking off with the stat that rewired football analysis&#8212;<strong>Expected Goals (xG)</strong>. It&#8217;s quoted on broadcasts, splashed across Twitter infographics, and still sparks arguments every weekend.</p><p>By the end of this issue, you&#8217;ll know:</p><ul><li><p>What xG <em>really</em> measures (and what it doesn&#8217;t)</p></li><li><p>The one misconception that trips up even seasoned pros</p></li><li><p>Why xG is a game&#8209;changer&#8212;and why its loudest critics are (mostly) wrong. <em>Looking at you, Jamie Redknapp.</em></p></li><li><p>How to pull xG data with a handful of Python lines (templates included)</p></li></ul><p>Enjoy!</p><div><hr></div><h2><strong>1 &#8212; So, What </strong><em><strong>Is</strong></em><strong> an Expected Goal?</strong></h2><p>Put simply, an expected goal (xG) is a value between <strong>0</strong> and <strong>1</strong> that measures how likely a shot is to become a goal. For example:</p><ul><li><p>A long-range screamer might be <code>0.01 xG</code> (1% chance).</p></li><li><p>A tap-in could be <code>0.92 xG</code> (92% chance).</p></li></ul><p>Or more formally, xG quantifies the probability of a shot converting into a goal <em><strong>before</strong></em> the ball is struck.</p><p>That last piece is crucial: xG is fundamentally a <strong>pre-shot probability</strong>, not strictly a finishing metric. It&#8217;s a <strong>chance-creation</strong> measure, capturing how effectively a player (and by extension a team) reaches dangerous zones into one distilled value.</p><p><strong>Case in point</strong>: Remember those two screamers <em>Declan Rice</em> scored in the first-leg quarter-final against Real Madrid?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HFUQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HFUQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!HFUQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!HFUQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!HFUQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HFUQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png" width="446" height="297.43543956043953" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:446,&quot;bytes&quot;:3204924,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HFUQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!HFUQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!HFUQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!HFUQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc658e2b-7c0a-4f3c-8c5c-b39b4c033c6d_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The second one had an xG value of <code>0.06</code>. That means if an <em>average</em> player attempted that same free-kick 100 times from 27 yards out, only 6 would typically go in. Yet Rice nailed it.</p><p>(And don&#8217;t get me started on the fact that he&#8217;d taken just 9 free kick shots in his entire professional career before attempting those two against the reigning European champions.)</p><p>That&#8217;s the power&#8212;and <em>fun</em>&#8212;of xG. It highlights when something is truly out of the ordinary.</p><div><hr></div><h3><em>But Martin, how do we actually decide it&#8217;s 6%, not 5% or 4%?</em></h3><p>Glad you asked! xG providers (like Opta or StatsBomb) analyze hundreds of thousands of historical shots with similar conditions&#8212;<em>distance to goal, angle, body part, defensive pressure, pass type leading to the occasion,</em> position of the goalkeeper and more. Then they look at how often those shots were converted. And that&#8217;s basically it.</p><p>A few rules of thumb:</p><ul><li><p>Closer to goal &#8594; <strong>higher xG</strong></p></li><li><p>Wider shooting angle &#8594; <strong>lower xG</strong></p></li><li><p>Headers generally have <strong>lower xG</strong> than footed shots</p></li><li><p>Penalties are worth about <strong>0.79 xG</strong></p></li></ul><p>Different providers weigh these factors slightly differently, so you may notice small variations in xG values from one site to another (or as the famous saying goes &#8230; not all xG are created equal).</p><p>But, ultimately, xG shows how many goals an <em>average</em> team would be expected to score from those chances. It&#8217;s a measure of <strong>how good</strong> a shooting opportunity is, based on the historical likelihood that a similar shot ends in a goal.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.footballmarketreview.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2><strong>2 &#8212; The Big Misconception: No More Than 1 xG per Attack</strong></h2><p>So far, you&#8217;ve learned that data providers assign an xG value to each <em>shot</em>. But how do we get a team&#8217;s (or a player&#8217;s) <em>total xG</em> for a match?</p><h3><em><strong>But Martin, don&#8217;t we just add up all the xG?</strong></em></h3><p>You&#8217;d think so, but that can <em>overshoot</em> reality. Here&#8217;s the issue.</p><p>A team can&#8217;t score more than one goal in a single attacking sequence. Let&#8217;s say we have a striker who attempted two shots in the same attacking sequence:</p><ul><li><p>Shot #1: <code>0.45 xG</code> (one-on-one with the keeper)</p></li><li><p>Shot #2: <code>0.70 xG</code> (rebound from the first shot on an open net)</p></li></ul><p>If you just add them, you get <strong>1.15</strong>, implying the possibility of more than one goal in that same possession&#8212;<em>which is impossible</em>.</p><p>To avoid inflated totals, data providers calculate the probability of <strong>no goal</strong> happening, then subtract that value from 1:</p><ul><li><p>In our example, the chance of not scoring would be equal to = (1 - 0.45) &#215; (1 - 0.70) = 0.55 &#215; 0.30 = 0.165 meaning that there is a 16.5% chance of the attack not finishing with a goal.</p></li><li><p>And this leaves us with a 1 - 0.165 = 0.835 (83.5%) chance of the attack finishing with a goal.</p></li></ul><p>Likewise, a single player can&#8217;t rack up 1.15 xG from one continuous attack. The provider caps the total at <strong>0.835</strong> (83.5%) for that sequence.</p><p>So, individual shots can still have 0.45 and 0.70 xG, but <strong>match stats</strong> will show the possession&#8217;s combined xG as <strong>0.835</strong>.</p><p>Phew! I hope I did not lose you.</p><p>Long story short:</p><ul><li><p><strong>One shot</strong>? Use its xG &#8220;as is.&#8221;</p></li><li><p><strong>Team or player totals</strong>? Data providers adjust to ensure no single attacking possession exceeds <strong>1 xG</strong>.</p></li></ul><p>Plenty of fans&#8212;and even some professionals&#8212;overlook this nuance. But now <em>you</em> know better!</p><div><hr></div><h2>3 &#8212; xG&#8217;s blind spot</h2><p>Before I gush about the two ways xG changed football analytics, a quick reality check: <strong>xG isn&#8217;t perfect.</strong> It&#8217;s an <em>aggregate</em> measure&#8212;it doesn&#8217;t care <em>who</em> pulls the trigger or <em>how</em> the shot is struck.</p><p>xG rates the <strong>chance</strong>, not the <strong>shooter</strong>&#8212;a subtlety many people miss.</p><p>If the average conversion rate from a position is 30&#8239;%, that doesn&#8217;t mean <em>every</em> player finishes 30&#8239;% of the time. <strong>Gabriel&#8239;Jesus</strong> might tuck them away 20&#8239;% of the time, while <strong>Erling&#8239;Haaland</strong> buries 50&#8239;%.</p><p>And that&#8217;s the point: xG measures the <em>quality of the chance</em>, not the <em>quality of the player</em> on the end of it.</p><p>Still, fans and analysts love using the gap between <strong>Goals</strong> and <strong>xG</strong> as a finishing barometer. It&#8217;s handy&#8212;just easy to misread.</p><p>Remember, xG is assigned <em>before</em> contact. It shows how often a player <em>gets</em> into prime areas <strong>plus</strong> the historical finishing rate from those locations.</p><p>We&#8217;ll cover a sharper finishing metric&#8212;<strong>Expected Goals on Target (xGOT)</strong>&#8212;in a future issue. xGOT grades the strike <em>after</em> it leaves the boot. Until then, Goals&#8239;&#8722;&#8239;xG is fine&#8212;just know it blends chance quality <strong>and</strong> historical finishing.</p><div><hr></div><h2><strong>4 &#8212; Two Reasons xG Revolutionized How We Think About Football</strong></h2><h3><strong>(a) xG Tells a Fuller Story Than Goals Alone</strong></h3><p>Goals are rare and don&#8217;t always reflect who actually <em>controlled</em> a match. A team might play poorly yet score a couple of lucky goals and win 2&#8211;0, while another team might dominate every aspect but fail to find the net.</p><p>xG reveals how many <strong>dangerous chances</strong> a team generated (and allowed). For instance:</p><ul><li><p>A 2&#8211;0 win with an xG scoreline of <strong>2.5&#8211;0.7</strong> suggests the winning side not only finished well but also likely stifled the opponent.</p></li><li><p>A 2&#8211;0 win with an xG scoreline of <strong>0.7&#8211;2.5</strong> implies the hosts scored on minimal opportunities while the visitors simply couldn&#8217;t convert. Could be luck, poor finishing, or a brilliant goalkeeper.</p></li></ul><p>And because xG captures this deeper performance nuance, <em>it&#8217;s arguably (dare I say it) the most accurate predictor of future team (and player) success we currently have</em> (according to the data providers, not just me).</p><h3><em><strong>But wait, Martin&#8212;doesn&#8217;t game state matter?</strong></em></h3><p>What if a strong attacking team scores two early goals, then sits back to protect its lead in the last 15 minutes? That scenario could let the opponents rack up a bunch of late xG, even though the attacking team stayed in control.</p><p>Exactly. That&#8217;s why nobody should rely on xG (or any other metric for that matter) in isolation. Context matters, so it&#8217;s best paired with xG <em>match evolution</em> graphs (which we&#8217;ll create in future newsletters) or deeper contextual analysis.</p><p>And finally, let&#8217;s not forget that defensive teams can still rack up xG: Even if you &#8220;park the bus,&#8221; you might create high-value counterattacks against fewer defenders&#8212;sometimes resulting in a surprisingly high xG.</p><div><hr></div><h3><strong>(b) xG Separates Skill from Luck</strong></h3><p>The most common (early) critique of xG was: <em>&#8220;If the real scoreline doesn&#8217;t match the xG, then xG is pointless!&#8221;</em> But it&#8217;s actually the other way around: if the final score departs drastically from xG, that might indicate <strong>randomness</strong> or <strong>exceptional</strong> finishing/defending.</p><p>And that&#8217;s precisely why clubs like Brighton stuck with Graham Potter even during their disastrous (results-wise) 2020/21 season. The xG numbers showed they were creating&#8212;and conceding&#8212;chances at a level worthy of European qualification (as opposed to their <em>actual</em> 16th-place finish, just two spots above the relegation zone).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!azyt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!azyt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png 424w, https://substackcdn.com/image/fetch/$s_!azyt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png 848w, https://substackcdn.com/image/fetch/$s_!azyt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png 1272w, https://substackcdn.com/image/fetch/$s_!azyt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!azyt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png" width="1226" height="336" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:336,&quot;width&quot;:1226,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:101123,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!azyt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png 424w, https://substackcdn.com/image/fetch/$s_!azyt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png 848w, https://substackcdn.com/image/fetch/$s_!azyt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png 1272w, https://substackcdn.com/image/fetch/$s_!azyt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2287ad9-2ed0-4306-9da4-53574aaa462f_1226x336.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Over the <strong>long term</strong>, xG and actual goals tend to converge. Short-term luck&#8212;good or bad&#8212;can skew results for a while, but eventually, high-chance-creating teams <em>rise</em>, while those living on half-chances often <em>slide</em>.</p><p>And that&#8217;s exactly what happened with Brighton: by the 2022/23 season, the Seagulls finished 6th and earned a place in European football.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JGSB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JGSB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png 424w, https://substackcdn.com/image/fetch/$s_!JGSB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png 848w, https://substackcdn.com/image/fetch/$s_!JGSB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png 1272w, https://substackcdn.com/image/fetch/$s_!JGSB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JGSB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png" width="1224" height="296" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:296,&quot;width&quot;:1224,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84934,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JGSB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png 424w, https://substackcdn.com/image/fetch/$s_!JGSB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png 848w, https://substackcdn.com/image/fetch/$s_!JGSB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png 1272w, https://substackcdn.com/image/fetch/$s_!JGSB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b3a076e-4b80-4814-9d53-b9bf1573df02_1224x296.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Over time, xG and actual goals tend to converge. A freak week, month, or even half&#8209;season can bend the curve, but keep creating high&#8209;value chances (and limiting the opposition) and the scoreboard will eventually fall in line.</p><p><strong>In the long run:</strong></p><ul><li><p>Clubs that <strong>consistently outperform</strong> xG&#8212;Manchester&#8239;City, peak Liverpool&#8212;aren&#8217;t &#8220;lucky&#8221;; they own a repeatable edge the model can&#8217;t quite capture.</p></li><li><p>Teams that <strong>habitually underperform</strong> xG are usually paying for poor finishing, shaky defending, tactical flaws, or endless managerial roulette.</p></li></ul><p><em>Captain&#8239;Obvious, at your service.</em></p><p><strong>In the short run,</strong> though, you can dominate xG and still lose&#8212;and those are the matches pundits seize on to declare the stat &#8220;pointless.&#8221; Context is everything; one game is noise, a season is signal.</p><p>So, no, <strong>xG isn&#8217;t perfect</strong>, but it brings priceless <em>nuance</em> to any discussion of skill and luck. The problem isn&#8217;t that pundits misunderstand the metric; they misapply it.</p><p>Cue Jamie&#8239;Redknapp. After Newcastle thumped Crystal Palace 5&#8211;0, he scoffed at the Magpies&#8217; modest 1.39&#8211;2.0 xG and declared, &#8220;xG is nonsense.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YC8t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YC8t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png 424w, https://substackcdn.com/image/fetch/$s_!YC8t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png 848w, https://substackcdn.com/image/fetch/$s_!YC8t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!YC8t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YC8t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png" width="492" height="371.0274725274725" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1098,&quot;width&quot;:1456,&quot;resizeWidth&quot;:492,&quot;bytes&quot;:2166752,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YC8t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png 424w, https://substackcdn.com/image/fetch/$s_!YC8t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png 848w, https://substackcdn.com/image/fetch/$s_!YC8t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png 1272w, https://substackcdn.com/image/fetch/$s_!YC8t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbcf19c62-0958-485f-8809-16d95108a98f_2020x1524.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://www.skysports.com/football/video/12606/13350226/jamie-redknapp-was-bemused-by-newcastles-low-xg-against-crystal-palace">https://www.skysports.com/football/video/12606/13350226/jamie-redknapp-was-bemused-by-newcastles-low-xg-against-crystal-palace</a></p><h3>Why the score and xG diverged</h3><p>A big gap usually comes from one&#8212;or a mix&#8212;of three factors:</p><ol><li><p><strong>Clinical over&#8209;performance</strong> &#8212; Freakish finishing, goalkeeper howlers, or own goals (which carry zero xG).</p></li><li><p><strong>Cold under&#8209;performance</strong> &#8212; Fluffed sitters, heroic saves, or a missed penalty (~0.79&#8239;xG down the drain).</p></li><li><p><strong>Both of the above</strong> &#8212; One team red&#8209;hot, the other ice&#8209;cold.</p></li></ol><p>Against Palace, Newcastle hit the perfect storm:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4oGF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4oGF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png 424w, https://substackcdn.com/image/fetch/$s_!4oGF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png 848w, https://substackcdn.com/image/fetch/$s_!4oGF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png 1272w, https://substackcdn.com/image/fetch/$s_!4oGF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4oGF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png" width="484" height="134.1101243339254" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f347f8fe-0239-445d-ab41-5571e599423d_1126x312.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:312,&quot;width&quot;:1126,&quot;resizeWidth&quot;:484,&quot;bytes&quot;:52437,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4oGF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png 424w, https://substackcdn.com/image/fetch/$s_!4oGF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png 848w, https://substackcdn.com/image/fetch/$s_!4oGF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png 1272w, https://substackcdn.com/image/fetch/$s_!4oGF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff347f8fe-0239-445d-ab41-5571e599423d_1126x312.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That&#8217;s <strong>three goals from just 0.08&#8239;xG</strong>.</p><p>Meanwhile Palace&#8217;s best moment&#8212;a penalty worth ~0.79&#8239;xG&#8212;clattered wide, and Newcastle&#8217;s defence swatted away two other high&#8209;value shots.</p><p>So, Jamie, this wasn&#8217;t a straightforward 5&#8209;0 masterclass; it was a cocktail of wonder&#8209;strikes, an own goal, stout defending, and a blown spot&#8209;kick. xG lays the pattern bare, even if you missed the live broadcast. &#128522;</p><p>Enough theory&#8212;let&#8217;s grab some data. Here&#8217;s how to download current and historical xG numbers with just a few lines of Python.</p><div><hr></div><h2><strong>5 &#8212; How to Fetch xG Data Using Python</strong></h2><p>In this final section, you&#8217;ll learn how to download historical xG data from <a href="http://understat.com/">Understat.com</a> using just a few lines of Python code.</p><p>If you&#8217;re completely new to Python, the easiest way to get started is with <strong>Google Colab</strong>&#8212;a free, cloud-based service that lets you write and run Python code directly in your browser, no setup required.</p><ol><li><p>Go to <a href="https://colab.research.google.com/">https://colab.research.google.com</a> and sign in with your Google account.</p></li><li><p>In the Colab dashboard, click <strong>File</strong> in the top menu, then select <strong>New notebook</strong>.</p></li></ol><p>From there, you can type in the code I&#8217;m about to share, or simply download it from the link below.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.mediafire.com/file/lchpw28cpysbrcg/PFR_001_xG.ipynb/file&quot;,&quot;text&quot;:&quot;Grab the Free Python Code&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.mediafire.com/file/lchpw28cpysbrcg/PFR_001_xG.ipynb/file"><span>Grab the Free Python Code</span></a></p><p>Now, let&#8217;s see how to get your hands on xG data. We&#8217;ll use a Python library called <code>soccerdata</code> (created by <a href="https://x.com/p_robberechts">Pieter Robberechts</a>), which makes collecting valuable stats quick and easy. You can learn more about it <a href="https://soccerdata.readthedocs.io/en/latest/index.html">here</a>.</p><p>First, install the <code>soccerdata</code> package. Then import it alongside our data-wrangling library of choice, <code>polars</code>&#10084;&#65039;. Once that&#8217;s done, set your parameters. In the example below, we&#8217;re pulling xG data from the English Premier League for the current (as of writing) 2024/25 season.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n-em!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n-em!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png 424w, https://substackcdn.com/image/fetch/$s_!n-em!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png 848w, https://substackcdn.com/image/fetch/$s_!n-em!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png 1272w, https://substackcdn.com/image/fetch/$s_!n-em!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n-em!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png" width="523" height="200.97816593886463" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bc86a11c-8832-400f-bbda-f872aad56c19_916x352.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:352,&quot;width&quot;:916,&quot;resizeWidth&quot;:523,&quot;bytes&quot;:48428,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n-em!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png 424w, https://substackcdn.com/image/fetch/$s_!n-em!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png 848w, https://substackcdn.com/image/fetch/$s_!n-em!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png 1272w, https://substackcdn.com/image/fetch/$s_!n-em!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbc86a11c-8832-400f-bbda-f872aad56c19_916x352.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3><strong>Collecting Match-Level xG Data</strong></h3><p>Next, let&#8217;s move on to the actual data collection. Here&#8217;s how you can pull <strong>match-level xG</strong> information. In the snippet below, we grab data for every game in the current season, focusing on the home and away teams&#8217; goals as well as their respective xG figures. We also convert the resulting Pandas DataFrame into a Polars DataFrame to take advantage of Polars&#8217; exceptionally easy, plain&#8209;English expressions. (Stay tuned for a dedicated newsletter on this topic soon.)</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pata!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pata!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png 424w, https://substackcdn.com/image/fetch/$s_!pata!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png 848w, https://substackcdn.com/image/fetch/$s_!pata!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png 1272w, https://substackcdn.com/image/fetch/$s_!pata!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pata!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png" width="497" height="212.84326710816777" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:388,&quot;width&quot;:906,&quot;resizeWidth&quot;:497,&quot;bytes&quot;:63850,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pata!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png 424w, https://substackcdn.com/image/fetch/$s_!pata!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png 848w, https://substackcdn.com/image/fetch/$s_!pata!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png 1272w, https://substackcdn.com/image/fetch/$s_!pata!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84200e99-b6c7-4e00-966f-e953bb21bbcb_906x388.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Zo2Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png 424w, https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png 848w, https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png 1272w, https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png" width="604" height="150.58516483516485" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:363,&quot;width&quot;:1456,&quot;resizeWidth&quot;:604,&quot;bytes&quot;:111455,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png 424w, https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png 848w, https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png 1272w, https://substackcdn.com/image/fetch/$s_!Zo2Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F994f568f-3d0b-4ad9-8177-d0f3ad1dca50_1852x462.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3><strong>Collecting Player-Level Match xG</strong></h3><p>The code snippet below fetches data for each <strong>player&#8217;s xG performance</strong> on a match-by-match basis. Here, we&#8217;ve filtered the results to show <strong>Bukayo Saka</strong>. You can see that in his first match of the season against Wolves, he scored 1 goal from 5 shots, with a total xG of 0.52.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xhaa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xhaa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png 424w, https://substackcdn.com/image/fetch/$s_!xhaa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png 848w, https://substackcdn.com/image/fetch/$s_!xhaa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png 1272w, https://substackcdn.com/image/fetch/$s_!xhaa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xhaa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png" width="547" height="202.82022471910113" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:330,&quot;width&quot;:890,&quot;resizeWidth&quot;:547,&quot;bytes&quot;:68610,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xhaa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png 424w, https://substackcdn.com/image/fetch/$s_!xhaa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png 848w, https://substackcdn.com/image/fetch/$s_!xhaa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png 1272w, https://substackcdn.com/image/fetch/$s_!xhaa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9785d62e-fab2-494e-98f1-98311e0c2220_890x330.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lnUL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lnUL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png 424w, https://substackcdn.com/image/fetch/$s_!lnUL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png 848w, https://substackcdn.com/image/fetch/$s_!lnUL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png 1272w, https://substackcdn.com/image/fetch/$s_!lnUL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lnUL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png" width="558" height="157.51236263736263" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:411,&quot;width&quot;:1456,&quot;resizeWidth&quot;:558,&quot;bytes&quot;:104691,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lnUL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png 424w, https://substackcdn.com/image/fetch/$s_!lnUL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png 848w, https://substackcdn.com/image/fetch/$s_!lnUL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png 1272w, https://substackcdn.com/image/fetch/$s_!lnUL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9379020d-5bf3-41af-8cd4-87ec309165bf_1550x438.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3><strong>Collecting Player-Level Season xG</strong></h3><p>The following snippet retrieves each <strong>player&#8217;s cumulative xG</strong> over the entire season. In this example, we observe that, at the time of writing, Bukayo Saka has accumulated 6.18 xG across 19 matches, scoring 6 goals in total.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AfZt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AfZt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png 424w, https://substackcdn.com/image/fetch/$s_!AfZt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png 848w, https://substackcdn.com/image/fetch/$s_!AfZt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png 1272w, https://substackcdn.com/image/fetch/$s_!AfZt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AfZt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png" width="543" height="240.61848341232226" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:374,&quot;width&quot;:844,&quot;resizeWidth&quot;:543,&quot;bytes&quot;:77456,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AfZt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png 424w, https://substackcdn.com/image/fetch/$s_!AfZt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png 848w, https://substackcdn.com/image/fetch/$s_!AfZt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png 1272w, https://substackcdn.com/image/fetch/$s_!AfZt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92cdf050-1134-4907-80ba-47c3473e89d0_844x374.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CL9m!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CL9m!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png 424w, https://substackcdn.com/image/fetch/$s_!CL9m!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png 848w, https://substackcdn.com/image/fetch/$s_!CL9m!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png 1272w, https://substackcdn.com/image/fetch/$s_!CL9m!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CL9m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png" width="626" height="100.40589198036007" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:196,&quot;width&quot;:1222,&quot;resizeWidth&quot;:626,&quot;bytes&quot;:35034,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CL9m!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png 424w, https://substackcdn.com/image/fetch/$s_!CL9m!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png 848w, https://substackcdn.com/image/fetch/$s_!CL9m!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png 1272w, https://substackcdn.com/image/fetch/$s_!CL9m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0facb494-fde8-472e-81d3-430ea93940a4_1222x196.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3><strong>Collecting Player-Level Shots xG</strong></h3><p>Finally, here&#8217;s how to access <strong>shot-level data</strong> for a specific player. In the snippet below, each of Bukayo Saka&#8217;s attempts is listed with details like shot location, xG value, body part used, the situation (e.g., open play or set piece), and the outcome (goal, saved, or missed).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5kai!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5kai!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png 424w, https://substackcdn.com/image/fetch/$s_!5kai!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png 848w, https://substackcdn.com/image/fetch/$s_!5kai!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png 1272w, https://substackcdn.com/image/fetch/$s_!5kai!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5kai!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png" width="521" height="214.32822757111597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/02963937-9ac8-4b54-aa70-928d8014094e_914x376.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:376,&quot;width&quot;:914,&quot;resizeWidth&quot;:521,&quot;bytes&quot;:74442,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5kai!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png 424w, https://substackcdn.com/image/fetch/$s_!5kai!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png 848w, https://substackcdn.com/image/fetch/$s_!5kai!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png 1272w, https://substackcdn.com/image/fetch/$s_!5kai!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02963937-9ac8-4b54-aa70-928d8014094e_914x376.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8LHR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8LHR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png 424w, https://substackcdn.com/image/fetch/$s_!8LHR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png 848w, https://substackcdn.com/image/fetch/$s_!8LHR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png 1272w, https://substackcdn.com/image/fetch/$s_!8LHR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8LHR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png" width="1456" height="261" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:261,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:159832,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.pythonfootball.com/i/163528682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8LHR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png 424w, https://substackcdn.com/image/fetch/$s_!8LHR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png 848w, https://substackcdn.com/image/fetch/$s_!8LHR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png 1272w, https://substackcdn.com/image/fetch/$s_!8LHR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff85c8cb8-86dc-46ea-9feb-5c07881ad4c4_2452x440.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>It goes without saying that we&#8217;re only scratching the surface of what the <code>soccerdata</code> package can do&#8212;you can pull tons of other advanced metrics from it. But since this newsletter is already running long, I&#8217;ll let you explore the rest on your own.</p><p>Also note that you can access data going back to the <strong>2014/15</strong> season for all of Europe&#8217;s top five leagues by using these keys:</p><ul><li><p><code>'ENG-Premier League'</code></p></li><li><p><code>'ESP-La Liga'</code></p></li><li><p><code>'FRA-Ligue 1'</code></p></li><li><p><code>'GER-Bundesliga'</code></p></li><li><p><code>'ITA-Serie A'</code></p></li></ul><div><hr></div><p><strong>Boom! And that&#8217;s it for this first edition.</strong></p><p>If you found this newsletter helpful, please spread the word! You now know how xG is calculated, what it measures, why it matters, how to avoid the <em>&#8220;1.15 xG in one possession&#8221;</em> pitfall, and how to grab valuable xG data in seconds.</p><p>I&#8217;m still experimenting with the format of the newsletter, so your feedback is super welcome&#8212;would you prefer shorter content, longer deep dives, more Python, or more football concepts? Or does this format hit the mark?</p><p>My aim is to build a truly practical newsletter <em>together</em> with you.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.footballmarketreview.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"><em>Thanks for reading! Subscribe for free (if you haven&#8217;t already) to receive practical code and football deep-dives every Thursday.</em></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Until next week,</p><p><em><strong>Martin</strong></em></p><p><em><strong>The Python Football Review</strong></em></p><div><hr></div><p><em>P.S. If you enjoyed this newsletter and want to support it, please consider sharing it on Twitter or LinkedIn. I know it can feel like a chore (I usually hesitate too), so to say thanks, I&#8217;ll send you an <strong>exclusive extended Python notebook</strong> that downloads 10 seasons of xG data from Europe&#8217;s top five leagues&#8212;fully automated and wrangled into one dataset ready for analysis. Just send me an email at </em><code>martin@pythonfootball.com</code><em> once you&#8217;ve shared, and I&#8217;ll send it over. Cheers!</em></p>]]></content:encoded></item></channel></rss>