最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談matplotlib中FigureCanvasXAgg的用法

 更新時(shí)間:2020年06月16日 10:13:54   作者:小__Q  
這篇文章主要介紹了淺談matplotlib中FigureCanvasXAgg的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

背景知識(shí):

FigureCanvasXAgg就是一個(gè)渲染器,渲染器的工作就是drawing,執(zhí)行繪圖的這個(gè)動(dòng)作。渲染器是使物體顯示在屏幕上

主要內(nèi)容:

將一個(gè)figure渲染的canvas變?yōu)橐粋€(gè)Qt widgets,figure顯示的過程是需要管理器(manager),需要FigureCanvasBase來管理。報(bào)錯(cuò)信息'FigureCanvasQTAgg' object has no attribute 'manager'

將一個(gè)navigation toolbar渲染成Qt widgets

使用用戶事件來實(shí)時(shí)更新matplotlib plot

matplotlib針對(duì)GUI設(shè)計(jì)了兩層結(jié)構(gòu)概念:canvas,renderer。

下面我將以默認(rèn)自帶的后端 tkAgg:from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg as FigureCanvas為例,為大家講解畫布與渲染器的知識(shí)。

一. canvas(畫布)

對(duì)應(yīng)抽象的類:FigureCanvasBase and FigureManagerBase

作用:

保存對(duì)圖像的引用

更新圖像通過對(duì)畫布的引用

定義運(yùn)行注冊(cè)的事件方法

將本地工具箱事件轉(zhuǎn)為matplotlib事件抽象框架

定義繪制渲染圖片的方法

停止和開始nono-GUI事件循環(huán)

1. 追尋matplotlib.figure.Figure.show( )

以下引自matplotlib.figure.Figure.show( ) 源碼和注釋:

#matplotlib.figure.Figure.show( )
def show(self, warn=True):
 """
 If using a GUI backend with pyplot, display the figure window.

 If the figure was not created using
 :func:`~matplotlib.pyplot.figure`, it will lack a
 :class:`~matplotlib.backend_bases.FigureManagerBase`, and
 will raise an AttributeError.

 Parameters
 ----------
 warm : bool
  If ``True``, issue warning when called on a non-GUI backend

 Notes
 -----
 For non-GUI backends, this does nothing, in which case a warning will
 be issued if *warn* is ``True`` (default).
 """
 try:
  manager = getattr(self.canvas, 'manager')
 except AttributeError as err:
  raise AttributeError("%s\n"
        "Figure.show works only "
        "for figures managed by pyplot, normally "
        "created by pyplot.figure()." % err)

 if manager is not None:
  try:
   manager.show()
   return
  except NonGuiException:
   pass

它是通過manager.show()來實(shí)現(xiàn)畫圖的動(dòng)作的。

2. 追尋plt.show()

而在==plt.show( )==的源碼中我們可以查到:

#plt.show()
from matplotlib.backends import pylab_setup
_show = pylab_setup()
def show(*args, **kw):

 global _show
 return _show(*args, **kw)

而我們繼續(xù)查找就得到了,這是在backends包的__init__.py模塊里的代碼,代碼說了一大堆,無非就是說它返回了四個(gè)對(duì)象:backend_mod, new_figure_manager, draw_if_interactive, show。而show就是show = getattr(backend_mod, 'show', do_nothing_show)得到的其中backend_mod就是要導(dǎo)入模塊的絕對(duì)路徑,之后驗(yàn)證的show就是matplotlib.backends.backend_tkagg._BackendTkAgg,繼續(xù)追尋之后我們得到class _BackendTkAgg(_BackendTk): FigureCanvas = FigureCanvasTkAgg,之后我們用help函數(shù)得到

show(block=None) method of builtins.type instance
 Show all figures.
 
 `show` blocks by calling `mainloop` if *block* is ``True``, or if it
 is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in
 `interactive` mode.

我們繼續(xù)刨根,尋找從FigureCanvas開始的類的關(guān)系和其方法,類的繼承結(jié)構(gòu)關(guān)系如下圖

然后終于在FigureCnavasTk類的聲明中找到了這樣的一句聲明:

show = cbook.deprecated("2.2", name="FigureCanvasTk.show",
       alternative="FigureCanvasTk.draw")(
        lambda self: self.draw())

也就是說show歸根結(jié)底是backend里的一個(gè)FigureCanvasTk.draw()的一個(gè)變形 !

pylab_setup代碼如下:

