示例#1
0
    def writeSvg(self, fileName=None):
        if fileName is None:
            fileName = QtGui.QFileDialog.getSaveFileName()
        fileName = str(fileName)
        PlotItem.lastFileDir = os.path.dirname(fileName)

        self.svg = QtSvg.QSvgGenerator()
        self.svg.setFileName(fileName)
        res = 120.
        view = self.scene().views()[0]
        bounds = view.viewport().rect()
        bounds = QtCore.QRectF(0, 0, bounds.width(), bounds.height())

        self.svg.setResolution(res)
        self.svg.setViewBox(bounds)

        self.svg.setSize(QtCore.QSize(bounds.width(), bounds.height()))

        painter = QtGui.QPainter(self.svg)
        view.render(painter, bounds)

        painter.end()

        ## Workaround to set pen widths correctly
        import re
        data = open(fileName).readlines()
        for i in range(len(data)):
            line = data[i]
            m = re.match(
                r'(<g .*)stroke-width="1"(.*transform="matrix\(([^\)]+)\)".*)',
                line)
            if m is not None:
                #print "Matched group:", line
                g = m.groups()
                matrix = list(map(float, g[2].split(',')))
                #print "matrix:", matrix
                scale = max(abs(matrix[0]), abs(matrix[3]))
                if scale == 0 or scale == 1.0:
                    continue
                data[i] = g[0] + ' stroke-width="%0.2g" ' % (
                    1.0 / scale) + g[1] + '\n'
                #print "old line:", line
                #print "new line:", data[i]
        open(fileName, 'w').write(''.join(data))
示例#2
0
    def export(self, fileName=None):
        if fileName is None:
            self.fileSaveDialog(filter="Scalable Vector Graphics (*.svg)")
            return
        self.svg = QtSvg.QSvgGenerator()
        self.svg.setFileName(fileName)
        self.svg.setSize(QtCore.QSize(100,100))
        #self.svg.setResolution(600)
        #self.svg.setViewBox()
        targetRect = QtCore.QRect(0, 0, self.params['width'], self.params['height'])
        sourceRect = self.getSourceRect()
        painter = QtGui.QPainter(self.svg)
        try:
            self.setExportMode(True)
            self.render(painter, QtCore.QRectF(targetRect), sourceRect)
        finally:
            self.setExportMode(False)
        painter.end()

        ## Workaround to set pen widths correctly
        data = open(fileName).readlines()
        for i in range(len(data)):
            line = data[i]
            m = re.match(r'(<g .*)stroke-width="1"(.*transform="matrix\(([^\)]+)\)".*)', line)
            if m is not None:
                #print "Matched group:", line
                g = m.groups()
                matrix = map(float, g[2].split(','))
                #print "matrix:", matrix
                scale = max(abs(matrix[0]), abs(matrix[3]))
                if scale == 0 or scale == 1.0:
                    continue
                data[i] = g[0] + ' stroke-width="%0.2g" ' % (1.0/scale) + g[1] + '\n'
                #print "old line:", line
                #print "new line:", data[i]
        open(fileName, 'w').write(''.join(data))
