def dokey(self): if self.did(self.dokey): return self.dobackground() for plotitem in self.plotitems: self.dokeyitem(plotitem) if self.key is not None: c = self.key.paint(self.keyitems) bbox = c.bbox() def parentchildalign(pmin, pmax, cmin, cmax, pos, dist, inside): ppos = pmin + 0.5 * (cmax - cmin) + dist + pos * ( pmax - pmin - cmax + cmin - 2 * dist) cpos = 0.5 * (cmin + cmax) + (1 - inside) * (1 - 2 * pos) * ( cmax - cmin + 2 * dist) return ppos - cpos if bbox: x = parentchildalign(self.xpos_pt, self.xpos_pt + self.size_pt, bbox.llx_pt, bbox.urx_pt, self.key.hpos, unit.topt(self.key.hdist), self.key.hinside) y = parentchildalign(self.ypos_pt, self.ypos_pt + self.size_pt, bbox.lly_pt, bbox.ury_pt, self.key.vpos, unit.topt(self.key.vdist), self.key.vinside) self.insert(c, [trafo.translate_pt(x, y)])
def paint(self, canvas, data, axis, axispos): if self.breaklinesattrs is not None: breaklinesdist_pt = unit.topt(self.breaklinesdist) breaklineslength_pt = unit.topt(self.breaklineslength) breaklinesextent_pt = (0.5*breaklinesdist_pt*math.fabs(self.cos) + 0.5*breaklineslength_pt*math.fabs(self.sin)) if canvas.extent_pt < breaklinesextent_pt: canvas.extent_pt = breaklinesextent_pt for v in [data.subaxes[name].vminover for name in data.names[1:]]: # use a tangent of the basepath (this is independent of the tickdirection) p = axispos.vbasepath(v, None).normpath() breakline = p.tangent(0, length=self.breaklineslength) widthline = p.tangent(0, length=self.breaklinesdist).transformed(trafomodule.rotate(self.breaklinesangle+90, *breakline.atbegin())) # XXX Uiiii tocenter = map(lambda x: 0.5*(x[0]-x[1]), zip(breakline.atbegin(), breakline.atend())) towidth = map(lambda x: 0.5*(x[0]-x[1]), zip(widthline.atbegin(), widthline.atend())) breakline = breakline.transformed(trafomodule.translate(*tocenter).rotated(self.breaklinesangle, *breakline.atbegin())) breakline1 = breakline.transformed(trafomodule.translate(*towidth)) breakline2 = breakline.transformed(trafomodule.translate(-towidth[0], -towidth[1])) canvas.layer("baseline").fill(path.path(path.moveto_pt(*breakline1.atbegin_pt()), path.lineto_pt(*breakline1.atend_pt()), path.lineto_pt(*breakline2.atend_pt()), path.lineto_pt(*breakline2.atbegin_pt()), path.closepath()), [color.gray.white]) canvas.layer("baseline").stroke(breakline1, self.defaultbreaklinesattrs + self.breaklinesattrs) canvas.layer("baseline").stroke(breakline2, self.defaultbreaklinesattrs + self.breaklinesattrs) _title.paint(self, canvas, data, axis, axispos)
def paint(self, canvas, data, axis, axispos): if self.breaklinesattrs is not None: breaklinesdist_pt = unit.topt(self.breaklinesdist) breaklineslength_pt = unit.topt(self.breaklineslength) breaklinesextent_pt = (0.5*breaklinesdist_pt*math.fabs(self.cos) + 0.5*breaklineslength_pt*math.fabs(self.sin)) if canvas.extent_pt < breaklinesextent_pt: canvas.extent_pt = breaklinesextent_pt for v in [data.subaxes[name].vminover for name in data.names[1:]]: # use a tangent of the basepath (this is independent of the tickdirection) p = axispos.vbasepath(v, None).normpath() breakline = p.tangent(0, length=self.breaklineslength) widthline = p.tangent(0, length=self.breaklinesdist).transformed(trafomodule.rotate(self.breaklinesangle+90, *breakline.atbegin())) # XXX Uiiii tocenter = map(lambda x: 0.5*(x[0]-x[1]), zip(breakline.atbegin(), breakline.atend())) towidth = map(lambda x: 0.5*(x[0]-x[1]), zip(widthline.atbegin(), widthline.atend())) breakline = breakline.transformed(trafomodule.translate(*tocenter).rotated(self.breaklinesangle, *breakline.atbegin())) breakline1 = breakline.transformed(trafomodule.translate(*towidth)) breakline2 = breakline.transformed(trafomodule.translate(-towidth[0], -towidth[1])) canvas.fill(path.path(path.moveto_pt(*breakline1.atbegin_pt()), path.lineto_pt(*breakline1.atend_pt()), path.lineto_pt(*breakline2.atend_pt()), path.lineto_pt(*breakline2.atbegin_pt()), path.closepath()), [color.gray.white]) canvas.stroke(breakline1, self.defaultbreaklinesattrs + self.breaklinesattrs) canvas.stroke(breakline2, self.defaultbreaklinesattrs + self.breaklinesattrs) _title.paint(self, canvas, data, axis, axispos)
def __init__(self, x, y, lcurl=1, rcurl=None, langle=None, rangle=None): if langle is not None: langle = radians(langle) if rangle is not None: rangle = radians(rangle) roughknot_pt.__init__(self, unit.topt(x), unit.topt(y), lcurl, rcurl, langle, rangle)
def polygonal_path(Z, loop=True): pa = path.path( path.moveto(Z[0].real, Z[0].imag), path.multilineto_pt( [ ( unit.topt(z.real), unit.topt(z.imag) ) for z in Z[1:] ] )) if loop: pa.append(path.closepath()) return pa
def paint(self, plotitems): "creates the layout of the key" columndist_pt = unit.topt(self.columndist) c = canvas.canvas() itemspercolumn = (len(plotitems) + self.columns - 1) // self.columns x_pt = 0 while plotitems: subc = self.paintcolumn(plotitems[:itemspercolumn]) c.insert(subc, [trafo.translate_pt(x_pt, 0)]) x_pt += unit.topt(subc.bbox().width()) + columndist_pt del plotitems[:itemspercolumn] if self.keyattrs is not None: newc = canvas.canvas() newc.draw(c.bbox().enlarged(self.border).path(), self.keyattrs) newc.insert(c) c = newc return c
def dokey(self): if self.did(self.dokey): return self.dobackground() self.dostyles() if self.key is not None: c = self.key.paint(self.plotitems) bbox = c.bbox() def parentchildalign(pmin, pmax, cmin, cmax, pos, dist, inside): ppos = pmin+0.5*(cmax-cmin)+dist+pos*(pmax-pmin-cmax+cmin-2*dist) cpos = 0.5*(cmin+cmax)+(1-inside)*(1-2*pos)*(cmax-cmin+2*dist) return ppos-cpos if bbox: x = parentchildalign(self.xpos_pt, self.xpos_pt+self.size_pt, bbox.llx_pt, bbox.urx_pt, self.key.hpos, unit.topt(self.key.hdist), self.key.hinside) y = parentchildalign(self.ypos_pt, self.ypos_pt+self.size_pt, bbox.lly_pt, bbox.ury_pt, self.key.vpos, unit.topt(self.key.vdist), self.key.vinside) self.insert(c, [trafo.translate_pt(x, y)])
def paint(self, canvas, data, axis, axispos): if axis.title is not None and self.titleattrs is not None: x, y = axispos.vtickpoint_pt(self.titlepos) dx, dy = axispos.vtickdirection(self.titlepos) titleattrs = self.defaulttitleattrs + self.titleattrs if self.titledirection is not None: titleattrs.append(self.titledirection.trafo(dx, dy)) title = canvas.text_pt(x, y, axis.title, titleattrs) canvas.extent_pt += unit.topt(self.titledist) title.linealign_pt(canvas.extent_pt, -dx, -dy) canvas.extent_pt += title.extent_pt(dx, dy)
def paintcolumn(self, plotitems): "creates the layout of a key column" c = canvas.canvas() self.dist_pt = unit.topt(self.dist) self.hdist_pt = unit.topt(self.hdist) self.vdist_pt = unit.topt(self.vdist) self.symbolwidth_pt = unit.topt(self.symbolwidth) self.symbolheight_pt = unit.topt(self.symbolheight) self.symbolspace_pt = unit.topt(self.symbolspace) titleboxes = [] for plotitem in plotitems: titlebox = c.texrunner.text_pt( 0, 0, plotitem.title, self.defaulttextattrs + self.textattrs) titlebox.plotitem = plotitem titleboxes.append(titlebox) dy_pt = box.tile_pt(titleboxes, self.dist_pt, 0, -1) box.linealignequal_pt(titleboxes, self.symbolwidth_pt + self.symbolspace_pt, 1, 0) y_pt = -0.5 * self.symbolheight_pt + titleboxes[0].center[1] for titlebox in titleboxes: titlebox.plotitem.key_pt(c, 0, y_pt, self.symbolwidth_pt, self.symbolheight_pt) y_pt -= dy_pt for titlebox in titleboxes: c.insert(titlebox) return c
def paint(self, canvas, data, axis, axispos): if axis.title is not None and self.titleattrs is not None: x, y = axispos.vtickpoint_pt(self.titlepos) dx, dy = axispos.vtickdirection(self.titlepos) titleattrs = self.defaulttitleattrs + self.titleattrs if self.titledirection is not None: x2, y2 = axispos.vtickpoint_pt(self.titlepos+0.001) # XXX: axisdirection needed dx2, dy2 = x2-x, y2-y if dx*dy2-dy*dx2 < 0: dy2 *= -1 dx2 *= -1 titleattrs.append(self.titledirection.trafo(dy2, -dx2)) title = canvas.text_pt(x, y, axis.title, titleattrs) canvas.extent_pt += unit.topt(self.titledist) title.linealign_pt(canvas.extent_pt, -dx, -dy) canvas.extent_pt += title.extent_pt(dx, dy)
def paint(self, canvas, data, axis, axispos): if axis.title is not None and self.titleattrs is not None: x, y = axispos.vtickpoint_pt(self.titlepos) dx, dy = axispos.vtickdirection(self.titlepos) titleattrs = self.defaulttitleattrs + self.titleattrs if self.titledirection is not None: x2, y2 = axispos.vtickpoint_pt(self.titlepos+0.001) # XXX: axisdirection needed dx2, dy2 = x2-x, y2-y if dx*dy2-dy*dx2 < 0: dy2 *= -1 dx2 *= -1 titleattrs.append(self.titledirection.trafo(dy2, -dx2)) title = canvas.layer("title").text_pt(x, y, axis.title, titleattrs) canvas.extent_pt += unit.topt(self.titledist) title.linealign_pt(canvas.extent_pt, -dx, -dy) canvas.extent_pt += title.extent_pt(dx, dy)
def rate(self, distances, density): """rate distances - the distances are a list of positive floats in PostScript points - the density lineary rescales the rater (the optimum etc.), e.g. a value bigger than one increases the optimum (when it is positive) and a value lower than one decreases the optimum (when it is positive); the density itself should be positive""" if len(distances): opt = unit.topt(self.opt) / density rate = 0 for distance in distances: if distance < opt: rate += self.weight * (opt / distance - 1) else: rate += self.weight * (distance / opt - 1) return rate / float(len(distances))
def interpolated_path(Z, shape=1.0, loop=True): shape /= 6.0 I = range(0, len(Z)-2) if loop: I += [-1] segments = [ ( Z[i] + (Z[i+1]-Z[i-1])*shape, Z[i+1] - (Z[i+2]-Z[i])*shape, Z[i+1] ) for i in I ] pa = path.path( path.moveto(Z[0].real, Z[0].imag), path.multicurveto_pt( [ (unit.topt(W[0].real), unit.topt(W[0].imag), unit.topt(W[1].real), unit.topt(W[1].imag), unit.topt(W[2].real), unit.topt(W[2].imag) ) for W in segments ])) if loop: pa.append(path.closepath()) return pa
def paintcolumn(self, plotitems): "creates the layout of a key column" c = canvas.canvas() self.dist_pt = unit.topt(self.dist) self.hdist_pt = unit.topt(self.hdist) self.vdist_pt = unit.topt(self.vdist) self.symbolwidth_pt = unit.topt(self.symbolwidth) self.symbolheight_pt = unit.topt(self.symbolheight) self.symbolspace_pt = unit.topt(self.symbolspace) titleboxes = [] for plotitem in plotitems: titlebox = c.texrunner.text_pt(0, 0, plotitem.title, self.defaulttextattrs + self.textattrs) titlebox.plotitem = plotitem titleboxes.append(titlebox) dy_pt = box.tile_pt(titleboxes, self.dist_pt, 0, -1) box.linealignequal_pt(titleboxes, self.symbolwidth_pt + self.symbolspace_pt, 1, 0) y_pt = -0.5 * self.symbolheight_pt + titleboxes[0].center[1] for titlebox in titleboxes: titlebox.plotitem.key_pt(c, 0, y_pt, self.symbolwidth_pt, self.symbolheight_pt) y_pt -= dy_pt for titlebox in titleboxes: c.insert(titlebox) return c
def __init__(self, x, y, curl=1, angle=None): if not (angle is None): angle = radians(angle) endknot_pt.__init__(self, unit.topt(x), unit.topt(y), curl, angle)
def __init__(self, xpos=0, ypos=0, size=None, xscale=1, yscale=1, zscale=1 / goldenmean, projector=central(10, -30, 30), key=None, **axes): graph.__init__(self) self.xpos = xpos self.ypos = ypos self.size = size self.xpos_pt = unit.topt(xpos) self.ypos_pt = unit.topt(ypos) self.size_pt = unit.topt(size) self.xscale = xscale self.yscale = yscale self.zscale = zscale self.projector = projector self.key = key self.xorder = projector.zindex(0, -1, 0) > projector.zindex( 0, 1, 0) and 1 or 0 self.yorder = projector.zindex(-1, 0, 0) > projector.zindex( 1, 0, 0) and 1 or 0 self.zindexscale = math.sqrt(xscale * xscale + yscale * yscale + zscale * zscale) for axisname, aaxis in axes.items(): if aaxis is not None: if not isinstance(aaxis, axis.linkedaxis): self.axes[axisname] = axis.anchoredaxis( aaxis, self.texrunner, axisname) else: self.axes[axisname] = aaxis for axisname in ["x", "y"]: okey = axisname + "2" if not axes.has_key(axisname): if not axes.has_key(okey) or axes[okey] is None: self.axes[axisname] = axis.anchoredaxis( axis.linear(), self.texrunner, axisname) if not axes.has_key(okey): self.axes[okey] = axis.linkedaxis( self.axes[axisname], okey) else: self.axes[axisname] = axis.linkedaxis( self.axes[okey], axisname) if not axes.has_key("z"): self.axes["z"] = axis.anchoredaxis(axis.linear(), self.texrunner, "z") if self.axes.has_key("x"): self.xbasepath = self.axes["x"].basepath self.xvbasepath = self.axes["x"].vbasepath self.xgridpath = self.axes["x"].gridpath self.xtickpoint_pt = self.axes["x"].tickpoint_pt self.xtickpoint = self.axes["x"].tickpoint self.xvtickpoint_pt = self.axes["x"].vtickpoint_pt self.xvtickpoint = self.axes["x"].tickpoint self.xtickdirection = self.axes["x"].tickdirection self.xvtickdirection = self.axes["x"].vtickdirection if self.axes.has_key("y"): self.ybasepath = self.axes["y"].basepath self.yvbasepath = self.axes["y"].vbasepath self.ygridpath = self.axes["y"].gridpath self.ytickpoint_pt = self.axes["y"].tickpoint_pt self.ytickpoint = self.axes["y"].tickpoint self.yvtickpoint_pt = self.axes["y"].vtickpoint_pt self.yvtickpoint = self.axes["y"].vtickpoint self.ytickdirection = self.axes["y"].tickdirection self.yvtickdirection = self.axes["y"].vtickdirection if self.axes.has_key("z"): self.zbasepath = self.axes["z"].basepath self.zvbasepath = self.axes["z"].vbasepath self.zgridpath = self.axes["z"].gridpath self.ztickpoint_pt = self.axes["z"].tickpoint_pt self.ztickpoint = self.axes["z"].tickpoint self.zvtickpoint_pt = self.axes["z"].vtickpoint self.zvtickpoint = self.axes["z"].vtickpoint self.ztickdirection = self.axes["z"].tickdirection self.zvtickdirection = self.axes["z"].vtickdirection self.axesnames = ([], [], []) for axisname, aaxis in self.axes.items(): if axisname[0] not in "xyz" or (len(axisname) != 1 and (not axisname[1:].isdigit() or axisname[1:] == "1")): raise ValueError("invalid axis name") if axisname[0] == "x": self.axesnames[0].append(axisname) elif axisname[0] == "y": self.axesnames[1].append(axisname) else: self.axesnames[2].append(axisname) aaxis.setcreatecall(self.doaxiscreate, axisname)
def __init__(self, xpos=0, ypos=0, width=None, height=None, ratio=goldenmean, key=None, backgroundattrs=None, axesdist=0.8 * unit.v_cm, xaxisat=None, yaxisat=None, **axes): graph.__init__(self) self.xpos = xpos self.ypos = ypos self.xpos_pt = unit.topt(self.xpos) self.ypos_pt = unit.topt(self.ypos) self.xaxisat = xaxisat self.yaxisat = yaxisat self.key = key self.backgroundattrs = backgroundattrs self.axesdist_pt = unit.topt(axesdist) self.width = width self.height = height if width is None: if height is None: raise ValueError("specify width and/or height") else: self.width = ratio * self.height elif height is None: self.height = (1.0 / ratio) * self.width self.width_pt = unit.topt(self.width) self.height_pt = unit.topt(self.height) for axisname, aaxis in axes.items(): if aaxis is not None: if not isinstance(aaxis, axis.linkedaxis): self.axes[axisname] = axis.anchoredaxis( aaxis, self.texrunner, axisname) else: self.axes[axisname] = aaxis for axisname, axisat in [("x", xaxisat), ("y", yaxisat)]: okey = axisname + "2" if not axes.has_key(axisname): if not axes.has_key(okey) or axes[okey] is None: self.axes[axisname] = axis.anchoredaxis( axis.linear(), self.texrunner, axisname) if not axes.has_key(okey): self.axes[okey] = axis.linkedaxis( self.axes[axisname], okey) else: self.axes[axisname] = axis.linkedaxis( self.axes[okey], axisname) elif not axes.has_key(okey) and axisat is None: self.axes[okey] = axis.linkedaxis(self.axes[axisname], okey) if self.axes.has_key("x"): self.xbasepath = self.axes["x"].basepath self.xvbasepath = self.axes["x"].vbasepath self.xgridpath = self.axes["x"].gridpath self.xtickpoint_pt = self.axes["x"].tickpoint_pt self.xtickpoint = self.axes["x"].tickpoint self.xvtickpoint_pt = self.axes["x"].vtickpoint_pt self.xvtickpoint = self.axes["x"].tickpoint self.xtickdirection = self.axes["x"].tickdirection self.xvtickdirection = self.axes["x"].vtickdirection if self.axes.has_key("y"): self.ybasepath = self.axes["y"].basepath self.yvbasepath = self.axes["y"].vbasepath self.ygridpath = self.axes["y"].gridpath self.ytickpoint_pt = self.axes["y"].tickpoint_pt self.ytickpoint = self.axes["y"].tickpoint self.yvtickpoint_pt = self.axes["y"].vtickpoint_pt self.yvtickpoint = self.axes["y"].vtickpoint self.ytickdirection = self.axes["y"].tickdirection self.yvtickdirection = self.axes["y"].vtickdirection self.axesnames = ([], []) for axisname, aaxis in self.axes.items(): if axisname[0] not in "xy" or (len(axisname) != 1 and (not axisname[1:].isdigit() or axisname[1:] == "1")): raise ValueError("invalid axis name") if axisname[0] == "x": self.axesnames[0].append(axisname) else: self.axesnames[1].append(axisname) aaxis.setcreatecall(self.doaxiscreate, axisname)
def __init__(self, x, y): smoothknot_pt.__init__(self, unit.topt(x), unit.topt(y))
def paint(self, canvas, data, axis, positioner): namepos = [] for name in data.names: subaxis = data.subaxes[name] v = subaxis.vmin + self.namepos * (subaxis.vmax - subaxis.vmin) x, y = positioner.vtickpoint_pt(v) dx, dy = positioner.vtickdirection(v) namepos.append((v, x, y, dx, dy)) nameboxes = [] if self.nameattrs is not None: for (v, x, y, dx, dy), name in zip(namepos, data.names): nameattrs = self.defaultnameattrs + self.nameattrs if self.namedirection is not None: nameattrs.append(self.namedirection.trafo(dx, dy)) nameboxes.append(canvas.texrunner.text_pt(x, y, str(name), nameattrs)) labeldist_pt = canvas.extent_pt + unit.topt(self.namedist) if len(namepos) > 1: equaldirection = 1 for np in namepos[1:]: if np[3] != namepos[0][3] or np[4] != namepos[0][4]: equaldirection = 0 else: equaldirection = 0 if equaldirection and ((not namepos[0][3] and self.namevequalize) or (not namepos[0][4] and self.namehequalize)): box.linealignequal_pt(nameboxes, labeldist_pt, -namepos[0][3], -namepos[0][4]) else: for namebox, np in zip(nameboxes, namepos): namebox.linealign_pt(labeldist_pt, -np[3], -np[4]) if self.basepathattrs is not None: p = positioner.vbasepath() if p is not None: canvas.layer("baseline").stroke(p, self.defaultbasepathattrs + self.basepathattrs) if ( self.tickattrs is not None and (self.innerticklength is not None or self.outerticklength is not None) ): if self.innerticklength is not None: innerticklength_pt = unit.topt(self.innerticklength) if canvas.extent_pt < -innerticklength_pt: canvas.extent_pt = -innerticklength_pt elif self.outerticklength is not None: innerticklength_pt = 0 if self.outerticklength is not None: outerticklength_pt = unit.topt(self.outerticklength) if canvas.extent_pt < outerticklength_pt: canvas.extent_pt = outerticklength_pt elif innerticklength_pt is not None: outerticklength_pt = 0 for v in [data.subaxes[name].vminover for name in data.names] + [1]: x, y = positioner.vtickpoint_pt(v) dx, dy = positioner.vtickdirection(v) x1 = x + dx * innerticklength_pt y1 = y + dy * innerticklength_pt x2 = x - dx * outerticklength_pt y2 = y - dy * outerticklength_pt canvas.layer("ticks").stroke(path.line_pt(x1, y1, x2, y2), self.defaulttickattrs + self.tickattrs) for (v, x, y, dx, dy), namebox in zip(namepos, nameboxes): newextent_pt = namebox.extent_pt(dx, dy) + labeldist_pt if canvas.extent_pt < newextent_pt: canvas.extent_pt = newextent_pt for namebox in nameboxes: canvas.layer("labels").insert(namebox) _title.paint(self, canvas, data, axis, positioner)
def paint(self, canvas, data, axis, positioner): namepos = [] for name in data.names: subaxis = data.subaxes[name] v = subaxis.vmin + self.namepos * (subaxis.vmax - subaxis.vmin) x, y = positioner.vtickpoint_pt(v) dx, dy = positioner.vtickdirection(v) namepos.append((v, x, y, dx, dy)) nameboxes = [] if self.nameattrs is not None: for (v, x, y, dx, dy), name in zip(namepos, data.names): nameattrs = self.defaultnameattrs + self.nameattrs if self.namedirection is not None: nameattrs.append(self.namedirection.trafo(dx, dy)) nameboxes.append( canvas.textengine.text_pt(x, y, str(name), nameattrs)) labeldist_pt = canvas.extent_pt + unit.topt(self.namedist) if len(namepos) > 1: equaldirection = 1 for np in namepos[1:]: if np[3] != namepos[0][3] or np[4] != namepos[0][4]: equaldirection = 0 else: equaldirection = 0 if equaldirection and ((not namepos[0][3] and self.namevequalize) or (not namepos[0][4] and self.namehequalize)): box.linealignequal_pt(nameboxes, labeldist_pt, -namepos[0][3], -namepos[0][4]) else: for namebox, np in zip(nameboxes, namepos): namebox.linealign_pt(labeldist_pt, -np[3], -np[4]) if self.basepathattrs is not None: p = positioner.vbasepath() if p is not None: canvas.layer("baseline").stroke( p, self.defaultbasepathattrs + self.basepathattrs) if (self.tickattrs is not None and (self.innerticklength is not None or self.outerticklength is not None)): if self.innerticklength is not None: innerticklength_pt = unit.topt(self.innerticklength) if canvas.extent_pt < -innerticklength_pt: canvas.extent_pt = -innerticklength_pt elif self.outerticklength is not None: innerticklength_pt = 0 if self.outerticklength is not None: outerticklength_pt = unit.topt(self.outerticklength) if canvas.extent_pt < outerticklength_pt: canvas.extent_pt = outerticklength_pt elif innerticklength_pt is not None: outerticklength_pt = 0 for v in [data.subaxes[name].vminover for name in data.names] + [1]: x, y = positioner.vtickpoint_pt(v) dx, dy = positioner.vtickdirection(v) x1 = x + dx * innerticklength_pt y1 = y + dy * innerticklength_pt x2 = x - dx * outerticklength_pt y2 = y - dy * outerticklength_pt canvas.layer("ticks").stroke( path.line_pt(x1, y1, x2, y2), self.defaulttickattrs + self.tickattrs) for (v, x, y, dx, dy), namebox in zip(namepos, nameboxes): newextent_pt = namebox.extent_pt(dx, dy) + labeldist_pt if canvas.extent_pt < newextent_pt: canvas.extent_pt = newextent_pt for namebox in nameboxes: canvas.layer("labels").insert(namebox) _title.paint(self, canvas, data, axis, positioner)
def paint(self, canvas, data, axis, axispos): for t in data.ticks: t.temp_v = axis.convert(data, t) t.temp_x_pt, t.temp_y_pt = axispos.vtickpoint_pt(t.temp_v) t.temp_dx, t.temp_dy = axispos.vtickdirection(t.temp_v) maxticklevel, maxlabellevel = tick.maxlevels(data.ticks) labeldist_pt = unit.topt(self.labeldist) # create & align t.temp_labelbox for t in data.ticks: if t.labellevel is not None: labelattrs = attr.selectattrs(self.labelattrs, t.labellevel, maxlabellevel) if labelattrs is not None: labelattrs = self.defaultlabelattrs + labelattrs if self.labeldirection is not None: labelattrs.append( self.labeldirection.trafo(t.temp_dx, t.temp_dy)) if t.labelattrs is not None: labelattrs.extend(t.labelattrs) t.temp_labelbox = canvas.textengine.text_pt( t.temp_x_pt, t.temp_y_pt, t.label, labelattrs) if len(data.ticks) > 1: equaldirection = 1 for t in data.ticks[1:]: if t.temp_dx != data.ticks[ 0].temp_dx or t.temp_dy != data.ticks[0].temp_dy: equaldirection = 0 else: equaldirection = 0 if equaldirection and ( (not data.ticks[0].temp_dx and self.labelvequalize) or (not data.ticks[0].temp_dy and self.labelhequalize)): if self.labelattrs is not None: box.linealignequal_pt([ t.temp_labelbox for t in data.ticks if t.labellevel is not None ], labeldist_pt, -data.ticks[0].temp_dx, -data.ticks[0].temp_dy) else: for t in data.ticks: if t.labellevel is not None and self.labelattrs is not None: t.temp_labelbox.linealign_pt(labeldist_pt, -t.temp_dx, -t.temp_dy) for t in data.ticks: if t.ticklevel is not None and self.tickattrs is not None: tickattrs = attr.selectattrs( self.defaulttickattrs + self.tickattrs, t.ticklevel, maxticklevel) if tickattrs is not None: innerticklength = attr.selectattr(self.innerticklength, t.ticklevel, maxticklevel) outerticklength = attr.selectattr(self.outerticklength, t.ticklevel, maxticklevel) if innerticklength is not None or outerticklength is not None: if innerticklength is None: innerticklength = 0 if outerticklength is None: outerticklength = 0 innerticklength_pt = unit.topt(innerticklength) outerticklength_pt = unit.topt(outerticklength) x1 = t.temp_x_pt + t.temp_dx * innerticklength_pt y1 = t.temp_y_pt + t.temp_dy * innerticklength_pt x2 = t.temp_x_pt - t.temp_dx * outerticklength_pt y2 = t.temp_y_pt - t.temp_dy * outerticklength_pt canvas.layer("ticks").stroke( path.line_pt(x1, y1, x2, y2), tickattrs) if outerticklength_pt > canvas.extent_pt: canvas.extent_pt = outerticklength_pt if -innerticklength_pt > canvas.extent_pt: canvas.extent_pt = -innerticklength_pt if self.gridattrs is not None: gridattrs = attr.selectattrs( self.defaultgridattrs + self.gridattrs, t.ticklevel, maxticklevel) if gridattrs is not None: canvas.layer("grid").stroke(axispos.vgridpath(t.temp_v), gridattrs) if t.labellevel is not None and self.labelattrs is not None: canvas.layer("labels").insert(t.temp_labelbox) canvas.labels.append(t.temp_labelbox) extent_pt = t.temp_labelbox.extent_pt(t.temp_dx, t.temp_dy) + labeldist_pt if extent_pt > canvas.extent_pt: canvas.extent_pt = extent_pt if self.labelattrs is None: canvas.labels = None if self.basepathattrs is not None: canvas.layer("baseline").stroke( axispos.vbasepath(), self.defaultbasepathattrs + self.basepathattrs) # for t in data.ticks: # del t.temp_v # we've inserted those temporary variables ... and do not care any longer about them # del t.temp_x_pt # del t.temp_y_pt # del t.temp_dx # del t.temp_dy # if t.labellevel is not None and self.labelattrs is not None: # del t.temp_labelbox _title.paint(self, canvas, data, axis, axispos)
def text(self, x, y, charcodes, size_pt, **kwargs): return self.text_pt(unit.topt(x), unit.topt(y), charcodes, size_pt, **kwargs)
def paint(self, canvas, data, axis, axispos): for t in data.ticks: t.temp_v = axis.convert(data, t) t.temp_x_pt, t.temp_y_pt = axispos.vtickpoint_pt(t.temp_v) t.temp_dx, t.temp_dy = axispos.vtickdirection(t.temp_v) maxticklevel, maxlabellevel = tick.maxlevels(data.ticks) labeldist_pt = unit.topt(self.labeldist) # create & align t.temp_labelbox for t in data.ticks: if t.labellevel is not None: labelattrs = attr.selectattrs(self.labelattrs, t.labellevel, maxlabellevel) if labelattrs is not None: labelattrs = self.defaultlabelattrs + labelattrs if self.labeldirection is not None: labelattrs.append(self.labeldirection.trafo(t.temp_dx, t.temp_dy)) if t.labelattrs is not None: labelattrs.extend(t.labelattrs) t.temp_labelbox = canvas.texrunner.text_pt(t.temp_x_pt, t.temp_y_pt, t.label, labelattrs) if len(data.ticks) > 1: equaldirection = 1 for t in data.ticks[1:]: if t.temp_dx != data.ticks[0].temp_dx or t.temp_dy != data.ticks[0].temp_dy: equaldirection = 0 else: equaldirection = 0 if equaldirection and ((not data.ticks[0].temp_dx and self.labelvequalize) or (not data.ticks[0].temp_dy and self.labelhequalize)): if self.labelattrs is not None: box.linealignequal_pt([t.temp_labelbox for t in data.ticks if t.labellevel is not None], labeldist_pt, -data.ticks[0].temp_dx, -data.ticks[0].temp_dy) else: for t in data.ticks: if t.labellevel is not None and self.labelattrs is not None: t.temp_labelbox.linealign_pt(labeldist_pt, -t.temp_dx, -t.temp_dy) for t in data.ticks: if t.ticklevel is not None and self.tickattrs is not None: tickattrs = attr.selectattrs(self.defaulttickattrs + self.tickattrs, t.ticklevel, maxticklevel) if tickattrs is not None: innerticklength = attr.selectattr(self.innerticklength, t.ticklevel, maxticklevel) outerticklength = attr.selectattr(self.outerticklength, t.ticklevel, maxticklevel) if innerticklength is not None or outerticklength is not None: if innerticklength is None: innerticklength = 0 if outerticklength is None: outerticklength = 0 innerticklength_pt = unit.topt(innerticklength) outerticklength_pt = unit.topt(outerticklength) x1 = t.temp_x_pt + t.temp_dx * innerticklength_pt y1 = t.temp_y_pt + t.temp_dy * innerticklength_pt x2 = t.temp_x_pt - t.temp_dx * outerticklength_pt y2 = t.temp_y_pt - t.temp_dy * outerticklength_pt canvas.layer("ticks").stroke(path.line_pt(x1, y1, x2, y2), tickattrs) if outerticklength_pt > canvas.extent_pt: canvas.extent_pt = outerticklength_pt if -innerticklength_pt > canvas.extent_pt: canvas.extent_pt = -innerticklength_pt if self.gridattrs is not None: gridattrs = attr.selectattrs(self.defaultgridattrs + self.gridattrs, t.ticklevel, maxticklevel) if gridattrs is not None: canvas.layer("grid").stroke(axispos.vgridpath(t.temp_v), gridattrs) if t.labellevel is not None and self.labelattrs is not None: canvas.layer("labels").insert(t.temp_labelbox) canvas.labels.append(t.temp_labelbox) extent_pt = t.temp_labelbox.extent_pt(t.temp_dx, t.temp_dy) + labeldist_pt if extent_pt > canvas.extent_pt: canvas.extent_pt = extent_pt if self.labelattrs is None: canvas.labels = None if self.basepathattrs is not None: canvas.layer("baseline").stroke(axispos.vbasepath(), self.defaultbasepathattrs + self.basepathattrs) # for t in data.ticks: # del t.temp_v # we've inserted those temporary variables ... and do not care any longer about them # del t.temp_x_pt # del t.temp_y_pt # del t.temp_dx # del t.temp_dy # if t.labellevel is not None and self.labelattrs is not None: # del t.temp_labelbox _title.paint(self, canvas, data, axis, axispos)
def __init__(self, xpos=0, ypos=0, width=None, height=None, ratio=goldenmean, key=None, backgroundattrs=None, axesdist=0.8*unit.v_cm, flipped=False, xaxisat=None, yaxisat=None, **axes): graph.__init__(self) self.xpos = xpos self.ypos = ypos self.xpos_pt = unit.topt(self.xpos) self.ypos_pt = unit.topt(self.ypos) self.xaxisat = xaxisat self.yaxisat = yaxisat self.key = key self.backgroundattrs = backgroundattrs self.axesdist_pt = unit.topt(axesdist) self.flipped = flipped self.width = width self.height = height if width is None: if height is None: raise ValueError("specify width and/or height") else: self.width = ratio * self.height elif height is None: self.height = (1.0/ratio) * self.width self.width_pt = unit.topt(self.width) self.height_pt = unit.topt(self.height) for axisname, aaxis in axes.items(): if aaxis is not None: if not isinstance(aaxis, axis.linkedaxis): self.axes[axisname] = axis.anchoredaxis(aaxis, self.texrunner, axisname) else: self.axes[axisname] = aaxis for axisname, axisat in [("x", xaxisat), ("y", yaxisat)]: okey = axisname + "2" if not axes.has_key(axisname): if not axes.has_key(okey) or axes[okey] is None: self.axes[axisname] = axis.anchoredaxis(axis.linear(), self.texrunner, axisname) if not axes.has_key(okey): self.axes[okey] = axis.linkedaxis(self.axes[axisname], okey) else: self.axes[axisname] = axis.linkedaxis(self.axes[okey], axisname) elif not axes.has_key(okey) and axisat is None: self.axes[okey] = axis.linkedaxis(self.axes[axisname], okey) if self.axes.has_key("x"): self.xbasepath = self.axes["x"].basepath self.xvbasepath = self.axes["x"].vbasepath self.xgridpath = self.axes["x"].gridpath self.xtickpoint_pt = self.axes["x"].tickpoint_pt self.xtickpoint = self.axes["x"].tickpoint self.xvtickpoint_pt = self.axes["x"].vtickpoint_pt self.xvtickpoint = self.axes["x"].tickpoint self.xtickdirection = self.axes["x"].tickdirection self.xvtickdirection = self.axes["x"].vtickdirection if self.axes.has_key("y"): self.ybasepath = self.axes["y"].basepath self.yvbasepath = self.axes["y"].vbasepath self.ygridpath = self.axes["y"].gridpath self.ytickpoint_pt = self.axes["y"].tickpoint_pt self.ytickpoint = self.axes["y"].tickpoint self.yvtickpoint_pt = self.axes["y"].vtickpoint_pt self.yvtickpoint = self.axes["y"].vtickpoint self.ytickdirection = self.axes["y"].tickdirection self.yvtickdirection = self.axes["y"].vtickdirection self.axesnames = ([], []) for axisname, aaxis in self.axes.items(): if axisname[0] not in "xy" or (len(axisname) != 1 and (not axisname[1:].isdigit() or axisname[1:] == "1")): raise ValueError("invalid axis name") if axisname[0] == "x": self.axesnames[0].append(axisname) else: self.axesnames[1].append(axisname) aaxis.setcreatecall(self.doaxiscreate, axisname) self.axespositioners = dict(x=positioner.lineaxispos_pt(self.xpos_pt, self.ypos_pt, self.xpos_pt + self.width_pt, self.ypos_pt, (0, 1), self.xvgridpath), x2=positioner.lineaxispos_pt(self.xpos_pt, self.ypos_pt + self.height_pt, self.xpos_pt + self.width_pt, self.ypos_pt + self.height_pt, (0, -1), self.xvgridpath), y=positioner.lineaxispos_pt(self.xpos_pt, self.ypos_pt, self.xpos_pt, self.ypos_pt + self.height_pt, (1, 0), self.yvgridpath), y2=positioner.lineaxispos_pt(self.xpos_pt + self.width_pt, self.ypos_pt, self.xpos_pt + self.width_pt, self.ypos_pt + self.height_pt, (-1, 0), self.yvgridpath)) if self.flipped: self.axespositioners = dict(x=self.axespositioners["y2"], y2=self.axespositioners["x2"], y=self.axespositioners["x"], x2=self.axespositioners["y"])
def __init__(self, lcontrol, rcontrol): controlcurve_pt.__init__(self, (unit.topt(lcontrol[0]), unit.topt(lcontrol[1])), (unit.topt(rcontrol[0]), unit.topt(rcontrol[1])))
def __init__(self, xpos=0, ypos=0, size=None, xscale=1, yscale=1, zscale=1/goldenmean, projector=central(10, -30, 30), axesdist=0.8*unit.v_cm, key=None, **axes): graph.__init__(self) self.layer("hiddenaxes", below=self.layer("filldata")) for name in ["hiddenaxes.grid", "hiddenaxes.baseline", "hiddenaxes.ticks", "hiddenaxes.labels", "hiddenaxes.title"]: self.layer(name) self.xpos = xpos self.ypos = ypos self.size = size self.xpos_pt = unit.topt(xpos) self.ypos_pt = unit.topt(ypos) self.size_pt = unit.topt(size) self.xscale = xscale self.yscale = yscale self.zscale = zscale self.projector = projector self.axesdist_pt = unit.topt(axesdist) self.key = key self.xorder = projector.zindex(0, -1, 0) > projector.zindex(0, 1, 0) and 1 or 0 self.yorder = projector.zindex(-1, 0, 0) > projector.zindex(1, 0, 0) and 1 or 0 self.zindexscale = math.sqrt(xscale*xscale+yscale*yscale+zscale*zscale) # the pXYshow attributes are booleans stating whether plane perpendicular to axis X # at the virtual graph coordinate Y will be hidden by data or not. An axis is considered # to be visible if one of the two planes it is part of is visible. Other axes are drawn # in the hiddenaxes layer (i.e. layer group). # TODO: Tick and grid visibility is treated like the axis visibility at the moment. self.pz0show = self.vangle(0, 0, 0, 1, 0, 0, 1, 1, 0) > 0 self.pz1show = self.vangle(0, 0, 1, 0, 1, 1, 1, 1, 1) > 0 self.py0show = self.vangle(0, 0, 0, 0, 0, 1, 1, 0, 1) > 0 self.py1show = self.vangle(0, 1, 0, 1, 1, 0, 1, 1, 1) > 0 self.px0show = self.vangle(0, 0, 0, 0, 1, 0, 0, 1, 1) > 0 self.px1show = self.vangle(1, 0, 0, 1, 0, 1, 1, 1, 1) > 0 for axisname, aaxis in axes.items(): if aaxis is not None: if not isinstance(aaxis, axis.linkedaxis): self.axes[axisname] = axis.anchoredaxis(aaxis, self.texrunner, axisname) else: self.axes[axisname] = aaxis for axisname in ["x", "y"]: okey = axisname + "2" if not axes.has_key(axisname): if not axes.has_key(okey) or axes[okey] is None: self.axes[axisname] = axis.anchoredaxis(axis.linear(), self.texrunner, axisname) if not axes.has_key(okey): self.axes[okey] = axis.linkedaxis(self.axes[axisname], okey) else: self.axes[axisname] = axis.linkedaxis(self.axes[okey], axisname) elif not axes.has_key(okey): self.axes[okey] = axis.linkedaxis(self.axes[axisname], okey) if not axes.has_key("z"): self.axes["z"] = axis.anchoredaxis(axis.linear(), self.texrunner, "z") if self.axes.has_key("x"): self.xbasepath = self.axes["x"].basepath self.xvbasepath = self.axes["x"].vbasepath self.xgridpath = self.axes["x"].gridpath self.xtickpoint_pt = self.axes["x"].tickpoint_pt self.xtickpoint = self.axes["x"].tickpoint self.xvtickpoint_pt = self.axes["x"].vtickpoint_pt self.xvtickpoint = self.axes["x"].tickpoint self.xtickdirection = self.axes["x"].tickdirection self.xvtickdirection = self.axes["x"].vtickdirection if self.axes.has_key("y"): self.ybasepath = self.axes["y"].basepath self.yvbasepath = self.axes["y"].vbasepath self.ygridpath = self.axes["y"].gridpath self.ytickpoint_pt = self.axes["y"].tickpoint_pt self.ytickpoint = self.axes["y"].tickpoint self.yvtickpoint_pt = self.axes["y"].vtickpoint_pt self.yvtickpoint = self.axes["y"].vtickpoint self.ytickdirection = self.axes["y"].tickdirection self.yvtickdirection = self.axes["y"].vtickdirection if self.axes.has_key("z"): self.zbasepath = self.axes["z"].basepath self.zvbasepath = self.axes["z"].vbasepath self.zgridpath = self.axes["z"].gridpath self.ztickpoint_pt = self.axes["z"].tickpoint_pt self.ztickpoint = self.axes["z"].tickpoint self.zvtickpoint_pt = self.axes["z"].vtickpoint self.zvtickpoint = self.axes["z"].vtickpoint self.ztickdirection = self.axes["z"].tickdirection self.zvtickdirection = self.axes["z"].vtickdirection self.axesnames = ([], [], []) for axisname, aaxis in self.axes.items(): if axisname[0] not in "xyz" or (len(axisname) != 1 and (not axisname[1:].isdigit() or axisname[1:] == "1")): raise ValueError("invalid axis name") if axisname[0] == "x": self.axesnames[0].append(axisname) elif axisname[0] == "y": self.axesnames[1].append(axisname) else: self.axesnames[2].append(axisname) aaxis.setcreatecall(self.doaxiscreate, axisname)
def __init__(self, xpos=0, ypos=0, size=None, xscale=1, yscale=1, zscale=1/goldenmean, projector=central(10, -30, 30), key=None, **axes): graph.__init__(self) self.xpos = xpos self.ypos = ypos self.size = size self.xpos_pt = unit.topt(xpos) self.ypos_pt = unit.topt(ypos) self.size_pt = unit.topt(size) self.xscale = xscale self.yscale = yscale self.zscale = zscale self.projector = projector self.key = key self.xorder = projector.zindex(0, -1, 0) > projector.zindex(0, 1, 0) and 1 or 0 self.yorder = projector.zindex(-1, 0, 0) > projector.zindex(1, 0, 0) and 1 or 0 self.zindexscale = math.sqrt(xscale*xscale+yscale*yscale+zscale*zscale) for axisname, aaxis in axes.items(): if aaxis is not None: if not isinstance(aaxis, axis.linkedaxis): self.axes[axisname] = axis.anchoredaxis(aaxis, self.texrunner, axisname) else: self.axes[axisname] = aaxis for axisname in ["x", "y"]: okey = axisname + "2" if not axes.has_key(axisname): if not axes.has_key(okey) or axes[okey] is None: self.axes[axisname] = axis.anchoredaxis(axis.linear(), self.texrunner, axisname) if not axes.has_key(okey): self.axes[okey] = axis.linkedaxis(self.axes[axisname], okey) else: self.axes[axisname] = axis.linkedaxis(self.axes[okey], axisname) if not axes.has_key("z"): self.axes["z"] = axis.anchoredaxis(axis.linear(), self.texrunner, axisname) if self.axes.has_key("x"): self.xbasepath = self.axes["x"].basepath self.xvbasepath = self.axes["x"].vbasepath self.xgridpath = self.axes["x"].gridpath self.xtickpoint_pt = self.axes["x"].tickpoint_pt self.xtickpoint = self.axes["x"].tickpoint self.xvtickpoint_pt = self.axes["x"].vtickpoint_pt self.xvtickpoint = self.axes["x"].tickpoint self.xtickdirection = self.axes["x"].tickdirection self.xvtickdirection = self.axes["x"].vtickdirection if self.axes.has_key("y"): self.ybasepath = self.axes["y"].basepath self.yvbasepath = self.axes["y"].vbasepath self.ygridpath = self.axes["y"].gridpath self.ytickpoint_pt = self.axes["y"].tickpoint_pt self.ytickpoint = self.axes["y"].tickpoint self.yvtickpoint_pt = self.axes["y"].vtickpoint_pt self.yvtickpoint = self.axes["y"].vtickpoint self.ytickdirection = self.axes["y"].tickdirection self.yvtickdirection = self.axes["y"].vtickdirection if self.axes.has_key("z"): self.zbasepath = self.axes["z"].basepath self.zvbasepath = self.axes["z"].vbasepath self.zgridpath = self.axes["z"].gridpath self.ztickpoint_pt = self.axes["z"].tickpoint_pt self.ztickpoint = self.axes["z"].tickpoint self.zvtickpoint_pt = self.axes["z"].vtickpoint self.zvtickpoint = self.axes["z"].vtickpoint self.ztickdirection = self.axes["z"].tickdirection self.zvtickdirection = self.axes["z"].vtickdirection self.axesnames = ([], [], []) for axisname, aaxis in self.axes.items(): if axisname[0] not in "xyz" or (len(axisname) != 1 and (not axisname[1:].isdigit() or axisname[1:] == "1")): raise ValueError("invalid axis name") if axisname[0] == "x": self.axesnames[0].append(axisname) elif axisname[0] == "y": self.axesnames[1].append(axisname) else: self.axesnames[2].append(axisname) aaxis.setcreatecall(self.doaxiscreate, axisname)