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 tickstick_label_formatter
- This function returns the tick label string for a given tick label valuetick_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_()