pythondataframegraphjupyter-notebookplotly

plotly cant plot scatter graphs anymore


I am using the update plotly version 6.3.0 and im trying to plot a simple stock close price in 1year period. The uploaded image is the graph output, how it can be seen its not right. Im also in jupyter notebook, but the other code that i did a long time ago in plotly not graphing either.

import yfinance as yf
import numpy as np
import pandas as pd 
import statsmodels.api as sum
from statsmodels.tsa.stattools import coint, adfuller
import plotly.graph_objects as go
petr4 = yf.download("PETR4.SA", period="1y")["Close"]
petr4.index = petr4.index.tz_localize(None)
fig = go.Figure()
fig.add_trace(go.Scatter(x=petr4.index, y=petr4))
fig.update_layout(title_text="petr", width=500, height=500)
fig.show()

enter image description here


Solution

  • Open source code and practices change over time. You have to be ready to troubleshoot now and then.
    You'll note the Jan 23, 2025 post 'What’s New in YFinance? 3 Game-Changing Updates You Must Know' starts off saying: "As Heraclitus once said: “The only constant in life is change.”


    Solution Option A - specify the column name of the dataframe to plot:

    import yfinance as yf
    import numpy as np
    import pandas as pd 
    import statsmodels.api as sum
    from statsmodels.tsa.stattools import coint, adfuller
    import plotly.graph_objects as go
    petr4 = yf.download("PETR4.SA", period="1y", auto_adjust=False)["Close"] #explcitly set `auto_adjust` to avoid `FutureWarning:YF.download() has changed argument auto_adjust default to True`
    petr4.index = petr4.index.tz_localize(None)
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=petr4.index, y=petr4['PETR4.SA']))
    fig.update_layout(title_text="petr", width=500, height=500)
    fig.show()
    

    To figure out what to, you'd separate things out and run this code to find out what you are dealing with up to the point fig = go.Figure():

    type(petr4)
    

    Then you'd run this code to get the columns from the Pandas dataframe:

    petr4.columns
    

    Then you'd see Index(['PETR4.SA'], dtype='object', name='Ticker') and try plugging petr4['PETR4.SA'] in as the y-axis data.

    Granted that assumes some familiarity with Pandas.


    Solution Option B: Find an issue post and try recommendations - specifically, multi_level_index=False

    I removed the ["Close"] you had after the intial petr4 assignment and ran up to the line petr4 = yf.download("PETR4.SA", period="1y").

    Then in the next Jupyter cell I typed petr4 and ran that and saw a nice dataframe with one of the columns having Close on top and PETR4.SA below.

    I typed petr4.columns to investigate further and saw:

    MultiIndex([('Adj Close', 'PETR4.SA'),
                (    'Close', 'PETR4.SA'),
                (     'High', 'PETR4.SA'),
                (      'Low', 'PETR4.SA'),
                (     'Open', 'PETR4.SA'),
                (   'Volume', 'PETR4.SA')],
               names=['Price', 'Ticker'])
    

    Seeing 'MultiIndex' I searched on the internet for 'yfinance close multiindex' and saw, "Dec 24, 2024 — Upgraded to yfinance 2.51 this week yf.Download for a single ticker now produces columns with an un-wanted multi-index with an altered ...". That looked pertinent.
    That would lead you to ISSUE POST: 'yf.download returns multi-index columns'.

    Or if you are lucky, you'll scroll down and see the Jan 23, 2025 post 'What’s New in YFinance? 3 Game-Changing Updates You Must Know' that has in the introductory paragraph:

    "YFinance, the popular Python library for retrieving financial data, has introduced significant changes in its latest version 0.2.51 (released in December 2024). These updates have caused confusion among users but also bring interesting functional improvements. In this article, we’ll explore the key updates, how to handle them, and provide practical code examples."

    Or in the list of hits, possibly see the Nov 26, 2024 post '[Python] Updates in yfinance: The Multi-Level Index in the “download” Function'.

    All those list some options for dealing with this change.
    Here is trying one of the ones listed in ISSUE POST: 'yf.download returns multi-index columns'. This reply points out that the API now has an option you can add via an argument to specify you want the old style, & so you could alter your line petr4 = yf.download("PETR4.SA", period="1y")["Close"] to instead be petr4 = yf.download("PETR4.SA", period="1y",multi_level_index=False)["Close"]. That implemented in your code block fully would be:

    import yfinance as yf
    import numpy as np
    import pandas as pd 
    import statsmodels.api as sum
    from statsmodels.tsa.stattools import coint, adfuller
    import plotly.graph_objects as go
    petr4 = yf.download("PETR4.SA", period="1y",multi_level_index=False, auto_adjust=False)["Close"]
    petr4.index = petr4.index.tz_localize(None)
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=petr4.index, y=petr4))
    fig.update_layout(title_text="petr", width=500, height=500)
    fig.show()
    

    (Note I also added auto_adjust=Falseas an argument to avoid FutureWarning:YF.download() has changed argument auto_adjust default to True I am presently seeing.)

    Granted again, I knew about the columns attribute of Pandas dataframes to even get that far.


    Solution Option C: Troubleshoot via StackOverflow recent posts about yfinance

    Go to StackOverlfow and put in 'yfinance' in the search bar and toggle on 'Newest' as the order for the listing. Then scroll back in recent time and see if anything vaguely looks like your are encountering.

    You'd see the post 'Tried plotting yfinance data by framing into pandas with the help of seaborn and matplotlib. Shows error no matter what. How to fix this?' that looks reminiscent of yours and close by this this answer summarized that states:

    "Your error was caused by the following code sns.lineplot(x='Date',y='Close',data=df) This is because df is multi-indexed. "

    The proposed solution there implemented in your code block:

    import yfinance as yf
    import numpy as np
    import pandas as pd 
    import statsmodels.api as sum
    from statsmodels.tsa.stattools import coint, adfuller
    import plotly.graph_objects as go
    petr4 = yf.download("PETR4.SA", period="1y").droplevel(1, axis=1)["Close"]
    petr4.index = petr4.index.tz_localize(None)
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=petr4.index, y=petr4))
    fig.update_layout(title_text="petr", width=500, height=500)
    fig.show()
    

    Even if not clear how to combine the post's suggestion with your code, that statment,'This is because df is multi-indexed' might have lead you to how I got to Solution B because not you may think to search something like 'yfinance close multiindex' on the internet.