简体   繁体   中英

Minor ticks in Chaco plot?

The minor ticks in Chaco are always omitted: 在此处输入图片说明

This is not always convinient. Is it possible to have minor ticks in Chaco like ones in matplotlib:

在此处输入图片说明

Haven't found anything related.. Thanks.

Edit: This feature has now been added to Chaco 4.6, so if you're using this version or later, use the following similar code. If not see the original post below. Also see the documentation here and another example here .

if __name__ == "__main__":
    from traits.etsconfig.api import ETSConfig
    ETSConfig.toolkit = 'qt4'
    #
    import warnings
    warnings.filterwarnings(action = "ignore", category = FutureWarning, module="chaco")
    warnings.filterwarnings(action = "ignore", category = FutureWarning, module="traits")
#
from PySide import QtGui, QtCore
import numpy as np
from enable.api import Component, Container, Window
from chaco.api import *
import sys
#
class ChacoPlot(QtGui.QWidget):
    def __init__(self, parent=None):
        super(ChacoPlot, self).__init__(parent)
        #
        self.container = OverlayPlotContainer(padding=40)
        #
        self.enableWindow = Window(self, -1, component=self.container)
        windowLayout = QtGui.QVBoxLayout(self)
        windowLayout.addWidget(self.enableWindow.control)
        #
        self.xRange = DataRange1D()
        self.yRange = DataRange1D()
        #
        self.xMapper = LinearMapper(range=self.xRange)
        self.yMapper = LinearMapper(range=self.yRange)
        #
        self.plots = {}
        # keep a list of plots added to the container
    #
    def setMinimumSize(self, width, height):
        self.enableWindow.control.setMinimumSize(width, height)
    #
    def addLine(self, name, plotType):
        xSource = ArrayDataSource([0])
        ySource = ArrayDataSource([0])
        #
        self.xRange.add(xSource)
        self.yRange.add(ySource)
        #
        index_mapper = self.xMapper
        value_mapper = self.yMapper
        #
        # plotType is a class name
        plot = plotType(    index = xSource,
                            value = ySource,
                            index_mapper = index_mapper,
                            value_mapper = value_mapper,
                            visible = False
                       )
        #
        self.container.add(plot)
        #
        self.plots[name] = {'plot':plot, 'xSource':xSource, 'ySource':ySource}
    #
    def updateLine(self, name, xData, yData):
        plot = self.plots[name]
        #
        if np.array(xData).size != 0:
            plot['plot'].visible = True
        else:
            plot['plot'].visible = False
            xData = [0]
            yData = [0]
        #
        plot['xSource'].set_data(xData)
        plot['ySource'].set_data(yData)
    #
    def addAxis(self, plotName, orientation):
        plot = self.plots[plotName]['plot']
        #
        if orientation == 'top' or orientation == 'bottom':
            mapper = self.xMapper
        if orientation == 'left' or orientation == 'right':
            mapper = self.yMapper
        #
        axis = PlotAxis(plot, orientation=orientation, mapper=mapper)
        plot.overlays.append(axis)
        #
        return axis
    #
    def addMinorAxis(self, plotName, orientation):
        plot = self.plots[plotName]['plot']
        #
        if orientation == 'top' or orientation == 'bottom':
            mapper = self.xMapper
            range = self.xRange
        if orientation == 'left' or orientation == 'right':
            mapper = self.yMapper
            range = self.yRange
        #
        newAxis = MinorPlotAxis(plot, orientation=orientation, mapper=mapper)
        plot.overlays.append(newAxis)
        #
        return axis
    #
#
if __name__ == "__main__":
    appQT = QtGui.QApplication.instance()
    #
    x1 = np.arange(300)/18.0
    y1 = np.sin(x1)
    x2 = np.arange(300)/18.0
    y2 = 2.0*np.cos(x2)
    #
    plot = ChacoPlot()
    plot.setMinimumSize(400,300)
    #
    plot.addLine('line1', LinePlot)
    plot.addLine('line2', LinePlot)
    plot.updateLine('line1', x1, y1)
    plot.updateLine('line2', x2, y2)
    #
    plot.addAxis('line1', 'bottom')
    plot.addAxis('line1', 'left')
    plot.addMinorAxis('line1', 'bottom')
    plot.addMinorAxis('line1', 'left')
    #
    plot.show()
    appQT.exec_()

Original: Chaco doesn't have this feature specifically, but you can add minor ticks by adding an extra PlotAxis . You need to modify a few properties of the axis:

  • tick_generator - This object defines the position of the ticks
  • tick_label_formatter - This function returns the tick label string for a given tick label value
  • tick_in and tick_out - These numbers define the size of the ticks (in and out of the axis)