示例#3
0
    def exportdata(self):

        self.dialog = QtGui.QFileDialog()
        self.dialog.setOption(QtGui.QFileDialog.ShowDirsOnly)
        self.dialog.setFileMode(QtGui.QFileDialog.DirectoryOnly)

        folder_name = self.dialog.getSaveFileName(self, "Save Directory")
        filepath = os.path.join(os.path.abspath(os.sep), folder_name)
        if not os.path.exists(filepath):
            makedirs(filepath)

        # arr = QtCore.QByteArray()
        # buf = QtCore.QBuffer(arr)
        # svg = QtSvg.QSvgGenerator()
        # svg.setOutputDevice(buf)
        # dpi = QtGui.QDesktopWidget().physicalDpiX()
        # svg.setResolution(dpi)

        svg = QtSvg.QSvgGenerator()
        svg.setFileName("hh")
        svg.setSize(QtCore.QSize(2000, 2000))
        svg.setViewBox(self.rect())
        svg.setTitle("SVG svg Example Drawing")
        svg.setDescription("An SVG drawing created by the SVG Generator ")

        p = QtGui.QPainter()
        p.begin(svg)
        try:
            self.render(p)
        finally:
            p.end()
        # gen.setViewBox(QtGui.QRect(0, 0, 200, 200));
        # gen.setTitle(tr("SVG Gen Example Drawing"));
        # gen.setDescription(tr("An SVG drawing created by the SVG Generator ""Example provided with Qt."));

        lambda_data = os.path.join(filepath, "Lambda_data.csv")
        with open(lambda_data, "w") as output:
            try:
                writer = csv.writer(output, lineterminator='\n')
                for val in np.array(glo_var.lambdas)[:, 1]:
                    writer.writerow([val])
            except:
                pass

        summary = os.path.join(filepath, "Summary.csv")
        with open(summary, "w") as output:
            try:
                writer = csv.writer(output,
                                    delimiter='\t',
                                    lineterminator='\n')
                writer.writerow(["alpha", glo_var.alpha])
                writer.writerow(["beta", glo_var.beta])
                writer.writerow(["l", glo_var.l])
                writer.writerow(["Phase", self.phas.pointer.region_aft])
            except:
                pass

        # for name, pitem in self.pltlist:
        # 	self.exportimg(pitem,os.path.join(filepath,name + ".svg"))
        # 	# self.exportimg(pitem,os.path.join(filepath,name + ".png"))

        currentanddensity = os.path.join(filepath, "Current & Density.csv")
        with open(currentanddensity, "w") as output:
            writer = csv.writer(output, delimiter='\t', lineterminator='\n')
            # combine alpha, beta    pre and post. Do it here to lessen the computation
            alpha_x_data = np.concatenate([
                np.array(self.jalph.alphas_pre),
                np.linspace(self.jalph.trans_point, 1, 2)
            ])
            alpha_j_data = np.concatenate(
                [self.jalph.j_l_values,
                 np.array([self.jalph.jpost] * 2)])
            alpha_rho_data = np.array(self.jalph.rho_avg_pre +
                                      self.jalph.rho_avg_post)

            beta_x_data = np.concatenate([
                np.array(self.jbet.betas_pre),
                np.linspace(self.jbet.trans_point, 1, 2)
            ])
            beta_j_data = np.concatenate(
                [self.jbet.j_r_values,
                 np.array([self.jbet.jpost] * 2)])
            beta_rho_data = np.array(self.jbet.rho_avg_pre +
                                     self.jbet.rho_avg_post)

            alpha_data = np.vstack(
                [alpha_x_data, alpha_j_data, alpha_rho_data])
            beta_data = np.vstack([beta_x_data, beta_j_data, beta_rho_data])

            writer.writerow([
                "alpha", "Current", "Average Density", '\t', '\t', "beta",
                "Current", "Average Density"
            ])
            for i in range(len(alpha_x_data)):
                writer.writerow(
                    list(alpha_data[:, i]) + [''] * 2 + list(beta_data[:, i]))
            writer.writerow('\n')
            writer.writerow(
                ['beta', glo_var.beta, '', '', '', 'alpha', glo_var.alpha, ''])
            writer.writerow([
                'transition point', self.jalph.trans_point, '', '', '',
                'transition point', self.jbet.trans_point, ''
            ])

        self.pdfgroup1 = ['Lambda_fig', 'Density_fig']
        self.pdfgroup2 = ['Current_alpha_fig', 'Current_beta_fig']

        for name, pitem in self.pltlist:
            # self.exportimg(pitem,os.path.join(filepath,name + ".png"))
            path = os.path.join(filepath, name + ".svg")
            #			if name == 'Current_alpha_fig':
            #				self.jalph.p3.setLabel('right',"\u2329\u03c1 \u232a",**glo_var.labelstyle)
            #				self.jalph.p3main.plotItem.legend.items=[]
            #				self.jalph.p3.plot(pen=self.jalph.jpen, name='J')
            #				self.jalph.p3.plot(pen=self.jalph.rho_dash, name='\u2329\u03c1 \u232a')

            #			elif name == 'Current_beta_fig':
            #				self.jbet.p4.setLabel('right',"\u2329\u03c1 \u232a",**glo_var.labelstyle)
            #				self.jbet.p4main.plotItem.legend.items=[]
            #				self.jbet.p4.plot(pen=self.jbet.jpen, name='J')
            #				self.jbet.p4.plot(pen=self.jbet.rho_dash, name='\u2329\u03c1 \u232a')
            self.exportimg(pitem, path)

            if name in self.pdfgroup1:
                self.makepdf(path, os.path.join(filepath, name + ".pdf"), 500,
                             260, 20, 240)
            elif name == 'Current_alpha_fig':
                self.makepdf(path, os.path.join(filepath, name + ".pdf"), 350,
                             280, 30, 230)