def pylab_setup(name=None):
 '''return new_figure_manager, draw_if_interactive and show for pyplot

 This provides the backend-specific functions that are used by
 pyplot to abstract away the difference between interactive backends.

 Parameters
 ----------
 name : str, optional
  The name of the backend to use. If `None`, falls back to
  ``matplotlib.get_backend()`` (which return :rc:`backend`).

 '''
 # Import the requested backend into a generic module object
 if name is None:
  # validates, to match all_backends
  name = matplotlib.get_backend()
 if name.startswith('module://'):
  backend_name = name[9:]
 else:
  backend_name = 'backend_' + name
  backend_name = backend_name.lower() # until we banish mixed case
  backend_name = 'matplotlib.backends.%s' % backend_name.lower()

 # the last argument is specifies whether to use absolute or relative
 # imports. 0 means only perform absolute imports.
 #得到模塊的絕對(duì)路徑backend_mod,然后通過絕對(duì)路徑加.就可以調(diào)用各個(gè)抽象類
 #<module 'matplotlib.backends.backend_tkagg' from 'D:\\Python36\\lib\\site-packages\\matplotlib\\backends\\backend_tkagg.py'>默認(rèn)實(shí)驗(yàn)的!
 backend_mod = __import__(backend_name, globals(), locals(),
        [backend_name], 0)

 # Things we pull in from all backends
 new_figure_manager = backend_mod.new_figure_manager

 # image backends like pdf, agg or svg do not need to do anything
 # for "show" or "draw_if_interactive", so if they are not defined
 # by the backend, just do nothing
 def do_nothing_show(*args, **kwargs):
  frame = inspect.currentframe()
  fname = frame.f_back.f_code.co_filename
  if fname in ('<stdin>', '<ipython console>'):
   warnings.warn("""
Your currently selected backend, '%s' does not support show().
Please select a GUI backend in your matplotlibrc file ('%s')
or with matplotlib.use()""" %
       (name, matplotlib.matplotlib_fname()))

 def do_nothing(*args, **kwargs):
  pass

 backend_version = getattr(backend_mod, 'backend_version', 'unknown')

 show = getattr(backend_mod, 'show', do_nothing_show)

 draw_if_interactive = getattr(backend_mod, 'draw_if_interactive',
         do_nothing)

 _log.debug('backend %s version %s', name, backend_version)

 # need to keep a global reference to the backend for compatibility
 # reasons. See https://github.com/matplotlib/matplotlib/issues/6092
 global backend
 backend = name
 return backend_mod, new_figure_manager, draw_if_interactive, show

3. 追尋plt.figure()

我們創(chuàng)建的這個(gè)figure必須有manager,否則則會(huì)報(bào)錯(cuò),如果是plt.figure初始化的,plt.figure( )源碼如下:

plt.figure()示例

def figure():

 figManager = _pylab_helpers.Gcf.get_fig_manager(num)

 figManager = new_figure_manager(num,figsize=figsize,dpi=dpi,facecolor=facecolor,edgecolor=edgecolor,frameon=frameon,FigureClass=FigureClass,**kwargs)
 ......
 ......
 return figManager.canvas.figure

4. 追尋matplotlib.figure.Figure()

