def line(ax, p1, p2, permutation=None, **kwargs): """ Draws a line on `ax` from p1 to p2. Parameters ---------- ax: Matplotlib AxesSubplot, None The subplot to draw on. p1: 2-tuple The (x,y) starting coordinates p2: 2-tuple The (x,y) ending coordinates kwargs: Any kwargs to pass through to Matplotlib. """ pp1 = project_point(p1, permutation=permutation) pp2 = project_point(p2, permutation=permutation) ax.add_line(Line2D((pp1[0], pp2[0]), (pp1[1], pp2[1]), **kwargs))
def _redraw_labels(self): """ Redraw axis labels, typically after draw or resize events. """ ax = self.get_axes() # Remove any previous labels for mpl_object in self._to_remove: mpl_object.remove() self._to_remove = [] # Redraw the labels with the appropriate angles for (label, position, rotation, kwargs) in self._labels.values(): transform = ax.transAxes x, y = project_point(position) # Calculate the new angle. position = numpy.array([x,y]) new_rotation = ax.transData.transform_angles(numpy.array((rotation,)), position.reshape((1,2)))[0] text = ax.text(x, y, label, rotation=new_rotation, transform=transform, horizontalalignment="center", **kwargs) text.set_rotation_mode("anchor") self._to_remove.append(text)
def set_ternary_axis_label(ax, label, position, rotation, event_names=None, **kwargs): """ Sets axis labels and registers a callback to adjust text angle when the user resizes or triggers a redraw in interactive mode. Not intended to be called directly by the user. Parameters ---------- ax: Matplotlib AxesSubplot, None The subplot to draw on. label: String The axis label. position: 3-tuple The coordinates to place the label at. rotation: float The angle of rotation of the label. event_names: sequence of strings The Matplotlib events to callback on. kwargs: Any kwargs to pass through to matplotlib. """ # http://stackoverflow.com/questions/4018860/text-box-with-line-wrapping-in-matplotlib if not event_names: event_names = ('resize_event', 'draw_event') transform = ax.transAxes x, y = project_point(position) text = ax.text(x, y, label, rotation=rotation, transform=transform, **kwargs) text.set_rotation_mode("anchor") # Set callback. Make sure that we don't rotate other text fields, like the # title. hash_ = text.__hash__() callback = partial(mpl_callback, rotation=rotation, hash_=hash_) figure = ax.get_figure() for event_name in event_names: figure.canvas.mpl_connect(event_name, callback)
def ticks(ax, scale, ticks=None, locations=None, multiple=1, axis='b', offset=0.01, clockwise=False, **kwargs): """ Sets tick marks and labels. Parameters ---------- ax: Matplotlib AxesSubplot, None The subplot to draw on. scale: float, 1.0 Simplex scale size. ticks: list of strings, None The tick labels locations: list of points, None The locations of the ticks multiple: float, None Specifies which ticks gridelines to draw. For example, if scale=30 and multiple=6, only 5 ticks will be drawn. axis: str, 'b' The axis or axes to draw the ticks for. `axis` must be a substring of 'lrb' (as sets) offset: float, 0.01 controls the length of the ticks clockwise: bool, False Draw ticks marks clockwise or counterclockwise kwargs: Any kwargs to pass through to matplotlib. """ axis = axis.lower() valid_axis_chars = set(['l', 'r', 'b']) axis_chars = set(axis) if not axis_chars.issubset(valid_axis_chars): raise ValueError, "axis must be some combination of 'l', 'r', and 'b'" if not ticks: locations = arange(0, scale + multiple, multiple) ticks = locations offset *= scale if 'r' in axis: for index, i in enumerate(locations): loc1 = (scale - i, i, 0) if clockwise: # Right parallel loc2 = (scale - i, i + offset, 0) text_location = (scale - i, i + 2 * offset, 0) tick = ticks[index] else: # Horizontal loc2 = (scale - i + offset, i, 0) text_location = (scale - i + 2.6 * offset, i - 0.5 * offset, 0) tick = ticks[-(index+1)] line(ax, loc1, loc2, **kwargs) x, y = project_point(text_location) ax.text(x, y, str(tick), horizontalalignment="center",) if 'l' in axis: for index, i in enumerate(locations): loc1 = (0, i, 0) if clockwise: # Horizontal loc2 = (-offset, i, 0) text_location = (-2 * offset, i - 0.5 * offset, 0) tick = ticks[-(index+1)] else: # Right parallel loc2 = (-offset, i + offset, 0) text_location = (-2 * offset, i + 1.5 * offset, 0) tick = ticks[index] line(ax, loc1, loc2, **kwargs) x, y = project_point(text_location) ax.text(x, y, str(tick), horizontalalignment="center",) if 'b' in axis: for index, i in enumerate(locations): loc1 = (i, 0, 0) if clockwise: # Right parallel loc2 = (i + offset, -offset, 0) text_location = (i + 3 * offset, -3.5 * offset, 0) tick = ticks[index] else: # Left parallel loc2 = (i, -offset, 0) text_location = (i + 0.5 * offset, - 3.5 * offset, 0) tick = ticks[-(index+1)] line(ax, loc1, loc2, **kwargs) x, y = project_point(text_location) ax.text(x, y, str(tick), horizontalalignment="center",)
def annotate(self, text, position, **kwargs): ax = self.get_axes() p = project_point(position) ax.annotate(text, (p[0], p[1]), **kwargs)
def transform_fn(p): return project_point(p, **_self.projection)