| | 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) |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |