0

I have the following plot function that saves a random walk input (the random walk is supposed to mimic a stock and bond portfolio that rebalances between each other given specific inputs, the exposure is supposed to show the exposure to the stock portfolio):

def stock_save_img_run(k):
    stock_vals = pd.read_csv('stock_vals_run_' + str(k) + '.csv', sep=';', encoding='utf-8-sig')
    plt.subplot(2, 1, 1)
    plt.plot(stock_vals['date'], stock_vals['stock_val'], color='#191970')
    plt.plot(stock_vals['date'], stock_vals['protected_amt'], color='#191970', ls='dashed')
    plt.stackplot(stock_vals['date'], stock_vals['exposure'] * stock_vals['stock_val'], (1 - stock_vals['exposure']) * stock_vals['stock_val'], color=('gray'), colors=('gray', 'silver'))
    plt.subplot(2, 1, 2)
    plt.plot(stock_vals['date'], stock_vals['exposure'], color='#191970', lw='0.5')
    plt.ylabel('Exposure (in %)')
    plt.savefig('chart_' + str(k) + '.png')
    plt.show()
    plt.cla()
    del stock_vals

The regular output should look like this: correct output

This works for the first run. If I run the script again, the output will look like this: incorrect output

In order to get the plot to look normal again, I have to uncomment this line:
##plt.plot(stock_vals['date'], stock_vals['exposure'], color='#191970', lw='0.5')

As you can imagine, the output will look like this for this particular run: third run to reset

As you can see, the chart on the top looks normal again. When I run it again (fourth run), both charts will look like they are supposed to look. The fifth run will destroy everything again - rinse and repeat.

Given that I know the workaround to get it solved, I'm flabbergasted as to why this occurs.

Spurious
  • 1,903
  • 5
  • 27
  • 53
  • Are you sure you need the first `color=('gray')` in the `plt.stackplot` command? – Aguy Aug 27 '16 at 20:26
  • The `plt.*` functions operate on 'the current axes'. Unless you are typing the commands into the terminal, it is far better to keep references to `Axes` objects and operate on them directly. – tacaswell Aug 27 '16 at 22:54

1 Answers1

2

Obtaining handles over separate Axes instances might be a step in a helpful direction:

def stock_save_img_run(k):
    stock_vals = pd.read_csv('stock_vals_run_' + str(k) + '.csv', sep=';', encoding='utf-8-sig')
    fig, (top_axes, bottom_axes) = plt.subplots(2, 1)
    top_axes.plot(stock_vals['date'], stock_vals['stock_val'], color='#191970')
    top_axes.plot(stock_vals['date'], stock_vals['protected_amt'], color='#191970', ls='dashed')
    top_axes.stackplot(stock_vals['date'], stock_vals['exposure'] * stock_vals['stock_val'], 
                       (1 - stock_vals['exposure']) * stock_vals['stock_val'], color=('gray'),
                       colors=('gray', 'silver'))
    bottom_axes.plot(stock_vals['date'], stock_vals['exposure'], color='#191970', lw='0.5')
    bottom_axes.set_ylabel('Exposure (in %)')
    plt.savefig('chart_' + str(k) + '.png')
    plt.show()
    top_axes.cla()
    bottom_axes.cla()
    del stock_vals
  • It raises an error/warning: `UserWarning: sharex argument to subplots() was an integer. Did you intend to use subplot() (without 's')? Traceback (most recent call last): [...] ValueError: sharex [1] must be one of ['all', 'row', 'col', 'none']` So it didnt get through. – Spurious Aug 27 '16 at 17:04
  • Apologies, that should have been `plt.subplots(2, 1)` rather than `plt.subplots(2, 1, 1)`. I've edited my initial answer to correct this. –  Aug 27 '16 at 18:46
  • I still get an error: `Traceback (most recent call last): fig, top_axes, bottom_axes = plt.subplots(2, 1) ValueError: not enough values to unpack (expected 3, got 2)` – Spurious Aug 27 '16 at 18:50
  • `plt.subplots` returns the [Figure](http://matplotlib.org/api/figure_api.html) instance and then a tuple containing each of the [Axes](http://matplotlib.org/api/axes_api.html) instances representing the individual subplots. Because of this, there should have been brackets around `top_axes` and `bottom_axes`, as there are now. How's it looking now? –  Aug 27 '16 at 18:54
  • It seems to be working now but that was the case for me as well. Thanks anyways and I'll report back. Won't mark it as correct before I've done some more tests but will vote you up in the meantime. One little thing: `del stock_vals` in the last row, not `stock_cals`. – Spurious Aug 27 '16 at 19:05
  • Ok in the very next test it didn't work and the same thing occured. This is so weird. – Spurious Aug 27 '16 at 19:07
  • What are you doing in between calls of this function? Are you plotting the same data every time you run the script? –  Aug 27 '16 at 23:15
  • I have a number of `.csv` files that I am looping through, so it's `for k in range(T): cppi_save_img_run(k)` and `T = input()`. – Spurious Aug 28 '16 at 10:59