Changeset 6d05e1d in sasview for src/sas/qtgui/Plotter2D.py


Ignore:
Timestamp:
Dec 6, 2016 5:39:24 AM (7 years ago)
Author:
Piotr Rozyczko <rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
55d89f8
Parents:
b94889a
git-author:
Piotr Rozyczko <rozyczko@…> (12/06/16 05:38:55)
git-committer:
Piotr Rozyczko <rozyczko@…> (12/06/16 05:39:24)
Message:

More functionality for quick plots + unit tests

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Plotter2D.py

    ref01be4 r6d05e1d  
    1 import logging 
    21import copy 
    32import numpy 
     
    65from PyQt4 import QtGui 
    76 
    8 # TODO: Replace the qt4agg calls below with qt5 equivalent. 
    9 # Requires some code modifications. 
    10 # https://www.boxcontrol.net/embedding-matplotlib-plot-on-pyqt5-gui.html 
    11 # 
    12 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas 
    13 from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar 
    14 import matplotlib.pyplot as plt 
    15  
    167DEFAULT_CMAP = pylab.cm.jet 
    178 
    189import sas.qtgui.PlotUtilities as PlotUtilities 
    19 import sas.qtgui.PlotHelper as PlotHelper 
    2010from sas.qtgui.PlotterBase import PlotterBase 
    2111 
     
    4131        self.zmax=data.zmax 
    4232        self.label=data.name 
    43         self.xLabel(xlabel="%s(%s)"%(data._xaxis, data._xunit)) 
    44         self.yLabel(ylabel="%s(%s)"%(data._yaxis, data._yunit)) 
     33        self.dimension=2 
     34        self.xLabel="%s(%s)"%(data._xaxis, data._xunit) 
     35        self.yLabel="%s(%s)"%(data._yaxis, data._yunit) 
    4536        self.title(title=data.title) 
    4637 
     
    5748        # Title only for regular charts 
    5849        if not self.quickplot: 
    59             ax.set_title(label=self.title) 
     50            ax.set_title(label=self._title) 
    6051 
    6152        # Re-adjust colorbar 
     
    7566        cb = self.figure.colorbar(im, cax=cbax) 
    7667        cb.update_bruteforce(im) 
    77         cb.set_label('$' + self._scale + '$') 
     68        cb.set_label('$' + self.scale + '$') 
    7869 
    7970        # Schedule the draw for the next time the event loop is idle. 
    8071        self.canvas.draw_idle() 
     72 
     73    def contextMenuQuickPlot(self): 
     74        """ 
     75        Define context menu and associated actions for the quickplot MPL widget 
     76        """ 
     77        # Actions 
     78        self.contextMenu = QtGui.QMenu(self) 
     79        self.actionSaveImage = self.contextMenu.addAction("Save Image") 
     80        self.actionPrintImage = self.contextMenu.addAction("Print Image") 
     81        self.actionCopyToClipboard = self.contextMenu.addAction("Copy to Clipboard") 
     82        self.contextMenu.addSeparator() 
     83        self.actionToggleGrid = self.contextMenu.addAction("Toggle Grid On/Off") 
     84        self.contextMenu.addSeparator() 
     85        self.actionChangeScale = self.contextMenu.addAction("Toggle Linear/Log Scale") 
     86 
     87        # Define the callbacks 
     88        self.actionSaveImage.triggered.connect(self.onImageSave) 
     89        self.actionPrintImage.triggered.connect(self.onImagePrint) 
     90        self.actionCopyToClipboard.triggered.connect(self.onClipboardCopy) 
     91        self.actionToggleGrid.triggered.connect(self.onGridToggle) 
     92        self.actionChangeScale.triggered.connect(self.onToggleScale) 
     93 
     94    def onToggleScale(self, event): 
     95        """ 
     96        Toggle axis and replot image 
     97 
     98        """ 
     99        zmin_2D_temp = self.zmin 
     100        zmax_2D_temp = self.zmax 
     101        if self.scale == 'log_{10}': 
     102            self.scale = 'linear' 
     103            if not self.zmin is None: 
     104                zmin_2D_temp = math.pow(10, self.zmin) 
     105            if not self.zmax is None: 
     106                zmax_2D_temp = math.pow(10, self.zmax) 
     107        else: 
     108            self.scale = 'log_{10}' 
     109            if not self.zmin is None: 
     110                # min log value: no log(negative) 
     111                if self.zmin <= 0: 
     112                    zmin_2D_temp = -32 
     113                else: 
     114                    zmin_2D_temp = math.log10(self.zmin) 
     115            if not self.zmax is None: 
     116                zmax_2D_temp = math.log10(self.zmax) 
     117 
     118        self.image(data=self.data.data, qx_data=self.qx_data, 
     119                   qy_data=self.qy_data, xmin=self.xmin, 
     120                   xmax=self.xmax, 
     121                   ymin=self.ymin, ymax=self.ymax, 
     122                   cmap=self.cmap, zmin=zmin_2D_temp, 
     123                   zmax=zmax_2D_temp) 
     124 
     125 
     126    def image(self, data, qx_data, qy_data, xmin, xmax, ymin, ymax, 
     127              zmin, zmax, color=0, symbol=0, markersize=0, 
     128              label='data2D', cmap=DEFAULT_CMAP): 
     129        """ 
     130        Render the current data 
     131 
     132        """ 
     133        #self.data = data 
     134        self.qx_data = qx_data 
     135        self.qy_data = qy_data 
     136        self.xmin = xmin 
     137        self.xmax = xmax 
     138        self.ymin = ymin 
     139        self.ymax = ymax 
     140        self.zmin = zmin 
     141        self.zmax = zmax 
     142        #c = self.color(color) 
     143        # If we don't have any data, skip. 
     144        if data == None: 
     145            return 
     146        if data.ndim == 1: 
     147            #output = self._build_matrix() 
     148            output = PlotUtilities.build_matrix(data, self.qx_data, self.qy_data) 
     149        else: 
     150            output = copy.deepcopy(data) 
     151 
     152        zmin_temp = self.zmin 
     153        # check scale 
     154        if self.scale == 'log_{10}': 
     155            try: 
     156                if  self.zmin <= 0  and len(output[output > 0]) > 0: 
     157                    zmin_temp = self.zmin_2D 
     158                    output[output > 0] = numpy.log10(output[output > 0]) 
     159                    #In log scale Negative values are not correct in general 
     160                    #output[output<=0] = math.log(numpy.min(output[output>0])) 
     161                elif self.zmin <= 0: 
     162                    zmin_temp = self.zmin 
     163                    output[output > 0] = numpy.zeros(len(output)) 
     164                    output[output <= 0] = -32 
     165                else: 
     166                    zmin_temp = self.zmin 
     167                    output[output > 0] = numpy.log10(output[output > 0]) 
     168                    #In log scale Negative values are not correct in general 
     169                    #output[output<=0] = math.log(numpy.min(output[output>0])) 
     170            except: 
     171                #Too many problems in 2D plot with scale 
     172                output[output > 0] = numpy.log10(output[output > 0]) 
     173                pass 
     174 
     175        self.cmap = cmap 
     176        if self.dimension != 3: 
     177            #Re-adjust colorbar 
     178            self.figure.subplots_adjust(left=0.2, right=.8, bottom=.2) 
     179 
     180            im = self.ax.imshow(output, interpolation='nearest', 
     181                                origin='lower', 
     182                                vmin=zmin_temp, vmax=self.zmax, 
     183                                cmap=self.cmap, 
     184                                extent=(self.xmin, self.xmax, 
     185                                        self.ymin, self.ymax)) 
     186 
     187            cbax = self.figure.add_axes([0.84, 0.2, 0.02, 0.7]) 
     188        else: 
     189            # clear the previous 2D from memory 
     190            # mpl is not clf, so we do 
     191            self.figure.clear() 
     192 
     193            self.figure.subplots_adjust(left=0.1, right=.8, bottom=.1) 
     194 
     195            X = self.x_bins[0:-1] 
     196            Y = self.y_bins[0:-1] 
     197            X, Y = numpy.meshgrid(X, Y) 
     198 
     199            try: 
     200                # mpl >= 1.0.0 
     201                ax = self.figure.gca(projection='3d') 
     202                #ax.disable_mouse_rotation() 
     203                cbax = self.figure.add_axes([0.84, 0.1, 0.02, 0.8]) 
     204                if len(X) > 60: 
     205                    ax.disable_mouse_rotation() 
     206            except: 
     207                # mpl < 1.0.0 
     208                try: 
     209                    from mpl_toolkits.mplot3d import Axes3D 
     210                except: 
     211                    logging.error("PlotPanel could not import Axes3D") 
     212                self.figure.clear() 
     213                ax = Axes3D(self.figure) 
     214                if len(X) > 60: 
     215                    ax.cla() 
     216                cbax = None 
     217            self.figure.canvas.resizing = False 
     218            im = ax.plot_surface(X, Y, output, rstride=1, cstride=1, cmap=cmap, 
     219                                 linewidth=0, antialiased=False) 
     220            self.set_axis_off() 
     221 
     222        if cbax == None: 
     223            ax.set_frame_on(False) 
     224            cb = self.figure.colorbar(im, shrink=0.8, aspect=20) 
     225        else: 
     226            cb = self.figure.colorbar(im, cax=cbax) 
     227        cb.update_bruteforce(im) 
     228        cb.set_label('$' + self.scale + '$') 
     229        if self.dimension != 3: 
     230            self.figure.canvas.draw_idle() 
     231        else: 
     232            self.figure.canvas.draw() 
Note: See TracChangeset for help on using the changeset viewer.