|
import streamlit as st |
|
import pandas as pd |
|
import numpy as np |
|
import plotly.express as px |
|
import datetime as dt |
|
|
|
|
|
st.set_page_config(layout="wide", page_icon="⚽", page_title="FPL Stats") |
|
st.title("⚽ FPL Lab") |
|
st.caption("A live dashboard of the top 200 Premiere League players across all positions. Metrics plotted include Cost, Points Earned, Form, Selection Rate, etc. Use the Position Analysis tab to pick cheap/high value players.") |
|
st.toast('Includes all data through W5', icon='⚽') |
|
|
|
|
|
|
|
df = pd.read_csv('week5_fpl.csv') |
|
df.fillna(0, inplace=True) |
|
pattern = r'(.+)\r\n(.{3})(.+)' |
|
df[['name', 'team', 'position']] = df['Player'].str.extract(pattern) |
|
df = df.rename(columns={'Seelection Rate': 'Selection Rate',}) |
|
df[['Cost (M)','Form','Points Earned']] = df[['Cost (M)','Form','Points Earned']].astype(float) |
|
df['P/C'] = df['Points Earned'] / df['Cost (M)'] |
|
df[['Status','Player','name','team','position']] = df[['Status','Player','name','team','position']].astype(str) |
|
df['Selection Rate'] = df['Selection Rate'].str.rstrip('%').astype('float') |
|
|
|
|
|
with st.sidebar: |
|
st.title("Player Search") |
|
options = st.multiselect( |
|
'Choose Position', |
|
['FWD','MID','DEF','GKP']) |
|
price = st.slider( |
|
"Pick a price range:", |
|
min_value=0, |
|
max_value=20, |
|
value=(0, 15)) |
|
st.write("Price Range: $",price) |
|
new_df = df[df['position'].isin(options)] |
|
new_df = new_df[(new_df['Cost (M)'] >= price[0]) & (new_df['Cost (M)'] <= price[1])] |
|
new_df = new_df.rename(columns={'Points Earned': 'Points',}) |
|
st.dataframe(new_df[['name','position','Points','Cost (M)','P/C']],hide_index=True) |
|
|
|
|
|
tab1, tab2,tab3 = st.tabs(["Position Analysis", "Total Metrics","Player Utility"]) |
|
with tab1: |
|
st.caption("These plots look at points earned and cost of the players. We want players closer to the bottom right of the graphs meaning they earn points but are cheap.") |
|
position_scatter_fig = px.scatter(df, y="Cost (M)", x="Points Earned", color="Form", template="plotly_dark", facet_col="position",hover_data=['name','team','position','Form']) |
|
position_scatter_fig.update_xaxes(showgrid=False,showline=False) |
|
position_scatter_fig.update_yaxes(showgrid=False) |
|
st.plotly_chart(position_scatter_fig, use_container_width=True) |
|
|
|
heatmap_fig = px.density_heatmap(df, x="Points Earned", y="Cost (M)",template="plotly_dark",facet_col="position") |
|
heatmap_fig.update_xaxes(showgrid=False,showline=False) |
|
heatmap_fig.update_yaxes(showgrid=False) |
|
st.plotly_chart(heatmap_fig, use_container_width=True) |
|
|
|
with tab2: |
|
st.caption("Here we have a consolidated scatter plot of the data on the other page, and a look at team point contributions ") |
|
summary_fig = px.scatter(df, x="Cost (M)", y="Points Earned", size="Selection Rate", color="Form",hover_data=['name','team','position','Form'], template="plotly_dark", title="Player Cost vs Points Earned (sized by selection rate and colored by form)",size_max=12) |
|
summary_fig.update_xaxes(showgrid=False,showline=False) |
|
summary_fig.update_yaxes(showgrid=False) |
|
st.plotly_chart(summary_fig, use_container_width=True) |
|
|
|
fig_bar = px.bar(df, x="team", y="Points Earned",template="plotly_dark", color='Cost (M)', title="Points Contributed and Cost by Team",hover_data=['name','team','position','Form']) |
|
fig_bar.update_layout(barmode='stack', xaxis={'categoryorder':'total descending'}) |
|
fig_bar.update_xaxes(showgrid=False,showline=False) |
|
fig_bar.update_yaxes(showgrid=False) |
|
st.plotly_chart(fig_bar, use_container_width=True) |
|
|
|
|
|
with tab3: |
|
st.caption("We introduce a new features here to measure player utility. This is calculated by dividing points earned by cost referred to as P/C. Outliers in these plots could indicate high utility players for your roster.") |
|
utility_scatter = px.scatter(df, x="Form", y="P/C", color="Cost (M)",hover_data=['name','team','position','Form'], template="plotly_dark", title="Player Utility vs Form, colored by cost",size_max=12) |
|
utility_scatter.update_xaxes(showgrid=False,showline=False) |
|
utility_scatter.update_yaxes(showgrid=False) |
|
st.plotly_chart(utility_scatter, use_container_width=True) |
|
|
|
utility_bar = px.violin(df, x="position", y="P/C", points='all', color='position',hover_data=['name','team','position','Form'], template="plotly_dark", title="Utility Distribution Across Positions") |
|
utility_bar.update_xaxes(showgrid=False,showline=False) |
|
utility_bar.update_yaxes(showgrid=False) |
|
st.plotly_chart(utility_bar, use_container_width=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|