16

Basically I'm just running a for-loop that plots and saves a bunch of figures as PNG and when I'm up to like 25 figures to save in total I get this "Fail to allocate bitmap" error however I make sure to clear the axis, figure and figure window in between each one, so what gives?

Here's my code just in case:

def update_trade_graphs(instruments):
    print('chokepoint 13')
    for i in range(0, len(instruments)):
        if instruments[i].linked_trade is False:
            continue

        # Update variables
        bid = instruments[i].orderbook['bids'][0][0] if len(instruments[i].orderbook['bids']) > 0 else None
        ask = instruments[i].orderbook['asks'][0][0] if len(instruments[i].orderbook['asks']) > 0 else None

        trades[instruments[i].linked_trade].time_series.append(date2num(current_time_mark))
        trades[instruments[i].linked_trade].bid_prices.append(bid)
        trades[instruments[i].linked_trade].ask_prices.append(ask)

        for timespan in timespans_all:
            if timespan in trades[instruments[i].linked_trade].buy_targets:
                pass
            else:
                trades[instruments[i].linked_trade].buy_targets[timespan] = []

            trades[instruments[i].linked_trade].buy_targets[timespan].append(instruments[i].minmax[timespan][0])

            if timespan in trades[instruments[i].linked_trade].sell_targets:
                pass
            else:
                trades[instruments[i].linked_trade].sell_targets[timespan] = []

            trades[instruments[i].linked_trade].sell_targets[timespan].append(instruments[i].minmax[timespan][1])

        # Plot graph
        fig = plt.figure()
        ax1 = plt.subplot2grid((1, 1), (0, 0))

        for timespan in timespans_all:
            ax1.plot_date(trades[instruments[i].linked_trade].time_series,
                          trades[instruments[i].linked_trade].buy_targets[timespan], '-', label='Buy Target', color='c')
            ax1.plot_date(trades[instruments[i].linked_trade].time_series,
                          trades[instruments[i].linked_trade].sell_targets[timespan], '-', label='Sell Target',
                          color='m')

        ax1.plot_date(trades[instruments[i].linked_trade].time_series, trades[instruments[i].linked_trade].bid_prices,
                      '-', label='Bid', color='r')
        ax1.plot_date(trades[instruments[i].linked_trade].time_series, trades[instruments[i].linked_trade].ask_prices,
                      '-', label='Ask', color='b')

        ax1.axhline(trades[instruments[i].linked_trade].entry_price, linestyle=':', color='c')
        if trades[instruments[i].linked_trade].exit_price > 0:
            ax1.axhline(trades[instruments[i].linked_trade].exit_price, linestyle=':', color='m')

        for label in ax1.xaxis.get_ticklabels():
            label.set_rotation(90)
        ax1.grid(True)

        plt.xlabel('Date')
        plt.ylabel('Price')
        plt.title(trades[instruments[i].linked_trade].symbol)

        plt.subplots_adjust(left=0.09, bottom=0.23, right=0.94, top=0.95, wspace=0.2, hspace=0)

        plt.savefig('trade_{0}.png'.format(instruments[i].linked_trade))
        plt.close(fig)
        plt.clf()
        plt.cla()
Valentin Lorentz
  • 9,556
  • 6
  • 47
  • 69
Jordy
  • 319
  • 2
  • 4
  • 8
  • 5
    Try to change `plt.close(fig)` by `plt.close('all') `. – Serenity Dec 25 '18 at 04:37
  • Tried that already. – Jordy Dec 25 '18 at 12:18
  • 6
    Without the 'instruments', I cannot run and test your code. Can you make a reproducible example? – gepcel Dec 27 '18 at 05:52
  • 8
    already tried with a non-interactive backend? `mpl.use('Agg')` and/or maybe `plt.ioff()`... I used to have all kinds of problems saving many figures in interactive mode... all gone with `Agg` backend – filippo Dec 27 '18 at 10:26
  • I fixed it by doing putting gc.collect() after the plt.close() line. However now I get "Process finished with exit code -1073740791 (0xC0000409)" after running the program for about 2 days. – Jordy Dec 28 '18 at 13:37
  • I'll try implement your solution on top of it, I have a feeling that might do it but it will take like 2 days before I'm sure it works. – Jordy Dec 28 '18 at 13:43
  • If that fails I'll go with this workaround: https://stackoverflow.com/questions/7125710/matplotlib-errors-result-in-a-memory-leak-how-can-i-free-up-that-memory – Jordy Dec 28 '18 at 13:43
  • 4
    please provide code that runs (or fails), without missing dependencies. This is "just" a function. Please turn it into a complete example. Thanks. – Jörg Beyer Dec 29 '18 at 19:31
  • 3
    try reusing the same figure, like `fig = plt.figure(1)` . – igrinis Dec 30 '18 at 08:44
  • 1
    one possible workaround for this is using multiprocessing, if you unroll your loop into processes, then you should have such issues as you start a new process every time. its not a great solution, but its probably a workable workaround – Nullman Dec 30 '18 at 11:46
  • The solution provided by @Serenity worked great for me. 485 figures later its plotting with no issues. – Casivio Apr 09 '20 at 00:52
  • 1
    anyone reading the comments : https://github.com/matplotlib/mplfinance/issues/386#issuecomment-852001046 ```import matplotlib matplotlib.use("Agg")``` – Chapo Jun 11 '21 at 02:11

0 Answers0