Compare commits

..

No commits in common. "master" and "4cbed48308a79b09027fa7022fe7f84d00633ae1" have entirely different histories.

29 changed files with 38861 additions and 320629 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
.RData

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
# Aplikacja `CoachStats` # Analiza piłkarska z aplikacją `CoachStats`
## Wstęp ## Wstęp
@ -9,18 +9,21 @@ CoachStats to innowacyjne narzędzie służące do analizowania statystyk Expect
- **Analiza XG:** Analiza XG dla danej sytuacji meczowej. - **Analiza XG:** Analiza XG dla danej sytuacji meczowej.
- **Personalizowana makieta:** Możliwość tworzenia własnej makiety odpowiadającej sytuacji meczowej. - **Personalizowana makieta:** Możliwość tworzenia własnej makiety odpowiadającej sytuacji meczowej.
## Uruchomienie ## Technologie
Aby uruchomić aktualną wersję aplikacji, wykonaj następujące kroki: ## Instalacja i Uruchomienie
1. **Uruchomienie serwera:** Aby uruchomić serwer należy wejść w [link](https://sg-server-ne4h.onrender.com/) oraz zaczekać do pojawienia się komunikatu o błędzie 404. Aplikacja korzysta z darmowej wersji obsługi serwera, stąd sposób jego uruchomienia nie jest standardowy. Aby uruchomić beta wersję aplikacji, wykonaj następujące kroki:
2. **Uruchomienie aplikacji webowej** Po wykonaiu kroku 1 można wejść na właściwą stronę [aplikacji](https://statgoals.onrender.com/). 1. **Uruchomienie Klienta:**
Otwórz terminal w folderze `app` i uruchom następującą komendę:\
`npm run dev`
2. **Uruchomienie Serwera Flask:**
W innym terminalu, przejdź do folderu `app/src/flask-server` i uruchom serwer Flask przy użyciu poniższej komendy:\
`python server.py`
## Dane ## Dane
- <https://statsbomb.com/what-we-do/soccer-data/> - <https://statsbomb.com/what-we-do/soccer-data/>
## Szczegóły
Działanie aplikacji zostało opisane w podręczniku użytkownika znajdującym się w drzewie plików na repozytorium. Poza tym odsyłam do [repozytorium](https://git.wmi.amu.edu.pl/s478993/fantastyczne_gole) uniwersytetu na którym powstała aplikacja. Zawiera ono kod źródłowy aplikacji.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

View File

@ -5,49 +5,11 @@ import { Link } from "react-router-dom";
const Hero = () => { const Hero = () => {
const [isOpen, setIsOpen] = useState(false);
const [gameMinute, setGameMinute] = useState(''); const [gameMinute, setGameMinute] = useState('');
const [firstShot, setfirstShot] = useState(0); const toggleDropdown = () => setIsOpen(!isOpen);
const [oneOnOne, SetoneOnOne] = useState(0); const handleMinuteChange = (e) => setGameMinute(e.target.value);
const [afterAirDuel, SetafterAirDuele] = useState(0);
const [openGoal, SetOpenGoal] = useState(0);
const [afterDribbling, SetafterDribbling] = useState(0);
const [redirect, SetRedirect] = useState(0);
const handleMinuteChange = (e) => { setGameMinute(e.target.value);
//sentQuestion();
}
const handleFirstShotChange = (event) => {
setfirstShot(event.target.checked);
//sentQuestion();
};
const handleOneOnOneChange = (event) => {
SetoneOnOne(event.target.checked);
//sentQuestion();
};
const handleAfterAirDuelChange = (event) => {
SetafterAirDuele(event.target.checked);
//sentQuestion();
};
const handleOpenGoalChange = (event) => {
SetOpenGoal(event.target.checked);
//sentQuestion();
};
const handleAfterDribblingChange = (event) => {
SetafterDribbling(event.target.checked);
//sentQuestion();
};
const handleRedirectChange = (event) => {
SetRedirect(event.target.checked);
//sentQuestion();
};
const [data, setData] = useState(""); const [data, setData] = useState("");
//zmienne globalne //zmienne globalne
@ -55,24 +17,10 @@ const handleRedirectChange = (event) => {
//przez listener nanoszący zawodników na boisko. 1 - strzelec , 2 - bramkarz , 3 - obronca, 4 - napasnik. zmienna przez aktywacje przycskówk bb1, bb2, bb3 i bb4 //przez listener nanoszący zawodników na boisko. 1 - strzelec , 2 - bramkarz , 3 - obronca, 4 - napasnik. zmienna przez aktywacje przycskówk bb1, bb2, bb3 i bb4
let active_bbt = "bbt1"; let active_bbt = "bbt1";
const [number_of_defenders, setNumberOfDevenders] = useState(()=>{ const [number_of_defenders, setNumberOfDevenders] = useState(0);
return 0; const [number_of_strikers, setNumberOfStrikers] = useState(0)
}); const [number_of_goalkeepers, setNumberOfGoalkeppers] = useState(0);
const [number_of_shooters,setNumberOfShooters] = useState(0);
const [number_of_strikers, setNumberOfStrikers] = useState(() => {
return 0;
})
const [number_of_goalkeepers, setNumberOfGoalkeppers] = useState(()=>{
return 0;
});
const [number_of_shooters,setNumberOfShooters] = useState(() => {
return 0}
);
const number_of_shooters_rev = React.useRef(number_of_shooters)
const number_of_strikers_rev = React.useRef(number_of_strikers)
const number_of_goalkeepers_rev = React.useRef(number_of_goalkeepers)
const number_of_defenders_rev = React.useRef(number_of_defenders)
// zmienne globalne bedace danymi wejsciowymi do modelu // zmienne globalne bedace danymi wejsciowymi do modelu
@ -82,10 +30,10 @@ const handleRedirectChange = (event) => {
var stricers = new Array; var stricers = new Array;
var defenders = new Array; var defenders = new Array;
const [bodyPart,setBodyPart] = useState('Right Foot'); const [bodyPart,setBodyPart] = useState('prawa');
const [technique,setTechnique] = useState('Normal'); const [technique,setTechnique] = useState('zwykly');
const [actionType,setActionType] = useState('Open Play'); const [actionType,setActionType] = useState('pozycyjny');
const [shooterPossition,setPossition] = useState('Center Forward'); const [shooterPossition,setPossition] = useState('napastnik');
//zamiana procentowych pozycji na kartezyjskie //zamiana procentowych pozycji na kartezyjskie
function konwerturX(x){ function konwerturX(x){
@ -109,6 +57,7 @@ const handleRedirectChange = (event) => {
// Reset Boiska // Reset Boiska
function resetField() { function resetField() {
var footballField = document.getElementById('footballField'); var footballField = document.getElementById('footballField');
var footballs = document.querySelectorAll('.football'); var footballs = document.querySelectorAll('.football');
var list = document.getElementById('list') var list = document.getElementById('list')
@ -120,20 +69,13 @@ const handleRedirectChange = (event) => {
players.forEach(function(element) { players.forEach(function(element) {
list.removeChild(element); list.removeChild(element);
}) })
setNumberOfDevenders(0); setNumberOfDevenders(0);
setNumberOfStrikers(0) setNumberOfStrikers(0)
setNumberOfGoalkeppers(0) setNumberOfGoalkeppers(0)
setNumberOfShooters(0) setNumberOfShooters(0)
setGameMinute('')
number_of_shooters_rev.current = 0;
number_of_goalkeepers_rev.current = 0;
number_of_defenders_rev.current = 0;
number_of_strikers_rev.current = 0;
document.getElementById("ex").innerHTML = 0;
} }
//funkcja dodaje zawodnika do listy zawodnikow. zmienne x oraz y to wspolrzedne a position //funkcja dodaje zawodnika do listy zawodnikow. zmienne x oraz y to wspolrzedne a position
// to pozycja zawodnika 0 - strzelec, 1 - bramkarz, 2 - broniacy, 3 napastnik // to pozycja zawodnika 0 - strzelec, 1 - bramkarz, 2 - broniacy, 3 napastnik
// ball - to odnosnik do punktu na boisku // ball - to odnosnik do punktu na boisku
@ -144,15 +86,14 @@ const handleRedirectChange = (event) => {
list.removeChild(player) list.removeChild(player)
bojo.removeChild(ball) bojo.removeChild(ball)
if(possition == 1){ if(possition == 1){
setNumberOfGoalkeppers(number_of_goalkeepers_rev.current -= 1); setNumberOfGoalkeppers(0)
}else if(possition == 2){ }else if(possition == 2){
setNumberOfDevenders(number_of_defenders_rev.current -= 1) ; setNumberOfDevenders(number_of_defenders-1) ;
}else if (possition == 3){ }else if (possition == 3){
setNumberOfStrikers(number_of_strikers_rev.current -= 1); setNumberOfStrikers(number_of_strikers-1) ;
}else if(possition == 0){ }else if(possition == 0){
setNumberOfShooters(number_of_shooters_rev.current -= 1); setNumberOfShooters(0)
} }
//sentQuestion()
} }
// funkcja zsczytuje pozycje zawodnikow przed wyslaniem zapytania do serwera // funkcja zsczytuje pozycje zawodnikow przed wyslaniem zapytania do serwera
@ -186,22 +127,19 @@ const handleRedirectChange = (event) => {
var pName = "Strzelec" var pName = "Strzelec"
//kolor kropki //kolor kropki
// kolor tła kafelka // kolor tła kafelka
var pColor = "#fc0303" var pColor = "#fc0303"
if(possition == 1){ if(possition == 1){
var pName = "Bramkarz" var pName = "Bramkarz"
var pColor = "#03e7fc" var pColor = "#03e7fc"
setNumberOfGoalkeppers(number_of_goalkeepers_rev.current += 1);
}else if(possition == 2){ }else if(possition == 2){
var pName = "Obrońca" var pName = "Obrońca"
var pColor = "#0324fc" var pColor = "#0324fc"
setNumberOfDevenders(number_of_defenders_rev.current += 1);
}else if (possition ==3){ }else if (possition ==3){
var pName = "Napastnik" var pName = "Napastnik"
var pColor = "#fc6703" var pColor = "#fc6703"
setNumberOfStrikers(number_of_strikers_rev.current += 1);
}else{
setNumberOfShooters(number_of_shooters_rev.current += 1);
} }
var player = document.createElement('div'); var player = document.createElement('div');
player.className = 'player'; player.className = 'player';
player.style.width = "inherit" player.style.width = "inherit"
@ -210,18 +148,18 @@ const handleRedirectChange = (event) => {
// div z nazwa gracza // div z nazwa gracza
var tekst = document.createElement('div') var tekst = document.createElement('div')
tekst.style.fontSize = "12px"; tekst.style.fontSize = "10px";
tekst.innerHTML = pName; tekst.innerHTML = pName;
// div z pozycja gracza // div z pozycja gracza
var posytion = document.createElement('div') var posytion = document.createElement('div')
posytion.style.fontSize = "12px" posytion.style.fontSize = "10px"
posytion.innerHTML = konwerturX(ball.style.left) + " m, " + konwetujY(ball.style.top) + " m"; posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m";
player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)]) player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)])
//div z przyciskiem usuwającym //div z przyciskiem usuwającym
var btnDelete = document.createElement('button') var btnDelete = document.createElement('button')
btnDelete.innerHTML = 'Usuń' btnDelete.innerHTML = 'Usun'
btnDelete.style.fontSize = "12px" btnDelete.style.fontSize = "10px"
btnDelete.style = 'background-color: #FFB266;color:#000000' btnDelete.style = 'background-color: #FFB266;color:#000000'
btnDelete.addEventListener("click",function(){deletePlayer(ball,player,possition)},false) btnDelete.addEventListener("click",function(){deletePlayer(ball,player,possition)},false)
//dodanie elementów do kafelka //dodanie elementów do kafelka
@ -271,8 +209,8 @@ const handleRedirectChange = (event) => {
tekst.style.color = "white" tekst.style.color = "white"
posytion.style.color = "white" posytion.style.color = "white"
x = parseFloat(x) -3 x = parseFloat(x) -2
y = parseFloat(y) -3 y = parseFloat(y) -2
if(bojo.parentNode.querySelector(":hover")){ if(bojo.parentNode.querySelector(":hover")){
ball.style.left = x + "%" ball.style.left = x + "%"
@ -282,28 +220,25 @@ const handleRedirectChange = (event) => {
//var shooterY = konwetujY(ball.style.top) //var shooterY = konwetujY(ball.style.top)
posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m"; posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m";
player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)]); player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)]);
bojo.addEventListener("mouseup", function afterUp(){ bojo.addEventListener("mouseup", function(){
ball.style.background = pColor ball.style.background = pColor
bojo.removeEventListener("mousemove", whileMove) bojo.removeEventListener("mousemove", whileMove)
bojo.removeEventListener("mouseup", afterUp)
}) })
})
bojo.addEventListener("mouseup", function reload(){ })
//sentQuestion();
bojo.removeEventListener("mouseup",reload)
})
}) })
//sentQuestion();
} }
// // Wyłanie zapytania do serwera // // Wyłanie zapytania do serwera
function sentQuestion() { function sentQuestion() {
///Dziwny Blad ///Dziwny Blad
loadPlayers() loadPlayers()
if (number_of_shooters_rev.current == 1) { if (number_of_shooters == 1) {
//console.log('Wysyłanie wartości: ', bodyPart, technique, actionType, shooterPossition, gameMinute, firstShot);
// Użyj backticksów zamiast zwykłych cudzysłowów // Użyj backticksów zamiast zwykłych cudzysłowów
fetch(`http://127.0.0.1:5000/get_model?shooter=${shooter}&goalkeeper=${goalkeeper}&defenders=${defenders}&strickers=${stricers}&bodyPart=${bodyPart}&technique=${technique}&actionType=${actionType}&shooterPossition=${shooterPossition}&gameMinute=${gameMinute}&shot_first_time=${firstShot}&shot_one_on_one=${oneOnOne}&shot_aerial_won=${afterAirDuel}&shot_open_goal=${openGoal}&shot_follows_dribble=${afterDribbling}&shot_redirect=${redirect}`).then( fetch(`http://127.0.0.1:5000/get_model?shooter=${shooter}&goalkeeper=${goalkeeper}&defenders=${defenders}&strickers=${stricers}&bodyPart=${bodyPart}&technique=${technique}&actionType=${actionType}&shooterPossition=${shooterPossition}`).then(
res => res.json() res => res.json()
).then( ).then(
data => { data => {
@ -311,8 +246,7 @@ const handleRedirectChange = (event) => {
console.log(data); console.log(data);
// Przenieś tę linię do środka bloku .then(), aby uniknąć błędów // Przenieś tę linię do środka bloku .then(), aby uniknąć błędów
let eX = data.response; let eX = data.response;
document.getElementById("ex").innerHTML = eX; document.getElementById("ex").innerHTML = "Współczynnik xG: " + eX;
//updateXGMeter(eX);
} }
).catch(error => { ).catch(error => {
console.error('Błąd:', error); console.error('Błąd:', error);
@ -320,9 +254,10 @@ const handleRedirectChange = (event) => {
} else { } else {
alert('Piłka nie jest obecnie na boisku.'); alert('Piłka nie jest obecnie na boisku.');
} }
} }
/* Funkcja dodająca listener do boiska*/ /* Funkcja dodająca listener do boiska*/
@ -341,32 +276,38 @@ const handleRedirectChange = (event) => {
ball.style.top = y + "%" ball.style.top = y + "%"
//dodanie zawodnika do listy oraz punktu do mapy w zaleznosci od aktywnosci przycisku 1,2,3 lub 4 //dodanie zawodnika do listy oraz punktu do mapy w zaleznosci od aktywnosci przycisku 1,2,3 lub 4
if(active_bbt=="bbt1"){ if(active_bbt=="bbt1"){
if(number_of_shooters_rev.current < 1 ){ if(number_of_shooters < 1 ){
addPlayer(0,ball) addPlayer(0,ball)
bojo.appendChild(ball) bojo.appendChild(ball)
ball.style.background = "#fc0303" ball.style.background = "#fc0303"
setNumberOfShooters(number_of_shooters+1)
}else{alert("mozesz dodac tylko jednego strzelca")} }else{alert("mozesz dodac tylko jednego strzelca")}
}else if(active_bbt == "bbt2"){ }else if(active_bbt == "bbt2"){
if ( number_of_goalkeepers_rev.current < 1){
if ( number_of_goalkeepers < 1){
addPlayer(1,ball) addPlayer(1,ball)
bojo.appendChild(ball) bojo.appendChild(ball)
ball.style.background = "#03e7fc" ball.style.background = "#03e7fc"
setNumberOfGoalkeppers(number_of_goalkeepers+1)
}else{alert("mozesz dodac tylko jednego bramkarza")} }else{alert("mozesz dodac tylko jednego bramkarza")}
}else if(active_bbt == "bbt3"){ }else if(active_bbt == "bbt3"){
if(number_of_defenders_rev.current < 10){ if(number_of_defenders <= 10){
addPlayer(2,ball); addPlayer(2,ball);
setNumberOfDevenders(number_of_defenders+1)
bojo.appendChild(ball) bojo.appendChild(ball)
ball.style.background = "#0324fc" ball.style.background = "#0324fc"
}else{alert("maksymalna liczba obroncow")} }else{alert("maksymalna liczba obroncow")}
}else if(active_bbt == "bbt4"){ }else if(active_bbt == "bbt4"){
if(number_of_strikers_rev.current < 10){ if(number_of_strikers <= 10){
addPlayer(3,ball); addPlayer(3,ball);
setNumberOfStrikers(number_of_strikers+1);
bojo.appendChild(ball) bojo.appendChild(ball)
ball.style.background = "#fc6703" ball.style.background = "#fc6703"
}else{alert("maksymalna liczba napastnikow")} }else{alert("maksymalna liczba napastnikow")}
} }
} }
// funkcja działą po utworzeniu komponentów, dodaje listenry do elementów // funkcja działą po utworzeniu komponentów, dodaje listenry do elementów
@ -395,18 +336,16 @@ const handleRedirectChange = (event) => {
<div className="container"> <div className="container">
{/* Listy zwijane */} {/* Listy zwijane */}
<div className="top-bar" id = "top-bar"> <div className="top-bar">
<form className="dropdown" id = "bodyPartList"> <form className="dropdown" id = "bodyPartList">
<select className="dropbtn" <select className="dropbtn"
onChange={event => {setBodyPart(event.target.value); onChange={event => setBodyPart(event.target.value)}
//sentQuestion()
}}
defaultValue={bodyPart}> defaultValue={bodyPart}>
<option value = "Right Foot">Noga Prawa</option> <option value = "prawa">Noga Prawa</option>
<option value = "Left Foot">Noga Lewa</option> <option value = "lewa">Noga Lewa</option>
<option value = "Head">Głowa</option> <option value = "glowa">Głowa</option>
<option value = "Other" >Inna</option> <option value = "inna" >Inna</option>
</select> </select>
</form> </form>
@ -414,62 +353,37 @@ const handleRedirectChange = (event) => {
<form className="dropdown" id = "shootTypeList"> <form className="dropdown" id = "shootTypeList">
<select className="dropbtn" onChange={event => {setTechnique(event.target.value); <select className="dropbtn" onChange={event => setTechnique(event.target.value)}
//sentQuestion()
}}
defaultValue = {technique}> defaultValue = {technique}>
<option value="Normal"> Zwykły </option> <option value="zwykly"> Zwykły </option>
<option value = "Volley"> Wolej </option> <option value = "voley"> Wolej </option>
<option value = "Half Volley"> Półwolej </option> <option value = "pol-voley"> Półwolej </option>
<option value = "Lob"> Lob </option> <option value = "lob"> Lob </option>
<option value = "Diving Header"> Szczupak </option> <option value = "szczupak"> Szczupak </option>
<option value = "Overhead Kick"> Kopnięcie z góry </option> <option value = "z_gory"> Kopnięcie z góry </option>
<option value = "Backheel"> Piętka </option> <option value = "pietka"> Piętka </option>
</select> </select>
</form> </form>
<form className="dropdown" id = "actionTypeList" onChange={event => {setActionType(event.target.value); <form className="dropdown" id = "actionTypeList" onChange={event => setActionType(event.target.value)}
//sentQuestion()
}}
defaultValue={technique}> defaultValue={technique}>
<select className="dropbtn"> <select className="dropbtn">
<option value = "Open Play"> Atak Pozycyjny </option> <option value = "pozycyjny"> Atak Pozycyjny </option>
<option value = "Free Kick"> Rzut Wolny </option> <option value = "wolny"> Rzut Wolny </option>
<option value = "Penalty"> Rzut Karny </option> <option value = "karny"> Rzut Karny </option>
<option value= "Corner"> Rzut Rozny </option> <option value= "rozny"> Rzut Rozny </option>
<option value="rozpoczecie"> Rozpoczęcie </option>
</select> </select>
</form> </form>
<form className="dropdown" id = "possitionList" <form className="dropdown" id = "possitionList"
onChange={event => {setPossition(event.target.value); onChange={event => setPossition(event.target.value)}
//sentQuestion()
}}
defaultValue={shooterPossition}> defaultValue={shooterPossition}>
<select className="dropbtn"> <select className="dropbtn">
<option value="Right Center Forward">Prawy Środkowy Napastnik</option> <option value= "napastnik" > Napastnik </option>
<option value="Left Center Forward">Lewy Środkowy Napastnik</option> <option value = "bramkarz"> Bramkarz </option>
<option value="Secondary Striker">Drugi Napastnik</option> <option value = "obronca"> Obrońca </option>
<option value="Center Forward">Środkowy Napastnik</option> <option value = "pomocnik"> Pomocnik </option>
<option value="Center Midfield">Środkowy Pomocnik</option>
<option value="Left Center Midfield">Lewy Środkowy Pomocnik</option>
<option value="Right Center Midfield">Prawy Środkowy Pomocnik</option>
<option value="Left Midfield">Lewy Pomocnik</option>
<option value="Center Attacking Midfield">Środkowy Ofensywny Pomocnik</option>
<option value="Left Defensive Midfield">Lewy Defensywny Pomocnik</option>
<option value="Left Attacking Midfield">Lewy Ofensywny Pomocnik</option>
<option value="Right Attacking Midfield">Prawy Ofensywny Pomocnik</option>
<option value="Right Defensive Midfield">Prawy Defensywny Pomocnik</option>
<option value="Center Defensive Midfield">Środkowy Defensywny Pomocnik</option>
<option value="Right Midfield">Prawy Pomocnik</option>
<option value="Left Wing Back">Lewy Pomocnik Skrzydłowy</option>
<option value="Left Wing">Lewe Skrzydło</option>
<option value="Right Wing">Prawe Skrzydło</option>
<option value="Right Wing Back">Prawy Pomocnik Skrzydłowy</option>
<option value="Center Back">Środkowy Obrońca</option>
<option value="Left Center Back">Lewy Środkowy Obrońca</option>
<option value="Right Center Back">Prawy Środkowy Obrońca</option>
<option value="Right Back">Prawy Obrońca</option>
<option value="Left Back">Lewy Obrońca</option>
<option value="Goalkeeper">Bramkarz</option>
</select> </select>
</form> </form>
@ -495,40 +409,25 @@ const handleRedirectChange = (event) => {
<div className="field-pic"></div> <div className="field-pic"></div>
</div> </div>
<div className="rightMenu">
<div className="xg-meter">
<b id="ex" className="xg-value">0</b>
</div> </div>
<div className="additional-parameters">
<h3>Parametry strzału</h3> {/* <div className="ChoosingPlayer">
<label> <button className="cho-one_on_one" id = "bbt8">Sam na sam</button>
<input type="checkbox" id="firstShot" onChange={handleFirstShotChange} /> </div>
Pierwszy w meczu <div className="ChoosingPlayer">
</label> <button className="cho-first_time" id = "bbt12">Pierwszy w meczu</button>
<label> </div>
<input type="checkbox" id="oneOnOne" onChange={handleOneOnOneChange} /> <div className="ChoosingPlayer">
Akcja sam na sam <button className="cho-aerial_won" id = "bbt13">Pojedynek powietrzny</button>
</label> </div>
<label> <div className="ChoosingPlayer">
<input type="checkbox" id="afterAirDuel" onChange={handleAfterAirDuelChange} /> <button className="cho-follows_dribble" id = "bbt14">Drybling</button>
Po pojedynku powietrznym </div>
</label> <div className="ChoosingPlayer">
<label> <button className="cho-redirect" id = "bbt15">Rykoszet</button>
<input type="checkbox" id="openGoal" onChange={handleOpenGoalChange} /> </div> */}
Na pustą bramkę
</label>
<label>
<input type="checkbox" id="afterDribbling" onChange={handleAfterDribblingChange} />
Poprzedzony dryblingiem
</label>
<label>
<input type="checkbox" id="redirect" onChange={handleRedirectChange} />
Rykoszet
</label>
</div>
</div>
</div>
<div className="bottom-bar"> <div className="bottom-bar">
<button className="cho-shooter" id = "bbt1">Strzelec</button> <button className="cho-shooter" id = "bbt1">Strzelec</button>
@ -538,8 +437,13 @@ const handleRedirectChange = (event) => {
<button className="reset-button" onClick={resetField}>Reset</button> <button className="reset-button" onClick={resetField}>Reset</button>
<button className="info-button" onClick={sentQuestion}>xG</button> <button className="info-button" onClick={sentQuestion}>xG</button>
</div> </div>
<div>
<b id = "ex" className="Ex">
</b>
</div> </div>
</div> </div>
</div>
); );
}; };

View File

@ -3,7 +3,6 @@ import React from 'react'
const Loader = () => { const Loader = () => {
return ( return (
<div>Loader</div> <div>Loader</div>
) )
} }

View File

@ -2,157 +2,105 @@ from joblib import load
import pandas as pd import pandas as pd
from math import sqrt from math import sqrt
import math import math
import numpy as np
import xgboost
from sklearn.preprocessing import OrdinalEncoder
# Funkcja zwraca prawdopodobieństwo zdobycia gola # Funkcja zwraca prawdopodobieństwo zdobycia gola
def LogisticRegression_predict_proba(position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead): def LogisticRegression_predict_proba(position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead):
# distance_to_goalM = sqrt(( (position_x**2) + (position_y**2)))
# distance_to_goalM = sqrt(( (position_x**2) + (position_y**2)))
model = load('regresja_logistyczna.joblib') model = load('regresja_logistyczna.joblib')
X_new = pd.DataFrame(columns=['position_x', 'position_y', 'distance_to_goalM', 'angle','match_minute', 'Number_Intervening_Opponents','Number_Intervening_Teammates', 'isFoot', 'isHead']) X_new = pd.DataFrame(columns=['position_x', 'position_y', 'distance_to_goalM', 'angle','match_minute', 'Number_Intervening_Opponents','Number_Intervening_Teammates', 'isFoot', 'isHead'])
X_new.loc[len(X_new.index)] = [position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead] X_new.loc[len(X_new.index)] = [position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead]
return model.predict_proba(X_new)[0][1].round(2) return model.predict_proba(X_new)[0][1].round(2)
#xgBoost #xgBoost
def xgboost_predict_proba(minute=0, position_name='Center Forward', shot_body_part_name='Right Foot', def xgboost_predict_proba(minute, position_name, shot_body_part_name, shot_technique_name,
shot_technique_name='Normal', shot_type_name='Open Play', shot_first_time=False, shot_type_name, shot_first_time, shot_one_on_one,
shot_one_on_one=False, shot_aerial_won=False, shot_aerial_won, shot_deflected, shot_open_goal,
shot_open_goal=False, shot_follows_dribble=False, shot_redirect=False, x1=0.0, y1=0.0, shot_follows_dribble, shot_redirect, x1, y1,
number_of_players_opponents=0, number_of_players_teammates=0, number_of_players_opponents, number_of_players_teammates,
angle=0.0, distance=0.0, x_player_opponent_Goalkeeper=np.nan, angle, distance, x_player_opponent_Goalkeeper,
x_player_opponent_8=np.nan, x_player_opponent_1=np.nan, x_player_opponent_2=np.nan, x_player_opponent_8, x_player_opponent_1, x_player_opponent_2,
x_player_opponent_3=np.nan, x_player_teammate_1=np.nan, x_player_opponent_4=np.nan, x_player_opponent_3, x_player_teammate_1, x_player_opponent_4,
x_player_opponent_5=np.nan, x_player_opponent_6=np.nan, x_player_teammate_2=np.nan, x_player_opponent_5, x_player_opponent_6, x_player_teammate_2,
x_player_opponent_9=np.nan, x_player_opponent_10=np.nan, x_player_opponent_11=np.nan, x_player_opponent_9, x_player_opponent_10, x_player_opponent_11,
x_player_teammate_3=np.nan, x_player_teammate_4=np.nan, x_player_teammate_5=np.nan, x_player_teammate_3, x_player_teammate_4, x_player_teammate_5,
x_player_teammate_6=np.nan, x_player_teammate_7=np.nan, x_player_teammate_8=np.nan, x_player_teammate_6, x_player_teammate_7, x_player_teammate_8,
y_player_opponent_Goalkeeper=np.nan, y_player_opponent_8=np.nan, x_player_teammate_9, x_player_teammate_10,
x_player_teammate_9=np.nan, x_player_teammate_10=np.nan, y_player_opponent_Goalkeeper, y_player_opponent_8,
y_player_opponent_1=np.nan, y_player_opponent_2=np.nan, y_player_opponent_3=np.nan, y_player_opponent_1, y_player_opponent_2, y_player_opponent_3,
y_player_teammate_1=np.nan, y_player_opponent_4=np.nan, y_player_opponent_5=np.nan, y_player_teammate_1, y_player_opponent_4, y_player_opponent_5,
y_player_opponent_6=np.nan, y_player_teammate_2=np.nan, y_player_opponent_9=np.nan, y_player_opponent_6, y_player_teammate_2, y_player_opponent_9,
y_player_opponent_10=np.nan, y_player_opponent_11=np.nan, y_player_teammate_3=np.nan, y_player_opponent_10, y_player_opponent_11, y_player_teammate_3,
y_player_teammate_4=np.nan, y_player_teammate_5=np.nan, y_player_teammate_6=np.nan, y_player_teammate_4, y_player_teammate_5, y_player_teammate_6,
y_player_teammate_7=np.nan, y_player_teammate_8=np.nan, y_player_teammate_9=np.nan, y_player_teammate_7, y_player_teammate_8, y_player_teammate_9,
y_player_teammate_10=np.nan, x_player_opponent_7=np.nan, y_player_opponent_7=np.nan, y_player_teammate_10, x_player_opponent_7, y_player_opponent_7,
x_player_teammate_Goalkeeper=np.nan, y_player_teammate_Goalkeeper=np.nan): x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper,
shot_kick_off):
model = xgboost.XGBClassifier() model = load('xgboost.joblib')
model.load_model('xgboost.json') X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name', 'shot_technique_name',
'shot_type_name', 'shot_first_time', 'shot_one_on_one',
enc = OrdinalEncoder() 'shot_aerial_won', 'shot_deflected', 'shot_open_goal',
enc = load('labelEncoder.joblib') 'shot_follows_dribble', 'shot_redirect', 'x1', 'y1',
'number_of_players_opponents', 'number_of_players_teammates',
X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name', 'shot_technique_name', 'angle', 'distance', 'x_player_opponent_Goalkeeper',
'shot_type_name', 'shot_first_time', 'shot_one_on_one', 'x_player_opponent_8', 'x_player_opponent_1', 'x_player_opponent_2',
'shot_aerial_won', 'shot_open_goal', 'x_player_opponent_3', 'x_player_teammate_1', 'x_player_opponent_4',
'shot_follows_dribble', 'shot_redirect', 'x1', 'y1', 'x_player_opponent_5', 'x_player_opponent_6', 'x_player_teammate_2',
'number_of_players_opponents', 'number_of_players_teammates', 'x_player_opponent_9', 'x_player_opponent_10', 'x_player_opponent_11',
'angle', 'distance', 'x_player_opponent_Goalkeeper', 'x_player_teammate_3', 'x_player_teammate_4', 'x_player_teammate_5',
'x_player_opponent_8', 'x_player_opponent_1', 'x_player_opponent_2', 'x_player_teammate_6', 'x_player_teammate_7', 'x_player_teammate_8',
'x_player_opponent_3', 'x_player_teammate_1', 'x_player_opponent_4', 'x_player_teammate_9', 'x_player_teammate_10',
'x_player_opponent_5', 'x_player_opponent_6', 'x_player_teammate_2', 'y_player_opponent_Goalkeeper', 'y_player_opponent_8',
'x_player_opponent_9', 'x_player_opponent_10', 'x_player_opponent_11', 'y_player_opponent_1', 'y_player_opponent_2', 'y_player_opponent_3',
'x_player_teammate_3', 'x_player_teammate_4', 'x_player_teammate_5', 'y_player_teammate_1', 'y_player_opponent_4', 'y_player_opponent_5',
'x_player_teammate_6', 'x_player_teammate_7', 'x_player_teammate_8', 'y_player_opponent_6', 'y_player_teammate_2', 'y_player_opponent_9',
'x_player_teammate_9', 'x_player_teammate_10', 'y_player_opponent_10', 'y_player_opponent_11', 'y_player_teammate_3',
'y_player_opponent_Goalkeeper', 'y_player_opponent_8', 'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6',
'y_player_opponent_1', 'y_player_opponent_2', 'y_player_opponent_3', 'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9',
'y_player_teammate_1', 'y_player_opponent_4', 'y_player_opponent_5', 'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7',
'y_player_opponent_6', 'y_player_teammate_2', 'y_player_opponent_9', 'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper',
'y_player_opponent_10', 'y_player_opponent_11', 'y_player_teammate_3', 'shot_kick_off'])
'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6',
'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9',
'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7',
'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper'])
X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name, shot_technique_name, X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name, shot_technique_name,
shot_type_name, shot_first_time, shot_one_on_one, shot_type_name, shot_first_time, shot_one_on_one,
shot_aerial_won, shot_open_goal, shot_aerial_won, shot_deflected, shot_open_goal,
shot_follows_dribble, shot_redirect, x1, y1, shot_follows_dribble, shot_redirect, x1, y1,
number_of_players_opponents, number_of_players_teammates, number_of_players_opponents, number_of_players_teammates,
angle, distance, x_player_opponent_Goalkeeper, angle, distance, x_player_opponent_Goalkeeper,
x_player_opponent_8, x_player_opponent_1, x_player_opponent_2, x_player_opponent_8, x_player_opponent_1, x_player_opponent_2,
x_player_opponent_3, x_player_teammate_1, x_player_opponent_4, x_player_opponent_3, x_player_teammate_1, x_player_opponent_4,
x_player_opponent_5, x_player_opponent_6, x_player_teammate_2, x_player_opponent_5, x_player_opponent_6, x_player_teammate_2,
x_player_opponent_9, x_player_opponent_10, x_player_opponent_11, x_player_opponent_9, x_player_opponent_10, x_player_opponent_11,
x_player_teammate_3, x_player_teammate_4, x_player_teammate_5, x_player_teammate_3, x_player_teammate_4, x_player_teammate_5,
x_player_teammate_6, x_player_teammate_7, x_player_teammate_8, x_player_teammate_6, x_player_teammate_7, x_player_teammate_8,
x_player_teammate_9, x_player_teammate_10, x_player_teammate_9, x_player_teammate_10,
y_player_opponent_Goalkeeper, y_player_opponent_8, y_player_opponent_Goalkeeper, y_player_opponent_8,
y_player_opponent_1, y_player_opponent_2, y_player_opponent_3, y_player_opponent_1, y_player_opponent_2, y_player_opponent_3,
y_player_teammate_1, y_player_opponent_4, y_player_opponent_5, y_player_teammate_1, y_player_opponent_4, y_player_opponent_5,
y_player_opponent_6, y_player_teammate_2, y_player_opponent_9, y_player_opponent_6, y_player_teammate_2, y_player_opponent_9,
y_player_opponent_10, y_player_opponent_11, y_player_teammate_3, y_player_opponent_10, y_player_opponent_11, y_player_teammate_3,
y_player_teammate_4, y_player_teammate_5, y_player_teammate_6, y_player_teammate_4, y_player_teammate_5, y_player_teammate_6,
y_player_teammate_7, y_player_teammate_8, y_player_teammate_9, y_player_teammate_7, y_player_teammate_8, y_player_teammate_9,
y_player_teammate_10, x_player_opponent_7, y_player_opponent_7, y_player_teammate_10, x_player_opponent_7, y_player_opponent_7,
x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper] x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper,
shot_kick_off]
X_new[['position_name', return model.predict_proba(X_new)[0][1].round(2)
'shot_technique_name',
'shot_type_name',
'shot_body_part_name']] = enc.transform(X_new[['position_name', 'shot_technique_name', 'shot_type_name', 'shot_body_part_name']], )
X_new[['minute',
'position_name',
'shot_technique_name',
'shot_type_name',
'number_of_players_opponents',
'number_of_players_teammates',
'shot_body_part_name']] = X_new[['minute',
'position_name',
'shot_technique_name',
'shot_type_name',
'number_of_players_opponents',
'number_of_players_teammates',
'shot_body_part_name']].astype(int)
# X_new[['minute',
# 'position_name',
# 'shot_technique_name',
# 'shot_type_name',
# 'number_of_players_opponents',
# 'number_of_players_teammates',
# 'shot_body_part_name']] = X_new[['minute',
# 'position_name',
# 'shot_technique_name',
# 'shot_type_name',
# 'number_of_players_opponents',
# 'number_of_players_teammates',
# 'shot_body_part_name']].astype('category')
X_new[['shot_first_time',
'shot_one_on_one',
'shot_aerial_won',
'shot_open_goal',
'shot_follows_dribble',
'shot_redirect']] = X_new[['shot_first_time',
'shot_one_on_one',
'shot_aerial_won',
'shot_open_goal',
'shot_follows_dribble',
'shot_redirect']].astype(int)
print(X_new)
print(X_new.dtypes)
return model.predict_proba(X_new)[0][1].round(3)
#XgBoost_2 #XgBoost_2
def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, minute,position_name,shot_body_part_name, def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, minute,position_name,shot_body_part_name,
shot_technique_name,shot_type_name,shot_first_time,shot_aerial_won,shot_open_goal, shot_technique_name,shot_type_name,shot_first_time,shot_aerial_won,shot_deflected,shot_open_goal,
shot_follows_dribble,shot_redirect): shot_follows_dribble,shot_redirect, shot_kick_off):
model = load('xgboost.joblib') model = load('xgboost.joblib')
X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name', X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name',
'shot_technique_name','shot_type_name', 'shot_first_time', 'shot_technique_name','shot_type_name', 'shot_first_time',
'shot_one_on_one','shot_aerial_won', 'shot_one_on_one','shot_aerial_won', 'shot_deflected',
'shot_open_goal','shot_follows_dribble', 'shot_redirect', 'shot_open_goal','shot_follows_dribble', 'shot_redirect',
'x1', 'y1','number_of_players_opponents', 'x1', 'y1','number_of_players_opponents',
'number_of_players_teammates','angle', 'distance', 'number_of_players_teammates','angle', 'distance',
'x_player_opponent_Goalkeeper', 'x_player_opponent_8', 'x_player_opponent_Goalkeeper',
'x_player_opponent_1', 'x_player_opponent_2','x_player_opponent_3', 'x_player_opponent_1', 'x_player_opponent_2','x_player_opponent_3',
'x_player_opponent_4','x_player_opponent_5', 'x_player_opponent_6', 'x_player_opponent_4','x_player_opponent_5', 'x_player_opponent_6',
'x_player_teammate_2','x_player_opponent_9', 'x_player_opponent_10', 'x_player_teammate_2','x_player_opponent_9', 'x_player_opponent_10',
@ -168,7 +116,8 @@ def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, min
'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6', 'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6',
'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9', 'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9',
'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7', 'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7',
'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper']) 'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper',
'shot_kick_off'])
shooter = konwertujDoListy(shooter) shooter = konwertujDoListy(shooter)
@ -188,10 +137,8 @@ def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, min
teamMatesList = zmienWMaciez(teamMatesList) teamMatesList = zmienWMaciez(teamMatesList)
opponentsList = zmienWMaciez(opponentsList) opponentsList = zmienWMaciez(opponentsList)
number_of_players_opponents = len(teamMatesList)
# DO ROZBUDOWY number_of_players_teammates = len(opponentsList)
number_of_players_opponents = 3
number_of_players_teammates = 3
# Bramkarz # Bramkarz
x_player_opponent_Goalkeeper = goalkeeper[0] x_player_opponent_Goalkeeper = goalkeeper[0]
y_player_opponent_Goalkeeper = goalkeeper[1] y_player_opponent_Goalkeeper = goalkeeper[1]
@ -199,16 +146,19 @@ def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, min
shot_one_on_one = True if number_of_players_opponents == 1 else False shot_one_on_one = True if number_of_players_opponents == 1 else False
# TeamMate goalkeppe # TeamMate goalkeppe
x_player_teammate_Goalkeeper = np.nan x_player_teammate_Goalkeeper = None
y_player_teammate_Goalkeeper = np.nan y_player_teammate_Goalkeeper = None
#Reszta Zawodnikow #Reszta Zawodnikow
print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
print(X_new.head)
X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name, X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name,
shot_technique_name,shot_type_name, shot_first_time, shot_technique_name,shot_type_name, shot_first_time,
shot_one_on_one,shot_aerial_won, shot_one_on_one,shot_aerial_won, shot_deflected,
shot_open_goal,shot_follows_dribble, shot_redirect, shot_open_goal,shot_follows_dribble, shot_redirect,
shooter[0], shooter[1],number_of_players_opponents, shooter[0], shooter[1],number_of_players_opponents,
number_of_players_teammates,angle, distance, number_of_players_teammates,angle, distance,
x_player_opponent_Goalkeeper, opponentsList[8][0], x_player_opponent_Goalkeeper,
opponentsList[0][0], opponentsList[1][0], opponentsList[2][0], opponentsList[0][0], opponentsList[1][0], opponentsList[2][0],
opponentsList[3][0], opponentsList[4][0], opponentsList[5][0], opponentsList[3][0], opponentsList[4][0], opponentsList[5][0],
opponentsList[6][0], opponentsList[7][0], teamMatesList[8][0], opponentsList[6][0], opponentsList[7][0], teamMatesList[8][0],
@ -225,17 +175,13 @@ def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, min
teamMatesList[0][1],teamMatesList[1][1], teamMatesList[2][1], teamMatesList[0][1],teamMatesList[1][1], teamMatesList[2][1],
teamMatesList[4][1],teamMatesList[5][1], teamMatesList[6][1], teamMatesList[7][1], teamMatesList[4][1],teamMatesList[5][1], teamMatesList[6][1], teamMatesList[7][1],
teamMatesList[8][1], teamMatesList[9][1], teamMatesList[8][1], teamMatesList[9][1],
x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper] x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper,
shot_kick_off]
categorical_columns = ['position_name', 'shot_technique_name', 'shot_type_name', 'number_of_players_opponents', 'number_of_players_teammates', 'shot_body_part_name'] # list all your object columns here
# X_new = pd.get_dummies(X_new, columns=categorical_columns)
X_new[categorical_columns] = X_new[categorical_columns].astype('category')
return model.predict_proba(X_new)[0][1].round(2) return model.predict_proba(X_new)[0][1].round(2)
# Pomocnicze Funkcje # Pomocnicze Funkcje
# trzeba uzupelnic
def sortNearestToShooter(playerList, shooter): def sortNearestToShooter(playerList, shooter):
return playerList return playerList
@ -252,14 +198,14 @@ def loc2angle(x, y):
rads = math.pi + rads if rads < 0 else rads rads = math.pi + rads if rads < 0 else rads
deg = math.degrees(rads) deg = math.degrees(rads)
return deg return deg
# zamiana stringa odzielonego ',' na liste
def konwertujDoListy(listaString): def konwertujDoListy(listaString):
listaString = listaString.split(",") listaString = listaString.split(",")
listaFloat = [] listaFloat = []
for elem in listaString: for elem in listaString:
listaFloat.append(float(elem)) listaFloat.append(float(elem))
return listaFloat return listaFloat
#Zamiana listy w formie [1x,1y,2x,2y,3x,3y...] do postaci maciezy [xi, yi]
def zmienWMaciez(lista): def zmienWMaciez(lista):
maciez = [] maciez = []
for i in range(0,len(lista),2): for i in range(0,len(lista),2):
@ -267,5 +213,5 @@ def zmienWMaciez(lista):
maciez.append(player) maciez.append(player)
if(len(maciez) < 10): if(len(maciez) < 10):
for i in range(len(maciez),11,1): for i in range(len(maciez),11,1):
maciez.append([np.nan,np.nan]) maciez.append([None,None])
return maciez return maciez