Here's an example. It's a lot of code, but it's fairly straightforward. Although it is common for people to make plots using the Plot helper class, I like to create plots manually since it's much easier to customize. Anyways hope it helps.

if __name__ == "__main__":
    from traits.etsconfig.api import ETSConfig
    ETSConfig.toolkit = 'qt4'
    #
    import warnings
    warnings.filterwarnings(action = "ignore", category = FutureWarning, module="chaco")
    warnings.filterwarnings(action = "ignore", category = FutureWarning, module="traits")
#
from PySide import QtGui, QtCore
import numpy as np
from enable.api import Component, Container, Window
from chaco.api import *
import sys
#
class ChacoPlot(QtGui.QWidget):
    def __init__(self, parent=None):
        super(ChacoPlot, self).__init__(parent)
        #
        self.container = OverlayPlotContainer(padding=40)
        #
        self.enableWindow = Window(self, -1, component=self.container)
        windowLayout = QtGui.QVBoxLayout(self)
        windowLayout.addWidget(self.enableWindow.control)
        #
        self.xRange = DataRange1D()
        self.yRange = DataRange1D()
        #
        self.xMapper = LinearMapper(range=self.xRange)
        self.yMapper = LinearMapper(range=self.yRange)
        #
        self.plots = {}
        # keep a list of plots added to the container
    #
    def setMinimumSize(self, width, height):
        self.enableWindow.control.setMinimumSize(width, height)
    #
    def addLine(self, name, plotType):
        xSource = ArrayDataSource([0])
        ySource = ArrayDataSource([0])
        #
        self.xRange.add(xSource)
        self.yRange.add(ySource)
        #
        index_mapper = self.xMapper
        value_mapper = self.yMapper
        #
        # plotType is a class name
        plot = plotType(    index = xSource,
                            value = ySource,
                            index_mapper = index_mapper,
                            value_mapper = value_mapper,
                            visible = False
                       )
        #
        self.container.add(plot)
        #
        self.plots[name] = {'plot':plot, 'xSource':xSource, 'ySource':ySource}
    #
    def updateLine(self, name, xData, yData):
        plot = self.plots[name]
        #
        if np.array(xData).size != 0:
            plot['plot'].visible = True
        else:
            plot['plot'].visible = False
            xData = [0]
            yData = [0]
        #
        plot['xSource'].set_data(xData)
        plot['ySource'].set_data(yData)
    #
    def addAxis(self, plotName, orientation):
        plot = self.plots[plotName]['plot']
        #
        if orientation == 'top' or orientation == 'bottom':
            mapper = self.xMapper
        if orientation == 'left' or orientation == 'right':
            mapper = self.yMapper
        #
        axis = PlotAxis(plot, orientation=orientation, mapper=mapper)
        plot.overlays.append(axis)
        #
        return axis
    #
    def addMinorAxis(self, plotName, orientation):
        plot = self.plots[plotName]['plot']
        #
        if orientation == 'top' or orientation == 'bottom':
            mapper = self.xMapper
            range = self.xRange
        if orientation == 'left' or orientation == 'right':
            mapper = self.yMapper
            range = self.yRange
        #
        newAxis = PlotAxis(plot, orientation=orientation, mapper=mapper)
        plot.overlays.append(newAxis)
        #
        newAxis.tick_generator = MinorTickGenerator()
        #
        newAxis.tick_label_formatter  = lambda x: ''
        newAxis.tick_in  = 2
        newAxis.tick_out = 2
    #
#
class MinorTickGenerator(AbstractTickGenerator):
    def __init__(self):
        super(MinorTickGenerator, self).__init__()
    #
    def get_ticks(self, data_low, data_high, bounds_low, bounds_high, interval, use_endpoints=False, scale='linear'):
        interval = interval
        #
        if interval == 'auto':
            interval = auto_interval(data_low, data_high)/5.0
        #
        return auto_ticks(data_low, data_high, bounds_low, bounds_high, interval, use_endpoints)
    #
#
if __name__ == "__main__":
    appQT = QtGui.QApplication.instance()
    #
    x1 = np.arange(300)/18.0
    y1 = np.sin(x1)
    x2 = np.arange(300)/18.0
    y2 = 2.0*np.cos(x2)
    #
    plot = ChacoPlot()
    plot.setMinimumSize(400,300)
    #
    plot.addLine('line1', LinePlot)
    plot.addLine('line2', LinePlot)
    plot.updateLine('line1', x1, y1)
    plot.updateLine('line2', x2, y2)
    #
    plot.addAxis('line1', 'bottom')
    plot.addAxis('line1', 'left')
    plot.addMinorAxis('line1', 'bottom')
    plot.addMinorAxis('line1', 'left')
    #
    plot.show()
    appQT.exec_()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM