Add 2 statements to solve the problem of cufflinks’ .iplot not displaying pictures

Environment: jupyter notebook, win7, win10, chrome browser, edge browser,

bug: .iplot of cufflinks does not display images

The phenomenon is:

1 – Use matplotlib.pyplot to display images.

2 – Plotly’s iplot method can save pictures to a folder, but using plotly’s iplot method, jupyter notebook does not display pictures.

It means that the problem is not with matplotlib and matplotlib.pyplot, it may be with plotly, it may not be with cufflinks.

debug method:

After searching online resources, I found the following methods, but they are not suitable for my situation and cannot solve my problem:

debug 1 Add cf.go_offline() # Setting it to offline cufflinks will not work

debug 2 add cf.set_config_file(offline=True) # No

debug 3 add cf.set_config_file(sharing=’public’,offline=True) # No

debug 4 add cf.set_config_file(sharing=’public’,theme=’pearl’,offline=True) # No

debug 5 Add matplotlib.use(‘TkAgg’) # Specify the drawing backend, no

debug 6 Add matplotlib.use(‘Qt5Agg’) # Specify the drawing backend, no

debug 7 add fig = go.Figure(data=go.Bar(y=[2, 3, 1])) # Output a photo first, no

debug 8 Add init_notebook_mode(connected=True) # Some kind of initialization, no

debug 9 add %matplotlib inline # magic jupyter notebook statement does not work

debug 10 added plt.ion() # matplotlib specified interaction is not possible

debug 11 added plt.show() # No

debug 12 reinstall the corresponding library # No

debug 13 import plotly.express as px
from IPython.display import HTML # Import HTML, no

Finally, I found these articles:

https://segmentfault.com/q/1010000043217739

python – How to plot using plotly with offline mode out not in iPython notebooks? – Stack Overflow

For debug, just add the following 2 lines of statements,

 import plotly.offline as pyo # The first sentence added

        ....

        xx.iplot() #Drawing
        pyo.init_notebook_mode() # The second sentence added

Here is an example

import plotly.offline as pyo # Add this statement first,


import pandas as pd
import numpy as np
import cufflinks as cf
import matplotlib.pyplot as plt

cf.datagen.histogram(3).iplot(kind='histogram')
pyo.init_notebook_mode() # Add this statement again to display .iplot

pyo.init_notebook_mode() This statement needs to be after .iplot(), otherwise the picture will still not be displayed

The specific reasons are yet to be investigated

================================================== =====

Let’s first look at how cufflinks data flows:

cufflinks is built on the Plotly library. The DataFrame data of pandas becomes a picture in the memory through cufflinks, and then displayed using iplot (Plotly):

  • DataFrame: represents the data frame of pandas;
  • Figure: represents drawable graphics, such as bar, box, histogram, etc.;
  • iplot: represents the drawing method and has many parameters that can be configured;

What is happening inside Plotly that causes the image not to be displayed?

================================================== =====

Deep dig into the source code of the above two sentences: py.offline.init_notebook_mode ()

from https://github.com/plotly/plotly.py/blob/master/packages/python/plotly/plotly/offline/offline.py

def init_notebook_mode(connected=False):
    """
    Initialize plotly.js in the browser if it hasn't been loaded into the DOM
    yet. This is an idempotent method and can and should be called from any
    offline methods that require plotly.js to be loaded into the notebook dom.

    Keyword arguments:

    connected (default=False) -- If True, the plotly.js library will be loaded
    from an online CDN. If False, the plotly.js library will be loaded locally
    from the plotly python package

    Use `connected=True` if you want your notebooks to have smaller file sizes.
    In the case where `connected=False`, the entirety of the plotly.js library
    will be loaded into the notebook, which will result in a file-size increase
    of a couple megabytes. Additionally, because the library will be downloaded
    from the web, you and your viewers must be connected to the internet to be
    able to view charts within this notebook.

    Use `connected=False` if you want you and your collaborators to be able to
    create and view these charts regardless of the availability of an internet
    connection. This is the default option since it is the most predictable.
    Note that under this setting the library will be included inline inside
    your notebook, resulting in much larger notebook sizes compared to the case
    where `connected=True`.
    """
    import plotly.io as pio

    ipython = get_module("IPython")
    if not ipython:
        raise ImportError("`iplot` can only run inside an IPython Notebook.")

    if connected:
        pio.renderers.default = "plotly_mimetype + notebook_connected"
    else:
        pio.renderers.default = "plotly_mimetype + notebook"

    # Trigger immediate activation of notebook. This way the plotly.js
    # library reference is available to the notebook immediately
    pio.renderers._activate_pending_renderers()

It’s very clear here, the code does 2 things:

1 – Default renderer set

2 – If you are in a Jupyter notebook (ipython) environment, trigger Jupyter notebook to activate immediately,

In this way, the above statement is equivalent to

import plotly.io as pio
pio.renderers.default = "plotly_mimetype + notebook"
pio.renderers._activate_pending_renderers()

Therefore, the final reason for not displaying images is: The renderer is not specified and activated.

=======================================

Dig deeper

The role of pio.renderers._activate_pending_renderers()

# from
# https://github.com/plotly/plotly.py/blob/master/packages/python/plotly/plotly/io/_renderers.py




def _activate_pending_renderers(self, cls=object):

        to_activate_with_cls = [
            r for r in self._to_activate if cls and isinstance(r, cls)
        ]

        while to_activate_with_cls:
            renderer = to_activate_with_cls.pop(0)
            renderer.activate()

        self._to_activate = [
            r for r in self._to_activate if not (cls and isinstance(r, cls))
        ]

In the above program, various renderer queues are expanded into lists, and then the renderers are activated.

The types of renderers are:

#from
# https://github.com/plotly/plotly.py/blob/master/packages/python/plotly/plotly/io/_renderers.py
#

from ._base_renderers import (
    MimetypeRenderer,
    PlotlyRenderer,
    JsonRenderer,
    ImageRenderer,
    PngRenderer,
    SvgRenderer,
    PdfRenderer,
    JpegRenderer,
    HtmlRenderer,
    ColabRenderer,
    KaggleRenderer,
    NotebookRenderer,
    ExternalRenderer,
    BrowserRenderer,
)

#from
# https://github.com/plotly/plotly.py/blob/master/packages/python/plotly/plotly/io/_renderers.py

from plotly.io._base_renderers import (
    MimetypeRenderer,
    ExternalRenderer,
    PlotlyRenderer,
    NotebookRenderer,
    KaggleRenderer,
    AzureRenderer,
    ColabRenderer,
    JsonRenderer,
    PngRenderer,
    JpegRenderer,
    SvgRenderer,
    PdfRenderer,
    BrowserRenderer,
    IFrameRenderer,
    SphinxGalleryHtmlRenderer,
    SphinxGalleryOrcaRenderer,
    CoCalcRenderer,
    DatabricksRenderer,
)

todo Can the bug mentioned at the beginning of this article be fixed using simpler import statements and renderer execution statements ?

* plotly Based onplot.js, not matplotlib.pyplot

** Detailed introduction to the graphic display of Displaying figures in Python Plotly

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Python entry skill treeHomepageOverview 384019 people are learning the system