finplot
finplot copied to clipboard
Problems with Updating finplot Chart When Switching DataFrames
Requirements (place an x
in each of the [ ]
)**
- [ x] I realize finplot is not a web lib. (Hint: it's native!)
- [x ] I've read the snippets and not found what I'm looking for.
- [x ] I've searched for any related issues and avoided creating a duplicate issue.
- [x ] I've updated finplot (
pip install -U finplot
). - [x ] I've supplied the required data to run my code below.
Code to reproduce
def update_chart(self, df):
print("updating chart..")
self.ax.reset()
self.axo.reset()
for item in self.ax.items:
if isinstance(item, fplt.FinLine):
fplt.remove_primitive(item)
self.df = df
fplt.candlestick_ochl(
self.df[['date', 'open', 'close', 'high', 'low']], ax=self.ax)
fplt.refresh()
print("done updating chart")
Describe the bug
Sometimes, a random pattern of lines or candles appear on top of the chart after switching DataFrames. This pattern doesn't correspond to any data in the DataFrame, and it doesn't happen when the DataFrame is loaded for the first time. It only occurs when I switch DataFrames by clicking on a button in my GUI.
I suspect that finplot might be keeping a reference to the old DataFrame somewhere, which could be causing these issues. However, I'm not sure how to solve this. I would appreciate any help or guidance.
The part where I tried removing the lines did not work and this is what i got inside self.ax.items
:
[<pyqtgraph.graphicsItems.InfiniteLine.InfiniteLine object at 0x14ca05c10>, <pyqtgraph.graphicsItems.InfiniteLine.InfiniteLine object at 0x14ca05ca0>, <pyqtgraph.graphicsItems.TextItem.TextItem object at 0x14ca05d30>, <pyqtgraph.graphicsItems.TextItem.TextItem object at 0x14ca05e50>]
Note that i used fplt.add_rect
and fplt.add_line
and labels.
I just want to be able to remove those 3 objects from the entire chart when switching between the dfs.
Screenshots
Reproducible in:
OS: Mac OS finplot version: 1.9.2 pyqtgraph version: 0.13.3 pyqt version: PyQt6
Looks like you need to run your for loop for removing the primitives before ax.reset()
.
Looks like you need to run your for loop for removing the primitives before
ax.reset()
.
if I inspect self.ax.items before the reset I do see some finplot object but the reset seems to clear all of those objects and what will be left after are those objects:
[<pyqtgraph.graphicsItems.InfiniteLine.InfiniteLine object at 0x14ca05c10>, <pyqtgraph.graphicsItems.InfiniteLine.InfiniteLine object at 0x14ca05ca0>, <pyqtgraph.graphicsItems.TextItem.TextItem object at 0x14ca05d30>, <pyqtgraph.graphicsItems.TextItem.TextItem object at 0x14ca05e50>]
Note that these objects are not of finplot type.
Which I don't use directly on my code, I just use what I said on my first comment. It looks that these objects are the one left on my chart after the reset. Oh I also get this error after switching timeframe and then hovering over the candles:
Inspection error: <class 'RuntimeError'> wrapped C/C++ object of type QGraphicsTextItem has been deleted
Did you try it? Has to do with internal state of finplot.
Also check 3c0f3c63ac46654299ec3e5a40eaa92d4a649990, so you won't have to remove the primitives yourself.
I do it like so:
for item in self.ax.items:
if isinstance(item, fplt.FinLine) or isinstance(item, fplt.FinPolyLine):
fplt.remove_primitive(item)
And still get the same results
Did you try 3c0f3c6? Please send me a minimal piece of code that I can use to reproduce the issue.
Did you try 3c0f3c6? Please send me a minimal piece of code that I can use to reproduce the issue.
I don't get what you meant by this because I think I did try. Here is a piece of code, For example I am adding trend lines over the candle tails then I try to delete them
def add_trend(self):
for x, (date, high, low, trend) in enumerate(self.df[['date', 'high', 'low', 'trend']].values):
# Plotting trendlines
if trend == 'up':
fplt.add_line((date, low), (date, high),
color='#00FF00', width=3, ax=self.ax)
elif trend == 'down':
fplt.add_line((date, low), (date, high),
color='#FF0000', width=3, ax=self.ax)
And I try to reset the chart to a different df like so
def update_chart(self, df):
print("updating chart..")
self.ax.reset()
self.axo.reset()
self.df = df
for item in self.ax.items:
if isinstance(item, fplt.FinLine) or isinstance(item, fplt.FinPolyLine):
fplt.remove_primitive(item)
fplt.candlestick_ochl(
self.df[['date', 'open', 'close', 'high', 'low']], ax=self.ax)
fplt.refresh()
print("done updating chart")
I need a complete, minimal example of your problem, including the data required to run it. Otherwise I can't help, sorry.
I need a complete, minimal example of your problem, including the data required to run it. Otherwise I can't help, sorry.
Sorry but the code is kind of complex and I won't be able to just copy and paste it. But, I did some checking and I found something weird.
I changed the add_trend
function I gave you before to add the lines to a list In order to keep track of them.
The list had around 15,000 lines but when inspecting self.ax I had just 80 objects
Why can't I see those line objects inside self.ax
I add them just like I showed you in the add_trend
function.
finplot adds them to the viewport, not the axis, that's why. Try ax.vb
to get ahold of those objects.
@IlanKalendarov I'm only able to help if I have some test code to work with. Could you please make a reproducible piece of code that highlights the error?