Getting Started 🗈
First we'll import the libraries we're going to use. When using Python, especially for data analysis in football, we mainly use libraries to import, manipulate and display data. The three libraries we're using are Pandas (which handles our data), Matplotlib (a data visualisation tool) and MPLSoccer (another data visualisation tool but specifically for football that is built "on top" of Matplotlib)
Next we import some fonts for the visualisation. We use Google fonts for this. Essentially what we're doing here is making a "call" to a font library via a URL and saying "hey, can we borrow these three fonts?"
Importing our data 💾
NOTE: I recommend using your own Deepnote dot com profile for this. It's free and easy to use!
First things first, upload your CSV file into your environment by going to Files on the left side panel and Upload File. This CSV is now stored and ready to use. You can have multiple CSV files and call them whenever you like. For example, you might have different seasons or saves. Just change the file name and off you go!
So this is where we start to use Pandas. The first step is to import the CSV into Python/Pandas. The site we're using here is called Deepnote. It's an IDE (integrated development environment). That's a fancy way of saying "a place I write code". I use this to run Python that isn't too bulky as I can share projects easily, I don't need to install anything on my system AND I can write notes/markup.
Anyway, what the syntax below is saying is "every time I write 'df' that means dataframe and I want you to reference that please".
df = pd.read_csv('fm.csv.') in plain English is...
our dataframe is... Pandas read the CSV called fm.csv. You can change the file name to your uploaded file in the "". (this is a string and you'll be see a lot of them in the syntax. A string is basically just text that is passed into our code.)
Finally, if you see a # in the code that means it's a comment and is where I'll occasionally explain things.
Maths & stuff 🧮
(Editors Note: Coding people, I know this isn't the pretty piece of code and could probably be written in a way better manner. Hit me up with some feedback! Right now, I've adopted the "if it fits it sits" philosophy)
Below is where we do a bit of filtering and calculate our percentiles. You can do this step in Excel and just import the clean data straight into the visualisation but this is here to make everything easier and repeatable. With this you can plug in a CSV, select a couple of columns, filter by position and Bob's your Uncle.
If you want to change the columns you select make sure you keep the "". That tells Python that this is a string (text) and the text matches what is in the CSV. I'd recommend you make column title changes before you upload as it makes things easier. If you want a column to be called xG for example, make sure it's called xG in the CSV file. If you want to change positions you need to edit the string where it says "D" or "M" or "ST", etc.
TLDR; the bit's you can edit are highlighted below.
columns = ["Int/90", "Pres A/90", "Ch C/90", "OP0KP/90", "K Ps/90", "Pr passes/90", "xA/90", "Asts/90","xG/90", "NP0xG/90"] - edit columns in here. Don't forget the "" and , in between. This passes a string in the quotations and the , separates the strings out and tells Python that another string is coming. When you close out the ], the final string does not need a , as it's the end of the columns you're inputting.
new_df = df[df["Position"].str.contains("AM ", case=False, na=False)].copy() - as stated above ONLY change where it currently says AM to whatever position you would like. Right now it's limited to "GK", "D", "WB", "M" or "ST" due to the way Football Manager uses very annoying ( ) as separators. This piece of syntax is taking the old dataframe and filters the Position column so it only includes that particular position. We then do the percentile calculation, add back in some columns and tie all of it together in a nice new ranked and filtered dataframe.
Baking our pizza 🍕
It's worth noting I've used pretty much the default pizza chart from the MPLSoccer documentation which can be found here and just made it a little prettier https://mplsoccer.readthedocs.io/en/latest/gallery/pizza_plots/plot_pizza_basic.html
I'm not going to break down every line of code here but I will put the bits you can edit/that are important
selected_row = new_df[new_df["Name"] == "Xherdan Shaqiri"] - edit the string that has Shaqiri in. This is the player you're selecting from the name column. So if you wanna select Wayne Rooney put "Wayne Rooney". Bonus computer science fact; this == operator is called the equality operator and means "equal to *thing* and only this *thing*"
params = ["Int/90", "Pres A/90", "Ch C/90", "OP0KP/90", "K Ps/90", "Pr passes/90", "xA/90", "Asts/90","xG/90", "NP0xG/90"] - these are our parameters for the pizza chart. These MUST be identical to the columns we selected above otherwise they won't match up.
Anywhere there's a hex code, for example "#52107A" - you can change any of the colours used in the graphic. Experiment! Please note though on slice_colors, the numbers following the hex code need to match up to the total amount of the parameters. So in my example there is a total of 10 and they're divided up into 2, 6 and 2 to highlight defensive, passing/creative and goal scoring actions. After that, the number following the text_colors must be the total amount of slices once again. If this is wrong you will get an error.
fig.text - these are all the additional bits of text on the chart. I would recommend leaving font size the same due to spacing reasons but again, feel free to change (stuff in "" remember!) what's written and experiment!
plt.savefig('xherdan_shaqiri_plot.png', format='png') - finally, this bit of code saves your chart as a file. You can change it to an SVG for example as well as it's name. If you're using Deepnote the saved file will appear in 'Files' on the left where you can download it. Alternatively, you can right click on the image at the bottom and save it that way.
(Editors Note: I'm still newish to Matplotlib so again, any feedback let me know, especially if you know your way around annotations)