Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -408,151 +408,160 @@ def server(input, output, session):
|
|
| 408 |
player_name = batter_name_id[batter_id]
|
| 409 |
stats = [merged_dict[x]['stat_title'] for x in merged_dict.keys()]
|
| 410 |
|
| 411 |
-
# Calculate percentiles and values
|
| 412 |
-
percentiles = [int((1 - x) * 100) if merged_dict[stat]["percentile_flip"] else int(x * 100) for x, stat in zip(new_player_percentiles.select(merged_dict.keys()).to_numpy()[0], merged_dict.keys())]
|
| 413 |
-
percentiles = np.clip(percentiles, 1, 100)
|
| 414 |
-
values = [str(f'{x:{merged_dict[stat]["format"]}}').strip('%') for x, stat in zip(new_player_metrics.select(merged_dict.keys()).to_numpy()[0], merged_dict.keys())]
|
| 415 |
-
|
| 416 |
-
# Get team logo URL
|
| 417 |
-
try:
|
| 418 |
-
logo_url = image_dict[team_dict[player_team_dict[batter_id]]]
|
| 419 |
-
except KeyError:
|
| 420 |
-
logo_url = "https://a.espncdn.com/combiner/i?img=/i/teamlogos/leagues/500/mlb.png&w=500&h=500"
|
| 421 |
-
|
| 422 |
-
# Create a custom colormap
|
| 423 |
-
color_list = ['#3661AD', '#B4CFD1', '#D82129']
|
| 424 |
-
cmap = LinearSegmentedColormap.from_list("custom_cmap", color_list)
|
| 425 |
-
norm = Normalize(vmin=0.1, vmax=0.9)
|
| 426 |
-
norm_percentiles = norm(percentiles / 100)
|
| 427 |
-
colors = [cmap(p) for p in norm_percentiles]
|
| 428 |
-
|
| 429 |
-
# Figure setup
|
| 430 |
-
num_stats = len(stats)
|
| 431 |
-
bar_height = 4.5
|
| 432 |
-
spacing = 1
|
| 433 |
-
fig_height = (bar_height + spacing) * num_stats
|
| 434 |
-
fig = plt.figure(figsize=(12, 12))
|
| 435 |
-
gs = GridSpec(6, 5, height_ratios=[0.1, 1.5, 0.9, 0.9, 7.6, 0.1], width_ratios=[0.2, 1.5, 7, 1.5, 0.2])
|
| 436 |
|
| 437 |
-
|
| 438 |
-
ax_title = fig.add_subplot(gs[1, 2])
|
| 439 |
-
ax_table = fig.add_subplot(gs[2, :])
|
| 440 |
-
ax_fv_table = fig.add_subplot(gs[3, :])
|
| 441 |
-
ax_fv_table.axis('off')
|
| 442 |
-
ax = fig.add_subplot(gs[4, :])
|
| 443 |
-
ax_logo = fig.add_subplot(gs[1, 3])
|
| 444 |
-
|
| 445 |
-
ax.set_xlim(-1, 99)
|
| 446 |
-
ax.set_ylim(-1, 99)
|
| 447 |
-
ax.set_aspect("equal")
|
| 448 |
-
ax.axis("off")
|
| 449 |
-
|
| 450 |
-
# Draw each bar
|
| 451 |
-
for i, (stat, percentile, value, color) in enumerate(zip(stats, percentiles, values, colors)):
|
| 452 |
-
y = fig_height - (i + 1) * (bar_height + spacing)
|
| 453 |
-
ax.add_patch(patches.Rectangle((0, y + bar_height / 4), 100, bar_height / 2, color="#C7DCDC", lw=0))
|
| 454 |
-
ax.add_patch(patches.Rectangle((0, y), percentile, bar_height, color=color, lw=0))
|
| 455 |
-
circle_y = y + bar_height - bar_height / 2
|
| 456 |
-
circle = plt.Circle((percentile, circle_y), bar_height / 2, color=color, ec='white', lw=1.5, zorder=10)
|
| 457 |
-
ax.add_patch(circle)
|
| 458 |
-
fs = 14
|
| 459 |
-
ax.text(percentile, circle_y, f"{percentile}", ha="center", va="center", fontsize=10, color='white', zorder=10, fontweight='bold')
|
| 460 |
-
ax.text(-5, y + bar_height / 2, stat, ha="right", va="center", fontsize=fs)
|
| 461 |
-
ax.text(115, y + bar_height / 2, str(value), ha="right", va="center", fontsize=fs, zorder=5)
|
| 462 |
-
if i < len(stats) and i > 0:
|
| 463 |
-
ax.hlines(y=y + bar_height + spacing / 2, color='#399098', linestyle=(0, (5, 5)), linewidth=1, xmin=-33, xmax=0)
|
| 464 |
-
ax.hlines(y=y + bar_height + spacing / 2, color='#399098', linestyle=(0, (5, 5)), linewidth=1, xmin=100, xmax=115)
|
| 465 |
-
|
| 466 |
-
# Draw vertical lines for 10%, 50%, and 90% with labels
|
| 467 |
-
for x, label, align, color in zip([10, 50, 90], ["Poor", "Average", "Great"], ['center', 'center', 'center'], color_list):
|
| 468 |
-
ax.axvline(x=x, ymin=0, ymax=1, color='#FFF', linestyle='-', lw=1, zorder=1, alpha=0.5)
|
| 469 |
-
ax.text(x, fig_height + 4, label, ha=align, va='center', fontsize=12, fontweight='bold', color=color)
|
| 470 |
-
triangle = patches.RegularPolygon((x, fig_height + 1), 3, radius=1, orientation=0, color=color, zorder=2)
|
| 471 |
-
ax.add_patch(triangle)
|
| 472 |
-
|
| 473 |
-
# # Title
|
| 474 |
-
# ax_title.set_ylim(0, 1)
|
| 475 |
-
# ax_title.text(0.5, 0.5, f"{player_name} - {player_position_dict[batter_id]}\nPercentile Rankings - 2024 AAA", ha="center", va="center", fontsize=24)
|
| 476 |
-
# ax_title.axis("off")
|
| 477 |
-
player_bio(batter_id, ax=ax_title, sport_id=sport_id, year_input=year_input)
|
| 478 |
-
|
| 479 |
-
# Add team logo
|
| 480 |
-
#response = requests.get(logo_url)
|
| 481 |
-
if input.switch():
|
| 482 |
-
response = requests.get(input.logo_select())
|
| 483 |
-
else:
|
| 484 |
-
response = requests.get(logo_url)
|
| 485 |
-
img = Image.open(BytesIO(response.content))
|
| 486 |
-
ax_logo.imshow(img)
|
| 487 |
-
ax_logo.axis("off")
|
| 488 |
-
ax.axis('equal')
|
| 489 |
-
|
| 490 |
-
# Metrics data table
|
| 491 |
-
metrics_data = {
|
| 492 |
-
"Pitches": new_player_metrics['pitches'][0],
|
| 493 |
-
"PA": new_player_metrics['pa'][0],
|
| 494 |
-
"BIP": new_player_metrics['bip'][0],
|
| 495 |
-
"HR": f"{new_player_metrics['home_run'][0]:.0f}",
|
| 496 |
-
"AVG": f"{new_player_metrics['avg'][0]:.3f}",
|
| 497 |
-
"OBP": f"{new_player_metrics['obp'][0]:.3f}",
|
| 498 |
-
"SLG": f"{new_player_metrics['slg'][0]:.3f}",
|
| 499 |
-
"OPS": f"{new_player_metrics['obp'][0] + new_player_metrics['slg'][0]:.3f}",
|
| 500 |
-
}
|
| 501 |
-
df_table = pd.DataFrame(metrics_data, index=[0])
|
| 502 |
-
ax_table.axis('off')
|
| 503 |
-
table = ax_table.table(cellText=df_table.values, colLabels=df_table.columns, cellLoc='center', loc='bottom', bbox=[0.07, 0, 0.86, 1])
|
| 504 |
-
for key, cell in table.get_celld().items():
|
| 505 |
-
if key[0] == 0:
|
| 506 |
-
cell.set_text_props(fontweight='bold')
|
| 507 |
-
table.auto_set_font_size(False)
|
| 508 |
-
table.set_fontsize(12)
|
| 509 |
-
table.scale(1, 1.5)
|
| 510 |
-
|
| 511 |
-
# Additional subplots for spacing
|
| 512 |
-
ax_top = fig.add_subplot(gs[0, :])
|
| 513 |
-
ax_bot = fig.add_subplot(gs[-1, :])
|
| 514 |
-
ax_top.axis('off')
|
| 515 |
-
ax_bot.axis('off')
|
| 516 |
-
ax_bot.text(0.05, 2, "By: Thomas Nestico (@TJStats)", ha="left", va="center", fontsize=14)
|
| 517 |
-
ax_bot.text(0.95, 2, "Data: MLB, Fangraphs", ha="right", va="center", fontsize=14)
|
| 518 |
-
fig.subplots_adjust(left=0.01, right=0.99, top=0.99, bottom=0.01)
|
| 519 |
|
| 520 |
-
# Player headshot
|
| 521 |
-
ax_headshot = fig.add_subplot(gs[1, 1])
|
| 522 |
try:
|
| 523 |
-
|
| 524 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 525 |
img = Image.open(BytesIO(response.content))
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 530 |
ax_headshot.axis('off')
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
|
| 549 |
-
|
| 550 |
-
|
| 551 |
-
|
| 552 |
-
|
| 553 |
-
table_fv.scale(1, 1.5)
|
| 554 |
-
ax_fv_table.set_title('Fangraphs Scouting Grades', style='italic')
|
| 555 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 556 |
|
| 557 |
|
| 558 |
#plt.show()
|
|
|
|
| 408 |
player_name = batter_name_id[batter_id]
|
| 409 |
stats = [merged_dict[x]['stat_title'] for x in merged_dict.keys()]
|
| 410 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 411 |
|
| 412 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
|
|
|
|
|
|
|
| 414 |
try:
|
| 415 |
+
|
| 416 |
+
# Calculate percentiles and values
|
| 417 |
+
percentiles = [int((1 - x) * 100) if merged_dict[stat]["percentile_flip"] else int(x * 100) for x, stat in zip(new_player_percentiles.select(merged_dict.keys()).to_numpy()[0], merged_dict.keys())]
|
| 418 |
+
percentiles = np.clip(percentiles, 1, 100)
|
| 419 |
+
values = [str(f'{x:{merged_dict[stat]["format"]}}').strip('%') for x, stat in zip(new_player_metrics.select(merged_dict.keys()).to_numpy()[0], merged_dict.keys())]
|
| 420 |
+
|
| 421 |
+
# Get team logo URL
|
| 422 |
+
try:
|
| 423 |
+
logo_url = image_dict[team_dict[player_team_dict[batter_id]]]
|
| 424 |
+
except KeyError:
|
| 425 |
+
logo_url = "https://a.espncdn.com/combiner/i?img=/i/teamlogos/leagues/500/mlb.png&w=500&h=500"
|
| 426 |
+
|
| 427 |
+
# Create a custom colormap
|
| 428 |
+
color_list = ['#3661AD', '#B4CFD1', '#D82129']
|
| 429 |
+
cmap = LinearSegmentedColormap.from_list("custom_cmap", color_list)
|
| 430 |
+
norm = Normalize(vmin=0.1, vmax=0.9)
|
| 431 |
+
norm_percentiles = norm(percentiles / 100)
|
| 432 |
+
colors = [cmap(p) for p in norm_percentiles]
|
| 433 |
+
|
| 434 |
+
# Figure setup
|
| 435 |
+
num_stats = len(stats)
|
| 436 |
+
bar_height = 4.5
|
| 437 |
+
spacing = 1
|
| 438 |
+
fig_height = (bar_height + spacing) * num_stats
|
| 439 |
+
fig = plt.figure(figsize=(12, 12))
|
| 440 |
+
gs = GridSpec(6, 5, height_ratios=[0.1, 1.5, 0.9, 0.9, 7.6, 0.1], width_ratios=[0.2, 1.5, 7, 1.5, 0.2])
|
| 441 |
+
|
| 442 |
+
# Define subplots
|
| 443 |
+
ax_title = fig.add_subplot(gs[1, 2])
|
| 444 |
+
ax_table = fig.add_subplot(gs[2, :])
|
| 445 |
+
ax_fv_table = fig.add_subplot(gs[3, :])
|
| 446 |
+
ax_fv_table.axis('off')
|
| 447 |
+
ax = fig.add_subplot(gs[4, :])
|
| 448 |
+
ax_logo = fig.add_subplot(gs[1, 3])
|
| 449 |
+
|
| 450 |
+
ax.set_xlim(-1, 99)
|
| 451 |
+
ax.set_ylim(-1, 99)
|
| 452 |
+
ax.set_aspect("equal")
|
| 453 |
+
ax.axis("off")
|
| 454 |
+
|
| 455 |
+
# Draw each bar
|
| 456 |
+
for i, (stat, percentile, value, color) in enumerate(zip(stats, percentiles, values, colors)):
|
| 457 |
+
y = fig_height - (i + 1) * (bar_height + spacing)
|
| 458 |
+
ax.add_patch(patches.Rectangle((0, y + bar_height / 4), 100, bar_height / 2, color="#C7DCDC", lw=0))
|
| 459 |
+
ax.add_patch(patches.Rectangle((0, y), percentile, bar_height, color=color, lw=0))
|
| 460 |
+
circle_y = y + bar_height - bar_height / 2
|
| 461 |
+
circle = plt.Circle((percentile, circle_y), bar_height / 2, color=color, ec='white', lw=1.5, zorder=10)
|
| 462 |
+
ax.add_patch(circle)
|
| 463 |
+
fs = 14
|
| 464 |
+
ax.text(percentile, circle_y, f"{percentile}", ha="center", va="center", fontsize=10, color='white', zorder=10, fontweight='bold')
|
| 465 |
+
ax.text(-5, y + bar_height / 2, stat, ha="right", va="center", fontsize=fs)
|
| 466 |
+
ax.text(115, y + bar_height / 2, str(value), ha="right", va="center", fontsize=fs, zorder=5)
|
| 467 |
+
if i < len(stats) and i > 0:
|
| 468 |
+
ax.hlines(y=y + bar_height + spacing / 2, color='#399098', linestyle=(0, (5, 5)), linewidth=1, xmin=-33, xmax=0)
|
| 469 |
+
ax.hlines(y=y + bar_height + spacing / 2, color='#399098', linestyle=(0, (5, 5)), linewidth=1, xmin=100, xmax=115)
|
| 470 |
+
|
| 471 |
+
# Draw vertical lines for 10%, 50%, and 90% with labels
|
| 472 |
+
for x, label, align, color in zip([10, 50, 90], ["Poor", "Average", "Great"], ['center', 'center', 'center'], color_list):
|
| 473 |
+
ax.axvline(x=x, ymin=0, ymax=1, color='#FFF', linestyle='-', lw=1, zorder=1, alpha=0.5)
|
| 474 |
+
ax.text(x, fig_height + 4, label, ha=align, va='center', fontsize=12, fontweight='bold', color=color)
|
| 475 |
+
triangle = patches.RegularPolygon((x, fig_height + 1), 3, radius=1, orientation=0, color=color, zorder=2)
|
| 476 |
+
ax.add_patch(triangle)
|
| 477 |
+
|
| 478 |
+
# # Title
|
| 479 |
+
# ax_title.set_ylim(0, 1)
|
| 480 |
+
# ax_title.text(0.5, 0.5, f"{player_name} - {player_position_dict[batter_id]}\nPercentile Rankings - 2024 AAA", ha="center", va="center", fontsize=24)
|
| 481 |
+
# ax_title.axis("off")
|
| 482 |
+
player_bio(batter_id, ax=ax_title, sport_id=sport_id, year_input=year_input)
|
| 483 |
+
|
| 484 |
+
# Add team logo
|
| 485 |
+
#response = requests.get(logo_url)
|
| 486 |
+
if input.switch():
|
| 487 |
+
response = requests.get(input.logo_select())
|
| 488 |
+
else:
|
| 489 |
+
response = requests.get(logo_url)
|
| 490 |
img = Image.open(BytesIO(response.content))
|
| 491 |
+
ax_logo.imshow(img)
|
| 492 |
+
ax_logo.axis("off")
|
| 493 |
+
ax.axis('equal')
|
| 494 |
+
|
| 495 |
+
# Metrics data table
|
| 496 |
+
metrics_data = {
|
| 497 |
+
"Pitches": new_player_metrics['pitches'][0],
|
| 498 |
+
"PA": new_player_metrics['pa'][0],
|
| 499 |
+
"BIP": new_player_metrics['bip'][0],
|
| 500 |
+
"HR": f"{new_player_metrics['home_run'][0]:.0f}",
|
| 501 |
+
"AVG": f"{new_player_metrics['avg'][0]:.3f}",
|
| 502 |
+
"OBP": f"{new_player_metrics['obp'][0]:.3f}",
|
| 503 |
+
"SLG": f"{new_player_metrics['slg'][0]:.3f}",
|
| 504 |
+
"OPS": f"{new_player_metrics['obp'][0] + new_player_metrics['slg'][0]:.3f}",
|
| 505 |
+
}
|
| 506 |
+
df_table = pd.DataFrame(metrics_data, index=[0])
|
| 507 |
+
ax_table.axis('off')
|
| 508 |
+
table = ax_table.table(cellText=df_table.values, colLabels=df_table.columns, cellLoc='center', loc='bottom', bbox=[0.07, 0, 0.86, 1])
|
| 509 |
+
for key, cell in table.get_celld().items():
|
| 510 |
+
if key[0] == 0:
|
| 511 |
+
cell.set_text_props(fontweight='bold')
|
| 512 |
+
table.auto_set_font_size(False)
|
| 513 |
+
table.set_fontsize(12)
|
| 514 |
+
table.scale(1, 1.5)
|
| 515 |
+
|
| 516 |
+
# Additional subplots for spacing
|
| 517 |
+
ax_top = fig.add_subplot(gs[0, :])
|
| 518 |
+
ax_bot = fig.add_subplot(gs[-1, :])
|
| 519 |
+
ax_top.axis('off')
|
| 520 |
+
ax_bot.axis('off')
|
| 521 |
+
ax_bot.text(0.05, 2, "By: Thomas Nestico (@TJStats)", ha="left", va="center", fontsize=14)
|
| 522 |
+
ax_bot.text(0.95, 2, "Data: MLB, Fangraphs", ha="right", va="center", fontsize=14)
|
| 523 |
+
fig.subplots_adjust(left=0.01, right=0.99, top=0.99, bottom=0.01)
|
| 524 |
+
|
| 525 |
+
# Player headshot
|
| 526 |
+
ax_headshot = fig.add_subplot(gs[1, 1])
|
| 527 |
+
try:
|
| 528 |
+
url = f'https://img.mlbstatic.com/mlb-photos/image/upload/c_fill,g_auto/w_640/v1/people/{batter_id}/headshot/milb/current.png'
|
| 529 |
+
response = requests.get(url)
|
| 530 |
+
img = Image.open(BytesIO(response.content))
|
| 531 |
+
ax_headshot.set_xlim(0, 1)
|
| 532 |
+
ax_headshot.set_ylim(0, 1)
|
| 533 |
+
ax_headshot.imshow(img, extent=[1/6, 5/6, 0, 1], origin='upper')
|
| 534 |
+
except PIL.UnidentifiedImageError:
|
| 535 |
+
ax_headshot.axis('off')
|
| 536 |
+
#return
|
| 537 |
ax_headshot.axis('off')
|
| 538 |
+
ax_table.set_title('Season Summary', style='italic')
|
| 539 |
+
|
| 540 |
+
# Fangraphs scouting grades table
|
| 541 |
+
print(batter_id)
|
| 542 |
+
|
| 543 |
+
if batter_id not in dict_mlb_fg.keys():
|
| 544 |
+
ax_fv_table.text(x=0.5, y=0.5, s='No Scouting Data', style='italic', ha='center', va='center', fontsize=20, bbox=dict(facecolor='white', alpha=1, pad=10))
|
| 545 |
+
return
|
| 546 |
+
df_fv_table = df_prospects[(df_prospects['minorMasterId'] == dict_mlb_fg[batter_id])][['cFV', 'Hit', 'Game', 'Raw', 'Spd', 'Fld']].reset_index(drop=True)
|
| 547 |
+
ax_fv_table.axis('off')
|
| 548 |
+
if df_fv_table.empty:
|
| 549 |
+
ax_fv_table.text(x=0.5, y=0.5, s='No Scouting Data', style='italic', ha='center', va='center', fontsize=20, bbox=dict(facecolor='white', alpha=1, pad=10))
|
| 550 |
+
return
|
| 551 |
+
df_fv_table.columns = ['FV', 'Hit', 'Game', 'Raw', 'Spd', 'Fld']
|
| 552 |
+
table_fv = ax_fv_table.table(cellText=df_fv_table.values, colLabels=df_fv_table.columns, cellLoc='center', loc='bottom', bbox=[0.07, 0, 0.86, 1])
|
| 553 |
+
for key, cell in table_fv.get_celld().items():
|
| 554 |
+
if key[0] == 0:
|
| 555 |
+
cell.set_text_props(fontweight='bold')
|
| 556 |
+
table_fv.auto_set_font_size(False)
|
| 557 |
+
table_fv.set_fontsize(12)
|
| 558 |
+
table_fv.scale(1, 1.5)
|
| 559 |
+
ax_fv_table.set_title('Fangraphs Scouting Grades', style='italic')
|
|
|
|
|
|
|
| 560 |
|
| 561 |
+
except ValueError:
|
| 562 |
+
fig = plt.figure(figsize=(26,26))
|
| 563 |
+
fig.text(x=0.1,y=0.9,s='No Statcast Data For This Batter',fontsize=36,ha='left')
|
| 564 |
+
return fig
|
| 565 |
|
| 566 |
|
| 567 |
#plt.show()
|