#				self.jalph.p3.setLabel('right',"\u2329 \u03c1 \u232a",**glo_var.labelstyle)
#				self.jalph.p3main.plotItem.legend.items=[]
#				self.jalph.p3.plot(pen=self.jalph.jpen, name='J')
#				self.jalph.p3.plot(pen=self.jalph.rho_dash, name='\u2329 \u03c1 \u232a')
            elif name == 'Current_beta_fig':
                self.makepdf(path, os.path.join(filepath, name + ".pdf"), 350,
                             280, 30, 230)


#				self.jbet.p4.setLabel('right',"\u2329 \u03c1 \u232a",**glo_var.labelstyle)
#				self.jbet.p4main.plotItem.legend.items=[]
#				self.jbet.p4.plot(pen=self.jbet.jpen, name='J')
#				self.jbet.p4.plot(pen=self.jbet.rho_dash, name='\u2329 \u03c1 \u232a')

            else:
                self.makepdf(path, os.path.join(filepath, name + ".pdf"), 410,
                             330, 10, 300)

            os.remove(path)
示例#4
0
def _generateItemSvg(item, nodes=None, root=None):
    ## This function is intended to work around some issues with Qt's SVG generator
    ## and SVG in general.
    ## 1) Qt SVG does not implement clipping paths. This is absurd.
    ##    The solution is to let Qt generate SVG for each item independently,
    ##    then glue them together manually with clipping.
    ##
    ##    The format Qt generates for all items looks like this:
    ##
    ##    <g>
    ##        <g transform="matrix(...)">
    ##            one or more of: <path/> or <polyline/> or <text/>
    ##        </g>
    ##        <g transform="matrix(...)">
    ##            one or more of: <path/> or <polyline/> or <text/>
    ##        </g>
    ##        . . .
    ##    </g>
    ##
    ## 2) There seems to be wide disagreement over whether path strokes
    ##    should be scaled anisotropically.
    ##      see: http://web.mit.edu/jonas/www/anisotropy/
    ##    Given that both inkscape and illustrator seem to prefer isotropic
    ##    scaling, we will optimize for those cases.
    ##
    ## 3) Qt generates paths using non-scaling-stroke from SVG 1.2, but
    ##    inkscape only supports 1.1.
    ##
    ##    Both 2 and 3 can be addressed by drawing all items in world coordinates.

    profiler = debug.Profiler()

    if nodes is None:  ## nodes maps all node IDs to their XML element.
        ## this allows us to ensure all elements receive unique names.
        nodes = {}

    if root is None:
        root = item

    ## Skip hidden items
    if hasattr(item, 'isVisible') and not item.isVisible():
        return None

    ## If this item defines its own SVG generator, use that.
    if hasattr(item, 'generateSvg'):
        return item.generateSvg(nodes)

    ## Generate SVG text for just this item (exclude its children; we'll handle them later)
    tr = QtGui.QTransform()
    if isinstance(item, QtGui.QGraphicsScene):
        xmlStr = "<g>\n</g>\n"
        doc = xml.parseString(xmlStr)
        childs = [i for i in item.items() if i.parentItem() is None]
    elif item.__class__.paint == QtGui.QGraphicsItem.paint:
        xmlStr = "<g>\n</g>\n"
        doc = xml.parseString(xmlStr)
        childs = item.childItems()
    else:
        childs = item.childItems()
        tr = itemTransform(item, item.scene())

        ## offset to corner of root item
        if isinstance(root, QtGui.QGraphicsScene):
            rootPos = QtCore.QPoint(0, 0)
        else:
            rootPos = root.scenePos()
        tr2 = QtGui.QTransform()
        tr2.translate(-rootPos.x(), -rootPos.y())
        tr = tr * tr2

        arr = QtCore.QByteArray()
        buf = QtCore.QBuffer(arr)
        svg = QtSvg.QSvgGenerator()
        svg.setOutputDevice(buf)
        dpi = QtGui.QDesktopWidget().logicalDpiX()
        svg.setResolution(dpi)

        p = QtGui.QPainter()
        p.begin(svg)
        if hasattr(item, 'setExportMode'):
            item.setExportMode(True, {'painter': p})
        try:
            p.setTransform(tr)
            item.paint(p, QtGui.QStyleOptionGraphicsItem(), None)
        finally:
            p.end()
            ## Can't do this here--we need to wait until all children have painted as well.
            ## this is taken care of in generateSvg instead.
            #if hasattr(item, 'setExportMode'):
            #item.setExportMode(False)

        if USE_PYSIDE:
            xmlStr = str(arr)
        else:
            xmlStr = bytes(arr).decode('utf-8')
        doc = xml.parseString(xmlStr.encode('utf-8'))

    try:
        ## Get top-level group for this item
        g1 = doc.getElementsByTagName('g')[0]
        ## get list of sub-groups
        g2 = [
            n for n in g1.childNodes
            if isinstance(n, xml.Element) and n.tagName == 'g'
        ]

        defs = doc.getElementsByTagName('defs')
        if len(defs) > 0:
            defs = [
                n for n in defs[0].childNodes if isinstance(n, xml.Element)
            ]
    except:
        print(doc.toxml())
        raise

    profiler('render')

    ## Get rid of group transformation matrices by applying
    ## transformation to inner coordinates
    correctCoordinates(g1, defs, item)
    profiler('correct')
    ## make sure g1 has the transformation matrix
    #m = (tr.m11(), tr.m12(), tr.m21(), tr.m22(), tr.m31(), tr.m32())
    #g1.setAttribute('transform', "matrix(%f,%f,%f,%f,%f,%f)" % m)

    #print "=================",item,"====================="
    #print g1.toprettyxml(indent="  ", newl='')

    ## Inkscape does not support non-scaling-stroke (this is SVG 1.2, inkscape supports 1.1)
    ## So we need to correct anything attempting to use this.
    #correctStroke(g1, item, root)

    ## decide on a name for this item
    baseName = item.__class__.__name__
    i = 1
    while True:
        name = baseName + "_%d" % i
        if name not in nodes:
            break
        i += 1
    nodes[name] = g1
    g1.setAttribute('id', name)

    ## If this item clips its children, we need to take care of that.
    childGroup = g1  ## add children directly to this node unless we are clipping
    if not isinstance(item, QtGui.QGraphicsScene):
        ## See if this item clips its children
        if int(item.flags() & item.ItemClipsChildrenToShape) > 0:
            ## Generate svg for just the path
            #if isinstance(root, QtGui.QGraphicsScene):
            #path = QtGui.QGraphicsPathItem(item.mapToScene(item.shape()))
            #else:
            #path = QtGui.QGraphicsPathItem(root.mapToParent(item.mapToItem(root, item.shape())))
            path = QtGui.QGraphicsPathItem(item.mapToScene(item.shape()))
            item.scene().addItem(path)
            try:
                #pathNode = _generateItemSvg(path, root=root).getElementsByTagName('path')[0]
                pathNode = _generateItemSvg(
                    path, root=root)[0].getElementsByTagName('path')[0]
                # assume <defs> for this path is empty.. possibly problematic.
            finally:
                item.scene().removeItem(path)

            ## and for the clipPath element
            clip = name + '_clip'
            clipNode = g1.ownerDocument.createElement('clipPath')
            clipNode.setAttribute('id', clip)
            clipNode.appendChild(pathNode)
            g1.appendChild(clipNode)

            childGroup = g1.ownerDocument.createElement('g')
            childGroup.setAttribute('clip-path', 'url(#%s)' % clip)
            g1.appendChild(childGroup)
    profiler('clipping')

    ## Add all child items as sub-elements.
    childs.sort(key=lambda c: c.zValue())
    for ch in childs:
        csvg = _generateItemSvg(ch, nodes, root)
        if csvg is None:
            continue
        cg, cdefs = csvg
        childGroup.appendChild(
            cg
        )  ### this isn't quite right--some items draw below their parent (good enough for now)
        defs.extend(cdefs)

    profiler('children')
    return g1, defs