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
Seaborn workaround for hue barplot
提问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()
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 hue
parameter 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)
回答by ImportanceOfBeingErnest
The hue
argument 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 hue
argument (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()