Why does Seaborn keep drawing non-existing range value on the x-axis?

Viewed 156

Snippet:

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

test = pd.DataFrame({'value':[1,2,5,7,8,10,11,12,15,16,18,20,36,37,39]})
test['range'] = pd.cut(test.value, np.arange(0,45,5)) # generate range
test = test.groupby('range')['value'].count().to_frame().reset_index() # count occurance in each range
test = test[test.value!=0] #filter out rows with value = 0

plt.figure(figsize=(10,5))
plt.xticks(rotation=90)
plt.yticks(np.arange(0,10, 1))
sns.barplot(x=test.range, y=test.value)

Output: enter image description here

If we look at what's in test:

     range   value
0   (0, 5]      3
1   (5, 10]     3
2   (10, 15]    3
3   (15, 20]    3
7   (35, 40]    3

The range (20,25], (25,30],(30,35] have already been filtered out, but they still appear in the plot. Why is that? How can I output a plot without empty ranges?


P.S. @jezrael 's solution works perfect with the snippet above. I tried it on a real dataset:

Snippet:

test['range'] = test['range'].cat.remove_unused_categories()

Warning:

A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

I used the following instead to avoid the warning:

test['range'].cat.remove_unused_categories(inplace=True)

This is caused by using multiple variables, so be aware:

test = blah blah blah
test_df = test[test.value!=0]
test_df['range'] = test_df['range'].cat.remove_unused_categories() # warning!
1 Answers
Related