コード例 #1
0
    def __init__(self, x, y, text=None, bbox=None):
        PlotInfo.__init__(self, "label")

        self.x = x
        """
        The label's x coordinate
        """

        self.y = y
        """
        The label's y coordinate
        """

        self.text = text
        """
        The text that should be displayed with the label
        """

        self.textX = x

        self.textY = y

        self.arrow = None

        self._marker = Marker()

        self._labelProperties = LabelProperties()

        if bbox:
            self.bbox = dict(bbox)
        else:
            self.bbox = None
コード例 #2
0
 def setMapStyle(self):
     layers = self.iface.legendInterface().layers()
     self.scrc = SymbolCategoryRenderClass(
         self.makeokdict(self.getTabs(csv=True)))
     self.labProp = LabelProperties(self.okdict)
     for layer in layers:
         layerType = layer.type()
         if layerType == QgsMapLayer.VectorLayer:
             node = len(layers)
             if layer.name() == u'LAYER3-polygon':
                 self.reorderLayers(layer, node)
             if layer.name() == u'LAYER7-polygon':
                 self.reorderLayers(layer, node - 1)
             if layer.name() == u'LAYER12-polygon':
                 self.reorderLayers(layer, node - 2)
             if layer.name() == u'LAYER19-polygon':
                 self.reorderLayers(layer, node - 3)
             if layer.name() == u'LAYER17-label':
                 self.labProp.makeLabels(layer)
             self.scrc.CategoryRender(self.style, layer)
         layer.triggerRepaint()
