def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): if negative_number.match(s): s = u"$" + s.replace(u'\u2212', u'-') + "$" attrib = {} if mtext: # if text anchoring can be supported, get the original coordinates # and add alignment information x, y = mtext.get_transform().transform_point(mtext.get_position()) attrib['halign'] = mtext.get_ha() attrib['valign'] = mtext.get_va() if angle != 0.0: ra = radians(angle) sa = sin(ra) ca = cos(ra) attrib['matrix'] = "%g %g %g %g %g %g" % (ca, sa, -sa, ca, x, y) x, y = 0, 0 self.gen_opacity(attrib, gc.get_rgb()[3]) self.writer.start(u'text', stroke="%g %g %g" % gc.get_rgb()[:3], type="label", size="%g" % prop.get_size_in_points(), pos="%g %g" % (x, y), attrib=attrib) s = common_texification(s) self.writer.data(u"%s" % s) self.writer.end(indent=False)
def get_text_width_height_descent(self, s, prop, ismath): if self.latexManager: s = common_texification(s) w, h, d = self.latexManager.get_width_height_descent(s, prop) return w, h, d else: return 1, 1, 1
def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): if negative_number.match(s): s = u"$" + s.replace(u'\u2212', u'-') + "$" attrib = {} if mtext: # if text anchoring can be supported, get the original coordinates # and add alignment information x, y = mtext.get_transform().transform_point(mtext.get_position()) attrib['halign'] = mtext.get_ha() attrib['valign'] = mtext.get_va() if angle != 0.0: ra = radians(angle) sa = sin(ra); ca = cos(ra) attrib['matrix'] = "%g %g %g %g %g %g" % (ca, sa, -sa, ca, x, y) x, y = 0, 0 self.gen_opacity(attrib, gc.get_rgb()[3]) self.writer.start( u'text', stroke="%g %g %g" % gc.get_rgb()[:3], type="label", size="%g" % prop.get_size_in_points(), pos="%g %g" % (x,y), attrib=attrib ) s = common_texification(s) self.writer.data(u"%s" % s) self.writer.end(indent=False)
def _get_ticks(data, xy, ticks, ticklabels): """Gets a {'x','y'}, a number of ticks and ticks labels, and returns the necessary axis options for the given configuration. """ axis_options = [] pgfplots_ticks = [] pgfplots_ticklabels = [] is_label_required = False for tick, ticklabel in zip(ticks, ticklabels): pgfplots_ticks.append(tick) # store the label anyway label = ticklabel.get_text() if ticklabel.get_visible(): label = mpl_backend_pgf.common_texification(label) pgfplots_ticklabels.append(label) else: is_label_required = True # Check if the label is necessary. If one of the labels is, then all of them # must appear in the TikZ plot. if label: try: label_float = float(label.replace(u"\N{MINUS SIGN}", "-")) is_label_required = is_label_required or (label and label_float != tick) except ValueError: is_label_required = True # Leave the ticks to PGFPlots if not in STRICT mode and if there are no explicit # labels. if data["strict"] or is_label_required: if pgfplots_ticks: ff = data["float format"] axis_options.append( "{}tick={{{}}}".format( xy, ",".join([ff.format(el) for el in pgfplots_ticks]) ) ) else: val = "{}" if "minor" in xy else "\\empty" axis_options.append("{}tick={}".format(xy, val)) if is_label_required: axis_options.append( u"{}ticklabels={{{}}}".format(xy, u",".join(pgfplots_ticklabels)) ) return axis_options
def _get_ticks(data, xy, ticks, ticklabels): """Gets a {'x','y'}, a number of ticks and ticks labels, and returns the necessary axis options for the given configuration. """ axis_options = [] pgfplots_ticks = [] pgfplots_ticklabels = [] is_label_required = False for tick, ticklabel in zip(ticks, ticklabels): pgfplots_ticks.append(tick) # store the label anyway label = ticklabel.get_text() if ticklabel.get_visible(): label = mpl_backend_pgf.common_texification(label) pgfplots_ticklabels.append(label) else: is_label_required = True # Check if the label is necessary. If one of the labels is, then all of them # must appear in the TikZ plot. if label: try: label_float = float(label.replace(u"\N{MINUS SIGN}", "-")) is_label_required = is_label_required or (label and label_float != tick) except ValueError: is_label_required = True # Leave the ticks to PGFPlots if not in STRICT mode and if there are no explicit # labels. if data["strict"] or is_label_required: if pgfplots_ticks: ff = data["float format"] axis_options.append( "{}tick={{{}}}".format( xy, ",".join([ff.format(el) for el in pgfplots_ticks]) ) ) else: val = "{}" if "minor" in xy else "\\empty" axis_options.append("{}tick={}".format(xy, val)) if is_label_required: axis_options.append( "{}ticklabels={{{}}}".format(xy, ",".join(pgfplots_ticklabels)) ) return axis_options
def test_common_texification(plain_text, escaped_text): assert common_texification(plain_text) == escaped_text
def __init__(self, data, obj): # noqa: C901 """Returns the PGFPlots code for an axis environment. """ self.content = [] # Are we dealing with an axis that hosts a colorbar? Skip then, those are # treated implicitily by the associated axis. self.is_colorbar = _is_colorbar_heuristic(obj) if self.is_colorbar: return # instantiation self.nsubplots = 1 self.subplot_index = 0 self.is_subplot = False if isinstance(obj, mpl.axes.Subplot): self._subplot(obj, data) self.axis_options = [] # check if axes need to be displayed at all if not obj.axison: self.axis_options.append("hide x axis") self.axis_options.append("hide y axis") # get plot title title = obj.get_title() data["current axis title"] = title if title: self.axis_options.append(u"title={{{}}}".format(title)) # get axes titles xlabel = obj.get_xlabel() xrotation = obj.xaxis.get_label().get_rotation() if xlabel: xlabel = mpl_backend_pgf.common_texification(xlabel) self.axis_options.append(u"xlabel={{{}}}".format(xlabel)) if xrotation != 0: self.axis_options.append( u"xlabel style={{rotate={}}}".format(xrotation - 90) ) ylabel = obj.get_ylabel() yrotation = obj.yaxis.get_label().get_rotation() if ylabel: ylabel = mpl_backend_pgf.common_texification(ylabel) self.axis_options.append(u"ylabel={{{}}}".format(ylabel)) if yrotation != 90: self.axis_options.append( u"ylabel style={{rotate={}}}".format(yrotation - 90) ) # Axes limits. ff = data["float format"] xlim = list(obj.get_xlim()) ylim = list(obj.get_ylim()) # Sort the limits so make sure that the smaller of the two is actually *min. self.axis_options.append(("xmin=" + ff + ", xmax=" + ff).format(*sorted(xlim))) self.axis_options.append(("ymin=" + ff + ", ymax=" + ff).format(*sorted(ylim))) # When the axis is inverted add additional option if xlim != sorted(xlim): self.axis_options.append("x dir=reverse") if ylim != sorted(ylim): self.axis_options.append("y dir=reverse") # axes scaling if obj.get_xscale() == "log": self.axis_options.append("xmode=log") self.axis_options.append( "log basis x={{{}}}".format(_try_f2i(obj.xaxis._scale.base)) ) if obj.get_yscale() == "log": self.axis_options.append("ymode=log") self.axis_options.append( "log basis y={{{}}}".format(_try_f2i(obj.yaxis._scale.base)) ) # Possible values for get_axisbelow(): # True (zorder = 0.5): Ticks and gridlines are below all Artists. # 'line' (zorder = 1.5): Ticks and gridlines are above patches (e.g. # rectangles) but still below lines / markers. # False (zorder = 2.5): Ticks and gridlines are above patches and lines / # markers. if not obj.get_axisbelow(): self.axis_options.append("axis on top") # aspect ratio, plot width/height aspect = obj.get_aspect() if aspect in ["auto", "normal"]: aspect_num = None # just take the given width/height values elif aspect == "equal": aspect_num = 1.0 else: aspect_num = float(aspect) self._set_axis_dimensions(data, aspect_num, xlim, ylim) # axis positions xaxis_pos = obj.get_xaxis().label_position if xaxis_pos == "top": # default: "bottom" self.axis_options.append("axis x line=top") yaxis_pos = obj.get_yaxis().label_position if yaxis_pos == "right": # default: "left" self.axis_options.append("axis y line=right") self._ticks(data, obj) self._grid(obj, data) # axis line styles # Assume that the bottom edge color is the color of the entire box. axcol = obj.spines["bottom"].get_edgecolor() data, col, _ = color.mpl_color2xcolor(data, axcol) if col != "black": self.axis_options.append("axis line style={{{}}}".format(col)) # background color bgcolor = obj.get_facecolor() data, col, _ = color.mpl_color2xcolor(data, bgcolor) if col != "white": self.axis_options.append("axis background/.style={{fill={}}}".format(col)) # find color bar colorbar = _find_associated_colorbar(obj) if colorbar: self._colorbar(colorbar, data) if self.is_subplot: self.content.append("\n\\nextgroupplot") else: self.content.append("\\begin{axis}") return
def __init__(self, data, obj): """Returns the PGFPlots code for an axis environment. """ self.content = [] # Are we dealing with an axis that hosts a colorbar? Skip then, those # are treated implicitily by the associated axis. self.is_colorbar = _is_colorbar_heuristic(obj) if self.is_colorbar: return # instantiation self.nsubplots = 1 self.subplot_index = 0 self.is_subplot = False if isinstance(obj, mpl.axes.Subplot): self._subplot(obj, data) self.axis_options = [] # check if axes need to be displayed at all if not obj.axison: self.axis_options.append("hide x axis") self.axis_options.append("hide y axis") # get plot title title = obj.get_title() if title: self.axis_options.append("title={{{}}}".format(title)) # get axes titles xlabel = obj.get_xlabel() if xlabel: xlabel = mpl_backend_pgf.common_texification(xlabel) self.axis_options.append("xlabel={{{}}}".format(xlabel)) ylabel = obj.get_ylabel() if ylabel: ylabel = mpl_backend_pgf.common_texification(ylabel) self.axis_options.append("ylabel={{{}}}".format(ylabel)) # Axes limits. # Sort the limits so make sure that the smaller of the two is actually # *min. xlim = sorted(list(obj.get_xlim())) self.axis_options.append("xmin={:.15g}, xmax={:.15g}".format(*xlim)) ylim = sorted(list(obj.get_ylim())) self.axis_options.append("ymin={:.15g}, ymax={:.15g}".format(*ylim)) # axes scaling if obj.get_xscale() == "log": self.axis_options.append("xmode=log") self.axis_options.append("log basis x={{{}}}".format( _try_f2i(obj.xaxis._scale.base))) if obj.get_yscale() == "log": self.axis_options.append("ymode=log") self.axis_options.append("log basis y={{{}}}".format( _try_f2i(obj.yaxis._scale.base))) if not obj.get_axisbelow(): self.axis_options.append("axis on top") # aspect ratio, plot width/height aspect = obj.get_aspect() if aspect == "auto" or aspect == "normal": aspect_num = None # just take the given width/height values elif aspect == "equal": aspect_num = 1.0 else: aspect_num = float(aspect) self._width(data, aspect_num, xlim, ylim) # axis positions xaxis_pos = obj.get_xaxis().label_position if xaxis_pos == "top": # default: "bottom" self.axis_options.append("axis x line=top") yaxis_pos = obj.get_yaxis().label_position if yaxis_pos == "right": # default: "left" self.axis_options.append("axis y line=right") self._ticks(data, obj) self._grid(obj, data) # axis line styles # Assume that the bottom edge color is the color of the entire box. axcol = obj.spines["bottom"].get_edgecolor() data, col, _ = color.mpl_color2xcolor(data, axcol) if col != "black": self.axis_options.append("axis line style={{{}}}".format(col)) # background color try: # mpl 2.* bgcolor = obj.get_facecolor() except AttributeError: # mpl 1.* bgcolor = obj.get_axis_bgcolor() data, col, _ = color.mpl_color2xcolor(data, bgcolor) if col != "white": self.axis_options.append( "axis background/.style={{fill={}}}".format(col)) # find color bar colorbar = _find_associated_colorbar(obj) if colorbar: self._colorbar(colorbar, data) # actually print the thing if self.is_subplot: self.content.append("\\nextgroupplot") else: self.content.append("\\begin{axis}") # # anchors # if hasattr(obj, '_matplotlib2tikz_anchors'): # try: # for coord, anchor_name in obj._matplotlib2tikz_anchors: # self.content.append( # '\\node (%s) at (axis cs:%e,%e) {};\n' % # (anchor_name, coord[0], coord[1]) # ) # except: # print('Axes attribute _matplotlib2tikz_anchors wrongly set:' # 'Expected a list of ((x,y), anchor_name), got \'%s\'' # % str(obj._matplotlib2tikz_anchors) # ) return
def __init__(self, data, obj): """Returns the PGFPlots code for an axis environment. """ self.content = [] # Are we dealing with an axis that hosts a colorbar? Skip then, those are # treated implicitily by the associated axis. self.is_colorbar = _is_colorbar_heuristic(obj) if self.is_colorbar: return # instantiation self.nsubplots = 1 self.subplot_index = 0 self.is_subplot = False if isinstance(obj, mpl.axes.Subplot): self._subplot(obj, data) self.axis_options = [] # check if axes need to be displayed at all if not obj.axison: self.axis_options.append("hide x axis") self.axis_options.append("hide y axis") # get plot title title = obj.get_title() data["current axis title"] = title if title: self.axis_options.append(u"title={{{}}}".format(title)) # get axes titles xlabel = obj.get_xlabel() if xlabel: xlabel = mpl_backend_pgf.common_texification(xlabel) self.axis_options.append(u"xlabel={{{}}}".format(xlabel)) ylabel = obj.get_ylabel() if ylabel: ylabel = mpl_backend_pgf.common_texification(ylabel) self.axis_options.append(u"ylabel={{{}}}".format(ylabel)) # Axes limits. # Sort the limits so make sure that the smaller of the two is actually *min. ff = data["float format"] xlim = sorted(list(obj.get_xlim())) self.axis_options.append(("xmin=" + ff + ", xmax=" + ff).format(*xlim)) ylim = sorted(list(obj.get_ylim())) self.axis_options.append(("ymin=" + ff + ", ymax=" + ff).format(*ylim)) # axes scaling if obj.get_xscale() == "log": self.axis_options.append("xmode=log") self.axis_options.append( "log basis x={{{}}}".format(_try_f2i(obj.xaxis._scale.base)) ) if obj.get_yscale() == "log": self.axis_options.append("ymode=log") self.axis_options.append( "log basis y={{{}}}".format(_try_f2i(obj.yaxis._scale.base)) ) # Possible values for get_axisbelow(): # True (zorder = 0.5): Ticks and gridlines are below all Artists. # 'line' (zorder = 1.5): Ticks and gridlines are above patches (e.g. # rectangles) but still below lines / markers. # False (zorder = 2.5): Ticks and gridlines are above patches and lines / # markers. if not obj.get_axisbelow(): self.axis_options.append("axis on top") # aspect ratio, plot width/height aspect = obj.get_aspect() if aspect in ["auto", "normal"]: aspect_num = None # just take the given width/height values elif aspect == "equal": aspect_num = 1.0 else: aspect_num = float(aspect) self._set_axis_dimensions(data, aspect_num, xlim, ylim) # axis positions xaxis_pos = obj.get_xaxis().label_position if xaxis_pos == "top": # default: "bottom" self.axis_options.append("axis x line=top") yaxis_pos = obj.get_yaxis().label_position if yaxis_pos == "right": # default: "left" self.axis_options.append("axis y line=right") self._ticks(data, obj) self._grid(obj, data) # axis line styles # Assume that the bottom edge color is the color of the entire box. axcol = obj.spines["bottom"].get_edgecolor() data, col, _ = color.mpl_color2xcolor(data, axcol) if col != "black": self.axis_options.append("axis line style={{{}}}".format(col)) # background color bgcolor = obj.get_facecolor() data, col, _ = color.mpl_color2xcolor(data, bgcolor) if col != "white": self.axis_options.append("axis background/.style={{fill={}}}".format(col)) # find color bar colorbar = _find_associated_colorbar(obj) if colorbar: self._colorbar(colorbar, data) if self.is_subplot: self.content.append("\n\\nextgroupplot") else: self.content.append("\\begin{axis}") return