Author: Guillermo Vinue
Date: 2026-02-27

# Analysis of Spanish spatial shooting data

#### Guillermo Vinue

#### 2026-02-27

This document contains all the needed R code to reproduce the results described in the paper Adding shooting data to a centralized platform for basketball data visualization.

    # Firstly, load BAwiR:
    library(BAwiR)

An example for obtaining the spatial shooting data from the official ACB website is as follows. Define the analyst’s name, user agent and x_apikey accordingly.

    data_days <- do_scrape_days_acb("2024", "analyst_name", TRUE, 2)

    data_shots <- do_scrape_shots_acb(data_days[1:2, ], TRUE, "user_agent_def", "x_apikey")

BAwiR contains a sample of the shooting data from the ACB 2024-2025 regular season. We can see it with these commands:

    ?acb_shooting_data_2425
    head(acb_shooting_data_2425)

Players and teams belonging to the data frame can be obtained with these commands:

    sort(unique(acb_shooting_data_2425$player_name))
    sort(unique(acb_shooting_data_2425$full_name))

The basketball court is divided into 10 zones as follows:

    df0 <- do_divide_court_zones(acb_shooting_data_2425)

Several filters can be applied with the following function:

    df1 <- do_filter_data(df0, "2024-2025", "", "", "", "", "")

The violin and boxplots to investigate the data distributions and statistical summaries are created as follows:

    do_violin_box_plots(df1, acb_players_2425)

The plot of the shooting patterns of the entire league by zones can be obtained as follows:

    shots_stats <- do_shots_stats(df1, df0)

    do_viz_shots_scatter(shots_stats, "all", FALSE)

The plots with the location of each individual shot attempted by Dylan Ennis and his shooting patterns by zones can be obtained as follows:

    df1 <- do_filter_data(df0, "2024-2025", "", "", "", "", "D. Ennis")

    shots_stats <- do_shots_stats(df1, df0)

    do_viz_shots_scatter(shots_stats, "player", TRUE)
    do_viz_shots_scatter(shots_stats, "player", FALSE)

The plots with the comparison of the Ennis’ and league field goal percentage and the heatmap showing the distribution of Ennis’ shot attempts across the court can be obtained as follows:

    do_viz_shots_gradient(df1, "player", "none", df0)
    do_viz_shots_gradient(df1, "player", "fg", df0)

Finally, the code to create the stickers is as follows:

    data_player_eff <- data.frame(team = "Real Madrid",
                                  win_perc = "83.3% (5/6)",
                                  pts_poss = 114,
                                  pts_poss_opp = 104,
                                  net_rtg = 10)

    get_sticker(data_player_eff, acb_sticker_data_2526, "A. Abalde", "English")

    sessionInfo()

    ## R version 4.3.3 (2024-02-29)
    ## Platform: x86_64-redhat-linux-gnu (64-bit)
    ## Running under: Fedora Linux 39 (Workstation Edition)
    ##
    ## Matrix products: default
    ## BLAS/LAPACK: FlexiBLAS OPENBLAS-OPENMP;  LAPACK version 3.11.0
    ##
    ## locale:
    ##  [1] LC_CTYPE=es_ES.UTF-8       LC_NUMERIC=C
    ##  [3] LC_TIME=es_ES.UTF-8        LC_COLLATE=C
    ##  [5] LC_MONETARY=es_ES.UTF-8    LC_MESSAGES=es_ES.UTF-8
    ##  [7] LC_PAPER=es_ES.UTF-8       LC_NAME=C
    ##  [9] LC_ADDRESS=C               LC_TELEPHONE=C
    ## [11] LC_MEASUREMENT=es_ES.UTF-8 LC_IDENTIFICATION=C
    ##
    ## time zone: Europe/Madrid
    ## tzcode source: system (glibc)
    ##
    ## attached base packages:
    ## [1] stats     graphics  grDevices utils     datasets  methods   base
    ##
    ## loaded via a namespace (and not attached):
    ##  [1] digest_0.6.37     R6_2.6.1          fastmap_1.2.0     xfun_0.52
    ##  [5] cachem_1.1.0      knitr_1.50        htmltools_0.5.8.1 rmarkdown_2.29
    ##  [9] lifecycle_1.0.4   cli_3.6.5         sass_0.4.10       jquerylib_0.1.4
    ## [13] compiler_4.3.3    tools_4.3.3       evaluate_1.0.3    bslib_0.9.0
    ## [17] yaml_2.3.10       rlang_1.1.6       jsonlite_2.0.0