View File

@ -1,8 +1,6 @@
from flask import Flask, request, jsonify from flask import Flask, request, jsonify
from flask_cors import CORS from flask_cors import CORS
from modele.modele import LogisticRegression_predict_proba, xgboost_predict_proba, xgboost_predict_proba_v2 from modele.modele import LogisticRegression_predict_proba, xgboost_predict_proba, xgboost_predict_proba_v2
import numpy as np
import math
app = Flask(__name__) app = Flask(__name__)
@ -26,218 +24,37 @@ def get_model():
# Elementy z list: czesc ciała,rodzaj uderzenia,pozycja strzelca oraz typ akcji # Elementy z list: czesc ciała,rodzaj uderzenia,pozycja strzelca oraz typ akcji
position_name = request.args.get('shooter')
body_part = request.args.get('bodyPart') body_part = request.args.get('bodyPart')
technique = request.args.get('technique') technique = request.args.get('technique')
acionType = request.args.get('actionType') acionType = request.args.get('actionType')
minute = request.args.get('gameMinute')
position_name = request.args.get('shooterPossition')
gameMinute = request.args.get('gameMinute')
shot_first_time = request.args.get('shot_first_time') print("pozycja strzelca: " + position_name)
shot_one_on_one = request.args.get('shot_one_on_one')
shot_aerial_won = request.args.get('shot_aerial_won')
shot_open_goal = request.args.get('shot_open_goal')
shot_follows_dribble = request.args.get('shot_follows_dribble')
shot_redirect = request.args.get('shot_redirect')
shooter_x, shooter_y = shooter.split(',')
shooter_x = float(shooter_x)
shooter_y = float(shooter_y)
print("minuta: ", minute)
print("pozycja x1 strzelca: ", shooter_x)
print("pozycja y1 strzelca: ", shooter_y)
print("czesc ciala: " + body_part) print("czesc ciala: " + body_part)
print("technika: " + technique) print("technika: " + technique)
print("typ akcji: " + acionType) print("typ akcji: " + acionType)
# lista atakujacy oraz obroncy # lista wspolzawodnikow oraz przeciwnikow
def konwertujDoListy(listaString): teamMatesList = request.args.get('defenders')
listaString = listaString.split(",") opponentsList = request.args.get('strickers')
listaFloat = []
for elem in listaString:
listaFloat.append(float(elem))
return listaFloat
def zmienWMaciez(lista):
maciez = []
for i in range(0,len(lista),2):
player = [float(lista[i]),float(lista[i+1])]
maciez.append(player)
if(len(maciez) < 10):
for i in range(len(maciez),11,1):
maciez.append([np.nan,np.nan])
return maciez
obroncy = request.args.get('defenders')
atakujacy = request.args.get('strickers')
print("wspolrzedne obroncow: ", obroncy)
if obroncy == "":
obroncy_macierz = [[np.nan, np.nan]]
else:
obroncy_lista = konwertujDoListy(obroncy)
obroncy_macierz = zmienWMaciez(obroncy_lista)
if atakujacy == "": print("wspolrzedne obroncow: " + teamMatesList)
atakujacy_macierz = [[np.nan, np.nan]] print("wspolrzedne przeciwnikow: " + opponentsList)
else:
atakujacy_lista = konwertujDoListy(atakujacy)
atakujacy_macierz = zmienWMaciez(atakujacy_lista)
if gameMinute == "":
gameMinute = 1.0 # to change
print("wspolrzedne obroncow: ", obroncy) # Bramkarz
print("wspolrzedne atakujacych: ", atakujacy) goalkepper = "2,2"
#goalkepper = request.args.get('goalkeeper')
def euclidean_distance(point1, point2):
"""Calculate the Euclidean distance between two points."""
return math.sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)
def sort_coordinates_by_distance(coordinates, reference_point):
"""Sort a list of coordinates based on Euclidean distance from a reference point.
Coordinates with NaN values are placed at the end of the list.
"""
def distance_or_inf(coord):
"""Helper function to handle coordinates with NaN values."""
if hasattr(coord, '__iter__') and len(coord) >= 2:
if np.isnan(coord[0]) or np.isnan(coord[1]):
return float('inf') # Set distance to infinity for NaN coordinates
return euclidean_distance(coord, reference_point)
return float('inf') # Set distance to infinity for non-iterable coordinates
sorted_coordinates = sorted(coordinates, key=distance_or_inf)
if(len(sorted_coordinates) < 10):
for i in range(len(sorted_coordinates),11,1):
sorted_coordinates.append([np.nan,np.nan])
return sorted_coordinates
# POSORTOWANI OBRONCY I ATAKUJACY print("bramkarz: " + str(goalkepper) )
posortowani_obroncy = sort_coordinates_by_distance(obroncy_macierz, [shooter_x, shooter_y])
posortowani_atakujacy = sort_coordinates_by_distance(atakujacy_macierz, [shooter_x, shooter_y])
print("Posortowani obroncy: ", posortowani_obroncy) response = xgboost_predict_proba_v2(shooter = shooter,
opponentsList = opponentsList, teamMatesList = teamMatesList ,minute = 20, position_name = position_name, shot_body_part_name = body_part, shot_technique_name = technique,
print("Posortowani atakujacy: ", posortowani_atakujacy) shot_type_name = acionType, shot_first_time = False,
shot_aerial_won = False, shot_deflected = False, shot_open_goal = False,
shot_follows_dribble = False, shot_redirect = False, shot_kick_off = False, goalkeeper= goalkepper
number_of_players_opponents = float(np.sum(~np.isnan(posortowani_obroncy).all(axis=1))) )
number_of_players_teammates = float(np.sum(~np.isnan(posortowani_atakujacy).all(axis=1)))
print("Liczba obroncow:", number_of_players_opponents)
print("Liczba atakujacych:", number_of_players_teammates)
## add angle, match minutes and number of players
def loc2angle(x, y):
rads = math.atan(7.32 * x / (x**2 + (y - 34)**2 - (7.32/2)**2))
rads = math.pi + rads if rads < 0 else rads
deg = math.degrees(rads)
return deg
def loc2distance(x, y):
return math.sqrt(x**2 + (y - 34)**2)
angle = loc2angle(x = shooter_x, y = shooter_y)
dist = loc2distance(x = shooter_x, y = shooter_y)
# BRAMKARZ
goalkepper = request.args.get('goalkeeper')
if goalkepper == "null":
goalkepper_x, goalkepper_y = np.nan, np.nan
else:
goalkepper_x, goalkepper_y = goalkepper.split(',')
goalkepper_x = float(goalkepper_x)
goalkepper_y = float(goalkepper_y)
print("bramkarz:", goalkepper_x, goalkepper_y)
if shot_first_time == 'true':
shot_first_time = True
else:
shot_first_time = False
if shot_one_on_one == 'true':
shot_one_on_one = True
else:
shot_one_on_one = False
if shot_aerial_won == 'true':
shot_aerial_won = True
else:
shot_aerial_won = False
if shot_open_goal == 'true':
shot_open_goal = True
else:
shot_open_goal = False
if shot_follows_dribble == 'true':
shot_follows_dribble = True
else:
shot_follows_dribble = False
if shot_redirect == 'true':
shot_redirect = True
else:
shot_redirect = False
#### CHECKLIST
print('CHECKLISTA')
print('shot_first_time', shot_first_time)
print('shot_one_on_one', shot_one_on_one)
print('shot_aerial_won', shot_aerial_won)
print('shot_open_goal', shot_open_goal)
print('shot_follows_dribble', shot_follows_dribble)
print('shot_redirect', shot_redirect)
# MODEL XGBOOST
response = xgboost_predict_proba(minute=int(gameMinute), #minute=0,
position_name=position_name,
shot_body_part_name=body_part,
shot_technique_name=technique,
shot_type_name=acionType,
shot_first_time=shot_first_time,
shot_one_on_one=shot_one_on_one,
shot_aerial_won=shot_aerial_won,
shot_open_goal=shot_open_goal,
shot_follows_dribble=shot_follows_dribble,
shot_redirect=shot_redirect,
x1=shooter_x, y1=shooter_y,
number_of_players_opponents=number_of_players_opponents,
number_of_players_teammates=number_of_players_teammates,
angle=angle, distance=dist,
x_player_opponent_Goalkeeper=goalkepper_x, y_player_opponent_Goalkeeper=goalkepper_y,
x_player_opponent_1=posortowani_obroncy[0][0], y_player_opponent_1=posortowani_obroncy[0][1],
x_player_opponent_2=posortowani_obroncy[1][0], y_player_opponent_2=posortowani_obroncy[1][1],
x_player_opponent_3=posortowani_obroncy[2][0], y_player_opponent_3=posortowani_obroncy[2][1],
x_player_opponent_4=posortowani_obroncy[3][0], y_player_opponent_4=posortowani_obroncy[3][1],
x_player_opponent_5=posortowani_obroncy[4][0], y_player_opponent_5=posortowani_obroncy[4][1],
x_player_opponent_6=posortowani_obroncy[5][0], y_player_opponent_6=posortowani_obroncy[5][1],
x_player_opponent_7=posortowani_obroncy[6][0], y_player_opponent_7=posortowani_obroncy[6][1],
x_player_opponent_8=posortowani_obroncy[7][0], y_player_opponent_8=posortowani_obroncy[7][1],
x_player_opponent_9=posortowani_obroncy[8][0], y_player_opponent_9=posortowani_obroncy[8][1],
x_player_opponent_10=posortowani_obroncy[9][0], y_player_opponent_10=posortowani_obroncy[9][1],
x_player_teammate_Goalkeeper=np.nan, y_player_teammate_Goalkeeper=np.nan,
x_player_teammate_1=posortowani_atakujacy[0][0], y_player_teammate_1=posortowani_atakujacy[0][1],
x_player_teammate_2=posortowani_atakujacy[1][0], y_player_teammate_2=posortowani_atakujacy[1][1],
x_player_teammate_3=posortowani_atakujacy[2][0], y_player_teammate_3=posortowani_atakujacy[2][1],
x_player_teammate_4=posortowani_atakujacy[3][0], y_player_teammate_4=posortowani_atakujacy[3][1],
x_player_teammate_5=posortowani_atakujacy[4][0], y_player_teammate_5=posortowani_atakujacy[4][1],
x_player_teammate_6=posortowani_atakujacy[5][0], y_player_teammate_6=posortowani_atakujacy[5][1],
x_player_teammate_7=posortowani_atakujacy[6][0], y_player_teammate_7=posortowani_atakujacy[6][1],
x_player_teammate_8=posortowani_atakujacy[7][0], y_player_teammate_8=posortowani_atakujacy[7][1],
x_player_teammate_9=posortowani_atakujacy[8][0], y_player_teammate_9=posortowani_atakujacy[8][1],
x_player_teammate_10=posortowani_atakujacy[9][0], y_player_teammate_10=posortowani_atakujacy[9][1])
# response = xgboost_predict_proba(shooter = shooter,
# opponentsList = opponentsList, teamMatesList = teamMatesList, minute = 20, position_name = position_name, shot_body_part_name = body_part, shot_technique_name = technique,
# shot_type_name = acionType, shot_first_time = False,
# shot_aerial_won = False, shot_deflected = False, shot_open_goal = False,
# shot_follows_dribble = False, shot_redirect = False, shot_kick_off = False, goalkeeper= goalkepper
# )
#print(response) #print(response)
res = str(response) res = str(response)

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -4,55 +4,19 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
.Ex { .Ex{
display: block; /* Może być inline-block, jeśli preferujesz */ display: block; /* Może być inline-block, jeśli preferujesz */
margin: 20px auto; /* Centralnie i z marginesem */ margin: 20px auto; /* Centralnie i z marginesem */
padding: 10px; padding: 10px;
background-color: #4CAF50; /* Przykładowy kolor tła */ background-color: #4CAF50; /* Przykładowy kolor tła */
color: white; /* Kolor tekstu */ color: white; /* Kolor tekstu */
text-align: center; text-align: center;
border-radius: 5px; /* Lekko zaokrąglone rogi */ border-radius: 5px; /* Lekko zaokrąglone rogi */
font-size: 20px; /* Duża, czytelna czcionka */ font-size: 20px; /* Duża, czytelna czcionka */
font-weight: bold; /* Pogrubienie dla lepszej widoczności */ font-weight: bold; /* Pogrubienie dla lepszej widoczności */
width: 100%; /* Poszerzone pole */ width: 50%; /* Dostosuj szerokość zgodnie z potrzebami */
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.5); /* Cień dla dodatkowej głębi */ /* Dodatkowe style, takie jak cienie, mogą być dodane */
/* Opcjonalnie, można dodać gradient tła dla większego efektu */ }
background-image: linear-gradient(to right, #32CD32 , #4CAF50);
transition: transform 0.3s ease; /* Delikatna animacja */
}
.Ex:hover {
transform: scale(1.10); /* Efekt powiększenia przy najechaniu */
}
.xg-meter {
width: 200px;
height: 100px; /* Zmiana wysokości, aby pasowała do proporcji bramki */
display: flex;
align-items: center;
justify-content: center;
text-align: center;
color: white;
font-size: 48px;
font-weight: bold;
background: url('assets/bramka.jpeg') no-repeat center center; /* Tło z obrazem bramki */
background-size: cover; /* Dopasowanie obrazu do rozmiaru elementu */
border-radius: 10px; /* Opcjonalnie, dla zaokrąglonych rogów */
}
.xg-value {
display: block;
background: rgba(0, 0, 0, 0.5); /* Półprzezroczyste tło dla lepszej czytelności tekstu */
padding: 5px 10px; /* Dodanie odstępu */
border-radius: 5px; /* Zaokrąglone rogi dla tekstu */
}
/* Funkcja JavaScript będzie sterować stopniem gradientu */
body { body {
margin: 50px; margin: 50px;
display: grid; display: grid;
@ -61,7 +25,7 @@
grid-template-rows: auto; grid-template-rows: auto;
grid-template-columns: auto auto auto; grid-template-columns: auto auto auto;
} }
.container { .container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -85,20 +49,19 @@
max-height: 100%; max-height: 100%;
} }
.container span { .container span {
display: block; display: block;
} }
.main-content { .main-content {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
.player{ .player{
width: inherit; width: inherit;
height: 8vh; height: 8vh;
@ -121,7 +84,7 @@
background-color: #cccccc; background-color: #cccccc;
justify-content: space-between; justify-content: space-between;
} }
.subMenu { .subMenu {
display: grid; display: grid;
grid-template-rows: auto auto auto; grid-template-rows: auto auto auto;
@ -132,15 +95,14 @@
background-color: #f0f0f0; /* Example background color */ background-color: #f0f0f0; /* Example background color */
z-index: 1000; /* Ensure it stays on top of other content */ z-index: 1000; /* Ensure it stays on top of other content */
} }
.player-list{
.player-list {
background-color: rgb(61, 38, 38); background-color: rgb(61, 38, 38);
width: 13vw; width: 13vw;
height: calc(50vw*68/105); height: calc(50vw*68/105);
overflow: scroll; overflow: scroll;
font-size: 12px; /* Example font size - adjust as needed */
}
}
.top-bar { .top-bar {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -150,7 +112,7 @@
/* Możesz dodać dodatkowe style, jak tło, obramowanie itp. */ /* Możesz dodać dodatkowe style, jak tło, obramowanie itp. */
z-index: 2; z-index: 2;
} }
.bottom-bar { .bottom-bar {
display: flex; display: flex;
justify-content: space-between; /* Rozmieszcza przyciski równomiernie */ justify-content: space-between; /* Rozmieszcza przyciski równomiernie */
@ -166,7 +128,7 @@
border-radius: 50%; border-radius: 50%;
position: absolute position: absolute
} }
.reset-button { .reset-button {
position: relative; position: relative;
margin: 5px; margin: 5px;
@ -238,7 +200,7 @@
color: #000000; color: #000000;
font-size: 16px; font-size: 16px;
} }
.cho-first_time { .cho-first_time {
position: relative; position: relative;
padding: 10px; padding: 10px;
@ -275,38 +237,7 @@
color: #000000; color: #000000;
font-size: 16px; font-size: 16px;
} }
.additional-parameters {
position: relative; /* Or absolute, depending on layout */
right: 0;
top: 30%; /* Adjusted to a higher position */
width: 250px; /* Increased width */
background-color: #000000;
padding: 15px; /* Increased padding */
border: 1px solid #ddd;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
z-index: 100; /* To ensure it stays on top */
color: #ffffff; /* Optional: change text color for better visibility on dark background */
}
.additional-parameters h3 {
margin-top: 0;
font-size: 18px; /* Increased font size for heading */
}
.additional-parameters label {
display: flex; /* Updated to flex for better alignment */
align-items: center; /* Aligns checkbox and label text vertically */
margin-bottom: 10px; /* Increased spacing between checkboxes */
font-size: 16px; /* Increased font size for labels */
}
.additional-parameters input[type="checkbox"] {
margin-right: 10px; /* Adds spacing between checkbox and label text */
}
/* DROPDOWNS */ /* DROPDOWNS */
/* Style the dropdown button */ /* Style the dropdown button */
.dropbtn { .dropbtn {
@ -322,13 +253,13 @@
.dropbtn:hover, .dropbtn:focus { .dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41; background-color: #3e8e41;
} }
/* The container <div> - needed to position the dropdown content */ /* The container <div> - needed to position the dropdown content */
.dropdown { .dropdown {
position: relative; position: relative;
display: inline-block; display: inline-block;
} }
.cho-dropdown_body_part { .cho-dropdown_body_part {
display: none; display: none;
position: absolute; position: absolute;
@ -337,7 +268,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; z-index: 1;
} }
.cho-dropdown_body_part a{ .cho-dropdown_body_part a{
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
@ -345,15 +276,15 @@
display: block; display: block;
font-size: 16px; font-size: 16px;
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.cho-dropdown_body_part a:hover {background-color: #f1f1f1} .cho-dropdown_body_part a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */ /* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_body_part { .dropdown:hover .cho-dropdown_body_part {
display: block; display: block;
} }
.cho-dropdown_position_name { .cho-dropdown_position_name {
display: none; display: none;
position: absolute; position: absolute;
@ -362,7 +293,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; z-index: 1;
} }
.cho-dropdown_position_name a { .cho-dropdown_position_name a {
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
@ -370,15 +301,15 @@
display: block; display: block;
font-size: 16px; font-size: 16px;
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.cho-dropdown_position_name a:hover {background-color: #f1f1f1} .cho-dropdown_position_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */ /* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_position_name { .dropdown:hover .cho-dropdown_position_name {
display: block; display: block;
} }
.cho-dropdown_technique_name { .cho-dropdown_technique_name {
position: relative; position: relative;
display: none; display: none;
@ -388,7 +319,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; z-index: 1;
} }
.cho-dropdown_technique_name a { .cho-dropdown_technique_name a {
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
@ -396,15 +327,15 @@
display: block; display: block;
font-size: 16px; font-size: 16px;
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.cho-dropdown_technique_name a:hover {background-color: #f1f1f1} .cho-dropdown_technique_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */ /* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_technique_name { .dropdown:hover .cho-dropdown_technique_name {
display: block; display: block;
} }
.cho-dropdown_type_name { .cho-dropdown_type_name {
display: none; display: none;
position: absolute; position: absolute;
@ -413,7 +344,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; z-index: 1;
} }
.cho-dropdown_type_name a { .cho-dropdown_type_name a {
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
@ -421,16 +352,16 @@
display: block; display: block;
font-size: 16px; font-size: 16px;
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.cho-dropdown_type_name a:hover {background-color: #f1f1f1} .cho-dropdown_type_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */ /* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_type_name { .dropdown:hover .cho-dropdown_type_name {
display: block; display: block;
} }
/* MANUAL INPUT */ /* MANUAL INPUT */
.cho-minute { .cho-minute {
margin-top: 10px; margin-top: 10px;
@ -643,5 +574,5 @@
-2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff; -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
} }
} }

BIN
data/.DS_Store vendored

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

BIN
notebooks/.DS_Store vendored

Binary file not shown.

View File

@ -11,33 +11,33 @@ library(purrr)
# code and data from https://github.com/Dato-Futbol/xg-model # code and data from https://github.com/Dato-Futbol/xg-model
get_shots <- function(file_path, name_detail, save_files = F){ get_shots <- function(file_path, name_detail, save_files = F){
players <- fromJSON("data/players.json") players <- fromJSON("data/players.json")
shots <- fromJSON(file_path) %>% shots <- fromJSON(file_path) %>%
filter(subEventName == "Shot") filter(subEventName == "Shot")
tags <- tibble(tags = shots$tags) %>% tags <- tibble(tags = shots$tags) %>%
hoist(tags, hoist(tags,
tags_id = "id") %>% tags_id = "id") %>%
unnest_wider(tags_id, names_sep = "") unnest_wider(tags_id, names_sep = "")
tags2 <- tags %>% tags2 <- tags %>%
mutate(is_goal = ifelse(rowSums(. == "101", na.rm = T) > 0, 1, 0), mutate(is_goal = ifelse(rowSums(. == "101", na.rm = T) > 0, 1, 0),
is_blocked = ifelse(rowSums(. == "2101", na.rm = T) > 0, 1, 0), is_blocked = ifelse(rowSums(. == "2101", na.rm = T) > 0, 1, 0),
is_CA = ifelse(rowSums(. == "1901", na.rm = T) > 0, 1, 0), # is countre attack is_CA = ifelse(rowSums(. == "1901", na.rm = T) > 0, 1, 0), # is countre attack
body_part = ifelse(rowSums(. == "401", na.rm = T) > 0, "left", body_part = ifelse(rowSums(. == "401", na.rm = T) > 0, "left",
ifelse(rowSums(. == "402", na.rm = T) > 0, "right", ifelse(rowSums(. == "402", na.rm = T) > 0, "right",
ifelse(rowSums(. == "403", na.rm = T) > 0, "head/body", "NA")))) ifelse(rowSums(. == "403", na.rm = T) > 0, "head/body", "NA"))))
pos <- tibble(positions = shots$positions) %>% pos <- tibble(positions = shots$positions) %>%
hoist(positions, hoist(positions,
y = "y", y = "y",
x = "x") %>% x = "x") %>%
unnest_wider(y, names_sep = "") %>% unnest_wider(y, names_sep = "") %>%
unnest_wider(x, names_sep = "") %>% unnest_wider(x, names_sep = "") %>%
dplyr::select(-c(x2, y2)) dplyr::select(-c(x2, y2))
shots_ok <- shots %>% shots_ok <- shots %>%
dplyr::select(matchId, teamId, playerId, eventSec, matchPeriod) %>% dplyr::select(matchId, teamId, playerId, eventSec, matchPeriod) %>%
bind_cols(pos, tags2) %>% bind_cols(pos, tags2) %>%
@ -46,14 +46,14 @@ get_shots <- function(file_path, name_detail, save_files = F){
left_join(players %>% left_join(players %>%
dplyr::select(c("wyId", "foot")), by = c("playerId" = "wyId")) %>% dplyr::select(c("wyId", "foot")), by = c("playerId" = "wyId")) %>%
mutate(league = name_detail) mutate(league = name_detail)
if(save_files){ if(save_files){
write_rds(shots, paste0("shots", name_detail, ".rds")) write_rds(shots, paste0("shots", name_detail, ".rds"))
write_rds(tags2, paste0("tags2", name_detail, ".rds")) write_rds(tags2, paste0("tags2", name_detail, ".rds"))
write_rds(pos, paste0("pos", name_detail, ".rds")) write_rds(pos, paste0("pos", name_detail, ".rds"))
write_rds(shots_ok, paste0("unblocked_shots", name_detail, ".rds")) write_rds(shots_ok, paste0("unblocked_shots", name_detail, ".rds"))
} }
shots_ok shots_ok
} }
# shotsEN <- get_shots("data/events/events_England.json", "EN") # shotsEN <- get_shots("data/events/events_England.json", "EN")
@ -63,12 +63,12 @@ get_shots <- function(file_path, name_detail, save_files = F){
# shotsGE <- get_shots("data/events/events_Germany.json", "GE") # shotsGE <- get_shots("data/events/events_Germany.json", "GE")
# shotsFR <- get_shots("data/events/events_France.json", "FR") # shotsFR <- get_shots("data/events/events_France.json", "FR")
# shotsEC <- get_shots("data/events/events_European_Championship.json", "EC") # shotsEC <- get_shots("data/events/events_European_Championship.json", "EC")
# #
# shots <- shotsEN %>% # shots <- shotsEN %>%
# bind_rows(shotsFR, shotsGE, shotsIT, shotsSP, shotsWC, shotsEC) # bind_rows(shotsFR, shotsGE, shotsIT, shotsSP, shotsWC, shotsEC)
get_final_data <- function(data) { get_final_data <- function(data) {
data <- data %>% select(eventSec, y1, x1, is_goal, is_blocked, is_CA, body_part, foot) data <- data %>% select(eventSec, y1, x1, is_goal, is_blocked, is_CA, body_part, foot)
data$x1 <- (100 - data$x1) * 105/100 data$x1 <- (100 - data$x1) * 105/100
data$y1 <- data$y1 * data$y1/100 data$y1 <- data$y1 * data$y1/100
@ -77,7 +77,7 @@ get_final_data <- function(data) {
data <- data %>% mutate(distance = sqrt( (100 - x1)^2 + (34 - y1)^2), data <- data %>% mutate(distance = sqrt( (100 - x1)^2 + (34 - y1)^2),
minute = round(eventSec / 60), minute = round(eventSec / 60),
eventSec = round(eventSec)) eventSec = round(eventSec))
data data
} }
@ -89,14 +89,14 @@ get_final_data <- function(data) {
get_data <- function(event_path, info_path) { get_data <- function(event_path, info_path) {
events <- read.csv(event_path) events <- read.csv(event_path)
info <- read.csv(info_path) info <- read.csv(info_path)
events <- merge(events, info[, c('id_odsp', 'country', 'date')], by = 'id_odsp', all.x = TRUE) events <- merge(events, info[, c('id_odsp', 'country', 'date')], by = 'id_odsp', all.x = TRUE)
data <- subset(events, event_type == 1) data <- subset(events, event_type == 1)
data_final <- data %>% select(sort_order, time, shot_place, shot_outcome, is_goal, location, bodypart, assist_method, situation, data_final <- data %>% select(sort_order, time, shot_place, shot_outcome, is_goal, location, bodypart, assist_method, situation,
fast_break) fast_break)
data_final data_final
} }
# data2 <- get_data(event_path = "data/events.csv", info_path = "data/ginf.csv") # data2 <- get_data(event_path = "data/events.csv", info_path = "data/ginf.csv")
@ -124,18 +124,18 @@ loc2locdistance <- function(x1, y1, x2, y2) {
get_shots2 <- function(json_file) { get_shots2 <- function(json_file) {
data <- fromJSON(json_file) %>% filter(type$name == "Shot") %>% dplyr::select(c(minute, position, location, shot)) data <- fromJSON(json_file) %>% filter(type$name == "Shot") %>% dplyr::select(c(minute, position, location, shot))
df_temp <- do.call(rbind, lapply(data$location, function(loc) c(120, 80) - loc)) df_temp <- do.call(rbind, lapply(data$location, function(loc) c(120, 80) - loc))
colnames(df_temp) <- c("x1", "y1") colnames(df_temp) <- c("x1", "y1")
data$x1 <- df_temp[,1] data$x1 <- df_temp[,1]
data$y1 <- df_temp[,2] data$y1 <- df_temp[,2]
data$shot$freeze_frame <- Map(function(ff, x1, y1) { data$shot$freeze_frame <- Map(function(ff, x1, y1) {
ff$x1 <- yd_to_m(x1) ff$x1 <- yd_to_m(x1)
ff$y1 <- yd_to_m(y1) ff$y1 <- yd_to_m(y1)
return(ff) return(ff)
}, },
data$shot$freeze_frame, data$x1, data$y1) data$shot$freeze_frame, data$x1, data$y1)
tryCatch({ tryCatch({
@ -148,17 +148,17 @@ get_shots2 <- function(json_file) {
df <- df %>% mutate(teammate = ifelse(teammate, "teammate", "opponent"), df <- df %>% mutate(teammate = ifelse(teammate, "teammate", "opponent"),
distance = loc2locdistance(x1 = x, y1 = y, x2 = x1, y2 = y1)) %>% distance = loc2locdistance(x1 = x, y1 = y, x2 = x1, y2 = y1)) %>%
arrange(distance) arrange(distance)
groups_count <- df %>% group_by(teammate) %>% count() %>% as.data.frame() groups_count <- df %>% group_by(teammate) %>% count() %>% as.data.frame()
if ( !("opponent" %in% groups_count$teammate) ) { if ( !("opponent" %in% groups_count$teammate) ) {
groups_count <- groups_count %>% add_row(teammate = "opponent", n = 0) groups_count <- groups_count %>% add_row(teammate = "opponent", n = 0)
} else if ( !("teammate" %in% groups_count$teammate) ) { } else if ( !("teammate" %in% groups_count$teammate) ) {
groups_count <- groups_count %>% add_row(teammate = "teammate", n = 0) groups_count <- groups_count %>% add_row(teammate = "teammate", n = 0)
} }
na_df <- as.data.frame(matrix("na", nrow = 21 - nrow(df), ncol = ncol(df))) na_df <- as.data.frame(matrix("na", nrow = 21 - nrow(df), ncol = ncol(df)))
colnames(na_df) <- colnames(df) colnames(na_df) <- colnames(df)
na_df$teammate <- rep(c("opponent", "teammate"), c(11, 10) - groups_count$n) na_df$teammate <- rep(c("opponent", "teammate"), c(11, 10) - groups_count$n)
dff <- rbind(df, na_df) dff <- rbind(df, na_df)
dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number(distance)) %>% ungroup() %>% dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number(distance)) %>% ungroup() %>%
@ -170,9 +170,9 @@ get_shots2 <- function(json_file) {
dff <- as.data.frame(matrix("na", nrow = 21, ncol = 3)) dff <- as.data.frame(matrix("na", nrow = 21, ncol = 3))
colnames(dff) <- c("x", "y", "teammate") colnames(dff) <- c("x", "y", "teammate")
dff$teammate <- rep(c("opponent", "teammate"), c(11, 10)) dff$teammate <- rep(c("opponent", "teammate"), c(11, 10))
dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number()) %>% ungroup() %>% dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number()) %>% ungroup() %>%
mutate(position_teammate = paste(teammate, rown, sep = "_")) %>% mutate(position_teammate = paste(teammate, rown, sep = "_")) %>%
select(-c(teammate, rown)) %>% select(-c(teammate, rown)) %>%
mutate(x = ifelse(x == "na", NA, x), mutate(x = ifelse(x == "na", NA, x),
y = ifelse(x == "na", NA, y)) y = ifelse(x == "na", NA, y))
} }
@ -181,7 +181,7 @@ get_shots2 <- function(json_file) {
# %>% # %>%
# stop("123") # stop("123")
wider_df <- dff %>% wider_df <- dff %>%
pivot_wider(names_from = position_teammate, values_from = c(x, y), names_sep = "_player_") %>% pivot_wider(names_from = position_teammate, values_from = c(x, y), names_sep = "_player_") %>%
mutate(across(everything(), as.numeric)) mutate(across(everything(), as.numeric))
wider_df wider_df
# wider_df <- apply(wider_df, MARGIN = 2, unlist) # wider_df <- apply(wider_df, MARGIN = 2, unlist)
@ -193,7 +193,7 @@ get_shots2 <- function(json_file) {
print(paste("An error occurred:", e$message)) print(paste("An error occurred:", e$message))
}) })
df_players_location <- df_players_location %>% t() df_players_location <- df_players_location %>% t()
tryCatch({ # TODO reduce error cases tryCatch({ # TODO reduce error cases
data$number_of_players_opponents <- mapply(function(sublist, x1_threshold) { data$number_of_players_opponents <- mapply(function(sublist, x1_threshold) {
# Extracting the first location value and converting it to numeric # Extracting the first location value and converting it to numeric
@ -213,12 +213,12 @@ get_shots2 <- function(json_file) {
# handle the error # handle the error
print(paste("An error occurred:", e$message)) print(paste("An error occurred:", e$message))
}) })
tryCatch({ # TODO reduce error cases tryCatch({ # TODO reduce error cases
data$number_of_players_teammates <- mapply(function(sublist, x1_threshold) { data$number_of_players_teammates <- mapply(function(sublist, x1_threshold) {
# Extracting the first location value and converting it to numeric # Extracting the first location value and converting it to numeric
first_location_values <- sapply(sublist$location, function(loc) as.numeric(loc[1])) first_location_values <- sapply(sublist$location, function(loc) as.numeric(loc[1]))
if ("teammate" %in% names(sublist)) { if ("teammate" %in% names(sublist)) {
# Filtering and counting # Filtering and counting
res <- sum(sublist$teammate & first_location_values > x1_threshold) # error here res <- sum(sublist$teammate & first_location_values > x1_threshold) # error here
@ -233,71 +233,71 @@ get_shots2 <- function(json_file) {
# handle the error # handle the error
print(paste("An error occurred:", e$message)) print(paste("An error occurred:", e$message))
}) })
data$shot <- data$shot %>% select(-freeze_frame, -statsbomb_xg, -key_pass_id) data$shot <- data$shot %>% select(-freeze_frame, -statsbomb_xg, -key_pass_id)
data$shot$body_part <- data$shot$body_part %>% select(-id) data$shot$body_part <- data$shot$body_part %>% select(-id)
data$shot$technique <- data$shot$technique %>% select(-id) data$shot$technique <- data$shot$technique %>% select(-id)
data$shot$type <- data$shot$type %>% select(-id) data$shot$type <- data$shot$type %>% select(-id)
data$position <- data$position %>% select(-id) data$position <- data$position %>% select(-id)
data$shot <- data$shot %>% select(-end_location) data$shot <- data$shot %>% select(-end_location)
tryCatch({ # TODO reduce error cases tryCatch({ # TODO reduce error cases
if ("one_on_one" %in% colnames(data$shot)) { if ("one_on_one" %in% colnames(data$shot)) {
data[is.na(data$shot$one_on_one), ]$shot$one_on_one <- FALSE data[is.na(data$shot$one_on_one), ]$shot$one_on_one <- FALSE
} else { } else {
data$shot$one_on_one <- FALSE data$shot$one_on_one <- FALSE
} }
if ("first_time" %in% colnames(data$shot)) { if ("first_time" %in% colnames(data$shot)) {
data[is.na(data$shot$first_time), ]$shot$first_time <- FALSE data[is.na(data$shot$first_time), ]$shot$first_time <- FALSE
} else { } else {
data$shot$first_time <- FALSE data$shot$first_time <- FALSE
} }
if ("aerial_won" %in% colnames(data$shot)) { if ("aerial_won" %in% colnames(data$shot)) {
data[is.na(data$shot$aerial_won), ]$shot$aerial_won <- FALSE data[is.na(data$shot$aerial_won), ]$shot$aerial_won <- FALSE
} else { } else {
data$shot$aerial_won <- FALSE data$shot$aerial_won <- FALSE
} }
if ("saved_to_post" %in% colnames(data$shot)) { if ("saved_to_post" %in% colnames(data$shot)) {
data[is.na(data$shot$saved_to_post), ]$shot$saved_to_post <- FALSE data[is.na(data$shot$saved_to_post), ]$shot$saved_to_post <- FALSE
} else { } else {
data$shot$saved_to_post <- FALSE data$shot$saved_to_post <- FALSE
} }
if ("deflected" %in% colnames(data$shot)) { if ("deflected" %in% colnames(data$shot)) {
data[is.na(data$shot$deflected), ]$shot$deflected <- FALSE data[is.na(data$shot$deflected), ]$shot$deflected <- FALSE
} else { } else {
data$shot$deflected <- FALSE data$shot$deflected <- FALSE
} }
if ("saved_off_target" %in% colnames(data$shot)) { if ("saved_off_target" %in% colnames(data$shot)) {
data[is.na(data$shot$saved_off_target), ]$shot$saved_off_target <- FALSE data[is.na(data$shot$saved_off_target), ]$shot$saved_off_target <- FALSE
} else { } else {
data$shot$saved_off_target <- FALSE data$shot$saved_off_target <- FALSE
} }
if ("open_goal" %in% colnames(data$shot)) { if ("open_goal" %in% colnames(data$shot)) {
data[is.na(data$shot$open_goal), ]$shot$open_goal <- FALSE data[is.na(data$shot$open_goal), ]$shot$open_goal <- FALSE
} else { } else {
data$shot$open_goal <- FALSE data$shot$open_goal <- FALSE
} }
if ("follows_dribble" %in% colnames(data$shot)) { if ("follows_dribble" %in% colnames(data$shot)) {
data[is.na(data$shot$follows_dribble), ]$shot$follows_dribble <- FALSE data[is.na(data$shot$follows_dribble), ]$shot$follows_dribble <- FALSE
} else { } else {
data$shot$follows_dribble <- FALSE data$shot$follows_dribble <- FALSE
} }
if ("redirect" %in% colnames(data$shot)) { if ("redirect" %in% colnames(data$shot)) {
data[is.na(data$shot$redirect), ]$shot$redirect <- FALSE data[is.na(data$shot$redirect), ]$shot$redirect <- FALSE
} else { } else {
data$shot$redirect <- FALSE data$shot$redirect <- FALSE
} }
if ("kick_off" %in% colnames(data$kick_off)) { if ("kick_off" %in% colnames(data$kick_off)) {
data[is.na(data$shot$kick_off), ]$shotf$kick_off <- FALSE data[is.na(data$shot$kick_off), ]$shotf$kick_off <- FALSE
} else { } else {
@ -308,21 +308,21 @@ get_shots2 <- function(json_file) {
# handle the error # handle the error
print(paste("An error occurred:", e$message)) print(paste("An error occurred:", e$message))
}) })
data <- data %>% mutate(is_goal = ifelse(shot$outcome$id == 97, 1, 0), data <- data %>% mutate(is_goal = ifelse(shot$outcome$id == 97, 1, 0),
x1 = yd_to_m(x1) %>% round(., digits = 1), x1 = yd_to_m(x1) %>% round(., digits = 1),
y1 = yd_to_m(y1) %>% round(., digits = 1), y1 = yd_to_m(y1) %>% round(., digits = 1),
angle = loc2angle(x1, y1) %>% round(., digits = 1), angle = loc2angle(x1, y1) %>% round(., digits = 1),
distance = loc2distance(x = x1, y = y1)) %>% distance = loc2distance(x = x1, y = y1)) %>%
select(-location) select(-location)
data$shot$outcome <- data$shot$outcome %>% select(-id) data$shot$outcome <- data$shot$outcome %>% select(-id)
data <- data %>% unnest(shot, names_sep = "_") %>% data <- data %>% unnest(shot, names_sep = "_") %>%
unnest(position, names_sep = "_") %>% unnest(position, names_sep = "_") %>%
unnest(shot_type, names_sep = "_") %>% unnest(shot_type, names_sep = "_") %>%
unnest(shot_outcome, names_sep = "_") %>% unnest(shot_outcome, names_sep = "_") %>%
unnest(shot_technique, names_sep = "_") %>% unnest(shot_technique, names_sep = "_") %>%
unnest(shot_body_part, names_sep = "_") unnest(shot_body_part, names_sep = "_")
data <- cbind(data, df_players_location) data <- cbind(data, df_players_location)
data data
} }
@ -338,12 +338,12 @@ skimr::skim(combined_data)
data3_final <- combined_data %>% select(-c(shot_outcome_name, data3_final <- combined_data %>% select(-c(shot_outcome_name,
shot_saved_off_target, shot_saved_off_target,
shot_saved_to_post, shot_saved_to_post,
kick_off)) %>% kick_off)) %>%
mutate(shot_kick_off = ifelse(is.na(shot_kick_off), FALSE, shot_kick_off)) mutate(shot_kick_off = ifelse(is.na(shot_kick_off), FALSE, shot_kick_off))
pattern <- "^(x_player_|y_player_).*$" pattern <- "^(x_player_|y_player_).*$"
cols <- names(data3_final)[grepl(pattern, names(data3_final))] cols <- names(data3_final)[grepl(pattern, names(data3_final))]
data_final <- data3_final %>% unnest(all_of(cols)) data_final <- data3_final %>% unnest(all_of(cols))
skimr::skim(data_final) skimr::skim(data_final)
write_csv(data_final, file = "data/final_data.csv") write_csv(data_final, file = "data/final_data.csv")
#df_test <- read.csv("data/final_data.csv", nrows = 10000) df_test <- read.csv("data/final_data.csv", nrows = 1000)
##################### The fourth dataset ############################## ##################### The fourth dataset ##############################

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long