コード例 #3
0
ファイル: Plot.py プロジェクト: sivasankariit/boomslang
    def __init__(self):
        self.plots = []

        self.title = None
        """
        The plot's title (will be centered above the axes themselves)
        """

        self.xFormatter = None
        self.yFormatter = None

        self.yLabel = None
        """
        The label for the plot's y-axis
        """

        self.xLabel = None
        """
        The label for the plot's x-axis
        """

        self._xLabelProperties = LabelProperties()
        self._yLabelProperties = LabelProperties()

        self.legend = None

        self._xLimits = None
        self._yLimits = None

        self.twinxLabel = None
        self.twinxIndex = -1
        self.twinxLimits = None

        self.lineStyles = None
        self.lineColors = None
        self.markers = None

        self.width = None

        self.height = None

        self.dpi = 100

        self.plotParams = None

        self.logx = False
        """
        If true, this plot's x-axis will be drawn in log scale.
        """

        self.logy = False
        """
        If true, this plot's y-axis will be drawn in log scale.
        """

        self.loglog = False
        """
        If true, both this plot's axes will be drawn in log scale.
        """

        self.logbase = 10
        """
        The base of the logarithm used to draw log scale axes.
        """

        self.logbasex = None
        """
        The base of the logarithm used to draw the x-axis. Overrides `logbase`,
        and only takes effect if logx or loglog are True.
        """

        self.logbasey = None
        """
        The base of the logarithm used to draw the y-axis. Overrides `logbase`,
        and only takes effect if logy or loglog are True.
        """

        self._grid = Grid()
        self._grid.visible = False

        self.insets = []

        self.hideTicks = False
        """
        If True, this plot's tick labels are hidden.
        """

        self.titleSize = None
        """
        The size of the text used for plot title.
        """

        self.latex = False

        self.axesLabelSize = None
        """
        The size of the text used for labeling the x and y axes.
        """

        self.xTickLabelSize = None
        """
        The size of the text used for x-axis tick labels
        """

        self.yTickLabelSize = None
        """
        The size of the text used for y-axis tick labels
        """

        self.titleProperties = LabelProperties()

        self.tight = False
        """
        If True, this plot is auto-scaled so that axis labels don't get cut off.
        """

        self.allows_tight = True

        self.projection = None
        """
コード例 #4
0
ファイル: Plot.py プロジェクト: sivasankariit/boomslang
class Plot(object):
    """
    Represents a single plot, usually consisting of a single X and Y axis.
    """

    def __init__(self):
        self.plots = []

        self.title = None
        """
        The plot's title (will be centered above the axes themselves)
        """

        self.xFormatter = None
        self.yFormatter = None

        self.yLabel = None
        """
        The label for the plot's y-axis
        """

        self.xLabel = None
        """
        The label for the plot's x-axis
        """

        self._xLabelProperties = LabelProperties()
        self._yLabelProperties = LabelProperties()

        self.legend = None

        self._xLimits = None
        self._yLimits = None

        self.twinxLabel = None
        self.twinxIndex = -1
        self.twinxLimits = None

        self.lineStyles = None
        self.lineColors = None
        self.markers = None

        self.width = None

        self.height = None

        self.dpi = 100

        self.plotParams = None

        self.logx = False
        """
        If true, this plot's x-axis will be drawn in log scale.
        """

        self.logy = False
        """
        If true, this plot's y-axis will be drawn in log scale.
        """

        self.loglog = False
        """
        If true, both this plot's axes will be drawn in log scale.
        """

        self.logbase = 10
        """
        The base of the logarithm used to draw log scale axes.
        """

        self.logbasex = None
        """
        The base of the logarithm used to draw the x-axis. Overrides `logbase`,
        and only takes effect if logx or loglog are True.
        """

        self.logbasey = None
        """
        The base of the logarithm used to draw the y-axis. Overrides `logbase`,
        and only takes effect if logy or loglog are True.
        """

        self._grid = Grid()
        self._grid.visible = False

        self.insets = []

        self.hideTicks = False
        """
        If True, this plot's tick labels are hidden.
        """

        self.titleSize = None
        """
        The size of the text used for plot title.
        """

        self.latex = False

        self.axesLabelSize = None
        """
        The size of the text used for labeling the x and y axes.
        """

        self.xTickLabelSize = None
        """
        The size of the text used for x-axis tick labels
        """

        self.yTickLabelSize = None
        """
        The size of the text used for y-axis tick labels
        """

        self.titleProperties = LabelProperties()

        self.tight = False
        """
        If True, this plot is auto-scaled so that axis labels don't get cut off.
        """

        self.allows_tight = True

        self.projection = None
        """
        Defines the projection used when drawing this plot. The only currently
        supported value other than the standard (no projection) is 'polar'.
        """

    @property
    def xLabelProperties(self):
        """
        A dictionary of properties that control the appearance of the X axis'
        axis label. See :ref:`styling-labels` for more information on which
        properties can be set.
        """
        return self._xLabelProperties

    @xLabelProperties.setter
    def xLabelProperties(self, propsobj):
        self._xLabelProperties.update(propsobj)

    @property
    def yLabelProperties(self):
        """
        A dictionary of properties that control the appearance of the Y axis'
        axis label. See :ref:`styling-labels` for more information on which
        properties can be set.
        """
        return self._yLabelProperties

    @yLabelProperties.setter
    def yLabelProperties(self, propsobj):
        self._yLabelProperties.update(propsobj)

    @property
    def xLimits(self):
        """
        A pair giving the minimum and maximum values visible on the x-axis.
        """
        return self._xLimits

    @xLimits.setter
    def xLimits(self, value):
        if type(value) not in [tuple, list] or len(value) != 2:
            raise AttributeError("xLimits must be set to a (min, max) tuple")

        self._xLimits = tuple(value)

    @property
    def yLimits(self):
        """
        A pair giving the minimum and maximum values visible on the x-axis.
        """
        return self._yLimits

    @yLimits.setter
    def yLimits(self, value):
        if type(value) not in [tuple, list] or len(value) != 2:
            raise AttributeError("yLimits must be set to a (min, max) tuple")

        self._yLimits = value

    @property
    def legendLabelSize(self):
        """
        The size of the text in this plot's legend.
        """

        return self.legend.labelSize

    @legendLabelSize.setter
    def legendLabelSize(self, size):
        self.setLegendLabelSize(size)

    @property
    def grid(self):
        """
        A boomslang.Grid.Grid that defines the properties of this plot's grid
        lines. See :ref:`plots-grid-lines` for configuration options.
        """
        return self._grid

    @grid.setter
    def grid(self, value):
        if isinstance(value, bool) and value == True:
            self._grid.visible = True
        else:
            raise AttributeError("Plot.grid cannot be re-assigned")

    def setTitleProperties(self, **propList):
        """
        Set the properties of the title. See :ref:`styling-labels` for more
        information about valid properties.
        """
        self.__setProperties(self.titleProperties, propList)

    def __setProperties(self, propsDict, propList):
        for (key, val) in propList.items():
            propsDict[key] = val

    def __str__(self):
        return str(self.__dict__)

    def setTitleSize(self, size):
        self.titleSize = size

    def setAxesLabelSize(self, size):
        self.axesLabelSize = size

    def setXTickLabelSize(self, size):
        self.xTickLabelSize = size

    def setYTickLabelSize(self, size):
        self.yTickLabelSize = size

    def setLegendLabelSize(self, size):
        if self.legend is None:
            self.legend = Legend()

        self.legend.labelSize = size

    def split(self, pieces):
        """
        Split this plot into `pieces` separate plots, each showing a different
        portion of the x-axis
        """

        splitPlots = [copy.deepcopy(self) for i in xrange(pieces)]

        for plot in splitPlots:
            plot.plots = []

        for plot in self.plots:
            elements = plot.split(pieces)
            for i in xrange(pieces):
                splitPlots[i].add(elements[i])
                splitPlots[i].setXLimits(min(elements[i].xValues), max(elements[i].xValues))
        return splitPlots

    def getDimensions(self):
        """
        Get the dimensions of this plot.
        """
        if self.width is None:
            (self.width, self.height) = getGoldenRatioDimensions(8.0)
        elif self.height is None:
            (goldWidth, goldHeight) = getGoldenRatioDimensions(self.width)
            self.height = goldHeight
        return (self.width, self.height)

    def hideTickLabels(self):
        self.hideTicks = True

    def setDimensions(self, width=None, height=None, dpi=100):
        """
        Set the dimensions for this plot to `width` x `height`
        """
        self.width = width
        self.height = height
        self.dpi = dpi

    def add(self, plottableObject):
        """
        Add a plottable object (a Line, Bar, etc.) to this plot, causing it to
        be drawn when the plot is drawn.
        """

        if not issubclass(plottableObject.__class__, PlotInfo):
            raise BoomslangPlotConfigurationException("All objects added to a Plot must be a subclass of PlotInfo")

        self.plots.append(plottableObject)

    def addInset(self, plot, **kwargs):
        """
        Add `plot` (a Plot object) as an inset to this plot object.

        Valid arguments are as follows:

        ============  ====================================================================================================================
        Argument      Description
        ============  ====================================================================================================================
        ``width``     The width of the inset as a fraction of the size of the parent plot
        ``height``    The height of the inset as a fraction of the size of the parent plot
        ``location``  The location of the inset. See :ref:`plots-locations` for valid locations.
        ``padding``   The amount of padding between the edge of the parent plot and the inset as a fraction of the size of the parent plot
        ============  ====================================================================================================================
        """
        inset = Inset(plot, **kwargs)
        self.insets.append(inset)

    def addLineStyle(self, style):
        """
        Add a line style to the list of line styles through which the plot will
        cycle when drawing lines. If no line styles are specified, the plot
        will default to the line style specified in the Line objects
        themselves.

        Note that, when drawing lines, all line styles for a given color are
        cycled through before another color is used.
        """
        if self.lineStyles is None:
            self.lineStyles = []

        currStyle = LineStyle()
        currStyle.style = style
        self.lineStyles.append(currStyle)

    def addLineColor(self, color):
        """
        Add a line color to the list of line colors through which the plot will
        cycle when drawing lines. If no line colors are specified, the line
        colors specified by the Line objects themselves will be used.

        Note that, when drawing lines, all line styles for a given color are
        cycled through before another color is used.
        """
        if self.lineColors is None:
            self.lineColors = []
        self.lineColors.append(color)

    def addMarker(self, marker):
        """
        Add a marker style to the list of marker styles through which the plot
        will cycle when drawing lines. If no markers are specified, the markers
        specified by the Line objects themselves will be used.

        Note that, when drawing lines, all line style/color combinations are
        cycled through with a given marker before a new marker is chosen.
        """
        if self.markers is None:
            self.markers = []

        currMarker = Marker()
        currMarker.marker = marker
        self.markers.append(currMarker)

    def getNumPlots(self):
        # Get the number of plottable objects currently registered for this
        # plot.
        return len(self.plots)

    def setTwinX(self, label, index, yMin=None, yMax=None):
        """
        Make the plot use a secondary y-axis with the provided label. All
        registered plottable objects at or after the given index will use this
        second axis.
        """
        self.twinxLabel = label
        self.twinxIndex = index

        if yMin is not None and yMax is not None:
            self.twinxLimits = (yMin, yMax)

    def setYFormatter(self, formatter):
        """
        Set the y-axis formatter used by this plot to the given function.
        """
        self.yFormatter = pylab.FuncFormatter(formatter)

    def setXFormatter(self, formatter):
        """
        Set the x-axis formatter used by this plot to the given function.
        """
        self.xFormatter = pylab.FuncFormatter(formatter)

    def setXLabel(self, xLabel):
        self.xLabel = xLabel

    def setYLabel(self, yLabel):
        self.yLabel = yLabel

    def setXLimits(self, minX, maxX):
        self.xLimits = (minX, maxX)

    def setYLimits(self, minY, maxY):
        self.yLimits = (minY, maxY)

    def hasFigLegend(
        self,
        columns=1,
        location="best",
        scatterPoints=3,
        draw_frame=True,
        bbox_to_anchor=None,
        labelSize=None,
        title=None,
        labelOrdering=None,
        leftToRight=False,
    ):
        """
        Declare that the figure has a legend with a given number of columns and
        location.
        """
        self.legend = Legend(
            columns=columns,
            scatterPoints=scatterPoints,
            drawFrame=draw_frame,
            location=location,
            figLegend=True,
            labelSize=labelSize,
            bboxToAnchor=bbox_to_anchor,
            title=title,
            labelOrdering=labelOrdering,
            leftToRight=leftToRight,
        )

    def hasLegend(
        self,
        columns=1,
        location="best",
        scatterPoints=3,
        draw_frame=True,
        bbox_to_anchor=None,
        labelSize=None,
        title=None,
        labelOrdering=None,
        leftToRight=False,
    ):
        """
        Declare that the plot has a legend with a given number of columns and
        location.
        """
        self.legend = Legend(
            columns=columns,
            scatterPoints=scatterPoints,
            drawFrame=draw_frame,
            location=location,
            figLegend=False,
            labelSize=labelSize,
            bboxToAnchor=bbox_to_anchor,
            title=title,
            labelOrdering=labelOrdering,
            leftToRight=leftToRight,
        )

    def setTitle(self, title):
        self.title = title

    def __cmp__(self, other):
        if not isinstance(other, Plot):
            raise ValueError("Can't compare a Plot with a non-Plot")

        return cmp(self.title, other.title)

    def __setupLayout(self):
        layout = PlotLayout()
        (width, height) = self.getDimensions()

        layout.setPlotDimensions(width, height, dpi=self.dpi)

        if self.plotParams is not None:
            layout.setPlotParameters(**self.plotParams)

        if self.titleSize is not None:
            layout.setTitleSize(self.titleSize)

        if self.latex == True:
            layout.useLatexLabels()

        if self.axesLabelSize is not None:
            layout.setAxesLabelSize(self.axesLabelSize)

        if self.xTickLabelSize is not None:
            layout.setXTickLabelSize(self.xTickLabelSize)

        if self.yTickLabelSize is not None:
            layout.setYTickLabelSize(self.yTickLabelSize)

        layout.addPlot(self)
        return layout

    def useLatexLabels(self):
        self.latex = True

    def plot(self):
        """
        Draw this plot to a matplotlib canvas.
        """
        layout = self.__setupLayout()
        layout.plot()

    def plot_fig(self):
        layout = self.__setupLayout()
        return layout._doPlot()

    def setPlotParameters(self, **kwdict):
        """
        Set the margins of this plot. See `matplotlib's SubplotParams documentation <http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.SubplotParams>`_ for more details. It is recommended that you set :py:attr:`boomslang.Plot.Plot.tight` to True instead of setting these parameters.
        """
        self.plotParams = dict(kwdict)

        if "left" not in self.plotParams:
            self.plotParams["left"] = 0.12

        if "bottom" not in self.plotParams:
            self.plotParams["bottom"] = 0.10

        if "right" not in self.plotParams:
            self.plotParams["right"] = 0.90

        if "top" not in self.plotParams:
            self.plotParams["top"] = 0.90

        if "wspace" not in self.plotParams:
            self.plotParams["wspace"] = 0.20

        if "hspace" not in self.plotParams:
            self.plotParams["hspace"] = 0.20

    def save(self, filename, **kwargs):
        """
        Save this plot to a file.
        """
        layout = self.__setupLayout()
        layout.save(filename, **kwargs)

    def subplot(self, fig, row, column, position, projection):
        kwdict = {}

        if projection is not None:
            kwdict["projection"] = projection

        ax = fig.add_subplot(row, column, position, **kwdict)
        return self.drawPlot(fig, ax)

    def drawPlot(self, fig, ax):
        """
        Used by PlotLayout to plot the graph at a given location in the layout.
        """

        ax2 = None

        if self.tight and self.allows_tight:
            ax.autoscale_view(tight=True)

        for inset in self.insets:
            inset.draw(fig, ax)

        if self.hideTicks == True:
            for xtl in ax.get_xticklabels():
                xtl.set_visible(False)
            for xtick in ax.get_xticklines():
                xtick.set_visible(False)
            for ytl in ax.get_yticklabels():
                ytl.set_visible(False)
            for ytick in ax.get_yticklines():
                ytick.set_visible(False)

        if self.grid.visible == True:
            self.grid.draw(fig, ax)

        if self.loglog or self.logx:
            myBase = None

            if self.logbasex is not None:
                myBase = self.logbasex
            else:
                myBase = self.logbase

            ax.set_xscale("log", basex=myBase)
        if self.loglog or self.logy:
            myBase = None

            if self.logbasey is not None:
                myBase = self.logbasey
            else:
                myBase = self.logbase

            ax.set_yscale("log", basey=myBase)

        if self.twinxIndex > 0:
            ax2 = ax.twinx()
            ax2.set_ylabel(self.twinxLabel)
            if self.twinxLimits is not None:
                ax2.set_ylim(ymin=self.twinxLimits[0], ymax=self.twinxLimits[1])

        plotHandles = []
        plotLabels = []

        if self.xFormatter is not None:
            ax.xaxis.set_major_formatter(self.xFormatter)

        if self.yFormatter is not None:
            ax.yaxis.set_major_formatter(self.yFormatter)

        if self.title is not None:
            ax.set_title(self.title, **self.titleProperties)

        i = 0
        myAxis = ax

        hasLineStyles = self.lineStyles is not None
        hasColors = self.lineColors is not None
        hasMarkers = self.markers is not None

        numLineStyles = 1
        numColors = 1
        numMarkers = 1

        if hasLineStyles:
            numLineStyles = len(self.lineStyles)

        if hasColors:
            numColors = len(self.lineColors)

        if hasMarkers:
            numMarkers = len(self.markers)

        plotIndex = 0

        for plotInfo in self.plots:
            if self.twinxIndex >= 0 and i == self.twinxIndex:
                myAxis = ax2

            myLineStyle = None
            myColor = None
            myMarker = None

            # cycle through styles first, then markers, then colors
            colorIndex = (plotIndex / (numMarkers * numLineStyles)) % numColors
            markerIndex = int(plotIndex / numLineStyles) % numMarkers
            lineStyleIndex = plotIndex % numLineStyles

            if hasLineStyles:
                myLineStyle = self.lineStyles[lineStyleIndex].style

            if hasColors:
                myColor = self.lineColors[colorIndex]

            if hasMarkers:
                myMarker = self.markers[markerIndex].marker

            plotIndex += 1

            if myLineStyle is not None:
                plotInfo.lineStyle = myLineStyle

            if myMarker is not None:
                plotInfo.marker = myMarker

            if myColor is not None:
                plotInfo.color = myColor

            plotInfo._preDraw()
            (currPlotHandles, currPlotLabels) = plotInfo.draw(fig, myAxis)

            labelIndices = [x for x in range(len(currPlotLabels)) if currPlotLabels[x] is not None]

            if len(labelIndices) > 0:
                plotHandles.extend([currPlotHandles[x] for x in labelIndices])
                plotLabels.extend([currPlotLabels[x] for x in labelIndices])

            if plotInfo.xLimits is not None:
                if self.xLimits is None:
                    self.xLimits = plotInfo.xLimits
                else:
                    (myXMin, myXMax) = plotInfo.xLimits
                    self.xLimits = (min(self.xLimits[0], myXMin), max(self.xLimits[1], myXMax))

            i += 1

        if self.xLimits is not None:
            ax.set_xlim(xmin=self.xLimits[0], xmax=self.xLimits[1])

        if self.yLimits is not None:
            ax.set_ylim(ymin=self.yLimits[0], ymax=self.yLimits[1])

        if self.xLabel is not None:
            ax.set_xlabel(self.xLabel, **self.xLabelProperties)

        if self.yLabel is not None:
            ax.set_ylabel(self.yLabel, **self.yLabelProperties)

        if self.legend is not None:
            if len(plotHandles) == 0:
                print >>sys.stderr, "ERROR: Plot wanted to draw a legend, " "but none of its elements have labels"
                sys.exit(1)

            if self.twinxIndex > 0:
                legendAxis = ax2
            else:
                legendAxis = ax

            self.legend.draw(fig, legendAxis, plotHandles, plotLabels)

        return (plotHandles, plotLabels)
コード例 #5
0
class ViewShpForRscCode:
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        dir = os.path.dirname(__file__)
        self.plugin_dir = dir.decode('cp1251')
        self.labProp = None
        self.fed = None
        self.scrc = None
        self.codename = None
        self.model = None
        self.okdict = {}
        self.root = QgsProject.instance().layerTreeRoot()
        self.style = QgsStyleV2().defaultStyle()
        self.dlg = ViewShpForRscCodeDialog()
        self.editRend = EditRenderDialog()
        self.editRend.listWgt.doubleClicked.connect(self.editSymbol)
        self.editRend.closeButton.clicked.connect(self.closeEditRend)
        self.editRend.csvExpButton.clicked.connect(self.expCSV)
        self.editRend.xmlExpButton.clicked.connect(self.expXML)
        self.editRend.saveButton.clicked.connect(
            functools.partial(self.expCSV, True))
        self.editRend.delButton.clicked.connect(self.removeCodeItem)
        self.editRend.addButton.clicked.connect(self.addCodeItem)
        self.dlg.runButton.clicked.connect(self.setMapStyle)
        self.dlg.closeButton.clicked.connect(self.closeDial)
        self.dlg.importXmlButton.clicked.connect(self.importXML)
        self.dlg.editRenderButton.clicked.connect(self.editRender)
        self.dlg.delTabButton.clicked.connect(self.removeTab)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'MapStyling_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&ViewShpForRscCodePlugin')
        self.toolbar = self.iface.addToolBar(u'MapStyling')
        self.toolbar.setObjectName(u'MapStyling')

    def tr(self, message):
        return QCoreApplication.translate('MapStyling', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        # Create the dialog (after translation) and keep reference
        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        if status_tip is not None:
            action.setStatusTip(status_tip)
        if whats_this is not None:
            action.setWhatsThis(whats_this)
        if add_to_toolbar:
            self.toolbar.addAction(action)
        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)
        self.actions.append(action)
        return action

    def GetModelForCombobox(self, list):
        model = QtGui.QStandardItemModel(1, 1)
        n = 0
        for l in list:
            item_str = l.rpartition('\\')[2]
            item = QtGui.QStandardItem(item_str)
            model.setItem(n, 0, item)
            n = n + 1
        return model

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/ViewShpForRscCode/icon.png'
        self.add_action(icon_path,
                        text=self.tr('ViewShpForRscCode'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&MViewShpForRscCodePlugin'),
                                        action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar
        QgsExpression.unregisterFunction("fontProperty")

    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        #self.dlg.show()
        # Run the dialog event loop
        self.fillCombos()
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass

    def fillCombos(self):
        xml = glob.glob(self.plugin_dir + '/svg/*.xml')
        tab = glob.glob(self.plugin_dir + '/tab/*.csv')
        self.dlg.scaleComboBox.setModel(self.GetModelForCombobox(xml))
        self.dlg.tabComboBox.setModel(self.GetModelForCombobox(tab))

    def reorderLayers(self, layer, node):
        lyr = self.root.findLayer(layer.id())
        lyrClone = lyr.clone()
        parent = lyr.parent()
        parent.insertChildNode(node, lyrClone)
        parent.removeChildNode(lyr)

    def setMapStyle(self):
        layers = self.iface.legendInterface().layers()
        self.scrc = SymbolCategoryRenderClass(
            self.makeokdict(self.getTabs(csv=True)))
        self.labProp = LabelProperties(self.okdict)
        for layer in layers:
            layerType = layer.type()
            if layerType == QgsMapLayer.VectorLayer:
                node = len(layers)
                if layer.name() == u'LAYER3-polygon':
                    self.reorderLayers(layer, node)
                if layer.name() == u'LAYER7-polygon':
                    self.reorderLayers(layer, node - 1)
                if layer.name() == u'LAYER12-polygon':
                    self.reorderLayers(layer, node - 2)
                if layer.name() == u'LAYER19-polygon':
                    self.reorderLayers(layer, node - 3)
                if layer.name() == u'LAYER17-label':
                    self.labProp.makeLabels(layer)
                self.scrc.CategoryRender(self.style, layer)
            layer.triggerRepaint()

    def getTabs(self, csv=None, lbl=None):
        if csv:
            tabName = self.dlg.tabComboBox.currentText()
            csv_path = os.path.join(self.plugin_dir, 'tab/' + tabName)
        return csv_path

    def makeokdict(self, csv_path):
        with open(csv_path) as f:
            reader = csv.reader(f, delimiter=';')
            for row in reader:
                if 'T' in row[0]:
                    self.okdict[row[0]] = [
                        row[1].decode('utf-8'),
                        row[2].decode('utf-8').split(',')
                    ]
                else:
                    self.okdict[row[0]] = [
                        row[1].decode('utf-8'), row[2].decode('utf-8')
                    ]
        return self.okdict

    def importXML(self):
        srcStyle = QgsStyleV2()
        dstStyle = self.style
        symLib = self.dlg.scaleComboBox.currentText()
        svg_dst = QgsApplication.svgPaths()[0]
        spath = self.plugin_dir + '/svg/'
        copylist = []
        if not os.path.isfile(spath):
            for path, dirs, filenames in os.walk(spath):
                for directory in dirs:
                    dir_path = os.path.join(svg_dst, directory)
                    if not os.path.exists(dir_path):
                        os.makedirs(os.path.join(dir_path))
                for sfile in filenames:
                    s_file = os.path.join(path, sfile)
                    d_file = os.path.join(path.replace(spath, svg_dst), sfile)
                    copylist.append([s_file, d_file])
            for c in copylist:
                shutil.copy(c[0], c[1])
        xml_path = spath + symLib
        srcStyle.importXML(xml_path)
        groupName = symLib.replace(".xml", "")
        if groupName not in dstStyle.groupNames():
            dstStyle.addGroup(groupName)
        groupid = dstStyle.groupId(groupName)
        for sym in srcStyle.symbolNames():
            symbol = srcStyle.symbol(sym)
            dstStyle.addSymbol(sym, symbol)
            dstStyle.saveSymbol(sym, symbol, groupid, [])
        QtGui.QMessageBox.information(QWidget(), u'Информация',
                                      u'Импорт завершен', QtGui.QMessageBox.Ok)
        return

    def editRender(self):
        tab = self.dlg.tabComboBox.currentText()
        self.editRend.listWgt.setIconSize(QSize(32, 32))
        self.editRend.listWgt.setEditTriggers(
            QtGui.QAbstractItemView.SelectedClicked)
        self.model = QStandardItemModel()
        self.model.setColumnCount(3)
        self.model.setHorizontalHeaderItem(0, QStandardItem(u'Код'))
        self.model.setHorizontalHeaderItem(1, QStandardItem(u'Название'))
        self.model.setHorizontalHeaderItem(2, QStandardItem(u'Знак'))
        self.editRend.listWgt.setModel(self.model)
        self.editRend.listWgt.setSelectionBehavior(QTableView.SelectRows)
        self.codename = {}
        with open(self.plugin_dir + '/tab/' + tab) as f:
            reader = csv.reader(f, delimiter=';')
            for row in reader:
                itemCode = QStandardItem(row[0])
                itemName = QStandardItem(row[1].decode('utf-8'))
                symName = row[2].decode('utf-8')
                if symName == 'None':
                    if 'L' in itemCode.text():
                        symName = 'NoneStyleLine'
                    if 'P' in itemCode.text():
                        symName = 'NoneStyleMark'
                    if 'S' in itemCode.text():
                        symName = 'NoneStylePoly'
                    if 'V' in itemCode.text():
                        symName = 'NoneStyleLine'
                itemSymb = QStandardItem(symName)
                symbol = self.style.symbol(symName)
                if symbol:
                    itemSymb = QStandardItem(symName)
                    icon = QgsSymbolLayerV2Utils.symbolPreviewIcon(
                        symbol, self.editRend.listWgt.iconSize())
                    itemSymb.setIcon(icon)
                self.model.appendRow([itemCode, itemName, itemSymb])
                self.codename[itemCode.text()] = symName
        self.editRend.listWgt.resizeRowsToContents()
        self.editRend.listWgt.setColumnWidth(2, 125)
        self.editRend.listWgt.setColumnWidth(1, 250)
        self.editRend.exec_()

    def editSymbol(self):
        row = self.editRend.listWgt.selectionModel().currentIndex().row()
        code = self.model.item(row, 0).text()
        name = self.model.item(row, 2).text()
        if name == 'None':
            t = QInputDialog.getItem(
                QWidget(),
                u'Создание условного знака',
                u'Укажите тип объекта',
                [u'Точка', u'Линия', u'Полигон', u'Текст'],
                editable=False)
            if t[1]:
                if t[0] == u'Точка':
                    name = 'NoneStyleMark'
                if t[0] == u'Линия':
                    name = 'NoneStyleLine'
                if t[0] == u'Полигон':
                    name = 'NoneStylePoly'
                if t[0] == u'Текст':
                    name = None
            else:
                return
        if 'T' in code:
            fontProps = self.fontDialog(name)
            if fontProps:
                item = QStandardItem(','.join(fontProps))
                self.model.setItem(row, 2, item)
            return
        symbol = self.style.symbol(name)
        if not symbol:
            return
        d = QgsSymbolV2SelectorDialog(symbol, self.style, None)
        if d.exec_() == 0:
            return
        if 'None' in name:
            name = ''
        newName = QInputDialog.getText(QWidget(),
                                       u"Имя условного знака",
                                       u"Введите имя условного знака:",
                                       text=name)
        if newName[1]:
            name = newName[0]
        if not newName[1]:
            return
        self.style.addSymbol(name, symbol, True)
        itemSymb = QStandardItem(name)
        icon = QgsSymbolLayerV2Utils.symbolPreviewIcon(
            symbol, self.editRend.listWgt.iconSize())
        itemSymb.setIcon(icon)
        self.model.setItem(row, 2, itemSymb)

    def fontDialog(self, name=False):
        fsc = None
        if name:
            fsc = name.split(',')
        self.fed = fontEditDialog(fsc)
        return self.fed.showDial()

    def removeTab(self):
        tab = self.dlg.tabComboBox.currentText()
        if tab == 'codeNameTab_100k.csv':
            QtGui.QMessageBox.information(QWidget(), u'Информация',
                                          u'Невозможно удалить этот файл',
                                          QtGui.QMessageBox.Ok)
            return
        tpath = self.plugin_dir + '/tab/' + tab
        os.remove(tpath)
        self.fillCombos()

    def closeDial(self):
        self.dlg.close()

    def closeEditRend(self):
        self.editRend.close()
        self.fillCombos()

    def expXML(self):
        QgsStyleV2ManagerDialog(self.style).exportItems()

    def expCSV(self, save=False):
        if not save:
            nameInput = QInputDialog.getText(QWidget(), u"Название таблицы",
                                             u"Введите название таблицы")
            if nameInput[1]:
                name = nameInput[0]
            else:
                return
        if save:
            name = self.dlg.tabComboBox.currentText().replace('.csv', '')
        with open(self.plugin_dir + '/tab/' + name + '.csv', 'wb') as fout:
            writer = UnicodeWriter(fout, delimiter=';')
            for r in range(self.model.rowCount()):
                itemCode = self.model.item(r, 0).text()
                itemName = self.model.item(r, 1).text()
                itemSymb = self.model.item(r, 2).text()
                writer.writerow([itemCode, itemName, itemSymb])

    def removeCodeItem(self):
        indexList = []
        for r in self.editRend.listWgt.selectionModel().selectedRows():
            row = r.row()
            indexList.append(row)
        for i in indexList[::-1]:
            self.model.removeRows(i, 1)

    def addCodeItem(self):
        itemCode = QStandardItem('None')
        itemName = QStandardItem('None')
        itemSymb = QStandardItem('None')
        itemList = [itemCode, itemName, itemSymb]
        selection = self.editRend.listWgt.selectionModel().selectedRows()
        if selection:
            self.model.insertRow(selection[-1::][0].row() + 1, itemList)
        else:
            self.model.appendRow(itemList)
コード例 #6
0
ファイル: PlotInfo.py プロジェクト: alexras/boomslang
    def __init__(self,
                 plotType,
                 xValues = None,
                 yValues = None,
                 xTickLabels = None,
                 yTickLabels = None,
                 xTickLabelPoints = None,
                 yTickLabelPoints = None,
                 xTickLabelProperties = None,
                 yTickLabelProperties = None,
                 label = None,
                 yMins = None,
                 yMaxes = None,
                 yErrors = None,
                 autosort = True,
                 xLimits = None,
                 errorBarColor = None,
                 errorBarLineWidth = None,
                 errorBarCapsize = None,
                 picker=None):

        if xValues is None:
            xValues = []

        if yValues is None:
            yValues = []

        if xTickLabels is None:
            xTickLabels = []

        if yTickLabels is None:
            yTickLabels = []

        if xTickLabelPoints is None:
            xTickLabelPoints = []

        if yTickLabelPoints is None:
            yTickLabelPoints = []

        if yMins is None:
            yMins = []

        if yMaxes is None:
            yMaxes = []

        if yErrors is None:
            yErrors = []

        self.plotType = plotType
        """
        Names the type of plot element
        """

        self.xValues = xValues
        """
        An array of x-axis values for the plot element
        """

        self.yValues = yValues
        """
        An array of y-axis values for the plot elements
        """

        self.xTickLabels = xTickLabels
        """
        A list of labels that should be drawn on the x-axis
        """

        self.yTickLabels = yTickLabels
        """
        A list of labels that should be drawn on the y-axis
        """

        self.xTickLabelPoints = xTickLabelPoints
        """
        The locations on the x-axis where the labels in :attr:`xTickLabels`
        should be drawn
        """

        self.yTickLabelPoints = yTickLabelPoints
        """
        The locations on the x-axis where the labels in :attr:`xTickLabels`
        should be drawn
        """

        self._xTickLabelProperties = LabelProperties()

        self._yTickLabelProperties = LabelProperties()

        if xTickLabelProperties is not None:
            self.xTickLabelProperties = xTickLabelProperties

        if yTickLabelProperties is not None:
            self.yTickLabelProperties = yTickLabelProperties

        self.label = label
        """
        A string used to label this plot element in a legend
        """

        self.yMins = yMins
        """
        For asymmetric error bars, a list of locations for the bottoms of this
        plot element's error bars
        """

        self.yMaxes = yMaxes
        """
        For asymmetric error bars, a list of locations for the tops of this
        plot element's error bars
        """

        self.yErrors = yErrors
        """
        For symmetric error bars, a list of error bar widths for this plot
        element's error bars
        """

        self.autosort = autosort
        """
        If true, x/y pairs in :py:attr:`xValues` and :py:attr:`yValues` are
        sorted by x value before the plot is rendered
        """

        self.xLimits = xLimits

        self.errorBarColor = errorBarColor
        self.errorBarLineWidth = errorBarLineWidth
        self.errorBarCapsize = errorBarCapsize

        self.picker = picker
コード例 #7
0
ファイル: PlotInfo.py プロジェクト: alexras/boomslang
class PlotInfo(object):
    def __init__(self,
                 plotType,
                 xValues = None,
                 yValues = None,
                 xTickLabels = None,
                 yTickLabels = None,
                 xTickLabelPoints = None,
                 yTickLabelPoints = None,
                 xTickLabelProperties = None,
                 yTickLabelProperties = None,
                 label = None,
                 yMins = None,
                 yMaxes = None,
                 yErrors = None,
                 autosort = True,
                 xLimits = None,
                 errorBarColor = None,
                 errorBarLineWidth = None,
                 errorBarCapsize = None,
                 picker=None):

        if xValues is None:
            xValues = []

        if yValues is None:
            yValues = []

        if xTickLabels is None:
            xTickLabels = []

        if yTickLabels is None:
            yTickLabels = []

        if xTickLabelPoints is None:
            xTickLabelPoints = []

        if yTickLabelPoints is None:
            yTickLabelPoints = []

        if yMins is None:
            yMins = []

        if yMaxes is None:
            yMaxes = []

        if yErrors is None:
            yErrors = []

        self.plotType = plotType
        """
        Names the type of plot element
        """

        self.xValues = xValues
        """
        An array of x-axis values for the plot element
        """

        self.yValues = yValues
        """
        An array of y-axis values for the plot elements
        """

        self.xTickLabels = xTickLabels
        """
        A list of labels that should be drawn on the x-axis
        """

        self.yTickLabels = yTickLabels
        """
        A list of labels that should be drawn on the y-axis
        """

        self.xTickLabelPoints = xTickLabelPoints
        """
        The locations on the x-axis where the labels in :attr:`xTickLabels`
        should be drawn
        """

        self.yTickLabelPoints = yTickLabelPoints
        """
        The locations on the x-axis where the labels in :attr:`xTickLabels`
        should be drawn
        """

        self._xTickLabelProperties = LabelProperties()

        self._yTickLabelProperties = LabelProperties()

        if xTickLabelProperties is not None:
            self.xTickLabelProperties = xTickLabelProperties

        if yTickLabelProperties is not None:
            self.yTickLabelProperties = yTickLabelProperties

        self.label = label
        """
        A string used to label this plot element in a legend
        """

        self.yMins = yMins
        """
        For asymmetric error bars, a list of locations for the bottoms of this
        plot element's error bars
        """

        self.yMaxes = yMaxes
        """
        For asymmetric error bars, a list of locations for the tops of this
        plot element's error bars
        """

        self.yErrors = yErrors
        """
        For symmetric error bars, a list of error bar widths for this plot
        element's error bars
        """

        self.autosort = autosort
        """
        If true, x/y pairs in :py:attr:`xValues` and :py:attr:`yValues` are
        sorted by x value before the plot is rendered
        """

        self.xLimits = xLimits

        self.errorBarColor = errorBarColor
        self.errorBarLineWidth = errorBarLineWidth
        self.errorBarCapsize = errorBarCapsize

        self.picker = picker

    @property
    def xTickLabelProperties(self):
        """
        A dictionary of properties that control the appearance of the X axis'
        tick labels. See :ref:`styling-labels` for more information on which
        properties can be set.
        """

        return self._xTickLabelProperties

    @xTickLabelProperties.setter
    def xTickLabelProperties(self, **props):
        self._xTickLabelProperties.update(props)

    @xTickLabelProperties.setter
    def xTickLabelProperties(self, propsobj):
        self._xTickLabelProperties.update(propsobj)


    @property
    def yTickLabelProperties(self):
        """
        A dictionary of properties that control the appearance of the Y axis'
        tick labels. See :ref:`styling-labels` for more information on which
        properties can be set.
        """

        return self._yTickLabelProperties

    @yTickLabelProperties.setter
    def yTickLabelProperties(self, props):
        self._yTickLabelProperties.update(props)

    def __str__(self):
        return str(self.__dict__)

    def _preDraw(self):
        """
        The _preDraw function is called on all plot elements before drawing
        occurs. This allows various fields to be set in a structured way
        prior to actual drawing.
        """
        pass

    def setXTickLabelProperties(self, **propList):
        # Deprecated: use xTickLabelProperties field instead
        self._xTickLabelProperties.update(propList)

    def setYTickLabelProperties(self, **propList):
        # Deprecated: use yTickLabelProperties field instead
        self._yTickLabelProperties.update(propList)

    def split(self, pieces):
        """
        Split this plot element into `pieces` separate plot elements, each of
        which is responsible for a disjoint range of the original plot
        element's x-axis. This is useful for situations where a plot element
        cannot fit comfortably in a single plot.
        """
        elements = []

        numXVals = len(self.xValues)

        valChunkSize = numXVals / pieces
        valChunkRemainder = numXVals % pieces

        for i in xrange(pieces):
            element = copy.deepcopy(self)

            if i < pieces - 1 or valChunkRemainder == 0:
                element.xValues = self.xValues[i * valChunkSize:(i+1) * valChunkSize]
                element.yValues = self.yValues[i * valChunkSize:(i+1) * valChunkSize]
            else:
                element.xValues = self.xValues[i * valChunkSize:]
                element.yValues = self.yValues[i * valChunkSize:]
            elements.append(element)
        return elements

    def getAttributes(self):
        """
        Get the attributes dictionary used to style the plot element. Extending
        this method allows plot elements to inherit attributes.
        """

        kwdict = {}

        if self.picker is not None:
            kwdict['picker'] = self.picker

        return kwdict


    def draw(self, fig, axis, transform=None):
        """
        The base method for drawing a plot element on the axis `axis` within
        the figure `fig`. Other plot elements should override this method, but
        should also be sure to call this method before doing any
        element-specific processing.
        """

        if len(self.xValues) > 0 and self.autosort:
            # This is a total kludge --AR

            sortAsymmetricErrorBars = len(self.yMins) > 0 or \
                len(self.yMaxes) > 0
            sortSymmetricErrorBars = len(self.yErrors) > 0

            if sortAsymmetricErrorBars:
                if len(self.yMins) != len(self.yValues):
                    warnings.warn("You don't have an error bar for every "
                                  "point, some points will be truncated")

                zipped = zip(self.xValues, self.yValues, self.yMins,
                             self.yMaxes)
                zipped.sort()
                self.xValues, self.yValues, self.yMins, self.yMaxes \
                    = zip(*zipped)
            elif sortSymmetricErrorBars:
                if len(self.yErrors) != len(self.yValues):
                    warnings.warn("You don't have an error bar for every "
                                  "point, some points will be truncated")

                zipped = zip(self.xValues, self.yValues, self.yErrors)
                zipped.sort()
                self.xValues, self.yValues, self.yErrors = zip(*zipped)
            else:
                zipped = zip(self.xValues, self.yValues)
                zipped.sort()
                self.xValues, self.yValues = zip(*zipped)

        if len(self.xTickLabels) > 0:
            if len(self.xTickLabelPoints) == 0:
                axis.set_xticks(self.xValues[0:len(self.xTickLabels)])
            else:
                axis.set_xticks(self.xTickLabelPoints)

            axis.set_xticklabels(self.xTickLabels, **self.xTickLabelProperties)

        if len(self.yTickLabels) > 0:
            if len(self.yTickLabelPoints) == 0:
                axis.set_yticks(self.yValues[0:len(self.yTickLabels)])
            else:
                axis.set_yticks(self.yTickLabelPoints)

            axis.set_yticklabels(self.yTickLabels, **self.yTickLabelProperties)

        self.drawErrorBars(axis)

    def drawErrorBars(self, axis, transform=None):
        """
        Draw error bars for the plot element using the plot element's
        `yMins`/`yMaxes` or `yErrors`. If `yMins` or `yMaxes` have non-zero
        length, they are used to draw error bars that can be
        asymmetric. Otherwise, `yErrors` are used to draw symmetric error bars.

        If some transform should be applied to the error bars, it is provided
        by the caller with the `transform` parameter.
        """

        errorBarKeywords = {}
        if  self.errorBarColor is not None:
            errorBarKeywords["ecolor"] = self.errorBarColor
        elif hasattr(self, "color"):
            errorBarKeywords["ecolor"] = self.color

        if self.errorBarCapsize is not None:
            errorBarKeywords["capsize"] = self.errorBarCapsize

        if self.errorBarLineWidth is not None:
            errorBarKeywords["linewidth"] = self.errorBarLineWidth

        if hasattr(self, "lineStyle"):
            errorBarKeywords["linestyle"] = self.lineStyle

        if transform:
            errorBarKeywords['transform'] = transform + axis.transData

        errorBarKeywords["fmt"] = None

        if len(self.yMins) > 0 and len(self.yMaxes) > 0:
            numYVals = len(self.yValues)
            yMin = [self.yValues[i] - self.yMins[i] for i in xrange(numYVals)]
            yMax = [self.yMaxes[i] - self.yValues[i] for i in xrange(numYVals)]


            errorBarKeywords["yerr"] = [yMin, yMax]

            axis.errorbar(self.xValues, self.yValues, **errorBarKeywords)
        elif len(self.yErrors) > 0:
            errorBarKeywords["yerr"] = self.yErrors
            axis.errorbar(self.xValues, self.yValues, **errorBarKeywords)
コード例 #8
0
ファイル: PlotInfo.py プロジェクト: jcmdev0/boomslang
    def __init__(self,
                 plotType,
                 xValues = None,
                 yValues = None,
                 xTickLabels = None,
                 yTickLabels = None,
                 xTickLabelPoints = None,
                 yTickLabelPoints = None,
                 xTickLabelProperties = None,
                 yTickLabelProperties = None,
                 label = None,
                 yMins = None,
                 yMaxes = None,
                 yErrors = None,
                 autosort = True,
                 xLimits = None,
                 errorBarColor = None,
                 errorBarLineWidth = None,
                 errorBarCapsize = None,
                 picker=None):

        if xValues is None:
            xValues = []

        if yValues is None:
            yValues = []

        if xTickLabels is None:
            xTickLabels = []

        if yTickLabels is None:
            yTickLabels = []

        if xTickLabelPoints is None:
            xTickLabelPoints = []

        if yTickLabelPoints is None:
            yTickLabelPoints = []

        # if xTickLabelProperties is None:
        #     xTickLabelProperties = LabelProperties()

        # if yTickLabelProperties is None:
        #     yTickLabelProperties = LabelProperties()

        if yMins is None:
            yMins = []

        if yMaxes is None:
            yMaxes = []

        if yErrors is None:
            yErrors = []

        self.plotType = plotType

        self.xValues = xValues
        self.yValues = yValues

        self.xTickLabels = xTickLabels
        self.yTickLabels = yTickLabels
        self.xTickLabelPoints = xTickLabelPoints
        self.yTickLabelPoints = yTickLabelPoints
        self._xTickLabelProperties = LabelProperties()
        self._yTickLabelProperties = LabelProperties()

        if xTickLabelProperties is not None:
            self.xTickLabelProperties = xTickLabelProperties

        if yTickLabelProperties is not None:
            self.yTickLabelProperties = yTickLabelProperties

        self.label = label

        self.yMins = yMins
        self.yMaxes = yMaxes
        self.yErrors = yErrors

        self.autosort = autosort

        self.xLimits = xLimits

        self.errorBarColor = errorBarColor
        self.errorBarLineWidth = errorBarLineWidth
        self.errorBarCapsize = errorBarCapsize

        self.picker = picker
コード例 #9
0
ファイル: PlotInfo.py プロジェクト: jcmdev0/boomslang
class PlotInfo(object):
    def __init__(self,
                 plotType,
                 xValues = None,
                 yValues = None,
                 xTickLabels = None,
                 yTickLabels = None,
                 xTickLabelPoints = None,
                 yTickLabelPoints = None,
                 xTickLabelProperties = None,
                 yTickLabelProperties = None,
                 label = None,
                 yMins = None,
                 yMaxes = None,
                 yErrors = None,
                 autosort = True,
                 xLimits = None,
                 errorBarColor = None,
                 errorBarLineWidth = None,
                 errorBarCapsize = None,
                 picker=None):

        if xValues is None:
            xValues = []

        if yValues is None:
            yValues = []

        if xTickLabels is None:
            xTickLabels = []

        if yTickLabels is None:
            yTickLabels = []

        if xTickLabelPoints is None:
            xTickLabelPoints = []

        if yTickLabelPoints is None:
            yTickLabelPoints = []

        # if xTickLabelProperties is None:
        #     xTickLabelProperties = LabelProperties()

        # if yTickLabelProperties is None:
        #     yTickLabelProperties = LabelProperties()

        if yMins is None:
            yMins = []

        if yMaxes is None:
            yMaxes = []

        if yErrors is None:
            yErrors = []

        self.plotType = plotType

        self.xValues = xValues
        self.yValues = yValues

        self.xTickLabels = xTickLabels
        self.yTickLabels = yTickLabels
        self.xTickLabelPoints = xTickLabelPoints
        self.yTickLabelPoints = yTickLabelPoints
        self._xTickLabelProperties = LabelProperties()
        self._yTickLabelProperties = LabelProperties()

        if xTickLabelProperties is not None:
            self.xTickLabelProperties = xTickLabelProperties

        if yTickLabelProperties is not None:
            self.yTickLabelProperties = yTickLabelProperties

        self.label = label

        self.yMins = yMins
        self.yMaxes = yMaxes
        self.yErrors = yErrors

        self.autosort = autosort

        self.xLimits = xLimits

        self.errorBarColor = errorBarColor
        self.errorBarLineWidth = errorBarLineWidth
        self.errorBarCapsize = errorBarCapsize

        self.picker = picker

    @property
    def xTickLabelProperties(self):
        """
        A dictionary of properties that control the appearance of the X axis'
        tick labels
        """

        return self._xTickLabelProperties

    @xTickLabelProperties.setter
    def xTickLabelProperties(self, **props):
        self._xTickLabelProperties.update(props)

    @xTickLabelProperties.setter
    def xTickLabelProperties(self, propsobj):
        self._xTickLabelProperties.update(propsobj)


    @property
    def yTickLabelProperties(self):
        """
        A dictionary of properties that control the appearance of the X axis'
        tick labels
        """

        return self._yTickLabelProperties

    @yTickLabelProperties.setter
    def yTickLabelProperties(self, props):
        self._yTickLabelProperties.update(props)

    def __str__(self):
        return str(self.__dict__)

    def _preDraw(self):
        """
        The _preDraw function is called on all plot elements before drawing
        occurs. This allows various fields to be set in a structured way
        prior to actual drawing.
        """
        pass

    def setXTickLabelProperties(self, **propList):
        self._xTickLabelProperties.update(propList)

    def setYTickLabelProperties(self, **propList):
        self._yTickLabelProperties.update(propList)

    def split(self, pieces):
        elements = []

        numXVals = len(self.xValues)

        valChunkSize = numXVals / pieces
        valChunkRemainder = numXVals % pieces

        for i in xrange(pieces):
            element = copy.deepcopy(self)

            if i < pieces - 1 or valChunkRemainder == 0:
                element.xValues = self.xValues[i * valChunkSize:(i+1) * valChunkSize]
                element.yValues = self.yValues[i * valChunkSize:(i+1) * valChunkSize]
            else:
                element.xValues = self.xValues[i * valChunkSize:]
                element.yValues = self.yValues[i * valChunkSize:]
            elements.append(element)
        return elements

    def getAttributes(self):
        kwdict = {}

        if self.picker is not None:
            kwdict['picker'] = self.picker

        return kwdict


    def draw(self, fig, axis):
        if len(self.xValues) > 0 and self.autosort:
            # This is a total kludge --AR

            sortAsymmetricErrorBars = len(self.yMins) > 0 or \
                len(self.yMaxes) > 0
            sortSymmetricErrorBars = len(self.yErrors) > 0

            if sortAsymmetricErrorBars:
                if len(self.yMins) != len(self.yValues):
                    warnings.warn("You don't have an error bar for every "
                                  "point, some points will be truncated")

                zipped = zip(self.xValues, self.yValues, self.yMins,
                             self.yMaxes)
                zipped.sort()
                self.xValues, self.yValues, self.yMins, self.yMaxes \
                    = zip(*zipped)
            elif sortSymmetricErrorBars:
                if len(self.yErrors) != len(self.yValues):
                    warnings.warn("You don't have an error bar for every "
                                  "point, some points will be truncated")

                zipped = zip(self.xValues, self.yValues, self.yErrors)
                zipped.sort()
                self.xValues, self.yValues, self.yErrors = zip(*zipped)
            else:
                zipped = zip(self.xValues, self.yValues)
                zipped.sort()
                self.xValues, self.yValues = zip(*zipped)

        if len(self.xTickLabels) > 0:
            if len(self.xTickLabelPoints) == 0:
                axis.set_xticks(self.xValues[0:len(self.xTickLabels)])
            else:
                axis.set_xticks(self.xTickLabelPoints)

            axis.set_xticklabels(self.xTickLabels, **self.xTickLabelProperties)

        if len(self.yTickLabels) > 0:
            if len(self.yTickLabelPoints) == 0:
                axis.set_yticks(self.yValues[0:len(self.yTickLabels)])
            else:
                axis.set_yticks(self.yTickLabelPoints)

            axis.set_yticklabels(self.yTickLabels, **self.yTickLabelProperties)

        self.drawErrorBars(axis)

    def drawErrorBars(self, axis, transform=None):
        errorBarKeywords = {}
        if  self.errorBarColor is not None:
            errorBarKeywords["ecolor"] = self.errorBarColor
        elif hasattr(self, "color"):
            errorBarKeywords["ecolor"] = self.color

        if self.errorBarCapsize is not None:
            errorBarKeywords["capsize"] = self.errorBarCapsize

        if self.errorBarLineWidth is not None:
            errorBarKeywords["linewidth"] = self.errorBarLineWidth

        if hasattr(self, "lineStyle"):
            errorBarKeywords["linestyle"] = self.lineStyle

        if transform:
            errorBarKeywords['transform'] = transform + axis.transData

        errorBarKeywords["fmt"] = None

        if len(self.yMins) > 0 and len(self.yMaxes) > 0:
            numYVals = len(self.yValues)
            yMin = [self.yValues[i] - self.yMins[i] for i in xrange(numYVals)]
            yMax = [self.yMaxes[i] - self.yValues[i] for i in xrange(numYVals)]


            errorBarKeywords["yerr"] = [yMin, yMax]

            axis.errorbar(self.xValues, self.yValues, **errorBarKeywords)
        elif len(self.yErrors) > 0:
            errorBarKeywords["yerr"] = self.yErrors
            axis.errorbar(self.xValues, self.yValues, **errorBarKeywords)
コード例 #10
0
ファイル: TickLabels.py プロジェクト: fordhurley/boomslang
 def __init__(self):
     self._formatter = None
     self.labels = None
     self.labelPoints = None
     self._properties = LabelProperties()
     self.size = None
コード例 #11
0
ファイル: Plot.py プロジェクト: fordhurley/boomslang
    def __init__(self):
        self.plots = []

        self.title = None
        """
        The plot's title (will be centered above the axes themselves)
        """

        self.xFormatter = None
        self.yFormatter = None

        self.yLabel = None
        """
        The label for the plot's y-axis
        """

        self.xLabel = None
        """
        The label for the plot's x-axis
        """

        self._xLabelProperties = LabelProperties()
        self._yLabelProperties = LabelProperties()

        self.legend = None

        self._xLimits = None
        self._yLimits = None

        self.twinxLabel = None
        self.twinxIndex = -1
        self.twinxLimits = None

        self.lineStyles = None
        self.lineColors = None
        self.markers = None

        self.width = None

        self.height = None

        self.dpi = 100

        self.plotParams = None

        self.logx = False
        """
        If true, this plot's x-axis will be drawn in log scale.
        """

        self.logy = False
        """
        If true, this plot's y-axis will be drawn in log scale.
        """

        self.loglog = False
        """
        If true, both this plot's axes will be drawn in log scale.
        """

        self.logbase = 10
        """
        The base of the logarithm used to draw log scale axes.
        """

        self.logbasex = None
        """
        The base of the logarithm used to draw the x-axis. Overrides `logbase`,
        and only takes effect if logx or loglog are True.
        """

        self.logbasey = None
        """
        The base of the logarithm used to draw the y-axis. Overrides `logbase`,
        and only takes effect if logy or loglog are True.
        """

        self._grid = Grid()
        self._grid.visible = False

        self.insets = []

        self.hideTicks = False
        """
        If True, this plot's tick labels are hidden.
        """

        self.titleSize = None
        """
        The size of the text used for plot title.
        """

        self.latex = False

        self.axesLabelSize = None
        """
        The size of the text used for labeling the x and y axes.
        """

        self.xTickLabelSize = None
        """
        The size of the text used for x-axis tick labels
        """

        self.yTickLabelSize = None
        """
        The size of the text used for y-axis tick labels
        """

        self.titleProperties = LabelProperties()

        self.tight = False
        """
        If True, this plot is auto-scaled so that axis labels don't get cut off.
        """

        self.allows_tight = True

        self.projection = None
        """
