Changeset 3538:94908933263d in orange


Ignore:
Timestamp:
04/16/07 10:23:29 (7 years ago)
Author:
Gregor <Gregor@…>
Branch:
default
Convert:
6563d362dda8259287b2038ab8e6ea5f98d01519
Message:
  • added smooth zooming
File:
1 edited

Legend:

Unmodified
Added
Removed
  • orange/OrangeWidgets/OWGraph.py

    r3486 r3538  
    8484        self.connect(self, SIGNAL('plotMouseReleased(const QMouseEvent&)'),self.onMouseReleased) 
    8585        self.optimizedDrawing = 1 
    86         self.pointWidth = 5 
     86        self.pointWidth = 7 
    8787        self.showFilledSymbols = 1 
    8888        self.showLegend = 1 
     
    101101        self.discPalette = ColorPaletteGenerator() 
    102102##        self.currentScale = {} 
    103          
     103 
    104104        if parent: 
    105105            if type(parent) > OWBaseWidget: 
     
    111111    def __setattr__(self, name, value): 
    112112        unisetattr(self, name, value, QwtPlot) 
    113                                  
     113 
    114114    # call to update dictionary with settings 
    115115    def updateSettings(self, **settings): 
     
    134134            self.setAxisScaleDraw(axis, HiddenScaleDraw()) 
    135135            self.axisScaleDraw(axis).setTickLength(0, 0, 0) 
    136             self.axisScaleDraw(axis).setOptions(0)  
     136            self.axisScaleDraw(axis).setOptions(0) 
    137137        else: 
    138138            self.axisScaleDraw(axis).setTickLength(1, 1, 3) 
    139139            self.axisScaleDraw(axis).setOptions(1) 
    140              
     140 
    141141            if (labels <> None): 
    142142                self.setAxisScaleDraw(axis, DiscreteAxisScaleDraw(labels)) 
     
    150150                self.setAxisMaxMajor(axis, 10) 
    151151            self.updateToolTips() 
    152          
     152 
    153153    def setYLlabels(self, labels): 
    154154        "Sets the Y-axis labels on the left." 
    155155        self.setLabels(labels, QwtPlot.yLeft) 
    156          
     156 
    157157    def setYRlabels(self, labels): 
    158158        "Sets the Y-axis labels on the right." 
    159159        self.setLabels(labels, QwtPlot.yRight) 
    160          
     160 
    161161    def setXlabels(self, labels): 
    162162        "Sets the x-axis labels if x-axis discrete." 
    163163        "Or leave up to QwtPlot (MaxMajor, MaxMinor) if x-axis continuous." 
    164164        self.setLabels(labels, QwtPlot.xBottom) 
    165          
     165 
    166166    def enableXaxis(self, enable): 
    167167        self.enableAxis(QwtPlot.xBottom, enable) 
     
    201201    def paintEvent(self, qpe): 
    202202        """ 
    203         Paints the graph.  
     203        Paints the graph. 
    204204        Called whenever repaint is needed by the system 
    205205        or user explicitly calls repaint() 
    206206        """ 
    207         for key in self.selectionCurveKeyList:     # the selection curves must set new point array  
     207        for key in self.selectionCurveKeyList:     # the selection curves must set new point array 
    208208            self.curve(key).pointArrayValid = 0    # at any change in the graphics otherwise the right examples will not be selected 
    209              
     209 
    210210        QwtPlot.paintEvent(self, qpe) #let the ancestor do its job 
    211211        self.replot() 
    212   
     212 
    213213    def setShowMainTitle(self, b): 
    214214        self.showMainTitle = b 
     
    320320    def setCanvasColor(self, c): 
    321321        self.setCanvasBackground(c) 
    322         self.repaint()    
     322        self.repaint() 
    323323 
    324324    # ############################################################ 
     
    351351            if example.getclass().isSpecial(): text += "&nbsp;"*4 + "%s = ?<br>" % (data.domain.classVar.name) 
    352352            else:                              text += "&nbsp;"*4 + "%s = %s<br>" % (data.domain.classVar.name, str(example.getclass().value)) 
    353      
     353 
    354354        if len(self.rawdata.domain.getmetas()) != 0: 
    355355            text += "<hr><b>Meta attributes:</b><br>" 
     
    376376        if xData != [] and yData != []: 
    377377            self.setCurveData(newCurveKey, xData, yData) 
    378              
     378 
    379379        return newCurveKey 
    380380 
     
    399399    def showTip(self, x, y, text): 
    400400        MyQToolTip.tip(self.tooltip, QRect(x+self.canvas().frameGeometry().x()-3, y+self.canvas().frameGeometry().y()-3, 6, 6), text) 
    401         
     401 
    402402    # mouse was only pressed and released on the same spot. visualization methods might want to process this event 
    403403    def staticMouseClick(self, e): 
     
    423423                continue 
    424424            self.removeCurve(key) 
    425              
     425 
    426426    def removeLastSelection(self): 
    427427        if self.selectionCurveKeyList != []: 
     
    435435        else: 
    436436            return 0 
    437          
     437 
    438438    def removeAllSelections(self, send = 1): 
    439439        for key in self.selectionCurveKeyList: 
     
    446446    def zoomOut(self): 
    447447        if len(self.zoomStack): 
    448             (xmin, xmax, ymin, ymax) = self.zoomStack.pop() 
    449             self.setAxisScale(QwtPlot.xBottom, xmin, xmax) 
    450             self.setAxisScale(QwtPlot.yLeft, ymin, ymax) 
    451             self.replot() 
     448            newXMin, newXMax, newYMin, newYMax = self.zoomStack.pop() 
     449            self.setNewZoom(self.axisScale(QwtPlot.xBottom).lBound(), self.axisScale(QwtPlot.xBottom).hBound(), self.axisScale(QwtPlot.yLeft).lBound(), self.axisScale(QwtPlot.yLeft).hBound(), newXMin, newXMax, newYMin, newYMax) 
    452450            return 1 
    453451        return 0 
     452 
     453    def setNewZoom(self, currXMin, currXMax, currYMin, currYMax, newXMin, newXMax, newYMin, newYMax): 
     454        zoomOutCurveKey = self.insertCurve(PolygonCurve(self, brush = None, xData = [currXMin, currXMax, currXMax, currXMin, currXMin], yData = [currYMin, currYMin, currYMax, currYMax, currYMin])) 
     455        if len(self.curveKeys()) > 2000:    # if too many curves then don't be smooth 
     456            steps = 1 
     457        else: 
     458            steps = 10 
     459        for i in range(1, steps+1): 
     460            midXMin = currXMin * (steps-i)/float(steps) + newXMin * i/float(steps) 
     461            midXMax = currXMax * (steps-i)/float(steps) + newXMax * i/float(steps) 
     462            midYMin = currYMin * (steps-i)/float(steps) + newYMin * i/float(steps) 
     463            midYMax = currYMax * (steps-i)/float(steps) + newYMax * i/float(steps) 
     464            self.setAxisScale(QwtPlot.xBottom, midXMin, midXMax) 
     465            self.setAxisScale(QwtPlot.yLeft, midYMin, midYMax) 
     466            if i == steps: 
     467                self.removeCurve(zoomOutCurveKey) 
     468            self.replot() 
    454469 
    455470 
     
    505520            (text, x, y) = self.tips.maybeTip(xFloat, yFloat) 
    506521            if type(text) == int: text = self.buildTooltip(text) 
    507          
     522 
    508523        if self.statusBar != None: 
    509524            self.statusBar.message(text) 
     
    520535            self.tempSelectionCurve.replaceLastPoint(xFloat,yFloat) 
    521536            self.repaint() 
    522              
     537 
    523538        self.event(e) 
    524539 
     
    536551 
    537552        if e.button() == Qt.LeftButton: 
    538             if self.state == ZOOMING:             
     553            if self.state == ZOOMING: 
    539554                xmin = min(self.xpos, e.x());  xmax = max(self.xpos, e.x()) 
    540555                ymin = min(self.ypos, e.y());  ymax = max(self.ypos, e.y()) 
    541                  
     556 
    542557                if self.zoomKey: self.removeCurve(self.zoomKey) 
    543558                self.zoomKey = None 
     
    549564                xmin = self.invTransform(QwtPlot.xBottom, xmin);  xmax = self.invTransform(QwtPlot.xBottom, xmax) 
    550565                ymin = self.invTransform(QwtPlot.yLeft, ymin);    ymax = self.invTransform(QwtPlot.yLeft, ymax) 
    551                  
     566 
    552567                self.blankClick = 0 
    553568                self.zoomStack.append((self.axisScale(QwtPlot.xBottom).lBound(), self.axisScale(QwtPlot.xBottom).hBound(), self.axisScale(QwtPlot.yLeft).lBound(), self.axisScale(QwtPlot.yLeft).hBound())) 
    554                 self.setAxisScale(QwtPlot.xBottom, xmin, xmax) 
    555                 self.setAxisScale(QwtPlot.yLeft, ymin, ymax) 
    556                 self.replot() 
     569                self.setNewZoom(self.axisScale(QwtPlot.xBottom).lBound(), self.axisScale(QwtPlot.xBottom).hBound(), self.axisScale(QwtPlot.yLeft).lBound(), self.axisScale(QwtPlot.yLeft).hBound(), xmin, xmax, ymin, ymax) 
    557570 
    558571            elif self.state == SELECT_RECTANGLE: 
     
    566579                ok = self.zoomOut() 
    567580                if not ok: 
    568                     self.removeLastSelection()                 
     581                    self.removeLastSelection() 
    569582                    self.blankClick = 1 # we just clicked and released the button at the same position 
    570583                    return 
     
    580593                        self.tempSelectionCurve = None 
    581594                        self.removeLastSelection() 
    582                     else:   # set new last point  
     595                    else:   # set new last point 
    583596                        self.tempSelectionCurve.replaceLastPoint(self.invTransform(QwtPlot.xBottom, e.x()), self.invTransform(QwtPlot.yLeft, e.y())) 
    584597                    self.replot() 
     
    586599                    ok = self.removeLastSelection() 
    587600                    if not ok: self.zoomOut() 
    588                  
     601 
    589602        #self.replot() 
    590603        self.event(e) 
     
    637650 
    638651            curve.setData([x1, x1, x2, x2, x1], [y1, y2, y2, y1, y1]) 
    639                      
     652 
    640653 
    641654    # save graph in matplotlib python file 
     
    653666        linestyles = ["o", "-", "-.", "--", ":", "-", "-"]      # qwt line styles: NoCurve, Lines, Sticks, Steps, Dots, Spline, UserCurve 
    654667        markers = ["None", "o", "s", "^", "d", "v", "^", "<", ">", "x", "+"]    # curveSymbols = [None, Ellipse, Rect, Triangle, Diamond, DTriangle, UTriangle, LTriangle, RTriangle, XCross, Cross] 
    655      
     668 
    656669        f.write("#add curves\n") 
    657670        for key in self.curveKeys(): 
     
    660673            yData = [c.y(i) for i in range(c.dataSize())] 
    661674            marker = markers[c.symbol().style()] 
    662              
     675 
    663676            markersize = c.symbol().size().width() 
    664             markeredgecolor = self._getColorFromObject(c.symbol().pen())  
     677            markeredgecolor = self._getColorFromObject(c.symbol().pen()) 
    665678            markerfacecolor = self._getColorFromObject(c.symbol().brush()) 
    666679            color = self._getColorFromObject(c.pen()) 
    667680            colorB = self._getColorFromObject(c.brush()) 
    668681            linewidth = c.pen().width() 
    669             if c.__class__ == PolygonCurve and len(xData) == 4: 
     682            if c.__class__ == PolygonCurve: 
    670683                x0 = min(xData); x1 = max(xData); diffX = x1-x0 
    671684                y0 = min(yData); y1 = max(yData); diffY = y1-y0 
    672685                f.write("gca().add_patch(Rectangle((%f, %f), %f, %f, edgecolor=%s, facecolor = %s, linewidth = %d, fill = 1))\n" % (x0,y0,diffX, diffY, color, colorB, linewidth)) 
    673             elif c.style() < len(linestyles):  
     686            elif c.style() < len(linestyles): 
    674687                linestyle = linestyles[c.style()] 
    675688                f.write("plot(%s, %s, marker = '%s', linestyle = '%s', markersize = %d, markeredgecolor = %s, markerfacecolor = %s, color = %s, linewidth = %d)\n" % (xData, yData, marker, linestyle, markersize, markeredgecolor, markerfacecolor, color, linewidth)) 
    676              
     689 
    677690        f.write("\n# add markers\n") 
    678691        for key in self.markerKeys(): 
     
    711724 
    712725        f.write("\n# possible settings to change\n#axes().set_frame_on(0) #hide the frame\n#axis('off') #hide the axes and labels on them\n\n") 
    713          
    714          
     726 
     727 
    715728        if self.legend().itemCount() > 0: 
    716729            legendItems = [] 
     
    722735                else: 
    723736                    legendItems.append((text, markers[item.symbol().style()], self._getColorFromObject(item.symbol().pen()) , self._getColorFromObject(item.symbol().brush()))) 
    724             f.write("""  
     737            f.write(""" 
    725738#functions to show legend below the figure 
    726739def drawSomeLegendItems(x, items, itemsPerAxis = 1, yDiff = 0.0): 
     
    729742    legend(lines, [item[0] for item in items], 'upper center', handlelen = 0.1, numpoints = 1, prop = font_manager.FontProperties(size=11)) 
    730743    gca().get_legend().draw_frame(False) 
    731          
     744 
    732745def drawLegend(items): 
    733746    if not items: return 
     
    737750    itemsPerAxis = len(items) / len(xs) + (len(items) %% len(xs) != 0) 
    738751    if "extraLabelForClass" in dir(): drawSomeLegendItems(extraLabelForClass[0], extraLabelForClass[1], itemsPerAxis, yDiff = 0.004) 
    739          
     752 
    740753    for i, x in enumerate(xs): 
    741754        drawSomeLegendItems(x, items[i*itemsPerAxis: min(len(items), (i+1)*itemsPerAxis)], itemsPerAxis) 
     
    782795        self.parent = parent 
    783796 
    784         if rotation != 0: self.setLabel(label + "  ")         
     797        if rotation != 0: self.setLabel(label + "  ") 
    785798        else:             self.setLabel(label) 
    786799 
     
    790803    def draw(self, painter, x, y, rect): 
    791804        rot = math.radians(self.rotation) 
    792         
     805 
    793806        x2 = x * math.cos(rot) - y * math.sin(rot) 
    794807        y2 = x * math.sin(rot) + y * math.cos(rot) 
    795                  
     808 
    796809        painter.rotate(-self.rotation) 
    797810        QwtPlotMarker.draw(self, painter, x2, y2, rect) 
    798811        painter.rotate(self.rotation) 
    799              
     812 
Note: See TracChangeset for help on using the changeset viewer.