0

I'm beginning on Python I want to add patches to a facet-grid with the following code and I get AttributeError: 'FacetGrid' object has no attribute 'add_patch'. I've done some extensive research but can't find any solution to this issue.

import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.patches import Circle, Rectangle, Arc
sns.set_style("white")
sns.set_color_codes()

def draw_pitch(ax=None, color='black', lw=2, outer_lines=True):
# If an axes object isn't provided to plot onto, just get current one
if ax is None:
    ax = plt.gca()

I think there might be an issue with this plt.gca() but don't know how or if I should replace it?

# Create goal
goal = Rectangle((-15,0), 30, .5, linewidth=3, color=color)

# The box
box = Rectangle((-81, 0), 162, 66, linewidth=lw, color=color,
                      fill=False)

#6ybox
ybox = Rectangle((-37, 0), 74, 22, linewidth=lw, color=color, fill=False)

#Penaltyarc
Parc = Arc((0,44),73.4,73.4, theta1=37, theta2=143,linewidth=lw, color=color, fill=False)
#Penalty

PSpot = Circle((0,44),radius=.5, linewidth=lw, color=color, fill=False)
# List of the court elements to be plotted onto the axes
pitch_elements = [goal, box, ybox, PSpot,Parc]

if outer_lines:
    # Draw the half court line, baseline and side out bound lines
    outer_lines = Rectangle((-136, 0), 272, 210, linewidth=lw,
                            color=color, fill=False)
    pitch_elements.append(outer_lines)

# Add the court elements onto the axes
for element in pitch_elements:

    ax.add_patch(element)

return ax
plt.figure(figsize=(12,11))
draw_pitch(outer_lines=True)
plt.xlim(-136,136)
plt.ylim(0,210)

cmap = 'jet'
file = 'Chances23clean.csv'
df = pd.read_csv(file)
df.teamf=df.teamf.apply(str)

g = sns.FacetGrid(df, col="teamf", col_wrap=4,size=3.5,ylim=(210,0),xlim=(136,-136))

g = (g.map(sns.kdeplot,"primaryLocation_x", "primaryLocation_y", shade=True,cmap=cmap,n_levels=40).set_titles("{col_name}",fontsize=300).set_axis_labels("","").set_ylabels('').set_xticklabels('','').set_yticklabels(''))

draw_pitch(g)

OK so I've made some nice progress by doing the following. Instead of having on the above code :

draw_pitch(g)

I have replaced it by

draw_pitch(g.axes[0])
draw_pitch(g.axes[1])
draw_pitch(g.axes[2])
...
draw_pitch(g.axes[19])

And it works, but is there a way to simplify the code here? Thanks a lot.

MattnDo
  • 444
  • 1
  • 5
  • 17
  • You'd facilitate the process tremendously by providing a [mcve] of the issue. – ImportanceOfBeingErnest Feb 21 '17 at 09:34
  • @ImportanceOfBeingErnest As you may see I'm a total newbie into coding and in stackoverflow. I'm more than happy to improve my question, but not sure where to start to make it more readable? Thanks again for your help. – MattnDo Feb 21 '17 at 10:06
  • The main problem here is that your issue is not reproducible. That is, I am not able to copy the code and run it on my machine in order to help you locate and solve the problem. Therefore it is important to create a [mcve]. Such a minimal example should not use any files to read in unless the problem is directly related to the specific file in use, but rather use a generic DataFrame in this case. Also it needs to define all the objects in the code, e.g. in your code `pitch_elements` is undefined. – ImportanceOfBeingErnest Feb 21 '17 at 13:32
  • Thanks, I'll try to figure out how I can give a generic DataFrame since my .csv contains several variables. In this case the variables "primaryLocation_x / y" can be or an integer or "nan". – MattnDo Feb 21 '17 at 13:52

1 Answers1

0

Try to replace draw_pitch(g) by draw_pitch(g.axes[0, 0]). Facetgrid stores axes in a 2d numpy array but if facetgrid has only one axis you have to write g.ax.

pcu
  • 1,204
  • 11
  • 27
  • Just tried with `draw_pitch(g.axes[0, 0])` and I get `IndexError: too many indices for array`. When I tried with `draw_pitch(g.ax)` I get `AttributeError` – MattnDo Feb 21 '17 at 08:30
  • @Mattn can you report what `print g.axes.shape` results in? Does `g.axes[0]` give a different error? – ImportanceOfBeingErnest Feb 21 '17 at 09:33
  • Thanks for your answer! `print(g.axes.shape)` doesn't report anything, while `g.axes[0]` does not give any error but...draw a pitch only on the first top left facet of the facetgrid. – MattnDo Feb 21 '17 at 09:49
  • `print(g.axes.shape)` **cannot not** report anything. It either prints the information that we need here in the console, or it throws an error. Please tell us what this print statement gives you. – ImportanceOfBeingErnest Feb 21 '17 at 13:25
  • I might get something wrong but when I put `draw_pitch(g.axes[0]) print (g.axes.shape)` at the end of my code, I just get what I described: "it draws a pitch only on the first top left facet of the facetgrid" and nothing after. Hope this helps. – MattnDo Feb 21 '17 at 13:58
  • The print function is one of the fundamental functions in python. It will always work and it is **the** most important debugging tool available. If you are unable to use it, start familiarizing with it. – ImportanceOfBeingErnest Feb 21 '17 at 14:17