Welcome to the Blaseball Notebooks tutorial! Here we'll go into details about the scripts used and how you can modify them to perform your own data analysis. This tutorial is entirely optional, you can still read the static notebooks without having to modify them yourself!
All the notebooks operate as snippets of Python code that run in order. All the data in this file was generated when I ran it, but you can rerun them yourself using Binder. Click the "Open in Binder" icon in the top-right corner and wait until it loads. Then you can modify and run individual snippets of code by using the provided interface. A quick rundown of it can be found here. Changes wont be saved in Binder, so download a copy if needed!
Note that the snippets are meant to be run in order, so you may run into problems if you only run one at a time. All notebooks will start with a setup snippet to get everything up and running, like below.
%matplotlib inline
from display import *
from blessings import *
The foundation of most of the code is using data retrieved from the blaseball
website itself. The APIs to access these have been well documented by SIBR, and are
wrapped in a library named blaseball-mike
for ease of access. We'll be going over
examples for each type of data as we go.
Note: Because we load directly from the website it does not work when the site is down. It also tends to take longer when games are running as there is more strain on the servers.
For more information, documentation can be found below:
https://jmaliksi.github.io/blaseball-mike/docs/blaseball_mike/index.html
https://docs.sibr.dev/docs/apis/reference/Blaseball-API.v1.yaml
# Let's check out good boy Beasley
beasley = Player.find_by_name("Beasley Day")
display_player(beasley)
# But what about Beasley's stlats?
get_batting_stlats(beasley)
Thwackability | Divinity | Musclitude | Moxie | Patheticism | Martyrdom | Tragicness | Buoyancy | |
---|---|---|---|---|---|---|---|---|
Beasley Day | 0.685 | 0.688801 | 0.077669 | 0.208479 | 0.468964 | 0.523706 | 0.1 | 0.753672 |
# And his baserunning?
get_baserunning_stlats(beasley)
Laserlikeness | Continuation | Base Thirst | Indulgence | Ground Friction | |
---|---|---|---|---|---|
Beasley Day | 0.396098 | 0.416221 | 0.961669 | 0.330239 | 0.673205 |
# Why not defense?
get_defense_stlats(beasley)
Omniscience | Tenaciousness | Watchfulness | Anticapitalism | Chasiness | |
---|---|---|---|---|---|
Beasley Day | 0.11034 | 0.14211 | 0.934442 | 0.198512 | 0.275182 |
# We can also get performance stats from Blaseball Reference!
# Note: you have to use separate code blocks for each stlat/stat lookup
get_batting_stats(beasley, season=11)
team_valid_from | team_valid_until | appearances | batting_average | on_base_percentage | slugging | plate_appearances | at_bats | hits | walks | singles | doubles | triples | quadruples | home_runs | runs_batted_in | strikeouts | sacrifice_bunts | sacrifice_flies | at_bats_risp | hits_risp | batting_average_risp | on_base_slugging | total_bases | hit_by_pitches | ground_outs | flyouts | gidp | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Beasley Day | 2020-10-25T19:42:22.164Z | None | 99 | 0.268 | 0.300 | 0.485 | 566 | 534 | 143 | 27 | 103 | 9 | 13 | 0 | 18 | 61 | 80 | 3 | 2 | 89 | 23 | 0.258 | 0.785 | 259 | 0 | 152 | 129 | 6 |
# Let's see that Team page!
pies = Team.load_by_name("Philly Pies")
display_team(pies)
# Just like with players, we can look up the stlats for the whole team
get_pitching_stlats(pies.rotation)
Unthwackability | Ruthlessness | Overpowerment | Shakespearianism | Coldness | Suppression | |
---|---|---|---|---|---|---|
Henry Marshallow | 0.233266 | 0.882016 | 1.123135 | 0.484581 | 0.571587 | 0.656728 |
Nicholas Mora | 1.140948 | 0.343723 | 0.553609 | 0.367345 | 0.482330 | 0.431032 |
Bright Zimmerman | 0.207882 | 0.511157 | 0.852666 | 0.679224 | 0.303950 | 0.870961 |
Ruslan Greatness | 0.484582 | 0.481892 | 0.944604 | 0.726276 | 0.320791 | 1.085039 |
Elvis Figueroa | 1.036387 | 1.015972 | 0.930460 | 0.689138 | 0.328725 | 0.592661 |
# And the same with stats
get_pitching_stats(pies.rotation, season=11)
team_valid_from | team_valid_until | games | wins | losses | win_pct | pitches_thrown | batters_faced | outs_recorded | innings | runs_allowed | shutouts | quality_starts | strikeouts | walks | home_runs_allowed | hits_allowed | hit_by_pitches | earned_run_average | walks_per_9 | hits_per_9 | strikeouts_per_9 | home_runs_per_9 | whip | strikeouts_per_walk | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Bright Zimmerman | 2020-10-25T19:42:22.164Z | None | 20 | 8 | 12 | 0.40 | 2320 | 802 | 543 | 181.0 | 122 | 0 | 4 | 90 | 48 | 21 | 234 | 0 | 6.07 | 2.39 | 11.64 | 4.48 | 1.04 | 1.731 | 1.88 |
Elvis Figueroa | 2020-10-25T19:42:22.164Z | None | 19 | 9 | 10 | 0.47 | 1716 | 666 | 501 | 167.0 | 68 | 1 | 11 | 127 | 8 | 18 | 172 | 0 | 3.66 | 0.43 | 9.27 | 6.84 | 0.97 | 1.198 | 15.88 |
Henry Marshallow | 2020-10-25T19:42:22.164Z | None | 20 | 8 | 12 | 0.40 | 2137 | 778 | 549 | 183.0 | 99 | 1 | 7 | 121 | 22 | 23 | 216 | 0 | 4.87 | 1.08 | 10.62 | 5.95 | 1.13 | 1.445 | 5.50 |
Nicholas Mora | 2020-10-25T19:42:22.164Z | None | 20 | 6 | 14 | 0.30 | 2277 | 779 | 532 | 177.1 | 115 | 1 | 4 | 69 | 83 | 27 | 176 | 0 | 5.84 | 4.21 | 8.93 | 3.50 | 1.37 | 1.623 | 0.83 |
Ruslan Greatness | 2020-10-25T19:42:22.164Z | None | 20 | 9 | 11 | 0.45 | 2286 | 787 | 541 | 180.1 | 113 | 1 | 5 | 95 | 64 | 20 | 195 | 0 | 5.64 | 3.19 | 9.73 | 4.74 | 1.00 | 1.596 | 1.48 |
# Let's relive some fun history
test_game = Game.load_by_season(season=4, day=43, team_id=pies.id)
display_game_results(test_game)
# Let's grab the Season 2 Pies, for nostalgia
# Format is <YEAR>-<MONTH>-<DAY>T<HOUR>:<MINUTE>:<SECOND>Z
# Note: Historical records only go back as far as mid-Season 2
mid_season_2 = "2020-07-29T18:00:00Z"
old_pies = Team.load_at_time(pies.id, time=mid_season_2)
display_team(old_pies)
# Oh hey, that was pre-AR Betsy. I wonder what her stlats looked like back then?
betsy_current = Player.find_by_name("Betsy Trombone")
betsy_old = Player.load_one_at_time(betsy_current.id, time=mid_season_2)
get_pitching_stlats([betsy_old, betsy_current])
Unthwackability | Ruthlessness | Overpowerment | Shakespearianism | Coldness | Suppression | |
---|---|---|---|---|---|---|
Betsy Trombone | 0.418548 | 0.725370 | 0.473664 | 0.474900 | 0.872849 | 0.021753 |
Betsy Trombone | 0.088462 | 0.920057 | 0.591330 | 0.317521 | 0.629130 | 0.704190 |