Errors for catplot in Medical Data Visualizer Challenge

Tell us what’s happening:
I followed all instructions for creating a Seaborn catplot for the Medical Data Visualizer challenge, and my plot is identical to the Figure_1.png example plot provided in the challenge. When I run, I receive two error messages related to the catplot. The messages are as follows:

ERROR: test_bar_plot_number_of_bars (test_module.CatPlotTestCase)
Traceback (most recent call last):
  File "/home/runner/boilerplate-medical-data-visualizer/", line 26, in test_bar_plot_number_of_bars
    actual = len([rect for rect in if isinstance(rect, mpl.patches.Rectangle)])
AttributeError: 'numpy.ndarray' object has no attribute 'get_children'

ERROR: test_line_plot_labels (test_module.CatPlotTestCase)
Traceback (most recent call last):
  File "/home/runner/boilerplate-medical-data-visualizer/", line 13, in test_line_plot_labels
    actual =
AttributeError: 'numpy.ndarray' object has no attribute 'get_xlabel'

I am a bit confused since the catplot utilizes kind='count', and the error messages are about bar and line plots. Any advice on how to clean-up these errors will be greatly appreciated!

My code for this portion of the challenge is as follows:
Your code so far

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# Import data
df = pd.read_csv('medical_examination.csv')
pd.set_option('display.max_columns', None)

# Add 'overweight' column
df['bmi'] = df['weight'] / ((df['height']/100) ** 2)

df['overweight'] = df['bmi'].apply(lambda x: 1 if x > 25 else 0)

# Normalize data by making 0 always good and 1 always bad. If the value of 'cholesterol' or 'gluc' is 1, make the value 0. If the value is more than 1, make the value 1.
df['cholesterol'] = df['cholesterol'].apply(lambda x: 0 if x == 1 else 1)

df['gluc'] = df['gluc'].apply(lambda x: 0 if x == 1 else 1)

# Draw Categorical Plot
def draw_cat_plot():
    cardio_df = df[['cardio','active', 'alco', 'cholesterol', 'gluc', 'overweight', 'smoke']]
    df_cat = pd.melt(cardio_df, id_vars=['cardio'], var_name='variable', value_name='value')

    # Draw the catplot with 'sns.catplot()'
    fig = sns.catplot(x="variable", hue="value", col="cardio", data=df_cat, kind='count')
    fig.set_axis_labels("variable", "total")

    # Do not modify the next two lines
    return fig

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36

Challenge: Medical Data Visualizer

Link to the challenge:

Add the line fig=fig.fig right before the save.
I tried looking at the documentation as to why this is needed - I still don’t fully grasp it though…

But as the error suggests, the object-type is wrong.

sns.catplot() returns a FacetGrid, which is a seaborn specific object that contains matplotlib Fig and Axes and other seaborn stuff. These tests expect a matplotlib Fig object and if you use seaborn and sns.catplot() it will be at FacetGrid.fig. Beware that not all seaborn graph functions return FacetGrid objects.

You could use any library (matplotlib, pandas, do it all by hand with numpy, seaborn, etc.) to generate the plot and pass the test as long as it has the correct parts and is a matplotlib Fig object.

1 Like

I appreciate the clarification. The instructions for the project specify to use an sns.catplot() which is where I was getting tripped up. Now I see that a Seaborn FacetGrid can be “wrapped” - for lack of a better word - in a Matplotlib figure.

Your comment provided the solution to my issue, thanks! An added bonus is jeremy.a.gray’s explanation below as to why it works.

That makes sense.
I was looking at the Seaborn documentation seaborn.FacetGrid — seaborn 0.11.2 documentation recently to try solve this riddle but couldn’t find anything… today I look again and notice that scrolling AAALLL the way down shows a list of attributes including “.fig”, now deprecated for “.figure”.
I got defeated by the layout of information xD