简体   繁体   中英

Changing x-labels and width while using catplot in seaborn

I have a sample dataset as follows;

pd.DataFrame({'Day_Duration':['Evening','Evening','Evening','Evening','Evening','Morning','Morning','Morning',
                         'Morning','Morning','Night','Night','Night','Night','Night','Noon','Noon','Noon',
                         'Noon','Noon'],'place_category':['Other','Italian','Japanese','Chinese','Burger',
                        'Other','Juice Bar','Donut','Bakery','American','Other','Italian','Japanese','Burger',\
                        'American','Other','Italian','Burger','American','Salad'],'Percent_delivery':[14.03,10.61,9.25,8.19,6.89,19.58,10.18,9.14,8.36,6.53,13.60,8.42,\
                                           8.22,7.66,6.67,17.71,10.62,8.44,8.33,7.50]})

The goal is to draw faceted barplot with Day_duration serving as facets, hence 4 facets in total. I used the following code to achieve the same,

import seaborn as sns
#g = sns.FacetGrid(top5_places, col="Day_Duration")
g=sns.catplot(x="place_category", y="Percent_delivery", hue='place_category',col='Day_Duration',\
                 data=top5_places,ci=None,kind='bar',height=4, aspect=.7)
g.set_xticklabels(rotation=90)

Attached is the figure I got;

Can I kindly get help with 2 things, first is it possible to get only 5 values on the x-axis for each facet(rather than seeing all the values for each facet), second, is there a way to make the bars a bit wider. Help is appreciated.

  • Because you're using hue the api applies a unique color to each value of place_category , but it also expects each category to be in the plot, as shown in your image.
    • The final figure is a FacetGrid. Using subplot is the manual way of creating one.
  • In order to plot only the top n categories for each Day_Duration , each plot will need to be done individually, with a custom color map.
  • cmap is a dictionary with place categories as keys and colors as values. It's used so there will be one legend and each category will be colored the same for each plot.
    • Because we're not using the legend automatically generated by the plot, one needs to be created manually.
  • patches uses Patch to create each item in the legend. (eg the rectangle, associated with color and name).
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.patches import Patch


# create a color map for unique values or place
place_cat = df.place_category.unique()
colors = sns.color_palette('husl', n_colors=10)
cmap = dict(zip(place_cat, colors))

# plot a subplot for each Day_Duration
plt.figure(figsize=(16, 6))
for i, tod in enumerate(df.Day_Duration.unique(), 1):
    data = df[df.Day_Duration == tod].sort_values(['Percent_delivery'], ascending=False)
    plt.subplot(1, 4, i)
    p = sns.barplot(x='place_category', y='Percent_delivery', data=data, hue='place_category', palette=cmap)
    p.legend_.remove()
    plt.xticks(rotation=90)
    plt.title(f'Day Duration: {tod}')

plt.tight_layout()
patches = [Patch(color=v, label=k) for k, v in cmap.items()]
plt.legend(handles=patches, bbox_to_anchor=(1.04, 0.5), loc='center left', borderaxespad=0)
plt.show()

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM