pandas 色相条形图的 Seaborn 解决方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43443219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 03:24:33  来源:igfitidea点击:

Seaborn workaround for hue barplot

pythonpandasmatplotlibdata-visualizationseaborn

提问by Franch

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

我在Jupyter 笔记本上有以下 DataFrame,它使用 seaborn 条形图绘制:

    day_index   avg_duration    trips
0       0         708.852242    114586
1       1         676.702190    120936
2       2         684.572677    118882
3       3         708.925340    117868
4       4         781.767476    108036
5       5         1626.575057   43740
6       6         1729.155673   37508

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

plt.figure(figsize=(16,10));
sns.set_style('ticks')
ax = sns.barplot(data=dfGroupedAgg, \
                 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

情节A:在此处输入图片说明

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?

可以看出,条形与 x_ticklabels 不匹配并且非常细。
如果我移除hue='trips'零件,这一切都已解决,这是一个已知的 seaborn 问题。尽管在可视化中显示行程数量非常重要,因此:有没有办法绕过 seaborn(可能直接使用 matplotlib)来添加色调属性?

采纳答案by MaxU

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

我认为hue在这种情况下您不需要指定参数:

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

在此处输入图片说明

回答by ImportanceOfBeingErnest

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

这个hue论点可能只对绘图引入一个新维度有意义,而不是在同一维度上显示另一个数量。

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

最好在没有hue参数的情况下绘制条形图(实际上将其称为色调是非常误导的),并根据"trips"列中的值简单地为条形着色。

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

这也显示在这个问题中: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

在此处输入图片说明