mplfinance
mplfinance copied to clipboard
Ability to plot arbitrary (non-ohlc) data
Hello! First of all, thank you, Daniel, and contributors for this great library. Works like a charm!
I like the concise default style of the graphs produced very much. However, I was wondering, is it possible to plot arbitrary data without prices? Usecase: for example, I wanna compare P/E ratios over time for 10 different companies. I'm not really interested in share price movement for this, but I'd still like to reuse the mplfinance's concise visual style, and not to recreate it manually with matplotlib. (needless to say, the type
becomes irrelevant in this case, maybe other things as well).
Sorry for the newbie question, and best regards.
Hi Pavel, Thanks for your interest in and appreciation for mplfinance. It's an interesting question.
I suppose we could add a type
, perhaps call it data
so that you could write:
mpf.plot(df,type=data)
or something like that, to indicate that the dataframe, df
, simply has columns that you want to plot, with no expectation for columns 'Open', 'High', 'Low', and 'Close'.
In the meantime there is a workaround that you can use. You can create a dummy dataframe for the OHLC data, and pass in your PE data via addplot.
Suppose we have a dataframe with 5 years of monthly PE data for 8 stocks:
print(pedf.shape)
print(pedf.head(3))
print(pedf.tail(2))
(60, 8)
AAPL AXP BA CAT CSCO CVX DIS DWDP
Date
2011-01-31 48.4743 43.38 69.48 97.01 21.15 94.93 38.87 23.8533
2011-02-28 50.4586 43.57 72.01 102.93 18.56 103.75 43.74 24.9827
2011-03-31 49.7786 45.20 73.93 111.35 17.15 107.43 43.09 25.3794
AAPL AXP BA CAT CSCO CVX DIS DWDP
Date
2015-11-30 118.30 71.64 145.45 72.65 27.250 91.32 113.47 35.0471
2015-12-31 105.26 69.55 144.59 67.96 27.155 89.96 105.08 34.6101
Create a dummy OHLC dataframe, with the same dates as the PE data:
dum = [float('nan')]*len(pedf)
dum[0] = pedf.iloc[0,0] # At least one valid data point to avoid warning from mplfinance
d = dict(Open=dum,High=dum,Low=dum,Close=dum)
dumdf = pd.DataFrame(d, index=pedf.index)
Now plot the PE data using addplot, along with the dummy ohlc dataframe:
ap = mpf.make_addplot(pedf,secondary_y=False)
mpf.plot(dumdf, addplot=ap, ylabel='PE Ratio')
The result:
Note that Pandas DataFrames have a .plot()
method as well.
One advantage to using DataFrame.plot()
directly is that you automatically get a legend based on the column headings. Legends are not yet supported directly in mplfinance, but if we implement type=data
we could do something simlar to what padas is doing here:
pedf.plot()
Of course, with mplfinance
you can use mplfinance styles:
mpf.plot(df,addplot=ap,ylabel='PE Ratio',style='nightclouds')
mpf.plot(df,addplot=ap,ylabel='PE Ratio',style='yahoo')
mpf.plot(df,addplot=ap,ylabel='PE Ratio',style='blueskies')
Hope that helps. Let me know if you might be interested in contributing type=data
to mplfinance.
All the best. --Daniel
P.S. By the way, just curious if you have seen this: https://github.com/DanielGoldfarb/pffap
Hi @DanielGoldfarb , hands down this is the best reply to any github question I've asked so far. Appreciate it, saves me a lot of time. As for contributing the implementation, sure, I'm all up for it. I'll first need to spend some more time playing around with mpf and pd, though. Do we leave this issue open for the upcoming implementation discussions/review, or just open another one in the future? As for pffap, haven't seen it, will definitely check it out. Thank you.
P.S. By the way, just curious if you have seen this: https://github.com/DanielGoldfarb/pffap
Wonderful training Daniel! Loved the video
Pavel,
We can leave this issue open for the enhancement/implementation of type=plain_data
or whatever we end up calling it.
No rush, but let me know when you have an idea how you want to implement it. Worst case, we could always do something similar to the above workaround, just hide it inside mpf.plot()
so the caller doesn't see it. But there may be a cleaner way too; I haven't thought it through yet.
All the best. --Daniel
type=plain_data
this is interesting. i can try this too