content: '''
  Backend Kivy
  =====
  
  .. image:: images/backend_kivy_example.jpg
      :align: right
  
  The :class:`FigureCanvasKivy` widget is used to create a matplotlib graph.
  This widget has the same properties as
  :class:`kivy.ext.mpl.backend_kivyagg.FigureCanvasKivyAgg`. FigureCanvasKivy
  instead of rendering a static image, uses the kivy graphics instructions
  :class:`kivy.graphics.Line` and :class:`kivy.graphics.Mesh` to render on the
  canvas.
  
  Installation
  ------------
  
  The matplotlib backend for kivy can be used by using the garden extension in
  kivy following this .. _link: http://kivy.org/docs/api-kivy.garden.html ::
  
      garden install matplotlib
  
  Or if you want to include it directly on your application ::
  
      cd myapp
      garden install --app matplotlib
  
  
  Initialization
  --------------
  
  A backend can be initialized in two ways. The first one is using pure pyplot
  as explained
  .. _here: http://matplotlib.org/faq/usage_faq.html#what-is-a-backend::
  
      import matplotlib
      matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
  
  Once this is done, any figure instantiated after will be wrapped by a
  :class:`FigureCanvasKivy` ready to use. From here there are two options to
  continue with the development.
  
  1. Use the :class:`FigureCanvasKivy` attribute defined as canvas from Figure,
  to embed your matplotlib graph in your own Kivy application as can be seen in
  the first example in the following section.
  
  .. warning::
  
      One can create a matplotlib widget by importing FigureCanvas::
  
          from kivy.garden.matplotlib.backend_kivyagg import FigureCanvas
          or
          from kivy.garden.matplotlib.backend_kivy import FigureCanvas
  
      and then instantiate an object::
  
          fig, ax = plt.subplots()
          my_mpl_kivy_widget = FigureCanvas(fig)
  
      which will certainly work but a problem will arise if events were connected
      before the FigureCanvas is instantiated. If this approach is taken please
      connect matplotlib events after generating the matplotlib kivy widget
      object ::
  
          fig, ax = plt.subplots()
          fig.canvas.mpl_connect('button_press_event', callback_handler)
          my_mpl_kivy_widget = FigureCanvas(fig)
  
      In this scenario button_press_event won't be connected with the object
      being created in line 3, because will be connected to the default canvas
      set by matplotlib. If this approach is taken be sure of connecting the
      events after instantiation like the following: ::
  
          fig, ax = plt.subplots()
          my_mpl_kivy_widget = FigureCanvas(fig)
          fig.canvas.mpl_connect('button_press_event', callback_handler)
  
  2. Use pyplot to write the application following matplotlib sintax as can be
  seen in the second example below. In this case a Kivy application will be
  created automatically from the matplotlib instructions and a NavigationToolbar
  will be added to the main canvas.
  
  
  Examples
  --------
  
  1. Example of a simple Hello world matplotlib App::
  
      fig, ax = plt.subplots()
      ax.text(0.6, 0.5, "hello", size=50, rotation=30.,
              ha="center", va="center",
              bbox=dict(boxstyle="round",
                        ec=(1., 0.5, 0.5),
                        fc=(1., 0.8, 0.8),
                        )
              )
      ax.text(0.5, 0.4, "world", size=50, rotation=-30.,
              ha="right", va="top",
              bbox=dict(boxstyle="square",
                        ec=(1., 0.5, 0.5),
                        fc=(1., 0.8, 0.8),
                        )
              )
      canvas = fig.canvas
  
  The object canvas can be added as a widget into the kivy tree widget.
  If a change is done on the figure an update can be performed using
  :meth:`~kivy.ext.mpl.backend_kivyagg.FigureCanvasKivyAgg.draw`.::
  
      # update graph
      canvas.draw()
  
  The plot can be exported to png with
  :meth:`~kivy.ext.mpl.backend_kivyagg.FigureCanvasKivyAgg.print_png`, as an
  argument receives the `filename`.::
  
      # export to png
      canvas.print_png("my_plot.png")
  
  2. Example of a pyplot application using matplotlib instructions::
  
      import numpy as np
      import matplotlib.pyplot as plt
  
      N = 5
      menMeans = (20, 35, 30, 35, 27)
      menStd = (2, 3, 4, 1, 2)
      ind = np.arange(N)  # the x locations for the groups
      width = 0.35       # the width of the bars
      figure, ax = plt.subplots()
  
      rects1 = ax.bar(ind, menMeans, width, color='r', yerr=menStd)
      womenMeans = (25, 32, 34, 20, 25)
      womenStd = (3, 5, 2, 3, 3)
      rects2 = ax.bar(ind + width, womenMeans, width, color='y', yerr=womenStd)
  
      ax.set_ylabel('----------------------Scores------------------')
      ax.set_title('Scores by group and gender')
      ax.set_xticks(ind + width)
      ax.set_yticklabels(('Ahh', '--G1--', 'G2', 'G3', 'G4', 'G5', 'G5',
                          'G5', 'G5'), rotation=90)
      ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))
      plt.draw()
      plt.savefig("test.png")
      plt.show()
  
  
  Navigation Toolbar
  -----------------
  
  If initialized by the first step a :class:`NavigationToolbarKivy` widget can be
  created as well by instantiating an object with a :class:`FigureCanvasKivy` as
  parameter. The actual widget is stored in its actionbar attribute.
  This can be seen in test_backend.py example ::
  
      bl = BoxLayout(orientation="vertical")
      my_mpl_kivy_widget1 = FigureCanvasKivy(fig1)
      my_mpl_kivy_widget2 = FigureCanvasKivy(fig2)
      nav1 = NavigationToolbar2Kivy(my_mpl_kivy_widget1)
      nav2 = NavigationToolbar2Kivy(my_mpl_kivy_widget2)
      bl.add_widget(nav1.actionbar)
      bl.add_widget(my_mpl_kivy_widget1)
      bl.add_widget(nav2.actionbar)
      bl.add_widget(my_mpl_kivy_widget2)
  
  
  Connecting Matplotlib events to Kivy Events
  -----------------------
  
  All matplotlib events are available: `button_press_event` which is raised
  on a mouse button clicked or on touch down, `button_release_event` which is
  raised when a click button is released or on touch up, `key_press_event` which
  is raised when a key is pressed, `key_release_event` which is raised when a key
  is released, `motion_notify_event` which is raised when the mouse is on motion,
  `resize_event` which is raised when the dimensions of the widget change,
  `scroll_event` which is raised when the mouse scroll wheel is rolled,
  `figure_enter_event` which is raised when mouse enters a new figure,
  `figure_leave_event` which is raised when mouse leaves a figure,
  `close_event` which is raised when the window is closed,
  `draw_event` which is raised on canvas draw,
  `pick_event` which is raised when an object is selected,
  `idle_event` (deprecated),
  `axes_enter_event` which is fired when mouse enters axes,
  `axes_leave_event` which is fired when mouse leaves axes.::
  
      def press(event):
          print('press released from test', event.x, event.y, event.button)
  
  
      def release(event):
          print('release released from test', event.x, event.y, event.button)
  
  
      def keypress(event):
          print('key down', event.key)
  
  
      def keyup(event):
          print('key up', event.key)
  
  
      def motionnotify(event):
          print('mouse move to ', event.x, event.y)
  
  
      def resize(event):
          print('resize from mpl ', event)
  
  
      def scroll(event):
          print('scroll event from mpl ', event.x, event.y, event.step)
  
  
      def figure_enter(event):
          print('figure enter mpl')
  
  
      def figure_leave(event):
          print('figure leaving mpl')
  
  
      def close(event):
          print('closing figure')
  
  
      fig.canvas.mpl_connect('button_press_event', press)
      fig.canvas.mpl_connect('button_release_event', release)
      fig.canvas.mpl_connect('key_press_event', keypress)
      fig.canvas.mpl_connect('key_release_event', keyup)
      fig.canvas.mpl_connect('motion_notify_event', motionnotify)
      fig.canvas.mpl_connect('resize_event', resize)
      fig.canvas.mpl_connect('scroll_event', scroll)
      fig.canvas.mpl_connect('figure_enter_event', figure_enter)
      fig.canvas.mpl_connect('figure_leave_event', figure_leave)
      fig.canvas.mpl_connect('close_event', close)
  
  '''
  
  from __future__ import (absolute_import, division, print_function,
                          unicode_literals)
  
  import six
  import os
  import matplotlib
  import matplotlib.transforms as transforms
  from matplotlib._pylab_helpers import Gcf
  from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
      FigureManagerBase, FigureCanvasBase, NavigationToolbar2, TimerBase
  from matplotlib.figure import Figure
  from matplotlib.transforms import Bbox, Affine2D
  from matplotlib.backend_bases import ShowBase, Event
  from matplotlib.backends.backend_agg import FigureCanvasAgg
  from matplotlib.mathtext import MathTextParser
  from matplotlib import rcParams
  from hashlib import md5
  from matplotlib import _png
  from matplotlib import _path
  
  try:
      import kivy
  except ImportError:
      raise ImportError("this backend requires Kivy to be installed.")
  
  from kivy.app import App
  from kivy.graphics.texture import Texture
  from kivy.graphics import Rectangle
  from kivy.uix.widget import Widget
  from kivy.uix.label import Label
  from kivy.uix.floatlayout import FloatLayout
  from kivy.uix.behaviors import FocusBehavior
  from kivy.uix.actionbar import ActionBar, ActionView, \
                                  ActionButton, ActionToggleButton, \
                                  ActionPrevious, ActionOverflow, ActionSeparator
  from kivy.base import EventLoop
  from kivy.core.text import Label as CoreLabel
  from kivy.core.image import Image
  from kivy.graphics import Color, Line
  from kivy.graphics import Rotate, Translate
  from kivy.graphics.instructions import InstructionGroup
  from kivy.graphics.tesselator import Tesselator
  from kivy.graphics.context_instructions import PopMatrix, PushMatrix
  from kivy.graphics import StencilPush, StencilPop, StencilUse,\
                                  StencilUnUse
  from kivy.logger import Logger
  from kivy.graphics import Mesh
  from kivy.resources import resource_find
  from kivy.uix.stencilview import StencilView
  from kivy.core.window import Window
  from kivy.uix.button import Button
  from kivy.uix.boxlayout import BoxLayout
  from kivy.uix.floatlayout import FloatLayout
  from kivy.uix.relativelayout import RelativeLayout
  from kivy.uix.popup import Popup
  from kivy.properties import ObjectProperty
  from kivy.uix.textinput import TextInput
  from kivy.lang import Builder
  from kivy.logger import Logger
  from kivy.clock import Clock
  from distutils.version import LooseVersion
  
  _mpl_ge_1_5 = LooseVersion(matplotlib.__version__) >= LooseVersion('1.5.0')
  _mpl_ge_2_0 = LooseVersion(matplotlib.__version__) >= LooseVersion('2.0.0')
  
  import numpy as np
  import io
  import textwrap
  import uuid
  import numbers
  from functools import partial
  from math import cos, sin, pi
  
  kivy.require('1.9.1')
  
  toolbar = None
  my_canvas = None
  
  
  class SaveDialog(FloatLayout):
      save = ObjectProperty(None)
      text_input = ObjectProperty(None)
      cancel = ObjectProperty(None)
  
  
  class MPLKivyApp(App):
      '''Creates the App initializing a FloatLayout with a figure and toolbar
         widget.
      '''
      figure = ObjectProperty(None)
      toolbar = ObjectProperty(None)
  
      def build(self):
          EventLoop.ensure_window()
          layout = FloatLayout()
          if self.figure:
              self.figure.size_hint_y = 0.9
              layout.add_widget(self.figure)
          if self.toolbar:
              self.toolbar.size_hint_y = 0.1
              layout.add_widget(self.toolbar)
          return layout
  
  
  def draw_if_interactive():
      '''Handle whether or not the backend is in interactive mode or not.
      '''
      if matplotlib.is_interactive():
          figManager = Gcf.get_active()
          if figManager:
              figManager.canvas.draw_idle()
  
  
  class Show(ShowBase):
      '''mainloop needs to be overwritten to define the show() behavior for kivy
         framework.
      '''
      def mainloop(self):
          app = App.get_running_app()
          if app is None:
              app = MPLKivyApp(figure=my_canvas, toolbar=toolbar)
              app.run()
  
  show = Show()
  
  
  def new_figure_manager(num, *args, **kwargs):
      '''Create a new figure manager instance for the figure given.
      '''
      # if a main-level app must be created, this (and
      # new_figure_manager_given_figure) is the usual place to
      # do it -- see backend_wx, backend_wxagg and backend_tkagg for
      # examples. Not all GUIs require explicit instantiation of a
      # main-level app (egg backend_gtk, backend_gtkagg) for pylab
      FigureClass = kwargs.pop('FigureClass', Figure)
      thisFig = FigureClass(*args, **kwargs)
      return new_figure_manager_given_figure(num, thisFig)
  
  
  def new_figure_manager_given_figure(num, figure):
      '''Create a new figure manager instance for the given figure.
      '''
      canvas = FigureCanvasKivy(figure)
      manager = FigureManagerKivy(canvas, num)
      global my_canvas
      global toolbar
      toolbar = manager.toolbar.actionbar if manager.toolbar else None
      my_canvas = canvas
      return manager
  
  
  class RendererKivy(RendererBase):
      '''The kivy renderer handles drawing/rendering operations. A RendererKivy
         should be initialized with a FigureCanvasKivy widget. On initialization
         a MathTextParser is instantiated to generate math text inside a
         FigureCanvasKivy widget. Additionally a list to store clip_rectangles
         is defined for elements that need to be clipped inside a rectangle such
         as axes. The rest of the render is performed using kivy graphics
         instructions.
      '''
      def __init__(self, widget):
          super(RendererKivy, self).__init__()
          self.widget = widget
          self.dpi = widget.figure.dpi
          self._markers = {}
          #  Can be enhanced by using TextToPath matplotlib, textpath.py
          self.mathtext_parser = MathTextParser("Bitmap")
          self.list_goraud_triangles = []
          self.clip_rectangles = []
          self.labels_inside_plot = []
  
      def contains(self, widget, x, y):
          '''Returns whether or not a point is inside the widget. The value
             of the point is defined in x, y as kivy coordinates.
          '''
          left = widget.x
          bottom = widget.y
          top = widget.y + widget.height
          right = widget.x + widget.width
          return (left <= x <= right and
                  bottom <= y <= top)
  
      def handle_clip_rectangle(self, gc, x, y):
          '''It checks whether the point (x,y) collides with any already
             existent stencil. If so it returns the index position of the
             stencil it collides with. if the new clip rectangle bounds are
             None it draws in the canvas otherwise it finds the correspondent
             stencil or creates a new one for the new graphics instructions.
             The point x,y is given in matplotlib coordinates.
          '''
          x = self.widget.x + x
          y = self.widget.y + y
          collides = self.collides_with_existent_stencil(x, y)
          if collides > -1:
              return collides
          new_bounds = gc.get_clip_rectangle()
          if new_bounds:
              x = self.widget.x + int(new_bounds.bounds[0])
              y = self.widget.y + int(new_bounds.bounds[1])
              w = int(new_bounds.bounds[2])
              h = int(new_bounds.bounds[3])
              collides = self.collides_with_existent_stencil(x, y)
              if collides == -1:
                  cliparea = StencilView(pos=(x, y), size=(w, h))
                  self.clip_rectangles.append(cliparea)
                  self.widget.add_widget(cliparea)
                  return len(self.clip_rectangles) - 1
              else:
                  return collides
          else:
              return -2
  
      def draw_path_collection(self, gc, master_transform, paths, all_transforms,
          offsets, offsetTrans, facecolors, edgecolors,
          linewidths, linestyles, antialiaseds, urls,
          offset_position):
          '''Draws a collection of paths selecting drawing properties from
             the lists *facecolors*, *edgecolors*, *linewidths*,
             *linestyles* and *antialiaseds*. *offsets* is a list of
             offsets to apply to each of the paths. The offsets in
             *offsets* are first transformed by *offsetTrans* before being
             applied.  *offset_position* may be either "screen" or "data"
             depending on the space that the offsets are in.
          '''
          len_path = len(paths[0].vertices) if len(paths) > 0 else 0
          uses_per_path = self._iter_collection_uses_per_path(
              paths, all_transforms, offsets, facecolors, edgecolors)
          # check whether an optimization is needed by calculating the cost of
          # generating and use a path with the cost of emitting a path in-line.
          should_do_optimization = \
              len_path + uses_per_path + 5 < len_path * uses_per_path
          if not should_do_optimization:
              return RendererBase.draw_path_collection(
                  self, gc, master_transform, paths, all_transforms,
                  offsets, offsetTrans, facecolors, edgecolors,
                  linewidths, linestyles, antialiaseds, urls,
                  offset_position)
          # Generate an array of unique paths with the respective transformations
          path_codes = []
          for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
              master_transform, paths, all_transforms)):
              transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
              if _mpl_ge_2_0:
                  polygons = path.to_polygons(transform, closed_only=False)
              else:
                  polygons = path.to_polygons(transform)
              path_codes.append(polygons)
          # Apply the styles and rgbFace to each one of the raw paths from
          # the list. Additionally a transformation is being applied to
          # translate each independent path
          for xo, yo, path_poly, gc0, rgbFace in self._iter_collection(
              gc, master_transform, all_transforms, path_codes, offsets,
              offsetTrans, facecolors, edgecolors, linewidths, linestyles,
              antialiaseds, urls, offset_position):
              list_canvas_instruction = self.get_path_instructions(gc0, path_poly,
                                      closed=True, rgbFace=rgbFace)
              for widget, instructions in list_canvas_instruction:
                  widget.canvas.add(PushMatrix())
                  widget.canvas.add(Translate(xo, yo))
                  widget.canvas.add(instructions)
                  widget.canvas.add(PopMatrix())
  
      def collides_with_existent_stencil(self, x, y):
          '''Check all the clipareas and returns the index of the clip area that
             contains this point. The point x, y is given in kivy coordinates.
          '''
          idx = -1
          for cliparea in self.clip_rectangles:
              idx += 1
              if self.contains(cliparea, x, y):
                  return idx
          return -1
  
      def get_path_instructions(self, gc, polygons, closed=False, rgbFace=None):
          '''With a graphics context and a set of polygons it returns a list
             of InstructionGroups required to render the path.
          '''
          instructions_list = []
          points_line = []
          for polygon in polygons:
              for x, y in polygon:
                  x = x + self.widget.x
                  y = y + self.widget.y
                  points_line += [float(x), float(y), ]
              tess = Tesselator()
              tess.add_contour(points_line)
              if not tess.tesselate():
                  Logger.warning("Tesselator didn't work :(")
                  return
              newclip = self.handle_clip_rectangle(gc, x, y)
              if newclip > -1:
                  instructions_list.append((self.clip_rectangles[newclip],
                          self.get_graphics(gc, tess, points_line, rgbFace,
                                            closed=closed)))
              else:
                  instructions_list.append((self.widget,
                          self.get_graphics(gc, tess, points_line, rgbFace,
                                            closed=closed)))
          return instructions_list
  
      def get_graphics(self, gc, polygons, points_line, rgbFace, closed=False):
          '''Return an instruction group which contains the necessary graphics
             instructions to draw the respective graphics.
          '''
          instruction_group = InstructionGroup()
          if isinstance(gc.line['dash_list'], tuple):
              gc.line['dash_list'] = list(gc.line['dash_list'])
          if rgbFace is not None:
              if len(polygons.meshes) != 0:
                  instruction_group.add(Color(*rgbFace))
                  for vertices, indices in polygons.meshes:
                      instruction_group.add(Mesh(
                          vertices=vertices,
                          indices=indices,
                          mode=str("triangle_fan")
                      ))
          instruction_group.add(Color(*gc.get_rgb()))
          if _mpl_ge_1_5 and (not _mpl_ge_2_0) and closed:
              points_poly_line = points_line[:-2]
          else:
              points_poly_line = points_line
          if gc.line['width'] > 0:
              instruction_group.add(Line(points=points_poly_line,
                  width=int(gc.line['width'] / 2),
                  dash_length=gc.line['dash_length'],
                  dash_offset=gc.line['dash_offset'],
                  dash_joint=gc.line['join_style'],
                  dash_list=gc.line['dash_list']))
          return instruction_group
  
      def draw_image(self, gc, x, y, im):
          '''Render images that can be displayed on a matplotlib figure.
             These images are generally called using imshow method from pyplot.
             A Texture is applied to the FigureCanvas. The position x, y is
             given in matplotlib coordinates.
          '''
          # Clip path to define an area to mask.
          clippath, clippath_trans = gc.get_clip_path()
          # Normal coordinates calculated and image added.
          x = self.widget.x + x
          y = self.widget.y + y
          bbox = gc.get_clip_rectangle()
          if bbox is not None:
              l, b, w, h = bbox.bounds
          else:
              l = 0
              b = 0
              w = self.widget.width
              h = self.widget.height
          h, w = im.get_size_out()
          rows, cols, image_str = im.as_rgba_str()
          texture = Texture.create(size=(w, h))
          texture.blit_buffer(image_str, colorfmt='rgba', bufferfmt='ubyte')
          if clippath is None:
              with self.widget.canvas:
                  Color(1.0, 1.0, 1.0, 1.0)
                  Rectangle(texture=texture, pos=(x, y), size=(w, h))
          else:
              if _mpl_ge_2_0:
                  polygons = clippath.to_polygons(clippath_trans, closed_only=False)
              else:
                  polygons = clippath.to_polygons(clippath_trans)
              list_canvas_instruction = self.get_path_instructions(gc, polygons,
                                                  rgbFace=(1.0, 1.0, 1.0, 1.0))
              for widget, instructions in list_canvas_instruction:
                  widget.canvas.add(StencilPush())
                  widget.canvas.add(instructions)
                  widget.canvas.add(StencilUse())
                  widget.canvas.add(Color(1.0, 1.0, 1.0, 1.0))
                  widget.canvas.add(Rectangle(texture=texture,
                                              pos=(x, y), size=(w, h)))
                  widget.canvas.add(StencilUnUse())
                  widget.canvas.add(StencilPop())
  
      def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
          '''Render text that is displayed in the canvas. The position x, y is
             given in matplotlib coordinates. A `GraphicsContextKivy` is given
             to render according to the text properties such as color, size, etc.
             An angle is given to change the orientation of the text when needed.
             If the text is a math expression it will be rendered using a
             MathText parser.
          '''
          if mtext:
              transform = mtext.get_transform()
              ax, ay = transform.transform_point(mtext.get_position())
  
              angle_rad = mtext.get_rotation() * np.pi / 180.
              dir_vert = np.array([np.sin(angle_rad), np.cos(angle_rad)])
  
              if mtext.get_rotation_mode() == "anchor":
                  # if anchor mode, rotation is undone first
                  v_offset = np.dot(dir_vert, [(x - ax), (y - ay)])
                  ax = ax + v_offset * dir_vert[0]
                  ay = ay + v_offset * dir_vert[1]
  
              w, h, d = self.get_text_width_height_descent(s, prop, ismath)
              ha, va = mtext.get_ha(), mtext.get_va()
              if ha == "center":
                  ax -= w / 2
              elif ha == "right":
                  ax -= w
              if va == "top":
                  ay -= h
              elif va == "center":
                  ay -= h / 2
  
              if mtext.get_rotation_mode() != "anchor":
                  # if not anchor mode, rotation is undone last
                  v_offset = np.dot(dir_vert, [(x - ax), (y - ay)])
                  ax = ax + v_offset * dir_vert[0]
                  ay = ay + v_offset * dir_vert[1]
  
              x, y = ax, ay
  
          x += self.widget.x
          y += self.widget.y
  
          if ismath:
              self.draw_mathtext(gc, x, y, s, prop, angle)
          else:
              font = resource_find(prop.get_name() + ".ttf")
              color = gc.get_rgb()
              if font is None:
                  plot_text = CoreLabel(font_size=prop.get_size_in_points(), color=color)
              else:
                  plot_text = CoreLabel(font_size=prop.get_size_in_points(),
                                  font_name=prop.get_name(), color=color)
              plot_text.text = six.text_type("{}".format(s))
              if prop.get_style() == 'italic':
                  plot_text.italic = True
              if self.weight_as_number(prop.get_weight()) > 500:
                  plot_text.bold = True
              plot_text.refresh()
              with self.widget.canvas:
                  if isinstance(angle, float):
                      PushMatrix()
                      Rotate(angle=angle, origin=(int(x), int(y)))
                      Rectangle(pos=(int(x), int(y)), texture=plot_text.texture,
                                size=plot_text.texture.size)
                      PopMatrix()
                  else:
                      Rectangle(pos=(int(x), int(y)), texture=plot_text.texture,
                                size=plot_text.texture.size)
  
      def draw_mathtext(self, gc, x, y, s, prop, angle):
          '''Draw the math text using matplotlib.mathtext. The position
             x,y is given in Kivy coordinates.
          '''
          ftimage, depth = self.mathtext_parser.parse(s, self.dpi, prop)
          w = ftimage.get_width()
          h = ftimage.get_height()
          texture = Texture.create(size=(w, h))
          if _mpl_ge_1_5:
              texture.blit_buffer(ftimage.as_rgba_str()[0][0], colorfmt='rgba',
                                  bufferfmt='ubyte')
          else:
              texture.blit_buffer(ftimage.as_rgba_str(), colorfmt='rgba',
                                  bufferfmt='ubyte')
          texture.flip_vertical()
          with self.widget.canvas:
              Rectangle(texture=texture, pos=(x, y), size=(w, h))
  
      def draw_path(self, gc, path, transform, rgbFace=None):
          '''Produce the rendering of the graphics elements using
             :class:`kivy.graphics.Line` and :class:`kivy.graphics.Mesh` kivy
             graphics instructions. The paths are converted into polygons and
             assigned either to a clip rectangle or to the same canvas for
             rendering. Paths are received in matplotlib coordinates. The
             aesthetics is defined by the `GraphicsContextKivy` gc.
          '''
          if _mpl_ge_2_0:
              polygons = path.to_polygons(transform, self.widget.width,
                                          self.widget.height, closed_only=False)
          else:
              polygons = path.to_polygons(transform, self.widget.width,
                                          self.widget.height)
          list_canvas_instruction = self.get_path_instructions(gc, polygons,
                                      closed=True, rgbFace=rgbFace)
          for widget, instructions in list_canvas_instruction:
              widget.canvas.add(instructions)
  
      def draw_markers(self, gc, marker_path, marker_trans, path,
          trans, rgbFace=None):
          '''Markers graphics instructions are stored on a dictionary and
             hashed through graphics context and rgbFace values. If a marker_path
             with the corresponding graphics context exist then the instructions
             are pulled from the markers dictionary.
          '''
          if not len(path.vertices):
              return
          # get a string representation of the path
          path_data = self._convert_path(
              marker_path,
              marker_trans + Affine2D().scale(1.0, -1.0),
              simplify=False)
          # get a string representation of the graphics context and rgbFace.
          style = str(gc._get_style_dict(rgbFace))
          dictkey = (path_data, str(style))
          # check whether this marker has been created before.
          list_instructions = self._markers.get(dictkey)
          # creating a list of instructions for the specific marker.
          if list_instructions is None:
              if _mpl_ge_2_0:
                  polygons = marker_path.to_polygons(marker_trans, closed_only=False)
              else:
                  polygons = marker_path.to_polygons(marker_trans)
              self._markers[dictkey] = self.get_path_instructions(gc,
                                          polygons, rgbFace=rgbFace)
          # Traversing all the positions where a marker should be rendered
          for vertices, codes in path.iter_segments(trans, simplify=False):
              if len(vertices):
                  x, y = vertices[-2:]
                  for widget, instructions in self._markers[dictkey]:
                      widget.canvas.add(PushMatrix())
                      widget.canvas.add(Translate(x, y))
                      widget.canvas.add(instructions)
                      widget.canvas.add(PopMatrix())
  
      def flipy(self):
          return False
  
      def _convert_path(self, path, transform=None, clip=None, simplify=None,
                        sketch=None):
          if clip:
              clip = (0.0, 0.0, self.width, self.height)
          else:
              clip = None
          if _mpl_ge_1_5:
              return _path.convert_to_string(
                  path, transform, clip, simplify, sketch, 6,
                  [b'M', b'L', b'Q', b'C', b'z'], False).decode('ascii')
          else:
              return _path.convert_to_svg(path, transform, clip, simplify, 6)
  
      def get_canvas_width_height(self):
          '''Get the actual width and height of the widget.
          '''
          return self.widget.width, self.widget.height
  
      def get_text_width_height_descent(self, s, prop, ismath):
          '''This method is needed specifically to calculate text positioning
             in the canvas. Matplotlib needs the size to calculate the points
             according to their layout
          '''
          if ismath:
              ftimage, depth = self.mathtext_parser.parse(s, self.dpi, prop)
              w = ftimage.get_width()
              h = ftimage.get_height()
              return w, h, depth
          font = resource_find(prop.get_name() + ".ttf")
          if font is None:
              plot_text = CoreLabel(font_size=prop.get_size_in_points())
          else:
              plot_text = CoreLabel(font_size=prop.get_size_in_points(),
                              font_name=prop.get_name())
          plot_text.text = six.text_type("{}".format(s))
          plot_text.refresh()
          return plot_text.texture.size[0], plot_text.texture.size[1], 1
  
      def new_gc(self):
          '''Instantiate a GraphicsContextKivy object
          '''
          return GraphicsContextKivy(self.widget)
  
      def points_to_pixels(self, points):
          return points / 72.0 * self.dpi
  		
      def weight_as_number(self, weight):
          ''' Replaces the deprecated matplotlib function of the same name
          '''
          # Return if number
          if isinstance(weight, numbers.Number):
              return weight
          # else use the mapping of matplotlib 2.2
          elif weight == 'ultralight':
              return 100
          elif weight == 'light':
              return 200
          elif weight == 'normal':
              return 400
          elif weight == 'regular':
              return 400
          elif weight == 'book':
              return 500
          elif weight == 'medium':
              return 500
          elif weight == 'roman':
              return 500
          elif weight == 'semibold':
              return 600
          elif weight == 'demibold':
              return 600
          elif weight == 'demi':
              return 600
          elif weight == 'bold':
              return 700
          elif weight == 'heavy':
              return 800
          elif weight == 'extra bold':
              return 800
          elif weight == 'black':
              return 900
          else:
              raise ValueError('weight ' + weight + ' not valid')
  
  
  class NavigationToolbar2Kivy(NavigationToolbar2):
      '''This class extends from matplotlib class NavigationToolbar2 and
         creates an action bar which is added to the main app to allow the
         following operations to the figures.
  
          Home: Resets the plot axes to the initial state.
          Left: Undo an operation performed.
          Right: Redo an operation performed.
          Pan: Allows to drag the plot.
          Zoom: Allows to define a rectangular area to zoom in.
          Configure: Loads a pop up for repositioning elements.
          Save: Loads a Save Dialog to generate an image.
      '''
  
      def __init__(self, canvas, **kwargs):
          self.actionbar = ActionBar(pos_hint={'top': 1.0})
          super(NavigationToolbar2Kivy, self).__init__(canvas)
          self.rubberband_color = (1.0, 0.0, 0.0, 1.0)
          self.lastrect = None
          self.save_dialog = Builder.load_string(textwrap.dedent('''\
              <SaveDialog>:
                  text_input: text_input
                  BoxLayout:
                      size: root.size
                      pos: root.pos
                      orientation: "vertical"
                      FileChooserListView:
                          id: filechooser
                          on_selection: text_input.text = self.selection and\
                          self.selection[0] or ''
  
                      TextInput:
                          id: text_input
                          size_hint_y: None
                          height: 30
                          multiline: False
  
                      BoxLayout:
                          size_hint_y: None
                          height: 30
                          Button:
                              text: "Cancel"
                              on_release: root.cancel()
  
                          Button:
                              text: "Save"
                              on_release: root.save(filechooser.path,\
                              text_input.text)
              '''))
  
      def _init_toolbar(self):
          '''A Toolbar is created with an ActionBar widget in which buttons are
             added with a specific behavior given by a callback. The buttons
             properties are given by matplotlib.
          '''
          basedir = os.path.join(rcParams['datapath'], 'images')
          actionview = ActionView()
          actionprevious = ActionPrevious(title="Navigation", with_previous=False)
          actionoverflow = ActionOverflow()
          actionview.add_widget(actionprevious)
          actionview.add_widget(actionoverflow)
          actionview.use_separator = True
          self.actionbar.add_widget(actionview)
          id_group = uuid.uuid4()
          for text, tooltip_text, image_file, callback in self.toolitems:
              if text is None:
                  actionview.add_widget(ActionSeparator())
                  continue
              fname = os.path.join(basedir, image_file + '.png')
              if text in ['Pan', 'Zoom']:
                  action_button = ActionToggleButton(text=text, icon=fname,
                                                     group=id_group)
              else:
                  action_button = ActionButton(text=text, icon=fname)
              action_button.bind(on_press=getattr(self, callback))
              actionview.add_widget(action_button)
  
      def configure_subplots(self, *largs):
          '''It will be implemented later.'''
          pass
  
      def dismiss_popup(self):
          self._popup.dismiss()
  
      def show_save(self):
          '''Displays a popup widget to perform a save operation.'''
          content = SaveDialog(save=self.save, cancel=self.dismiss_popup)
          self._popup = Popup(title="Save file", content=content,
                              size_hint=(0.9, 0.9))
          self._popup.open()
  
      def save(self, path, filename):
          self.canvas.export_to_png(os.path.join(path, filename))
          self.dismiss_popup()
  
      def save_figure(self, *args):
          self.show_save()
  
      def draw_rubberband(self, event, x0, y0, x1, y1):
          w = abs(x1 - x0)
          h = abs(y1 - y0)
          rect = [int(val)for val in (min(x0, x1) + self.canvas.x, min(y0, y1)
                          + self.canvas.y, w, h)]
          if self.lastrect is None:
              self.canvas.canvas.add(Color(*self.rubberband_color))
          else:
              self.canvas.canvas.remove(self.lastrect)
          self.lastrect = InstructionGroup()
          self.lastrect.add(Line(rectangle=rect, width=1.0, dash_length=5.0,
                  dash_offset=5.0))
          self.lastrect.add(Color(1.0, 0.0, 0.0, 0.2))
          self.lastrect.add(Rectangle(pos=(rect[0], rect[1]),
                                      size=(rect[2], rect[3])))
          self.canvas.canvas.add(self.lastrect)
  
      def release_zoom(self, event):
          self.lastrect = None
          return super(NavigationToolbar2Kivy, self).release_zoom(event)
  
  
  class GraphicsContextKivy(GraphicsContextBase, object):
      '''The graphics context provides the color, line styles, etc... All the
         mapping between matplotlib and kivy styling is done here.
         The GraphicsContextKivy stores colors as a RGB tuple on the unit
         interval, e.g., (0.5, 0.0, 1.0) such as in the Kivy framework.
         Lines properties and styles are set accordingly to the kivy framework
         definition for Line.
      '''
  
      _capd = {
          'butt': 'square',
          'projecting': 'square',
          'round': 'round',
      }
      line = {}
  
      def __init__(self, renderer):
          super(GraphicsContextKivy, self).__init__()
          self.renderer = renderer
          self.line['cap_style'] = self.get_capstyle()
          self.line['join_style'] = self.get_joinstyle()
          self.line['dash_offset'] = None
          self.line['dash_length'] = None
          self.line['dash_list'] = []
  
      def set_capstyle(self, cs):
          '''Set the cap style based on the kivy framework cap styles.
          '''
          GraphicsContextBase.set_capstyle(self, cs)
          self.line['cap_style'] = self._capd[self._capstyle]
  
      def set_joinstyle(self, js):
          '''Set the join style based on the kivy framework join styles.
          '''
          GraphicsContextBase.set_joinstyle(self, js)
          self.line['join_style'] = js
  
      def set_dashes(self, dash_offset, dash_list):
          GraphicsContextBase.set_dashes(self, dash_offset, dash_list)
          # dash_list is a list with numbers denoting the number of points
          # in a dash and if it is on or off.
          if dash_list is not None:
              self.line['dash_list'] = dash_list
          if dash_offset is not None:
              self.line['dash_offset'] = int(dash_offset)
  
      def set_linewidth(self, w):
          GraphicsContextBase.set_linewidth(self, w)
          self.line['width'] = w
  
      def _get_style_dict(self, rgbFace):
          '''Return the style string. style is generated from the
             GraphicsContext and rgbFace
          '''
          attrib = {}
          forced_alpha = self.get_forced_alpha()
          if rgbFace is None:
              attrib['fill'] = 'none'
          else:
              if tuple(rgbFace[:3]) != (0, 0, 0):
                  attrib['fill'] = str(rgbFace)
              if len(rgbFace) == 4 and rgbFace[3] != 1.0 and not forced_alpha:
                  attrib['fill-opacity'] = str(rgbFace[3])
  
          if forced_alpha and self.get_alpha() != 1.0:
              attrib['opacity'] = str(self.get_alpha())
  
          offset, seq = self.get_dashes()
          if seq is not None:
              attrib['line-dasharray'] = ','.join(['%f' % val for val in seq])
              attrib['line-dashoffset'] = six.text_type(float(offset))
  
          linewidth = self.get_linewidth()
          if linewidth:
              rgb = self.get_rgb()
              attrib['line'] = str(rgb)
              if not forced_alpha and rgb[3] != 1.0:
                  attrib['line-opacity'] = str(rgb[3])
              if linewidth != 1.0:
                  attrib['line-width'] = str(linewidth)
              if self.get_joinstyle() != 'round':
                  attrib['line-linejoin'] = self.get_joinstyle()
              if self.get_capstyle() != 'butt':
                  attrib['line-linecap'] = _capd[self.get_capstyle()]
          return attrib
  
  
  class TimerKivy(TimerBase):
      '''
      Subclass of :class:`backend_bases.TimerBase` that uses Kivy for timer events.
      Attributes:
      * interval: The time between timer events in milliseconds. Default
          is 1000 ms.
      * single_shot: Boolean flag indicating whether this timer should
          operate as single shot (run once and then stop). Defaults to False.
      * callbacks: Stores list of (func, args) tuples that will be called
          upon timer events. This list can be manipulated directly, or the
          functions add_callback and remove_callback can be used.
      '''
      def _timer_start(self):
          # Need to stop it, otherwise we potentially leak a timer id that will
          # never be stopped.
          self._timer_stop()
          self._timer = Clock.schedule_interval(self._on_timer, self._interval / 1000.0)
  
      def _timer_stop(self):
          if self._timer is not None:
              Clock.unschedule(self._timer)
              self._timer = None
  
      def _timer_set_interval(self):
          # Only stop and restart it if the timer has already been started
          if self._timer is not None:
              self._timer_stop()
              self._timer_start()
  
      def _on_timer(self, dt):
          super(TimerKivy, self)._on_timer()
  
  
  class FigureCanvasKivy(FocusBehavior, Widget, FigureCanvasBase):
      '''FigureCanvasKivy class. See module documentation for more information.
      '''
  
      def __init__(self, figure, **kwargs):
          Window.bind(mouse_pos=self._on_mouse_pos)
          self.bind(size=self._on_size_changed)
          self.bind(pos=self._on_pos_changed)
          self.entered_figure = True
          self.figure = figure
          super(FigureCanvasKivy, self).__init__(figure=self.figure, **kwargs)
  
      def draw(self):
          '''Draw the figure using the KivyRenderer
          '''
          self.clear_widgets()
          self.canvas.clear()
          self._renderer = RendererKivy(self)
          self.figure.draw(self._renderer)
  
      def on_touch_down(self, touch):
          '''Kivy Event to trigger the following matplotlib events:
             `motion_notify_event`, `scroll_event`, `button_press_event`,
             `enter_notify_event` and `leave_notify_event`
          '''
          newcoord = self.to_widget(touch.x, touch.y, relative=True)
          x = newcoord[0]
          y = newcoord[1]
  
          if super(FigureCanvasKivy, self).on_touch_down(touch):
              return True
          if self.collide_point(*touch.pos):
              self.motion_notify_event(x, y, guiEvent=None)
  
              touch.grab(self)
              if 'button' in touch.profile and touch.button in ("scrollup", "scrolldown",):
                  self.scroll_event(x, y, 5, guiEvent=None)
              else:
                  self.button_press_event(x, y, self.get_mouse_button(touch),
                                          dblclick=False, guiEvent=None)
              if self.entered_figure:
                  self.enter_notify_event(guiEvent=None, xy=None)
          else:
              if not self.entered_figure:
                  self.leave_notify_event(guiEvent=None)
          return False
  
      def on_touch_move(self, touch):
          '''Kivy Event to trigger the following matplotlib events:
             `motion_notify_event`, `enter_notify_event` and `leave_notify_event`
          '''
          newcoord = self.to_widget(touch.x, touch.y, relative=True)
          x = newcoord[0]
          y = newcoord[1]
          inside = self.collide_point(touch.x, touch.y)
          if inside:
              self.motion_notify_event(x, y, guiEvent=None)
          if not inside and not self.entered_figure:
              self.leave_notify_event(guiEvent=None)
              self.entered_figure = True
          elif inside and self.entered_figure:
              self.enter_notify_event(guiEvent=None, xy=(x, y))
              self.entered_figure = False
          return False
  
      def get_mouse_button(self, touch):
          '''Translate kivy convention for left, right and middle click button
             into matplotlib int values: 1 for left, 2 for middle and 3 for
             right.
          '''
          if 'button' in touch.profile:
              if touch.button == "left":
                  return 1
              elif touch.button == "middle":
                  return 2
              elif touch.button == "right":
                  return 3
          return -1
  
      def on_touch_up(self, touch):
          '''Kivy Event to trigger the following matplotlib events:
             `scroll_event` and `button_release_event`.
          '''
          newcoord = self.to_widget(touch.x, touch.y, relative=True)
          x = newcoord[0]
          y = newcoord[1]
          if touch.grab_current is self:
              if 'button' in touch.profile and touch.button in ("scrollup", "scrolldown",):
                  self.scroll_event(x, y, 5, guiEvent=None)
              else:
                  self.button_release_event(x, y, self.get_mouse_button(touch), guiEvent=None)
              touch.ungrab(self)
          else:
              return super(FigureCanvasKivy, self).on_touch_up(touch)
          return False
  
      def keyboard_on_key_down(self, window, keycode, text, modifiers):
          '''Kivy event to trigger matplotlib `key_press_event`.
          '''
          self.key_press_event(keycode[1], guiEvent=None)
          return super(FigureCanvasKivy, self).keyboard_on_key_down(window,
                                                      keycode, text, modifiers)
  
      def keyboard_on_key_up(self, window, keycode):
          '''Kivy event to trigger matplotlib `key_release_event`.
          '''
          self.key_release_event(keycode[1], guiEvent=None)
          return super(FigureCanvasKivy, self).keyboard_on_key_up(window, keycode)
  
      def _on_mouse_pos(self, *args):
          '''Kivy Event to trigger the following matplotlib events:
             `motion_notify_event`, `leave_notify_event` and
             `enter_notify_event`.
          '''
          pos = args[1]
          newcoord = self.to_widget(pos[0], pos[1], relative=True)
          x = newcoord[0]
          y = newcoord[1]
          inside = self.collide_point(*pos)
          if inside:
              self.motion_notify_event(x, y, guiEvent=None)
          if not inside and not self.entered_figure:
              self.leave_notify_event(guiEvent=None)
              self.entered_figure = True
          elif inside and self.entered_figure:
              self.enter_notify_event(guiEvent=None, xy=(pos[0], pos[1]))
              self.entered_figure = False
  
      def enter_notify_event(self, guiEvent=None, xy=None):
          event = Event('figure_enter_event', self, guiEvent)
          self.callbacks.process('figure_enter_event', event)
  
      def leave_notify_event(self, guiEvent=None):
          event = Event('figure_leave_event', self, guiEvent)
          self.callbacks.process('figure_leave_event', event)
  
      def _on_pos_changed(self, *args):
          self.draw()
  
      def _on_size_changed(self, *args):
          '''Changes the size of the matplotlib figure based on the size of the
             widget. The widget will change size according to the parent Layout
             size.
          '''
          w, h = self.size
          dpival = self.figure.dpi
          winch = float(w) / dpival
          hinch = float(h) / dpival
          self.figure.set_size_inches(winch, hinch, forward=False)
          self.resize_event()
          self.draw()
  
      def callback(self, *largs):
          self.draw()
  
      def blit(self, bbox=None):
          '''If bbox is None, blit the entire canvas to the widget. Otherwise
             blit only the area defined by the bbox.
          '''
          self.blitbox = bbox
  
      filetypes = FigureCanvasBase.filetypes.copy()
      filetypes['png'] = 'Portable Network Graphics'
  
      def print_png(self, filename, *args, **kwargs):
          '''Call the widget function to make a png of the widget.
          '''
          fig = FigureCanvasAgg(self.figure)
          FigureCanvasAgg.draw(fig)
  
          l, b, w, h = self.figure.bbox.bounds
          texture = Texture.create(size=(w, h))
          texture.blit_buffer(bytes(fig.get_renderer().buffer_rgba()),
                                  colorfmt='rgba', bufferfmt='ubyte')
          texture.flip_vertical()
          img = Image(texture)
          img.save(filename)
  
      def get_default_filetype(self):
          return 'png'
  
      def new_timer(self, *args, **kwargs):
          """
          Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
          This is useful for getting periodic events through the backend's native
          event loop. Implemented only for backends with GUIs.
          optional arguments:
          *interval*
            Timer interval in milliseconds
          *callbacks*
            Sequence of (func, args, kwargs) where func(*args, **kwargs) will
            be executed by the timer every *interval*.
          """
          return TimerKivy(*args, **kwargs)
  
  
  class FigureManagerKivy(FigureManagerBase):
      '''The FigureManager main function is to instantiate the backend navigation
         toolbar and to call show to instantiate the App.
      '''
  
      def __init__(self, canvas, num):
          super(FigureManagerKivy, self).__init__(canvas, num)
          self.canvas = canvas
          self.toolbar = self._get_toolbar()
  
      def show(self):
          pass
  
      def get_window_title(self):
          return Window.title
  
      def set_window_title(self, title):
          Window.title = title
  
      def resize(self, w, h):
          if (w > 0) and (h > 0):
              Window.size = w, h
  
      def _get_toolbar(self):
          if rcParams['toolbar'] == 'toolbar2':
              toolbar = NavigationToolbar2Kivy(self.canvas)
          else:
              toolbar = None
          return toolbar
  
  '''Now just provide the standard names that backend.__init__ is expecting
  '''
  FigureCanvas = FigureCanvasKivy
  FigureManager = FigureManagerKivy
  NavigationToolbar = NavigationToolbar2Kivy
  