Reputation: 14651
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
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''
Upvotes: 4
Views: 725
Reputation: 863166
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()
Upvotes: 4
Reputation: 6075
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")
Upvotes: 4
Reputation: 4300
Your syntax is a bit off. In your case fill_between
needs X values, then value of Y to which you want to fill, and then your Y values.
Here is a little example:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
s = pd.Series([-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])
x = np.arange(len(s))
plt.fill_between(x,0,s)
Then you can use your index
to set_xticklabels
.
Upvotes: 3