0

I'm making a function that takes a time series for real estate values, calculates returns over investment for a lag of 2, 5 and 10 years, and then plots these returns. My time series has the datetime as the index and only one column named 'value' with the values, like this:

time series with time as index and one column with value

This is my function:


def gain(ts):
    roi_2 = (ts - ts.shift(periods=24))/ts.shift(periods=24)*100
    roi_5 = (ts - ts.shift(periods=60))/ts.shift(periods=60)*100
    roi_10 = (ts - ts.shift(periods=120))/ts.shift(periods=120)*100
    plt.figure(figsize = (12,8))
    ax = plt.subplot(111)
    ax.spines["top"].set_visible(False)  
    ax.spines["right"].set_visible(False)
    ax.plot(roi_2, label='Return in 2 Years')
    ax.plot(roi_5, label='Return in 5 Years')
    ax.plot(roi_10, label='Return in 10 Years')
    ax.set_ylabel('Gain Percentage')
    ax.set_xlabel('Year')
    plt.yticks([-10,0,10,25,50,75,100,125,150,175,200], [str(x) + "%" for x in [-10,0,10,25,50,75,100,125,150,175,200]], fontsize=10)
    ax.grid(which='major', axis='y', linestyle= "--", lw=0.5, color="black", alpha=0.3)
    plt.title('Mean Zillow Home Value Index (ZHVI) - ROI Over Time Invested', fontsize=14)
    plt.legend()
    plt.show()
    return roi_2, roi_5, roi_10

When I call it passing my time series, I get this:

graph with three lines showing return on investment in real estate

What I am trying to do is to somehow highlight the point where the return is negative - is a loss. That would be any values under the 0 line in the plot. I've tried a way to fill the entire graph under y=0, or color the lines a different color once they go under 0, but any and all codes I've tried for that are not working. I think my main difficulty is to get the x and y for these points? I'm not sure what I am doing wrong but I'm sure it's simple, I just don't know much about time series and having data as index to figure this out.

My take is that a simple ax.fill_between(x, y1, 0) would do, but I can't make into my function because I can't figure out how to set the x and y1 for it...

  • X is df.time. Then you should be able to use fill_between – Jody Klymak Oct 20 '19 at 14:05
  • df.time did not work, but df.index did: ```ax.fill_between(roi_2.index, roi_2.value<0, -20, color='red', alpha=.2)``` the only minor issue is that this filled the entire plot between 0 and -20, not only the area between plot lines and 0... – Giovanna Fernandes Oct 20 '19 at 17:37

1 Answers1

0

I suppose you could split each roi into groups of greater >=0 and <0:

def gain(ts):
    def split_roi(roi):
        return roi[roi.value >= 0], roi[roi.value <0]
    roi_2_gain, roi_2_loss = split_roi(roi_2)
    # rest of code here ...

And just plot them separately

adrianp
  • 999
  • 1
  • 8
  • 13