而在matplotlib.figure.Figure() 中,其初始化函數(shù)__init__(),并沒有默認(rèn)生成manager這個(gè)屬性,所以在調(diào)用show的時(shí)候,就會(huì)報(bào)錯(cuò)!如上其show函數(shù)定義的那樣

 def __init__(self,
     figsize=None, # defaults to rc figure.figsize
     dpi=None, # defaults to rc figure.dpi
     facecolor=None, # defaults to rc figure.facecolor
     edgecolor=None, # defaults to rc figure.edgecolor
     linewidth=0.0, # the default linewidth of the frame
     frameon=None, # whether or not to draw the figure frame
     subplotpars=None, # default to rc
     tight_layout=None, # default to rc figure.autolayout
     constrained_layout=None, # default to rc
           #figure.constrained_layout.use
     ):
  """
  Parameters
  ----------
  figsize : 2-tuple of floats
   ``(width, height)`` tuple in inches

  dpi : float
   Dots per inch

  facecolor
   The figure patch facecolor; defaults to rc ``figure.facecolor``

  edgecolor
   The figure patch edge color; defaults to rc ``figure.edgecolor``

  linewidth : float
   The figure patch edge linewidth; the default linewidth of the frame

  frameon : bool
   If ``False``, suppress drawing the figure frame

  subplotpars : :class:`SubplotParams`
   Subplot parameters, defaults to rc

  tight_layout : bool
   If ``False`` use *subplotpars*; if ``True`` adjust subplot
   parameters using `.tight_layout` with default padding.
   When providing a dict containing the keys
   ``pad``, ``w_pad``, ``h_pad``, and ``rect``, the default
   `.tight_layout` paddings will be overridden.
   Defaults to rc ``figure.autolayout``.

  constrained_layout : bool
   If ``True`` use constrained layout to adjust positioning of plot
   elements. Like ``tight_layout``, but designed to be more
   flexible. See
   :doc:`/tutorials/intermediate/constrainedlayout_guide`
   for examples. (Note: does not work with :meth:`.subplot` or
   :meth:`.subplot2grid`.)
   Defaults to rc ``figure.constrained_layout.use``.
  """
  Artist.__init__(self)
  # remove the non-figure artist _axes property
  # as it makes no sense for a figure to be _in_ an axes
  # this is used by the property methods in the artist base class
  # which are over-ridden in this class
  del self._axes
  self.callbacks = cbook.CallbackRegistry()

  if figsize is None:
   figsize = rcParams['figure.figsize']
  if dpi is None:
   dpi = rcParams['figure.dpi']
  if facecolor is None:
   facecolor = rcParams['figure.facecolor']
  if edgecolor is None:
   edgecolor = rcParams['figure.edgecolor']
  if frameon is None:
   frameon = rcParams['figure.frameon']

  if not np.isfinite(figsize).all():
   raise ValueError('figure size must be finite not '
        '{}'.format(figsize))
  self.bbox_inches = Bbox.from_bounds(0, 0, *figsize)

  self.dpi_scale_trans = Affine2D().scale(dpi, dpi)
  # do not use property as it will trigger
  self._dpi = dpi
  self.bbox = TransformedBbox(self.bbox_inches, self.dpi_scale_trans)

  self.frameon = frameon

  self.transFigure = BboxTransformTo(self.bbox)

  self.patch = Rectangle(
   xy=(0, 0), width=1, height=1,
   facecolor=facecolor, edgecolor=edgecolor, linewidth=linewidth)
  self._set_artist_props(self.patch)
  self.patch.set_aa(False)

  self._hold = rcParams['axes.hold']
  if self._hold is None:
   self._hold = True

  self.canvas = None
  self._suptitle = None

  if subplotpars is None:
   subplotpars = SubplotParams()

  self.subplotpars = subplotpars
  # constrained_layout:
  self._layoutbox = None
  # set in set_constrained_layout_pads()
  self.set_constrained_layout(constrained_layout)

  self.set_tight_layout(tight_layout)

  self._axstack = AxesStack() # track all figure axes and current axes
  self.clf()
  self._cachedRenderer = None

  # groupers to keep track of x and y labels we want to align.
  # see self.align_xlabels and self.align_ylabels and
  # axis._get_tick_boxes_siblings
  self._align_xlabel_grp = cbook.Grouper()
  self._align_ylabel_grp = cbook.Grouper()

綜上所述,我們通過matplotlib.figure.Figure()來創(chuàng)建得到的fig,并不具備manager的屬性,而通過plt.figure()創(chuàng)建的fig,就默認(rèn)創(chuàng)建了manager。

二 . renderer(渲染器),默認(rèn)是tkagg

對(duì)應(yīng)抽象的類:RendererBase and GraphicsContextBase

作用:

- 很多渲染操作都傳遞給一個(gè)額外的抽象:GraphicsContextBase,它為處理顏色、線條樣式、起始樣式、混合屬性和反混疊選項(xiàng)等的代碼提供了一個(gè)干凈的分離。

Qt & matplotlib示例代碼

#import modules from Matplotlib
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
import matplotlib.pyplot as plt
#import random module to generate set
import random

class Window(QtGui.QDialog):
	def __init__(self, parent=None):
		super(Window, self).__init__(parent)
		#init figure and canvas
		self.figure = plt.figure()
		self.canvas = FigureCanvas(self.figure)
		#init nav toolbar
		self.toolbar = NavigationToolbar(self.canvas, self)
		# Add plot button
		self.button = QtGui.QPushButton('Plot')
		# connect button to custom slot (see later)
		self.button.clicked.connect(self.plot)
		# set the layout
		layout = QtGui.QVBoxLayout()
		layout.addWidget(self.toolbar)
		layout.addWidget(self.canvas)
		layout.addWidget(self.button)
		self.setLayout(layout)
	### our custom slot
	def plot(self):
		# random data
		data = [random.random() for i in range(25)]
		# create an axis
		ax = self.figure.add_subplot(1,1,1)
		# discards the old graph
		ax.hold(False)
		# plot data
		ax.plot(data, '*­')
		# refresh canvas
		self.canvas.draw()

三. Problems(GUI畫3D不能旋轉(zhuǎn))

