Source code for mavis.illustrate.scatter

from ..interval import Interval


[docs]class ScatterPlot: """ holds settings that will go into matplotlib after conversion using the mapping system """ def __init__( self, points, y_axis_label, ymax=None, ymin=None, xmin=None, xmax=None, hmarkers=None, height=100, point_radius=2, title='', yticks=None, colors=None ): self.hmarkers = hmarkers if hmarkers is not None else [] self.yticks = yticks if yticks is not None else [] self.colors = colors if colors else {} self.ymin = ymin self.ymax = ymax self.points = points if self.ymin is None: self.ymin = min([y.start for x, y in points] + yticks) if self.ymax is None: self.ymax = max([y.end for x, y in points] + yticks) self.xmin = xmin self.xmax = xmax if self.xmin is None: self.xmin = min([x.start for x, y in points]) if self.xmax is None: self.xmax = max([x.end for x, y in points]) self.y_axis_label = y_axis_label self.height = 100 self.point_radius = 2 self.title = title
[docs]def draw_scatter(DS, canvas, plot, xmapping): """ given a xmapping, draw the scatter plot svg group Args: DS (DiagramSettings): the settings/constants to use for building the svg canvas (svgwrite.canvas): the svgwrite object used to create new svg elements plot (ScatterPlot): the plot to be drawn xmapping (:class:`dict` of :class:`Interval` by :class:`Interval`): dict used for conversion of coordinates in the xaxis to pixel positions """ # generate the y coordinate mapping plot_group = canvas.g(class_='scatter_plot') yratio = plot.height / (abs(plot.ymax - plot.ymin)) ypx = [] xpx = [] for xpo, ypo in plot.points: try: temp = Interval.convert_ratioed_pos(xmapping, xpo.start) xp = Interval.convert_ratioed_pos(xmapping, xpo.end) xp = xp | temp xpx.append((xp, xpo)) temp = plot.height - abs(ypo.start - plot.ymin) * yratio yp = Interval(plot.height - abs(ypo.end - plot.ymin) * yratio, temp) ypx.append((yp, ypo)) except IndexError: pass for x, y in zip(xpx, ypx): xp, xpo = x yp, ypo = y if xp.length() > DS.SCATTER_MARKER_RADIUS: plot_group.add(canvas.line( (xp.start, yp.center), (xp.end, yp.center), stroke='#000000', stroke_width=DS.SCATTER_ERROR_BAR_STROKE_WIDTH )) if yp.length() > DS.SCATTER_MARKER_RADIUS: plot_group.add(canvas.line( (xp.center, yp.start), (xp.center, yp.end), stroke='#000000', stroke_width=DS.SCATTER_ERROR_BAR_STROKE_WIDTH )) plot_group.add(canvas.circle( center=(xp.center, yp.center), fill=plot.colors.get((xpo, ypo), '#000000'), r=DS.SCATTER_MARKER_RADIUS )) xmax = Interval.convert_ratioed_pos(xmapping, plot.xmax).end for py in plot.hmarkers: py = plot.height - abs(py - plot.ymin) * yratio plot_group.add( canvas.line( start=(0, py), end=(xmax, py), stroke='blue' ) ) # draw left y axis plot_group.add(canvas.line( start=(0, 0), end=(0, plot.height), stroke='#000000' )) ytick_labels = [0] # draw start and end markers on the y axis for y in plot.yticks: ytick_labels.append(len(str(y))) py = plot.height - abs(y - plot.ymin) * yratio plot_group.add( canvas.line( start=(0 - DS.SCATTER_YAXIS_TICK_SIZE, py), end=(0, py), stroke='#000000' )) plot_group.add( canvas.text( str(y), insert=( 0 - DS.SCATTER_YAXIS_TICK_SIZE - DS.PADDING, py + DS.SCATTER_YTICK_FONT_SIZE * DS.FONT_CENTRAL_SHIFT_RATIO), fill=DS.LABEL_COLOR, style=DS.FONT_STYLE.format(font_size=DS.SCATTER_YTICK_FONT_SIZE, text_anchor='end') )) shift = max(ytick_labels) x = 0 - DS.PADDING * 2 - DS.SCATTER_AXIS_FONT_SIZE - DS.SCATTER_YAXIS_TICK_SIZE - \ DS.SCATTER_YTICK_FONT_SIZE * DS.FONT_WIDTH_HEIGHT_RATIO * shift y = plot.height / 2 yaxis = canvas.text( plot.y_axis_label, insert=(x, y), fill=DS.LABEL_COLOR, style=DS.FONT_STYLE.format(font_size=DS.SCATTER_AXIS_FONT_SIZE, text_anchor='start'), class_='y_axis_label' ) plot_group.add(yaxis) cx = len(plot.y_axis_label) * DS.FONT_WIDTH_HEIGHT_RATIO * DS.SCATTER_AXIS_FONT_SIZE / 2 yaxis.rotate(270, (x + cx, y)) yaxis.translate(0, 0) y = plot.height setattr(plot_group, 'height', y) return plot_group