For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Plotting inside JupyterLab



  • Hi!
    I have setup a docker container for JupyterLab + backtrader, and I am trying to follow the tutorial inside a JupyterLab notebook.

    Everything works fine, except for the plotting. The error thrown is:

    /opt/conda/lib/python3.7/site-packages/backtrader/cerebro.py in plot(self, plotter, numfigs, iplot, start, end, width, height, dpi, tight, use, **kwargs)
        972 
        973         if not plotter:
    --> 974             from . import plot
        975             if self.p.oldsync:
        976                 plotter = plot.Plot_OldSync(**kwargs)
    
    /opt/conda/lib/python3.7/site-packages/backtrader/plot/__init__.py in <module>
         28         'Matplotlib seems to be missing. Needed for plotting support')
         29 else:
    ---> 30     matplotlib.use('TkAgg')
         31 
         32 
    /opt/conda/lib/python3.7/site-packages/matplotlib/__init__.py in use(arg, warn, force)
       1389         if force:
       1390             from matplotlib.pyplot import switch_backend
    -> 1391             switch_backend(name)
       1392     # Finally if pyplot is not imported update both rcParams and
       1393     # rcDefaults so restoring the defaults later with rcdefaults
    
    /opt/conda/lib/python3.7/site-packages/matplotlib/pyplot.py in switch_backend(newbackend)
        220                 "Cannot load backend {!r} which requires the {!r} interactive "
        221                 "framework, as {!r} is currently running".format(
    --> 222                     newbackend, required_framework, current_framework))
        223 
        224     rcParams['backend'] = rcParamsDefault['backend'] = newbackend
    
    ImportError: Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running
    

    The TkAgg backend requires a running X server, which is hard to do inside a headless docker container. Can you please remove that line in plot/__init__.py which forces the backend to be TkAgg?

    Users will then be able to choose their own preferred backend with matplotlib.use("XXX").

    Alternatively, you could let the user pass in a string option to cerebro.plot(), with a default value of TkAgg. This string can be used to choose the backend. And if the value passed is None, then don't set the backend at all.


  • administrators

    @hrjet said in Plotting inside JupyterLab:

    Can you please remove that line in plot/init.py which forces the backend to be TkAgg?

    No. It was written on purpose.

    @hrjet said in Plotting inside JupyterLab:

    Alternatively, you could let the user pass in a string option to cerebro.plot(), with a default value of TkAgg. This string can be used to choose the backend. And if the value passed is None, then don't set the backend at all.

    Subclass and do it.



  • @backtrader said in Plotting inside JupyterLab:

    Subclass and do it.

    I didn't understand. Which class should I subclass?


  • administrators

    You can pass your own plotter to plot, (Docs - Cerebro) Subclass the existing one, create a new one ...



  • @backtrader said in Plotting inside JupyterLab:

    You can pass your own plotter to plot, (Docs - Cerebro) Subclass the existing one, create a new one ...

    Ah, ok. But the problem is that plot/__init__.py will be triggered even if I sub-class Plot, since it is part of module initialization, not class initialization. (I am no expert in Python, so please correct me if I am wrong).

    Thanks for your replies.


  • administrators

    If you create your own plotter in your own package, you may issue your own call before that and then have the control. Or have a module which subclass in a broader sense, given that in Python you only need to replicate the methods and not strictly derive from the class you are trying to override.



  • I met this issue sometime ago, since I needed to regularly make the backtest plots and display them in tensorboard during training. Instead of subclassing the plotter, there is a simpler workaround for this issue, just import backtrader.plot and immediately overwrite matplotlib with agg backend. This worked for me. Hope it works for you too

    import backtrader.plot
    import matplotlib
    matplotlib.use('agg')


Log in to reply
 

});