def _render_on_subplot(self, subplot): """ Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES:: This function implicitly ends up rendering this arrow on a matplotlib subplot: sage: arrow(path=[[(0,1), (2,-1), (4,5)]]) """ options = self.options() width = float(options['width']) head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError('head parameter must be one of 0 (start), 1 (end) or 2 (both).') arrowsize = float(options.get('arrowsize',5)) head_width=arrowsize head_length=arrowsize*2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch from matplotlib.path import Path bpath = Path(self.vertices, self.codes) p = FancyArrowPatch(path=bpath, lw=width, arrowstyle='%s,head_width=%s,head_length=%s'%(style,head_width, head_length), fc=color, ec=color, linestyle=options['linestyle']) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) subplot.add_patch(p) return p
def _render_on_subplot(self, subplot): """ Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES: This function implicitly ends up rendering this arrow on a matplotlib subplot:: sage: arrow((0,1), (2,-1)) TESTS: The length of the ends (shrinkA and shrinkB) should not depend on the width of the arrow, because Matplotlib already takes this into account. See :trac:`12836`:: sage: fig = Graphics().matplotlib() sage: sp = fig.add_subplot(1,1,1) sage: a = arrow((0,0), (1,1)) sage: b = arrow((0,0), (1,1), width=20) sage: p1 = a[0]._render_on_subplot(sp) sage: p2 = b[0]._render_on_subplot(sp) sage: p1.shrinkA == p2.shrinkA True sage: p1.shrinkB == p2.shrinkB True """ options = self.options() head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError( 'head parameter must be one of 0 (start), 1 (end) or 2 (both).' ) width = float(options['width']) arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0 arrowsize = float(options.get('arrowsize', 5)) head_width = arrowsize head_length = arrowsize * 2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead), lw=width, arrowstyle='%s,head_width=%s,head_length=%s' % (style, head_width, head_length), shrinkA=arrowshorten_end, shrinkB=arrowshorten_end, fc=color, ec=color, linestyle=options['linestyle']) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) subplot.add_patch(p) return p
def _render_on_subplot(self, subplot): """ Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES: This function implicitly ends up rendering this arrow on a matplotlib subplot:: sage: arrow((0,1), (2,-1)) TESTS: The length of the ends (shrinkA and shrinkB) should not depend on the width of the arrow, because Matplotlib already takes this into account. See :trac:`12836`:: sage: fig = Graphics().matplotlib() sage: sp = fig.add_subplot(1,1,1) sage: a = arrow((0,0), (1,1)) sage: b = arrow((0,0), (1,1), width=20) sage: p1 = a[0]._render_on_subplot(sp) sage: p2 = b[0]._render_on_subplot(sp) sage: p1.shrinkA == p2.shrinkA True sage: p1.shrinkB == p2.shrinkB True """ options = self.options() head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError('head parameter must be one of 0 (start), 1 (end) or 2 (both).') width = float(options['width']) arrowshorten_end = float(options.get('arrowshorten',0))/2.0 arrowsize = float(options.get('arrowsize',5)) head_width=arrowsize head_length=arrowsize*2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead), lw=width, arrowstyle='%s,head_width=%s,head_length=%s'%(style,head_width, head_length), shrinkA=arrowshorten_end, shrinkB=arrowshorten_end, fc=color, ec=color, linestyle=options['linestyle']) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) subplot.add_patch(p) return p
def _render_on_subplot(self, subplot): """ Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES: This function implicitly ends up rendering this arrow on a matplotlib subplot:: sage: arrow(path=[[(0,1), (2,-1), (4,5)]]) Graphics object consisting of 1 graphics primitive """ from sage.plot.misc import get_matplotlib_linestyle options = self.options() width = float(options['width']) head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError( 'head parameter must be one of 0 (start), 1 (end) or 2 (both).' ) arrowsize = float(options.get('arrowsize', 5)) head_width = arrowsize head_length = arrowsize * 2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch from matplotlib.path import Path bpath = Path(self.vertices, self.codes) p = FancyArrowPatch(path=bpath, lw=width, arrowstyle='%s,head_width=%s,head_length=%s' % (style, head_width, head_length), fc=color, ec=color, linestyle=get_matplotlib_linestyle( options['linestyle'], return_type='long')) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) subplot.add_patch(p) return p
def _render_on_subplot(self, subplot): """ Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES:: This function implicitly ends up rendering this arrow on a matplotlib subplot: sage: arrow(path=[[(0,1), (2,-1), (4,5)]]) Graphics object consisting of 1 graphics primitive """ from sage.plot.misc import get_matplotlib_linestyle options = self.options() width = float(options["width"]) head = options.pop("head") if head == 0: style = "<|-" elif head == 1: style = "-|>" elif head == 2: style = "<|-|>" else: raise KeyError("head parameter must be one of 0 (start), 1 (end) or 2 (both).") arrowsize = float(options.get("arrowsize", 5)) head_width = arrowsize head_length = arrowsize * 2.0 color = to_mpl_color(options["rgbcolor"]) from matplotlib.patches import FancyArrowPatch from matplotlib.path import Path bpath = Path(self.vertices, self.codes) p = FancyArrowPatch( path=bpath, lw=width, arrowstyle="%s,head_width=%s,head_length=%s" % (style, head_width, head_length), fc=color, ec=color, ) p.set_linestyle(get_matplotlib_linestyle(options["linestyle"], return_type="long")) p.set_zorder(options["zorder"]) p.set_label(options["legend_label"]) subplot.add_patch(p) return p
def draw_MultipleLine(L, pos, ax, sg=None): for n in L: c = Circle(pos[n], radius=0.05, alpha=0.7) ax.add_patch(c) L.node[n]['patch'] = c x, y = pos[n] seen = {} for (u, v, d) in L.edges(data=True): n1 = L.node[u]['patch'] n2 = L.node[v]['patch'] rad = 0.1 if (u, v) in seen: rad = seen.get((u, v)) rad = (rad + np.sign(rad) * 0.1) * -1 alpha = 0.5 style = d['sty'] if style == 1: color = 'r' elif style == 2: color = 'b' elif style == 3: color = 'k' elif style == 4: color = 'y' elif style == 5: color = 'g' width = d['width'] line = width e = FancyArrowPatch(n1.center, n2.center, patchA=n1, patchB=n2, arrowstyle='-|>', connectionstyle='arc3,rad=%s' % rad, mutation_scale=10.0, lw=2, alpha=alpha, color=color) e.set_linewidth(line) e.set_label(line) seen[(u, v)] = rad ax.add_patch(e) return e
def _render_on_subplot(self, subplot): """ Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES: This function implicitly ends up rendering this arrow on a matplotlib subplot:: sage: arrow((0,1), (2,-1)) """ options = self.options() head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError( 'head parameter must be one of 0 (start), 1 (end) or 2 (both).' ) width = float(options['width']) arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0 + width * 2 arrowsize = float(options.get('arrowsize', 5)) head_width = arrowsize head_length = arrowsize * 2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead), lw=width, arrowstyle='%s,head_width=%s,head_length=%s' % (style, head_width, head_length), shrinkA=arrowshorten_end, shrinkB=arrowshorten_end, fc=color, ec=color, linestyle=options['linestyle']) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) subplot.add_patch(p) return p
def _render_on_subplot(self, subplot): r""" Render this arrow in a subplot. This version of the method uses a narrower arrow head, which is not customizable by parameters in the Sage class. """ from sage.plot.misc import get_matplotlib_linestyle options = self.options() head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError('head parameter must be one of 0 (start), 1 (end) or 2 (both).') style='fancy' width = float(options['width']) arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0 arrowsize = float(options.get('arrowsize', 5)) #head_width = arrowsize * 0.5 head_width = arrowsize * 0.7 tail_width = arrowsize * 0.7 head_length = arrowsize * 2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead), lw=width, arrowstyle='%s,head_width=%s,head_length=%s,tail_width=%s' % (style, head_width, head_length, tail_width), shrinkA=arrowshorten_end, shrinkB=arrowshorten_end, fc=color, ec=color, linestyle=get_matplotlib_linestyle(options['linestyle'], return_type='long')) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) subplot.add_patch(p) return p
def _render_on_subplot(self, subplot): r""" Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES: This function implicitly ends up rendering this arrow on a matplotlib subplot:: sage: arrow((0,1), (2,-1)) Graphics object consisting of 1 graphics primitive TESTS: The length of the ends (shrinkA and shrinkB) should not depend on the width of the arrow, because Matplotlib already takes this into account. See :trac:`12836`:: sage: fig = Graphics().matplotlib() sage: sp = fig.add_subplot(1,1,1, label='axis1') sage: a = arrow((0,0), (1,1)) sage: b = arrow((0,0), (1,1), width=20) sage: p1 = a[0]._render_on_subplot(sp) sage: p2 = b[0]._render_on_subplot(sp) sage: p1.shrinkA == p2.shrinkA True sage: p1.shrinkB == p2.shrinkB True Dashed arrows should have solid arrowheads, :trac:`12852`. We tried to make up a test for this, which turned out to be fragile and hence was removed. In general, robust testing of graphics seems basically need a human eye or AI. """ from sage.plot.misc import get_matplotlib_linestyle options = self.options() head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError( 'head parameter must be one of 0 (start), 1 (end) or 2 (both).' ) width = float(options['width']) arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0 arrowsize = float(options.get('arrowsize', 5)) head_width = arrowsize head_length = arrowsize * 2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch p = FancyArrowPatch( (self.xtail, self.ytail), (self.xhead, self.yhead), lw=width, arrowstyle='%s,head_width=%s,head_length=%s' % (style, head_width, head_length), shrinkA=arrowshorten_end, shrinkB=arrowshorten_end, fc=color, ec=color, linestyle=get_matplotlib_linestyle(options['linestyle'], return_type='long')) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) if options['linestyle'] != 'solid': # The next few lines work around a design issue in matplotlib. # Currently, the specified linestyle is used to draw both the path # and the arrowhead. If linestyle is 'dashed', this looks really # odd. This code is from Jae-Joon Lee in response to a post to the # matplotlib mailing list. # See http://sourceforge.net/mailarchive/forum.php?thread_name=CAG%3DuJ%2Bnw2dE05P9TOXTz_zp-mGP3cY801vMH7yt6vgP9_WzU8w%40mail.gmail.com&forum_name=matplotlib-users import matplotlib.patheffects as pe class CheckNthSubPath(object): def __init__(self, patch, n): """ creates an callable object that returns True if the provided path is the n-th path from the patch. """ self._patch = patch self._n = n def get_paths(self, renderer): self._patch.set_dpi_cor(renderer.points_to_pixels(1.)) paths, fillables = self._patch.get_path_in_displaycoord() return paths def __call__(self, renderer, gc, tpath, affine, rgbFace): path = self.get_paths(renderer)[self._n] vert1, code1 = path.vertices, path.codes import numpy as np return np.array_equal(vert1, tpath.vertices) and np.array_equal( code1, tpath.codes) class ConditionalStroke(pe.RendererBase): def __init__(self, condition_func, pe_list): """ path effect that is only applied when the condition_func returns True. """ super(ConditionalStroke, self).__init__() self._pe_list = pe_list self._condition_func = condition_func def draw_path(self, renderer, gc, tpath, affine, rgbFace): if self._condition_func(renderer, gc, tpath, affine, rgbFace): for pe1 in self._pe_list: pe1.draw_path(renderer, gc, tpath, affine, rgbFace) pe1 = ConditionalStroke(CheckNthSubPath(p, 0), [pe.Stroke()]) pe2 = ConditionalStroke( CheckNthSubPath(p, 1), [pe.Stroke(dashes={ 'dash_offset': 0, 'dash_list': None })]) p.set_path_effects([pe1, pe2]) subplot.add_patch(p) return p
def _render_on_subplot(self, subplot): r""" Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES: This function implicitly ends up rendering this arrow on a matplotlib subplot:: sage: arrow((0,1), (2,-1)) TESTS: The length of the ends (shrinkA and shrinkB) should not depend on the width of the arrow, because Matplotlib already takes this into account. See :trac:`12836`:: sage: fig = Graphics().matplotlib() sage: sp = fig.add_subplot(1,1,1) sage: a = arrow((0,0), (1,1)) sage: b = arrow((0,0), (1,1), width=20) sage: p1 = a[0]._render_on_subplot(sp) sage: p2 = b[0]._render_on_subplot(sp) sage: p1.shrinkA == p2.shrinkA True sage: p1.shrinkB == p2.shrinkB True Dashed arrows should have solid arrowheads, :trac:`12852`. This test saves the plot of a dashed arrow to an EPS file. Within the EPS file, ``stroke`` will be called twice: once to draw the line, and again to draw the arrowhead. We check that both calls do not occur while the dashed line style is enabled:: sage: a = arrow((0,0), (1,1), linestyle='dashed') sage: filename = tmp_filename(ext='.eps') sage: a.save(filename=filename) sage: with open(filename, 'r') as f: ....: contents = f.read().replace('\n', ' ') sage: two_stroke_pattern = r'setdash.*stroke.*stroke.*setdash' sage: import re sage: two_stroke_re = re.compile(two_stroke_pattern) sage: two_stroke_re.search(contents) is None True """ options = self.options() head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError('head parameter must be one of 0 (start), 1 (end) or 2 (both).') width = float(options['width']) arrowshorten_end = float(options.get('arrowshorten',0))/2.0 arrowsize = float(options.get('arrowsize',5)) head_width=arrowsize head_length=arrowsize*2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead), lw=width, arrowstyle='%s,head_width=%s,head_length=%s'%(style,head_width, head_length), shrinkA=arrowshorten_end, shrinkB=arrowshorten_end, fc=color, ec=color, linestyle=options['linestyle']) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) if options['linestyle']!='solid': # The next few lines work around a design issue in matplotlib. Currently, the specified # linestyle is used to draw both the path and the arrowhead. If linestyle is 'dashed', this # looks really odd. This code is from Jae-Joon Lee in response to a post to the matplotlib mailing # list. See http://sourceforge.net/mailarchive/forum.php?thread_name=CAG%3DuJ%2Bnw2dE05P9TOXTz_zp-mGP3cY801vMH7yt6vgP9_WzU8w%40mail.gmail.com&forum_name=matplotlib-users import matplotlib.patheffects as pe class CheckNthSubPath(object): def __init__(self, patch, n): """ creates an callable object that returns True if the provided path is the n-th path from the patch. """ self._patch = patch self._n = n def get_paths(self, renderer): self._patch.set_dpi_cor(renderer.points_to_pixels(1.)) paths, fillables = self._patch.get_path_in_displaycoord() return paths def __call__(self, renderer, gc, tpath, affine, rgbFace): path = self.get_paths(renderer)[self._n] vert1, code1 = path.vertices, path.codes import numpy as np if np.all(vert1 == tpath.vertices) and np.all(code1 == tpath.codes): return True else: return False class ConditionalStroke(pe._Base): def __init__(self, condition_func, pe_list): """ path effect that is only applied when the condition_func returns True. """ super(ConditionalStroke, self).__init__() self._pe_list = pe_list self._condition_func = condition_func def draw_path(self, renderer, gc, tpath, affine, rgbFace): if self._condition_func(renderer, gc, tpath, affine, rgbFace): for pe1 in self._pe_list: pe1.draw_path(renderer, gc, tpath, affine, rgbFace) pe1 = ConditionalStroke(CheckNthSubPath(p, 0),[pe.Stroke()]) pe2 = ConditionalStroke(CheckNthSubPath(p, 1),[pe.Stroke(linestyle="solid")]) p.set_path_effects([pe1, pe2]) subplot.add_patch(p) return p
def _render_on_subplot(self, subplot): r""" Render this arrow in a subplot. This is the key function that defines how this arrow graphics primitive is rendered in matplotlib's library. EXAMPLES: This function implicitly ends up rendering this arrow on a matplotlib subplot:: sage: arrow((0,1), (2,-1)) Graphics object consisting of 1 graphics primitive TESTS: The length of the ends (shrinkA and shrinkB) should not depend on the width of the arrow, because Matplotlib already takes this into account. See :trac:`12836`:: sage: fig = Graphics().matplotlib() sage: sp = fig.add_subplot(1,1,1) sage: a = arrow((0,0), (1,1)) sage: b = arrow((0,0), (1,1), width=20) sage: p1 = a[0]._render_on_subplot(sp) sage: p2 = b[0]._render_on_subplot(sp) sage: p1.shrinkA == p2.shrinkA True sage: p1.shrinkB == p2.shrinkB True Dashed arrows should have solid arrowheads, :trac:`12852`. This test saves the plot of a dashed arrow to an EPS file. Within the EPS file, ``stroke`` will be called twice: once to draw the line, and again to draw the arrowhead. We check that both calls do not occur while the dashed line style is enabled:: sage: a = arrow((0,0), (1,1), linestyle='dashed') sage: filename = tmp_filename(ext='.eps') sage: a.save(filename=filename) sage: with open(filename, 'r') as f: ....: contents = f.read().replace('\n', ' ') sage: two_stroke_pattern = r'setdash.*stroke.*stroke.*setdash' sage: import re sage: two_stroke_re = re.compile(two_stroke_pattern) sage: two_stroke_re.search(contents) is None True """ from sage.plot.misc import get_matplotlib_linestyle options = self.options() head = options.pop('head') if head == 0: style = '<|-' elif head == 1: style = '-|>' elif head == 2: style = '<|-|>' else: raise KeyError( 'head parameter must be one of 0 (start), 1 (end) or 2 (both).' ) width = float(options['width']) arrowshorten_end = float(options.get('arrowshorten', 0)) / 2.0 arrowsize = float(options.get('arrowsize', 5)) head_width = arrowsize head_length = arrowsize * 2.0 color = to_mpl_color(options['rgbcolor']) from matplotlib.patches import FancyArrowPatch p = FancyArrowPatch((self.xtail, self.ytail), (self.xhead, self.yhead), lw=width, arrowstyle='%s,head_width=%s,head_length=%s' % (style, head_width, head_length), shrinkA=arrowshorten_end, shrinkB=arrowshorten_end, fc=color, ec=color) p.set_linestyle( get_matplotlib_linestyle(options['linestyle'], return_type='long')) p.set_zorder(options['zorder']) p.set_label(options['legend_label']) if options['linestyle'] != 'solid': # The next few lines work around a design issue in matplotlib. Currently, the specified # linestyle is used to draw both the path and the arrowhead. If linestyle is 'dashed', this # looks really odd. This code is from Jae-Joon Lee in response to a post to the matplotlib mailing # list. See http://sourceforge.net/mailarchive/forum.php?thread_name=CAG%3DuJ%2Bnw2dE05P9TOXTz_zp-mGP3cY801vMH7yt6vgP9_WzU8w%40mail.gmail.com&forum_name=matplotlib-users import matplotlib.patheffects as pe class CheckNthSubPath(object): def __init__(self, patch, n): """ creates an callable object that returns True if the provided path is the n-th path from the patch. """ self._patch = patch self._n = n def get_paths(self, renderer): self._patch.set_dpi_cor(renderer.points_to_pixels(1.)) paths, fillables = self._patch.get_path_in_displaycoord() return paths def __call__(self, renderer, gc, tpath, affine, rgbFace): path = self.get_paths(renderer)[self._n] vert1, code1 = path.vertices, path.codes import numpy as np return np.array_equal(vert1, tpath.vertices) and np.array_equal( code1, tpath.codes) class ConditionalStroke(pe.RendererBase): def __init__(self, condition_func, pe_list): """ path effect that is only applied when the condition_func returns True. """ super(ConditionalStroke, self).__init__() self._pe_list = pe_list self._condition_func = condition_func def draw_path(self, renderer, gc, tpath, affine, rgbFace): if self._condition_func(renderer, gc, tpath, affine, rgbFace): for pe1 in self._pe_list: pe1.draw_path(renderer, gc, tpath, affine, rgbFace) pe1 = ConditionalStroke(CheckNthSubPath(p, 0), [pe.Stroke()]) pe2 = ConditionalStroke(CheckNthSubPath(p, 1), [pe.Stroke(linestyle="solid")]) p.set_path_effects([pe1, pe2]) subplot.add_patch(p) return p