有没有办法在ggplot中绘制pandas系列?
我正在尝试使用pandas和其他绘图工具,而不是matplotlib。这里有一些不错的建议:点击这里。我遇到了两个问题,主要是关于yhat的ggplot。
在pandas中绘制一个序列是很简单的。
frequ.plot()
但是在ggplot的文档中,我找不到如何做到这一点。结果我只能创建一个数据框:
cheese = DataFrame({'time': frequ.index, 'count' : frequ.values})
ggplot(cheese, aes(x='time', y='count')) + geom_line()
我本以为ggplot——一个与pandas“紧密集成”的项目——应该有办法绘制一个简单的序列。
第二个问题是,当x轴是一天中的时间时,我无法让stat_smooth()显示出来。看起来这可能和这个帖子有关,但我没有足够的声望在那儿发帖。我的代码是:
frequ = values.sampler.resample("1Min", how="count")
cheese = DataFrame({'time': frequ.index, 'count' : frequ.values})
ggplot(cheese, aes(x='time', y='count')) + geom_line() + stat_smooth()
如果有人能帮我解决非matplotlib的绘图问题,我将非常感激。谢谢!
(我使用的是ggplot 0.5.8)
2 个回答
10
我在使用Python的ggplot处理多个股票价格和经济时间序列时,经常遇到这个问题。记住,使用ggplot时,数据最好以长格式组织,这样可以避免很多问题。我用一个简单的两步法来解决这个问题。首先,我们来获取一些股票数据:
import pandas.io.data as web
import pandas as pd
import time
from ggplot import *
stocks = [ 'GOOG', 'MSFT', 'LNKD', 'YHOO', 'FB', 'GOOGL','HPQ','AMZN'] # stock list
# get stock price function #
def get_px(stock, start, end):
return web.get_data_yahoo(stock, start, end)['Adj Close']
# dataframe of equity prices
px = pd.DataFrame({n: get_px(n, '1/1/2014', date_today) for n in stocks})
px.head()
AMZN FB GOOG GOOGL HPQ LNKD MSFT YHOO
Date
2014-01-02 397.97 54.71 NaN 557.12 27.40 207.64 36.63 39.59
2014-01-03 396.44 54.56 NaN 553.05 28.07 207.42 36.38 40.12
2014-01-06 393.63 57.20 NaN 559.22 28.02 203.92 35.61 39.93
2014-01-07 398.03 57.92 NaN 570.00 27.91 209.64 35.89 40.92
2014-01-08 401.92 58.23 NaN 571.19 27.19 209.06 35.25 41.02
首先要明白,ggplot需要将日期时间索引作为pandas数据框中的一列,这样在从宽格式转换为长格式时才能正确绘图。我写了一个函数来解决这个问题。这个函数简单地从pandas系列索引创建一个类型为datetime的“日期”列。
def dateConvert(df):
df['Date'] = df.index
df.reset_index(drop=True)
return df
接下来,在数据框上运行这个函数。使用结果作为pandas的pd.melt中的对象,'日期'作为id_vars。返回的数据框现在可以使用标准的ggplot()格式进行绘图了。
px_returns = px.pct_change() # common stock transformation
cumRet = (1+px_returns).cumprod() - 1 # transform daily returns to cumulative
cumRet_dateConverted = dateConvert(cumRet) # run the function here see the result below#
cumRet_dateConverted.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 118 entries, 2014-01-02 00:00:00 to 2014-06-20 00:00:00
Data columns (total 9 columns):
AMZN 117 non-null float64
FB 117 non-null float64
GOOG 59 non-null float64
GOOGL 117 non-null float64
HPQ 117 non-null float64
LNKD 117 non-null float64
MSFT 117 non-null float64
YHOO 117 non-null float64
Date 118 non-null datetime64[ns]
dtypes: datetime64[ns](1), float64(8)
data = pd.melt(cumRet_dateConverted, id_vars='Date').dropna() # Here is the method I use to format the data in the long format. Please note the use of 'Date' as the id_vars.
data = data.rename(columns = {'Date':'Date','variable':'Stocks','value':'Returns'}) # common to rename these columns
从这里开始,你可以随意绘制你的数据。我常用的一个图是:
retPlot_YTD = ggplot(data, aes('Date','Returns',color='Stocks')) \
+ geom_line(size=2.) \
+ geom_hline(yintercept=0, color='black', size=1.7, linetype='-.') \
+ scale_y_continuous(labels='percent') \
+ scale_x_date(labels='%b %d %y',breaks=date_breaks('week') ) \
+ theme_seaborn(style='whitegrid') \
+ ggtitle(('%s Cumulative Daily Return vs Peers_YTD') % key_Stock)
fig = retPlot_YTD.draw()
ax = fig.axes[0]
offbox = ax.artists[0]
offbox.set_bbox_to_anchor((1, 0.5), ax.transAxes)
fig.show()
8
这其实是一种变通的方法,你可以使用 qplot
来快速绘制简洁的图表,特别是当你想用数据序列的时候。
from ggplot import *
qplot(meat.beef)