一個(gè)Axes3D創(chuàng)建callback函數(shù)給畫布上的圖形實(shí)現(xiàn)旋轉(zhuǎn)特性。如果說先給圖形(figure)增加axes或者其他配件的時(shí)候,在之后將圖形附加到畫布的時(shí)候,之前添加的axes的callback函數(shù)可能不能夠接收消息事件,也就沒辦法在繪出的GUI實(shí)現(xiàn)旋轉(zhuǎn)的性能。

所以應(yīng)該先將圖形附加到畫布上,然后再對(duì)圖形增加axes和其他的配件。

FigureCanvas(figure,canvas)

figure:需要附加的圖形(添加者),canvas提供渲染功能的對(duì)象(承載者)

每一次你調(diào)用FigureCanvas()的時(shí)候,你都是將圖形附加到新畫布上(這不是你所看到的的那個(gè)canvas),于是 the call-backs函數(shù)將不會(huì)被射擊(接收事件信號(hào)),因?yàn)樗麄冋诒O(jiān)聽一個(gè)你看不到的canvas。

四 . 附錄

以上這篇淺談matplotlib中FigureCanvasXAgg的用法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • ptyhon實(shí)現(xiàn)sitemap生成示例

    ptyhon實(shí)現(xiàn)sitemap生成示例

    這篇文章主要介紹了ptyhon實(shí)現(xiàn)sitemap生成示例,需要的朋友可以參考下
    2014-03-03
  • Python?OpenGL基本配置方式

    Python?OpenGL基本配置方式

    這篇文章主要介紹了Python?OpenGL基本配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 快速進(jìn)修Python指南之迭代器Iterator與生成器

    快速進(jìn)修Python指南之迭代器Iterator與生成器

    這篇文章主要為大家介紹了Java開發(fā)者快速進(jìn)修Python指南之迭代器Iterator與生成器示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 跟老齊學(xué)Python之集成開發(fā)環(huán)境(IDE)

    跟老齊學(xué)Python之集成開發(fā)環(huán)境(IDE)

    IDE的全稱是:Integrated Development Environment,簡稱IDE,也稱為Integration Design Environment、Integration Debugging Environment,翻譯成中文叫做“集成開發(fā)環(huán)境”,在臺(tái)灣那邊叫做“整合開發(fā)環(huán)境”。
    2014-09-09
  • Python合并多個(gè)裝飾器小技巧

    Python合并多個(gè)裝飾器小技巧

    這篇文章主要介紹了Python合并多個(gè)裝飾器小技巧,本文用改寫調(diào)用函數(shù)的方式實(shí)現(xiàn)把多個(gè)裝飾器合并成一行、一個(gè)函數(shù)來調(diào)用,需要的朋友可以參考下
    2015-04-04
  • Python requests HTTP驗(yàn)證登錄實(shí)現(xiàn)流程

    Python requests HTTP驗(yàn)證登錄實(shí)現(xiàn)流程

    這篇文章主要介紹了Python requests HTTP驗(yàn)證登錄實(shí)現(xiàn)流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • django連接oracle時(shí)setting 配置方法

    django連接oracle時(shí)setting 配置方法

    今天小編就為大家分享一篇django連接oracle時(shí)setting 配置方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • python中的文件打開與關(guān)閉操作命令介紹

    python中的文件打開與關(guān)閉操作命令介紹

    下面小編就為大家分享一篇python中的文件打開與關(guān)閉操作命令介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • pandas將DataFrame的列變成行索引的方法

    pandas將DataFrame的列變成行索引的方法

    下面小編就為大家分享一篇pandas將DataFrame的列變成行索引的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python中*args與**kwargs的高級(jí)應(yīng)用指南

    Python中*args與**kwargs的高級(jí)應(yīng)用指南

    在Python編程中,*args和**kwargs是兩個(gè)非常強(qiáng)大的功能,它們?cè)试S開發(fā)者構(gòu)建更加靈活和可擴(kuò)展的函數(shù),下面就跟隨小編一起來看看它的具體應(yīng)用吧
    2024-03-03

最新評(píng)論

嘉峪关市| 昌乐县| 陇南市| 隆化县| 陆川县| 余江县| 井研县| 佛冈县| 高陵县| 泸定县| 沅江市| 施秉县| 新野县| 威远县| 莱西市| 永吉县| 英超| 富顺县| 菏泽市| 平舆县| 蓬安县| 永修县| 仪征市| 略阳县| 南靖县| 南江县| 正定县| 潍坊市| 康乐县| 阿巴嘎旗| 洛隆县| 昆山市| 汉源县| 伊通| 鄯善县| 铅山县| 务川| 高陵县| 共和县| 长子县| 汾阳市|