在PyPlot背景图像范围内剪辑Seaborn Kdeplot

时间:2018-11-03 12:07:15

标签: python matplotlib seaborn

我想在Dataframe中由(x,y)坐标提供的NHL溜冰场的背景图像上绘制NHL镜头及其分布(通过Seaborn kdeplot)的图形。我编写的代码以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裁剪到background image的边界上(通过ax.imshow加载)?我尝试创建一个Path对象,该对象是一个矩形,大小为范围的大小,但是没有运气。

如果对生成此代码的方式还有其他建议,将不胜感激,因为这些新的可视化库对我来说还相对较新。

谢谢

1 个答案:

答案 0 :(得分:0)

最好包含一个Minimal, Complete, and Verifiable example,以便人们可以随您提供的代码一起玩。但是无论如何,使用sns.kdeplot()中的示例代码并使用matplotlib演示:Clipping images with patches,使用任意{{来裁剪PathCollection创建的kdeplot对象是相当简单的1}}

Patch

enter image description here

相关问题