fpl / app.py
ritwikbiswas's picture
Create app.py
3308a7e
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import datetime as dt
#### TITLE/PAGE
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='⚽')
#### DATA PROCESSING
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')
#### SIDEBAR
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)
#### TABS
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) #text="name",
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']) #color_continuous_scale='YlOrRd'
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) #text="name",
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") #text="name",
utility_bar.update_xaxes(showgrid=False,showline=False)
utility_bar.update_yaxes(showgrid=False)
st.plotly_chart(utility_bar, use_container_width=True)