Клип Seaborn Kdeplot в границах PyPlot Фоновое изображение - PullRequest
0 голосов
/ 03 ноября 2018

Я хочу построить график снимков НХЛ и их распределения (через kdeplot Seaborn) на фоновом изображении катка НХЛ, предоставленного (x, y) координатами в кадре данных. Код, который у меня есть, генерирует график на 99% от того места, где я хочу, но я не уверен на 100%, как обрезать края карты выстрела так, чтобы она не выходила за границы загруженного изображения. .

import os
import random

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from PIL import Image, ImageDraw, ImageFont

random_events = ('SHOT', 'MISSED_SHOT', 'GOAL')
random_team = ('Preferred', 'Other')
events = list()

for i in range(30):
    event = dict()
    event['event_type'] = random.choice(random_events)
    event['team'] = random.choice(random_team)
    event['coords_x'] = round(random.uniform(-100, 100), 2)
    event['coords_y'] = round(random.uniform(-42.5, 42.5), 2)
    events.append(event)

df = pd.DataFrame(events)
pref_df = df.loc[df['team'] == 'Preferred']
other_df = df.loc[df['team'] == 'Other']

# Fix Coordinates
pref_df.loc[pref_df['coords_x'] < 0, ['coords_x', 'coords_y']] *= -1
other_df.loc[other_df['coords_x'] > 0, ['coords_x', 'coords_y']] *= -1

print(pref_df)
print(other_df)

MY_DPI = 96
IMG_WIDTH = 1024
IMG_HEIGHT = 440
fig = plt.figure(figsize=(IMG_WIDTH / MY_DPI, IMG_HEIGHT / MY_DPI), dpi=MY_DPI)
ax = fig.add_subplot(111, frameon=False, xticks=[], yticks=[])

ax_extent = [-100, 100, -42.5, 42.5]
img = Image.open('Rink-Shotmap-Blank.png')
plt.imshow(img, extent=ax_extent)

# Draw the seaborn portion of the graph
sns.set_style("white")
sns.kdeplot(pref_df.coords_x, pref_df.coords_y, cmap='Reds', shade=True, shade_lowest=False, alpha=0.6)
sns.kdeplot(other_df.coords_x, other_df.coords_y, cmap="Blues", shade=True, shade_lowest=False, alpha=0.6)

# Hide all axes & bounding boxes
ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
ax.set_frame_on(False)
ax.axis('off')

plt.show()

Rink Shotmap

Есть ли способ обрезать kdeplot по границам фонового изображения (загружается через ax.imshow)? Я попытался создать объект Path, который представляет собой прямоугольник размером с экстент, но безуспешно.

Если есть какие-либо другие предложения относительно того, как генерируется этот код, это будет очень полезно, так как эти новые библиотеки визуализации являются относительно новыми для меня.

Спасибо

1 Ответ

0 голосов
/ 05 ноября 2018

Было бы неплохо включить Minimal, Complete и Verifiable пример , чтобы люди могли подыгрывать предоставленному вами коду. Но в любом случае, используя пример кода из sns.kdeplot () и используя демонстрацию matplotlib: Отсечение изображений с патчами , довольно просто обрезать PathCollection объекты, созданные kdeplot с использованием произвольного Patch

iris = sns.load_dataset("iris")
setosa = iris.loc[iris.species == "setosa"]
virginica = iris.loc[iris.species == "virginica"]
ax = sns.kdeplot(setosa.sepal_width, setosa.sepal_length,
                 cmap="Reds", shade=True, shade_lowest=False)
ax = sns.kdeplot(virginica.sepal_width, virginica.sepal_length,
                 cmap="Blues", shade=True, shade_lowest=False)

# create a Patch object, here in data coordinates to clip the KDE plots
p = matplotlib.patches.Rectangle(xy=[2.5,5], width=2, height=3, transform=ax.transData, facecolor="xkcd:greenish", alpha=0.3, zorder=-1)
for col in ax.collections:
    col.set_clip_path(p)

# simply for demonstration, show the patch on the axes (optional)    
ax.add_patch(p)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...