Pandas 数据框到 Seaborn 分组条形图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38609339/
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 01:40:53  来源:igfitidea点击:

Pandas Dataframe to Seaborn Grouped Barchart

pythonpandasvisualizationseaborn

提问by Vladimir Nabokov

I have the following dataframe which I have obtained from a larger dataframe which lists the worst 10 "Benchmark Returns" and their corresponding portfolio returns and dates:

我从一个更大的数据框中获得了以下数据框,其中列出了最差的 10 个“基准收益”及其相应的投资组合收益和日期:

enter image description here

在此处输入图片说明

I've managed to create a Seaborn bar plot which lists Benchmark Returns against their corresponding dates with this script:

我已经设法创建了一个 Seaborn 条形图,其中列出了使用此脚本的相应日期的基准回报:

import pandas as pd
import seaborn as sns

df = pd.read_csv('L:\My Documents\Desktop\Data NEW.csv', parse_dates = True)

df = df.nsmallest(10, columns = 'Benchmark Returns')
df = df[['Date', 'Benchmark Returns', 'Portfolio Returns']]
p6 = sns.barplot(x = 'Date', y = 'Benchmark Returns', data = df)
p6.set(ylabel = 'Return (%)')
for x_ticks in p6.get_xticklabels():
    x_ticks.set_rotation(90)

And it produces this plot:

它产生了这个情节:

enter image description here

在此处输入图片说明

However, what I'd like is a grouped bar plot that contains both Benchmark Returns and Portfolio Returns, where two different colours are used to distinguish between these two categories.

但是,我想要的是包含基准回报和投资组合回报的分组条形图,其中使用两种不同的颜色来区分这两个类别。

I've tried several different methods but nothing seems to work.

我尝试了几种不同的方法,但似乎没有任何效果。

Thanks in advance for all your help!

在此先感谢您的帮助!

回答by Sergey Bushmanov

Please look if this is what you wanted to see.

请看看这是不是你想看到的。

The trick is to transform the pandas dffrom wide to long format

诀窍是将大Pandasdf从宽格式转换为长格式

Step 1: Prepare data

第 1 步:准备数据

import seaborn as sns

np.random.seed(123)
index = np.random.randint(1,100,10)

x1 = pd.date_range('2000-01-01','2015-01-01').map(lambda t: t.strftime('%Y-%m-%d'))
dts = np.random.choice(x1,10)

benchmark = np.random.randn(10)
portfolio = np.random.randn(10)

df = pd.DataFrame({'Index': index,
                   'Dates': dts,
                   'Benchmark': benchmark,
                   'Portfolio': portfolio},
                    columns = ['Index','Dates','Benchmark','Portfolio'])

Step 2: From "wide" to "long" format

第 2 步:从“宽”格式到“长”格式

df1 = pd.melt(df, id_vars=['Index','Dates']).sort_values(['variable','value'])
df1

    Index   Dates   variable    value
9   48  2012-06-13  Benchmark   -1.410301
1   93  2002-07-31  Benchmark   -1.301489
8   97  2005-01-21  Benchmark   -1.100985
0   67  2011-06-01  Benchmark   0.126526
4   84  2003-09-25  Benchmark   0.465645
3   18  2009-07-13  Benchmark   0.522742
5   58  2007-12-04  Benchmark   0.724915
7   98  2002-12-28  Benchmark   0.746581
6   87  2009-02-07  Benchmark   1.495827
2   99  2000-04-21  Benchmark   2.207427
16  87  2009-02-07  Portfolio   -2.750224
14  84  2003-09-25  Portfolio   -1.855637
15  58  2007-12-04  Portfolio   -1.779455
19  48  2012-06-13  Portfolio   -1.774134
11  93  2002-07-31  Portfolio   -0.984868
12  99  2000-04-21  Portfolio   -0.748569
10  67  2011-06-01  Portfolio   -0.747651
18  97  2005-01-21  Portfolio   -0.695981
17  98  2002-12-28  Portfolio   -0.234158
13  18  2009-07-13  Portfolio   0.240367

Step 3: Plot

第 3 步:绘图

sns.barplot(x='Dates', y='value', hue='variable', data=df1)
plt.xticks(rotation=90)
plt.ylabel('Returns')
plt.title('Portfolio vs Benchmark Returns');

enter image description here

在此处输入图片说明