添加2个语句 解决cufflinks 的 .iplot 不显示图片的问题

环境:    jupyter notebook,    win7,win10,         chrome 浏览器 , edge浏览器,

bug:     cufflinks 的 .iplot 不显示图片

现象是:

1 - 用matplotlib.pyplot能显示图片 。

2 - plotly的iplot方法能保存图片到文件夹,但是用 plotly的iplot方法,jupyter notebook不显示图片   。

说明问题不在 matplotlib 和 matplotlib.pyplot,可能在plotly,可能不在cufflinks。


debug方法: 

搜索网络资源,得到以下方法,但是不适合我的情况,不能解决我的问题:

debug 1    加入  cf.go_offline()                                                          #   设为离线cufflinks不行

debug 2   加入  cf.set_config_file(offline=True)                                              #   不行

debug 3   加入  cf.set_config_file(sharing='public',offline=True)                           #   不行

debug 4   加入   cf.set_config_file(sharing='public',theme='pearl',offline=True)     #   不行

debug 5   加入  matplotlib.use('TkAgg')                #    指定绘图后端,不行

debug 6   加入  matplotlib.use('Qt5Agg')              #     指定绘图后端,不行

debug 7   加入   fig = go.Figure(data=go.Bar(y=[2, 3, 1]))          #    先输出一张照片,不行

debug 8   加入    init_notebook_mode(connected=True)            #    某种初始化,不行

debug 9   加入  %matplotlib inline                          #    魔法jupyter notebook 语句 不行

debug 10   加入 plt.ion()                                         #    matplotlib 指定交互不行

debug  11  加入   plt.show()                                    #    不行

debug  12  重装对应的库                                        #    不行

debug  13   import plotly.express as px
                  from IPython.display import HTML        # 导入HTML  ,    不行

最终,找到了这几篇文章:     

https://segmentfault.com/q/1010000043217739

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

debug   加入下面2行语句的就行啦,

        import plotly.offline as pyo    #  加入的第1句

        ....   

        xx.iplot()    #绘图
        pyo.init_notebook_mode()        #  加入的第2句

这里给个实例

import plotly.offline as pyo              #  先 加入这个语句 , 


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()                  #  再加入这个语句 ,可以显示 .iplot

pyo.init_notebook_mode()   这个语句需要在 .iplot() 后面  ,否则还是无法显示图片

具体原因待查

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

先看cufflinks的数据 是如何流动的:

cufflinks建立在Plotly库之上,pandas的DataFrame数据通过cufflinks成为内存中的图片,然后用iplot(Plotly)显示出来:

  • DataFrame:代表pandas的数据框;
  • Figure:代表可绘制图形,比如bar、box、histogram等等;
  • iplot:代表绘制方法,有很多参数可以配置;

Plotly 内部究竟发生了什么,导致图片显示不了呢?

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

深挖一步上面这两句的源代码: 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()

这里写得很清楚,代码做了2件事情:

1 - 设置了默认渲染器

2 - 如果在 Jupyter notebook (即 ipython )环境里,触发Jupyter notebook 立即激活,

这样,上述语句等价于

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

因此,不显示图片的最终原因是 : 渲染器没有指定和激活。

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

再深挖一步

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

上面的程序里将各种渲染器队列展开成list,然后激活渲染器

渲染器的种类有:

#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  是否可以用更简单的 import 语句渲染器执行语句 修复 本文开始提及的bug?


* plotly 基于plot.js,并不基于matplotlib.pyplot

** Displaying figures in Python   Plotly 的 图形 显示 的细节介绍 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值