Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seaborn workaround for hue barplot

I have the following DataFrame on a Jupyter notebook which plots using seaborn a barplot:

data = {'day_index': [0, 1, 2, 3, 4, 5, 6],
        'avg_duration': [708.852242, 676.7021900000001, 684.572677, 708.92534, 781.767476, 1626.575057, 1729.155673],
        'trips': [114586, 120936, 118882, 117868, 108036, 43740, 37508]}

df = pd.DataFrame(data)

daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

plt.figure(figsize=(16,10));
sns.set_style('ticks')
ax = sns.barplot(data=df, \
                 x='day_index', \
                 y='avg_duration', \
                 hue='trips', \
                 palette=sns.color_palette("Reds_d", n_colors=7, desat=1))

ax.set_xlabel("Week Days", fontsize=18, alpha=0.8)
ax.set_ylabel("Duration (seconds)", fontsize=18, alpha=0.8)
ax.set_title("Week's average Trip Duration", fontsize=24)
ax.set_xticklabels(daysOfWeek, fontsize=16)
ax.legend(fontsize=15)
sns.despine()
plt.show()

Plot A: enter image description here

As it can be seen the bars do not match the x_ticklabels and are very thin.
This is all fixed if I remove the hue='trips' part, it's a known seaborn issue. Although It's very important to show the amount of trips in the visualization so: is there a way around seaborn (maybe with matplotlib directly) to add a hue attribute?

like image 864
Franch Avatar asked Apr 16 '17 23:04

Franch


People also ask

What does hue mean in a seaborn barplot?

Plot with Seaborn barplot with gender as hue The first two dimensions of our data is the x and y axis. X is group and y is percentage in this case. Hue, the third dimension, is the gender.

How do you map hue levels in Seaborn?

The hue variable of seaborn.barplot () is mapped via palette: Colors to use for the different levels of the hue variable. Should be something that can be interpreted by seaborn.color_palette (), or a dictionary mapping hue levels to matplotlib colors. palette = ['tab:blue', 'tab:green', 'tab:orange', 'tab:red']

What is the use of barplot in Seaborn?

seaborn.barplot () method A barplot is basically used to aggregate the categorical data according to some methods and by default it’s the mean. It can also be understood as a visualization of the group by action.

How to plot bar graph using Seaborn?

Following steps are used : 1 Import Seaborn 2 Load Dataset from Seaborn as it contain good collection of datasets. 3 Plot Bar graph using seaborn.barplot () method. More ...


2 Answers

The hue argument probably only makes sense to introduce a new dimension to the plot, not to show another quantity on the same dimension.

It's probably best to plot the bars without the hue argument (it's quite misleading to call it hue actually) and simply colorize the bars according to the values in the "trips" column.

This is shown also in this question: Seaborn Barplot - Displaying Values.

The code here would look like:

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

di = np.arange(0,7)
avg  = np.array([708.852242,676.702190,684.572677,708.925340,781.767476,
                 1626.575057,1729.155673])
trips = np.array([114586,120936,118882,117868,108036,43740,37508])
df = pd.DataFrame(np.c_[di, avg, trips], columns=["day_index","avg_duration", "trips"])

daysOfWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', \
'Friday', 'Saturday', 'Sunday']

plt.figure(figsize=(10,7));
sns.set_style('ticks')
v  = df.trips.values
colors=plt.cm.viridis((v-v.min())/(v.max()-v.min()))
ax = sns.barplot(data=df, x='day_index',   y='avg_duration', palette=colors)

for index, row in df.iterrows():
    ax.text(row.day_index,row.avg_duration, row.trips, color='black', ha="center")

ax.set_xlabel("Week Days", fontsize=16, alpha=0.8)
ax.set_ylabel("Duration (seconds)", fontsize=16, alpha=0.8)
ax.set_title("Week's average Trip Duration", fontsize=18)
ax.set_xticklabels(daysOfWeek, fontsize=14)
ax.legend(fontsize=15)
sns.despine()
plt.show()

enter image description here

like image 185
ImportanceOfBeingErnest Avatar answered Sep 29 '22 09:09

ImportanceOfBeingErnest


I think you don't need to specify hue parameter in this case:

In [136]: ax = sns.barplot(data=dfGroupedAgg, \
     ...:                  x='day_index', \
     ...:                  y='avg_duration', \
     ...:                  palette=sns.color_palette("Reds_d", n_colors=7, desat=1))
     ...:

you can add amount of trips as annotations:

def autolabel(rects, labels=None, height_factor=1.05):
    for i, rect in enumerate(rects):
        height = rect.get_height()
        if labels is not None:
            try:
                label = labels[i]
            except (TypeError, KeyError):
                label = ' '
        else:
            label = '%d' % int(height)
        ax.text(rect.get_x() + rect.get_width()/2., height_factor*height,
                '{}'.format(label),
                ha='center', va='bottom')

autolabel(ax.patches, labels=df.trips, height_factor=1.02)

enter image description here

like image 45
MaxU - stop WAR against UA Avatar answered Sep 29 '22 10:09

MaxU - stop WAR against UA