Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with Updating finplot Chart When Switching DataFrames #440

Open
IlanKalendarov opened this issue Aug 5, 2023 · 11 comments
Open
Labels
bug Something isn't working

Comments

@IlanKalendarov
Copy link

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

image

Reproducible in:

OS: Mac OS
finplot version: 1.9.2
pyqtgraph version: 0.13.3
pyqt version: PyQt6

@IlanKalendarov IlanKalendarov added the bug Something isn't working label Aug 5, 2023
@highfestiva
Copy link
Owner

Looks like you need to run your for loop for removing the primitives before ax.reset().

@IlanKalendarov
Copy link
Author

IlanKalendarov commented Aug 6, 2023

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

@highfestiva
Copy link
Owner

Did you try it? Has to do with internal state of finplot.

@highfestiva
Copy link
Owner

Also check 3c0f3c6, so you won't have to remove the primitives yourself.

@IlanKalendarov
Copy link
Author

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

@highfestiva
Copy link
Owner

Did you try 3c0f3c6? Please send me a minimal piece of code that I can use to reproduce the issue.

@IlanKalendarov
Copy link
Author

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")

@highfestiva
Copy link
Owner

I need a complete, minimal example of your problem, including the data required to run it. Otherwise I can't help, sorry.

@IlanKalendarov
Copy link
Author

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

image

Why can't I see those line objects inside self.ax I add them just like I showed you in the add_trend function.

@highfestiva
Copy link
Owner

finplot adds them to the viewport, not the axis, that's why. Try ax.vb to get ahold of those objects.

@highfestiva
Copy link
Owner

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants