Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fill_between from a stacked dataframe

I have the following dataframe:

symbol       DAL        MS       QQQ       SPY      TLT  XLE
symbol                                                      
DAL          NaN       NaN       NaN       NaN      NaN  NaN
MS      0.560979       NaN       NaN       NaN      NaN  NaN
QQQ     0.621045  0.789771       NaN       NaN      NaN  NaN
SPY    -0.576444 -0.843485 -0.953304       NaN      NaN  NaN
TLT     0.186840  0.421957  0.333320 -0.347808      NaN  NaN
XLE     0.115093  0.578970  0.559711 -0.701126  0.38047  NaN

I then stack and order the dataframe and plot the result as a barchart as follows:

dfstacked = corr_df.stack().order()
dfstacked.plot(kind='bar')

symbol  symbol
SPY     QQQ      -0.953304
        MS       -0.843485
XLE     SPY      -0.701126
SPY     DAL      -0.576444
TLT     SPY      -0.347808
XLE     DAL       0.115093
TLT     DAL       0.186840
        QQQ       0.333320
XLE     TLT       0.380470
TLT     MS        0.421957
XLE     QQQ       0.559711
MS      DAL       0.560979
XLE     MS        0.578970
QQQ     DAL       0.621045
        MS        0.789771

enter image description here

What im trying to do now (without success) is to not plot this as a barchart but to instead plot it by filling in the area below and above zero. My guess is I should be using fill_between similar to these examples: link:

ax.fill_between(dfstacked.index, 0, dfstacked.values, where = dfstacked.values > 0, interpolate=True)
ax.fill_between(dfstacked.index, dfstacked.values, 0, where = dfstacked.values < 0, interpolate=True)

I get the error: TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

like image 582
darkpool Avatar asked Dec 18 '22 20:12

darkpool


2 Answers

You try reset_index:

dfstacked = dfstacked.reset_index(drop=True)
print dfstacked
0    -0.953304
1    -0.843485
2    -0.701126
3    -0.576444
4    -0.347808
5     0.115093
6     0.186840
7     0.333320
8     0.380470
9     0.421957
10    0.559711
11    0.560979
12    0.578970
13    0.621045
14    0.789771
dtype: float64

And then set axis x from multiindex:

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker


dfstacked = corr_df.stack().order()

ticklabels = dfstacked.index.tolist()

dfstacked = dfstacked.reset_index(drop=True)
print dfstacked


ax = dfstacked.plot()

ax.fill_between(dfstacked.index, 0, dfstacked.values, where = dfstacked.values > 0, interpolate=True)
ax.fill_between(dfstacked.index, dfstacked.values, 0, where = dfstacked.values < 0, interpolate=True)
ax.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))
plt.xticks(rotation=90)    
plt.show()

graph01

like image 172
jezrael Avatar answered Dec 21 '22 10:12

jezrael


You can play with the width and edgecolor parameters of plt.bar to get something that look less like an histogram.

x=[1,2,3,4,5,6]
y=[-3,-1,5,3,4,2]

plt.bar(x,y,color='b',width=1,edgecolor="none")

enter image description here

like image 45
Mel Avatar answered Dec 21 '22 11:12

Mel