コード例 #12
0
ファイル: Plot.py プロジェクト: fordhurley/boomslang
class Plot(object):
    """
    Represents a single plot, usually consisting of a single X and Y axis.
    """

    def __init__(self):
        self.plots = []

        self.title = None
        """
        The plot's title (will be centered above the axes themselves)
        """

        self.xFormatter = None
        self.yFormatter = None

        self.yLabel = None
        """
        The label for the plot's y-axis
        """

        self.xLabel = None
        """
        The label for the plot's x-axis
        """

        self._xLabelProperties = LabelProperties()
        self._yLabelProperties = LabelProperties()

        self.legend = None

        self._xLimits = None
        self._yLimits = None

        self.twinxLabel = None
        self.twinxIndex = -1
        self.twinxLimits = None

        self.lineStyles = None
        self.lineColors = None
        self.markers = None

        self.width = None

        self.height = None

        self.dpi = 100

        self.plotParams = None

        self.logx = False
        """
        If true, this plot's x-axis will be drawn in log scale.
        """

        self.logy = False
        """
        If true, this plot's y-axis will be drawn in log scale.
        """

        self.loglog = False
        """
        If true, both this plot's axes will be drawn in log scale.
        """

        self.logbase = 10
        """
        The base of the logarithm used to draw log scale axes.
        """

        self.logbasex = None
        """
        The base of the logarithm used to draw the x-axis. Overrides `logbase`,
        and only takes effect if logx or loglog are True.
        """

        self.logbasey = None
        """
        The base of the logarithm used to draw the y-axis. Overrides `logbase`,
        and only takes effect if logy or loglog are True.
        """

        self._grid = Grid()
        self._grid.visible = False

        self.insets = []

        self.hideTicks = False
        """
        If True, this plot's tick labels are hidden.
        """

        self.titleSize = None
        """
        The size of the text used for plot title.
        """

        self.latex = False

        self.axesLabelSize = None
        """
        The size of the text used for labeling the x and y axes.
        """

        self.xTickLabelSize = None
        """
        The size of the text used for x-axis tick labels
        """

        self.yTickLabelSize = None
        """
        The size of the text used for y-axis tick labels
        """

        self.titleProperties = LabelProperties()

        self.tight = False
        """
        If True, this plot is auto-scaled so that axis labels don't get cut off.
        """

        self.allows_tight = True

        self.projection = None
        """
        Defines the projection used when drawing this plot. The only currently
        supported value other than the standard (no projection) is 'polar'.
        """

    @property
    def xLabelProperties(self):
        """
        A dictionary of properties that control the appearance of the X axis'
        axis label. See :ref:`styling-labels` for more information on which
        properties can be set.
        """
        return self._xLabelProperties

    @xLabelProperties.setter
    def xLabelProperties(self, propsobj):
        self._xLabelProperties.update(propsobj)

    @property
    def yLabelProperties(self):
        """
        A dictionary of properties that control the appearance of the Y axis'
        axis label. See :ref:`styling-labels` for more information on which
        properties can be set.
        """
        return self._yLabelProperties

    @yLabelProperties.setter
    def yLabelProperties(self, propsobj):
        self._yLabelProperties.update(propsobj)

    @property
    def xLimits(self):
        """
        A pair giving the minimum and maximum values visible on the x-axis.
        """
        return self._xLimits

    @xLimits.setter
    def xLimits(self, value):
        if type(value) not in [tuple, list] or len(value) != 2:
            raise AttributeError("xLimits must be set to a (min, max) tuple")

        self._xLimits = tuple(value)

    @property
    def yLimits(self):
        """
        A pair giving the minimum and maximum values visible on the x-axis.
        """
        return self._yLimits

    @yLimits.setter
    def yLimits(self, value):
        if type(value) not in [tuple, list] or len(value) != 2:
            raise AttributeError("yLimits must be set to a (min, max) tuple")

        self._yLimits = value

    @property
    def legendLabelSize(self):
        """
        The size of the text in this plot's legend.
        """

        return self.legend.labelSize

    @legendLabelSize.setter
    def legendLabelSize(self, size):
        self.setLegendLabelSize(size)

    @property
    def grid(self):
        """
        A boomslang.Grid.Grid that defines the properties of this plot's grid
        lines. See :ref:`plots-grid-lines` for configuration options.
        """
        return self._grid

    @grid.setter
    def grid(self, value):
        if isinstance(value, bool) and value == True:
            self._grid.visible = True
        else:
            raise AttributeError("Plot.grid cannot be re-assigned")

    def setTitleProperties(self, **propList):
        """
        Set the properties of the title. See :ref:`styling-labels` for more
        information about valid properties.
        """
        self.__setProperties(self.titleProperties, propList)

    def __setProperties(self, propsDict, propList):
        for (key, val) in propList.items():
            propsDict[key] = val

    def __str__(self):
        return str(self.__dict__)

    def setTitleSize(self, size):
        self.titleSize = size

    def setAxesLabelSize(self, size):
        self.axesLabelSize = size

    def setXTickLabelSize(self, size):
        self.xTickLabelSize = size

    def setYTickLabelSize(self, size):
        self.yTickLabelSize = size

    def setLegendLabelSize(self, size):
        if self.legend is None:
            self.legend = Legend()

        self.legend.labelSize = size

    def split(self, pieces):
        """
        Split this plot into `pieces` separate plots, each showing a different
        portion of the x-axis
        """

        splitPlots = [copy.deepcopy(self) for i in xrange(pieces)]

        for plot in splitPlots:
            plot.plots = []

        for plot in self.plots:
            elements = plot.split(pieces)
            for i in xrange(pieces):
                splitPlots[i].add(elements[i])
                splitPlots[i].setXLimits(
                    min(elements[i].xValues), max(elements[i].xValues))
        return splitPlots

    def getDimensions(self):
        """
        Get the dimensions of this plot.
        """
        if self.width is None:
            (self.width, self.height) = getGoldenRatioDimensions(8.0)
        elif self.height is None:
            (goldWidth, goldHeight) = getGoldenRatioDimensions(self.width)
            self.height = goldHeight
        return (self.width, self.height)

    def hideTickLabels(self):
        self.hideTicks = True

    def setDimensions(self, width=None, height=None, dpi=100):
        """
        Set the dimensions for this plot to `width` x `height`
        """
        self.width = width
        self.height = height
        self.dpi = dpi

    def add(self, plottableObject):
        """
        Add a plottable object (a Line, Bar, etc.) to this plot, causing it to
        be drawn when the plot is drawn.
        """

        if not issubclass(plottableObject.__class__, PlotInfo):
            raise BoomslangPlotConfigurationException(
                "All objects added to a Plot must be a subclass of PlotInfo")

        self.plots.append(plottableObject)

    def addInset(self, plot, **kwargs):
        """
        Add `plot` (a Plot object) as an inset to this plot object.

        Valid arguments are as follows:

        ============  ====================================================================================================================
        Argument      Description
        ============  ====================================================================================================================
        ``width``     The width of the inset as a fraction of the size of the parent plot
        ``height``    The height of the inset as a fraction of the size of the parent plot
        ``location``  The location of the inset. See :ref:`plots-locations` for valid locations.
        ``padding``   The amount of padding between the edge of the parent plot and the inset as a fraction of the size of the parent plot
        ============  ====================================================================================================================
        """
        inset = Inset(plot, **kwargs)
        self.insets.append(inset)

    def addLineStyle(self, style):
        """
        Add a line style to the list of line styles through which the plot will
        cycle when drawing lines. If no line styles are specified, the plot
        will default to the line style specified in the Line objects
        themselves.

        Note that, when drawing lines, all line styles for a given color are
        cycled through before another color is used.
        """
        if self.lineStyles is None:
            self.lineStyles = []

        currStyle = LineStyle()
        currStyle.style = style
        self.lineStyles.append(currStyle)

    def addLineColor(self, color):
        """
        Add a line color to the list of line colors through which the plot will
        cycle when drawing lines. If no line colors are specified, the line
        colors specified by the Line objects themselves will be used.

        Note that, when drawing lines, all line styles for a given color are
        cycled through before another color is used.
        """
        if self.lineColors is None:
            self.lineColors = []
        self.lineColors.append(color)

    def addMarker(self, marker):
        """
        Add a marker style to the list of marker styles through which the plot
        will cycle when drawing lines. If no markers are specified, the markers
        specified by the Line objects themselves will be used.

        Note that, when drawing lines, all line style/color combinations are
        cycled through with a given marker before a new marker is chosen.
        """
        if self.markers is None:
            self.markers = []

        currMarker = Marker()
        currMarker.marker = marker
        self.markers.append(currMarker)

    def getNumPlots(self):
        # Get the number of plottable objects currently registered for this
        # plot.
        return len(self.plots)

    def setTwinX(self, label, index, yMin=None, yMax=None):
        """
        Make the plot use a secondary y-axis with the provided label. All
        registered plottable objects at or after the given index will use this
        second axis.
        """
        self.twinxLabel = label
        self.twinxIndex = index

        if yMin is not None and yMax is not None:
            self.twinxLimits = (yMin, yMax)

    def setYFormatter(self, formatter):
        """
        Set the y-axis formatter used by this plot to the given function.
        """
        self.yFormatter = pylab.FuncFormatter(formatter)

    def setXFormatter(self, formatter):
        """
        Set the x-axis formatter used by this plot to the given function.
        """
        self.xFormatter = pylab.FuncFormatter(formatter)

    def setXLabel(self, xLabel):
        self.xLabel = xLabel

    def setYLabel(self, yLabel):
        self.yLabel = yLabel

    def setXLimits(self, minX, maxX):
        self.xLimits = (minX, maxX)

    def setYLimits(self, minY, maxY):
        self.yLimits = (minY, maxY)

    def hasFigLegend(self, columns=1, location="best", scatterPoints=3,
                     draw_frame=True, bbox_to_anchor=None, labelSize=None,
                     title=None, labelOrdering=None, leftToRight=False):
        """
        Declare that the figure has a legend with a given number of columns and
        location.
        """
        self.legend = Legend(columns = columns,
                             scatterPoints = scatterPoints,
                             drawFrame = draw_frame,
                             location = location,
                             figLegend = True,
                             labelSize = labelSize,
                             bboxToAnchor = bbox_to_anchor,
                             title = title,
                             labelOrdering = labelOrdering,
                             leftToRight = leftToRight)

    def hasLegend(self, columns=1, location="best", scatterPoints=3,
                  draw_frame=True, bbox_to_anchor=None, labelSize = None,
                  title=None, labelOrdering=None, leftToRight=False):
        """
        Declare that the plot has a legend with a given number of columns and
        location.
        """
        self.legend = Legend(columns = columns,
                             scatterPoints = scatterPoints,
                             drawFrame = draw_frame,
                             location = location,
                             figLegend = False,
                             labelSize = labelSize,
                             bboxToAnchor = bbox_to_anchor,
                             title = title,
                             labelOrdering = labelOrdering,
                             leftToRight = leftToRight)

    def setTitle(self, title):
        self.title = title

    def __cmp__(self, other):
        if not isinstance(other, Plot):
            raise ValueError("Can't compare a Plot with a non-Plot")

        return cmp(self.title, other.title)

    def __setupLayout(self):
        layout = PlotLayout()
        (width, height) = self.getDimensions()

        layout.setPlotDimensions(width, height, dpi=self.dpi)

        if self.plotParams is not None:
            layout.setPlotParameters(**self.plotParams)

        if self.titleSize is not None:
            layout.setTitleSize(self.titleSize)

        if self.latex == True:
            layout.useLatexLabels()

        if self.axesLabelSize is not None:
            layout.setAxesLabelSize(self.axesLabelSize)

        if self.xTickLabelSize is not None:
            layout.setXTickLabelSize(self.xTickLabelSize)

        if self.yTickLabelSize is not None:
            layout.setYTickLabelSize(self.yTickLabelSize)

        layout.addPlot(self)
        return layout

    def useLatexLabels(self):
        self.latex = True

    def plot(self):
        """
        Draw this plot to a matplotlib canvas.
        """
        layout = self.__setupLayout()
        layout.plot()

    def plot_fig(self):
        layout = self.__setupLayout()
        return layout._doPlot()

    def setPlotParameters(self, **kwdict):
        """
        Set the margins of this plot. See `matplotlib's SubplotParams documentation <http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.SubplotParams>`_ for more details. It is recommended that you set :py:attr:`boomslang.Plot.Plot.tight` to True instead of setting these parameters.
        """
        self.plotParams = dict(kwdict)

        if "left" not in self.plotParams:
            self.plotParams["left"] = 0.12

        if "bottom" not in self.plotParams:
            self.plotParams["bottom"] = 0.10

        if "right" not in self.plotParams:
            self.plotParams["right"] = 0.90

        if "top" not in self.plotParams:
            self.plotParams["top"] = 0.90

        if "wspace" not in self.plotParams:
            self.plotParams["wspace"] = 0.20

        if "hspace" not in self.plotParams:
            self.plotParams["hspace"] = 0.20


    def save(self, filename, **kwargs):
        """
        Save this plot to a file.
        """
        layout = self.__setupLayout()
        layout.save(filename,**kwargs)

    def subplot(self, fig, row, column, position, projection):
        kwdict = {}

        if projection is not None:
            kwdict["projection"] = projection

        ax = fig.add_subplot(row, column, position, **kwdict)
        return self.drawPlot(fig, ax)

    def drawPlot(self, fig, ax):
        """
        Used by PlotLayout to plot the graph at a given location in the layout.
        """

        ax2 = None

        if self.tight and self.allows_tight:
            ax.autoscale_view(tight=True)

        for inset in self.insets:
            inset.draw(fig, ax)

        if self.hideTicks == True:
            for xtl in ax.get_xticklabels():
                xtl.set_visible(False)
            for xtick in ax.get_xticklines():
                xtick.set_visible(False)
            for ytl in ax.get_yticklabels():
                ytl.set_visible(False)
            for ytick in ax.get_yticklines():
                ytick.set_visible(False)

        if self.grid.visible == True:
            self.grid.draw(fig, ax)

        if self.loglog or self.logx:
            myBase = None

            if self.logbasex is not None:
                myBase = self.logbasex
            else:
                myBase = self.logbase

            ax.set_xscale('log', basex=myBase)
        if self.loglog or self.logy:
            myBase = None

            if self.logbasey is not None:
                myBase = self.logbasey
            else:
                myBase = self.logbase

            ax.set_yscale('log', basey=myBase)

        if self.twinxIndex > 0:
            ax2 = ax.twinx()
            ax2.set_ylabel(self.twinxLabel)
            if self.twinxLimits is not None:
                ax2.set_ylim(ymin=self.twinxLimits[0], ymax=self.twinxLimits[1])

        plotHandles = []
        plotLabels = []

        if self.xFormatter is not None:
            ax.xaxis.set_major_formatter(self.xFormatter)

        if self.yFormatter is not None:
            ax.yaxis.set_major_formatter(self.yFormatter)

        if self.title is not None:
            ax.set_title(self.title, **self.titleProperties)

        i = 0
        myAxis = ax

        hasLineStyles = self.lineStyles is not None
        hasColors = self.lineColors is not None
        hasMarkers = self.markers is not None

        numLineStyles = 1
        numColors = 1
        numMarkers = 1

        if hasLineStyles:
            numLineStyles = len(self.lineStyles)

        if hasColors:
            numColors = len(self.lineColors)

        if hasMarkers:
            numMarkers = len(self.markers)

        plotIndex = 0

        for plotInfo in self.plots:
            if self.twinxIndex >= 0 and i == self.twinxIndex:
                myAxis = ax2

            myLineStyle = None
            myColor = None
            myMarker = None

            # cycle through styles first, then markers, then colors
            colorIndex = (plotIndex / (numMarkers * numLineStyles)) % numColors
            markerIndex = int(plotIndex / numLineStyles) % numMarkers
            lineStyleIndex = plotIndex % numLineStyles

            if hasLineStyles:
                myLineStyle = self.lineStyles[lineStyleIndex].style

            if hasColors:
                myColor =  self.lineColors[colorIndex]

            if hasMarkers:
                myMarker = self.markers[markerIndex].marker


            plotIndex += 1

            if myLineStyle is not None:
                plotInfo.lineStyle = myLineStyle

            if myMarker is not None:
                plotInfo.marker = myMarker

            if myColor is not None:
                plotInfo.color = myColor

            plotInfo._preDraw()
            (currPlotHandles, currPlotLabels) = plotInfo.draw(fig, myAxis)

            labelIndices = [x for x in range(len(currPlotLabels)) \
                                if currPlotLabels[x] is not None]

            if len(labelIndices) > 0:
                plotHandles.extend([currPlotHandles[x] for x in labelIndices])
                plotLabels.extend([currPlotLabels[x] for x in labelIndices])

            if plotInfo.xLimits is not None:
                if self.xLimits is None:
                    self.xLimits = plotInfo.xLimits
                else:
                    (myXMin, myXMax) = plotInfo.xLimits
                    self.xLimits = (min(self.xLimits[0], myXMin),
                                 max(self.xLimits[1], myXMax))

            i += 1

        if self.xLimits is not None:
            ax.set_xlim(xmin=self.xLimits[0], xmax=self.xLimits[1])

        if self.yLimits is not None:
            ax.set_ylim(ymin=self.yLimits[0], ymax=self.yLimits[1])


        if self.xLabel is not None:
            ax.set_xlabel(self.xLabel, **self.xLabelProperties)

        if self.yLabel is not None:
            ax.set_ylabel(self.yLabel, **self.yLabelProperties)

        if self.legend is not None:
            if len(plotHandles) == 0:
                print >>sys.stderr, "ERROR: Plot wanted to draw a legend, " \
                    "but none of its elements have labels"
                sys.exit(1)

            if self.twinxIndex > 0:
                legendAxis = ax2
            else:
                legendAxis = ax

            self.legend.draw(fig, legendAxis, plotHandles, plotLabels)

        return (plotHandles, plotLabels)