2

I have a pyplot figure in a tkinter GUI and I am trying to update candlestick_ohlc plot from mplfinance every second with live data.

mySubplot = myFigure.add_subplot(111)

Then running every second with new data

mySubplot.clear()
...
repeat all axis formatting 
...
candlestick_ohlc(mySubplot, myData.values)

This is just very very slow to reformat my axis and redraw every candle when it is only the most recent candle that changes.

What is the most efficient way to do this?

AndrewK
  • 271
  • 2
  • 16

2 Answers2

3

Well personally I wouldn't use Tkinter and MPLfinance to do this!

This is because:

  1. Tkinter's frame rate is terrible like I mean absolutely terrible you will be lucky to get 5 fps by constantly changing the image with a while loop.
  2. Tkinter is old and outdated and doesnt have alot of useful functions which other popular GUI libaries have like Qt and GTK.
  3. MPLfinance is very intensive when your constantly using it make graphs and it is slow to produce graphs which makes your trading platform slow.
  4. The file size of your application will be huge.
  5. The data wont be accurate.

The way I would do this to make it "real time" is to run three functions in parallel by using cocurrent.futures, one function will be fetching data on the stock/currency/crypto from an api or through web scraping( I wouldn't recommend this as latency and lag will be high), the second function will be for making the candlestick graph, and the third function will be for running the loop for keeping the gui and constantly updating the picture of the graph as it changes.

For the GUI I would probably use a "game engine" known as pygame as it has a higher fps as it designed to make games however this will makes the application intensive but make the fps higher. If you did this in tkinter you would see the flickering of the frame as the graph is changing which is really annoying.

2

I would suggest using the new mplfinance API (mpf.plot() instead of candlestick_ohlc()). It may not be more effiecient in terms of processing (although I suspect it is somewhat more efficient) but it is definitely more efficient in terms of the amount of code you would have to write because the new API does a lot of the matplotlib formatting and other work for you.

I would suggest, within the new API using the Animation Support feature using "External Axes Mode". That will allow you to interact with tkinter. For general examples of Animation in mplfinance, see https://github.com/matplotlib/mplfinance/blob/master/markdown/animation.md and the links therein (for example https://github.com/matplotlib/mplfinance/blob/master/examples/mpf_animation_demo2.py). I think you will be able to tweak the code from those examples to what you will need to do the same thing with tkinter.

Daniel Goldfarb
  • 6,937
  • 5
  • 29
  • 61
  • I am confused about this (https://github.com/matplotlib/mplfinance/blob/master/examples/mpf_animation_demo2.py) example and how `FuncAnimation` works. Inside their `animate()` function they are just clearing the axis and replotting same as I do inside my `after(1000,updatetk)` loop. – AndrewK Jun 22 '21 at 00:11
  • 1
    That's correct. It is very similar to what you are already doing. The advantage is that you won't have to repeat all the formatting and related code each time (instead that is done internally in `mpf.plot()`, so your code can be much simpler. – Daniel Goldfarb Jun 22 '21 at 02:19
  • 1
    Ultimately if you are looking to make the code more efficient in terms of CPU cycles, you will have to read up on **blitting** for example here: https://matplotlib.org/stable/api/animation_api.html#funcanimation and here: https://matplotlib.org/stable/tutorials/advanced/blitting.html Personally I don't think that level of efficiency is necessary unless you have a very large number of candles (which you would want to avoid replotting every time, but may still have to plot them periodically depending how large you allow the plot to grow). – Daniel Goldfarb Jun 22 '21 at 02:20
  • I am only plotting 60 candles every 1 seconds but it takes 300 milliseconds to clear and plot again which seems like a long time and makes my tkinter lag. When I try using the `.clear()` and then `mpl.plot()` my axis still gets reset and not formatted the way I want. Is there a way to clear the candles without clearing the axis formatting? – AndrewK Jun 22 '21 at 02:59
  • 1
    I don't understand, if you are painting every second (1000 milliseconds), why a 300 millisecond clear and re-paint is causing a lag. Also, I would have to see your complete code to get a better idea what's going on with the formatting. It shouldn't be an issue. There may be a way to clear only the candles, but that will take some code changes to mplfinance (but possibly simple changes). – Daniel Goldfarb Jun 22 '21 at 16:22
  • I don't know how tkinter works but my resizing my window and panes and scrolling text box lags. I have a few plots I am replotting and I have got my time down for my in the `updatetk` function from 1 second to 200 milliseconds now and it works better although it still lags a little. – AndrewK Jun 23 '21 at 01:36