summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorPicca Frédéric-Emmanuel <picca@debian.org>2017-10-07 07:59:01 +0200
committerPicca Frédéric-Emmanuel <picca@debian.org>2017-10-07 07:59:01 +0200
commitbfa4dba15485b4192f8bbe13345e9658c97ecf76 (patch)
treefb9c6e5860881fbde902f7cbdbd41dc4a3a9fb5d /examples
parentf7bdc2acff3c13a6d632c28c4569690ab106eed7 (diff)
New upstream version 0.6.0+dfsg
Diffstat (limited to 'examples')
-rw-r--r--examples/customHdf5TreeModel.py290
-rwxr-xr-xexamples/fftPlotAction.py20
-rw-r--r--examples/icons.py10
-rw-r--r--examples/plotContextMenu.py100
-rwxr-xr-x[-rw-r--r--]examples/plotItemsSelector.py (renamed from examples/colorbar.py)50
-rw-r--r--examples/plotLimits.py93
-rw-r--r--examples/plotUpdateFromThread.py128
-rw-r--r--examples/plotWidget.py121
-rwxr-xr-xexamples/printPreview.py82
-rwxr-xr-xexamples/shiftPlotAction.py2
-rw-r--r--examples/syncaxis.py101
-rw-r--r--examples/viewer3DVolume.py27
-rw-r--r--[-rwxr-xr-x]examples/writetoh5.py (renamed from examples/spectoh5.py)20
13 files changed, 983 insertions, 61 deletions
diff --git a/examples/customHdf5TreeModel.py b/examples/customHdf5TreeModel.py
new file mode 100644
index 0000000..8bd444a
--- /dev/null
+++ b/examples/customHdf5TreeModel.py
@@ -0,0 +1,290 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""Qt Hdf5 widget examples
+"""
+
+import logging
+import sys
+import tempfile
+import numpy
+import h5py
+
+logging.basicConfig()
+_logger = logging.getLogger("customHdf5TreeModel")
+"""Module logger"""
+
+from silx.gui import qt
+import silx.gui.hdf5
+from silx.gui.data.DataViewerFrame import DataViewerFrame
+from silx.gui.widgets.ThreadPoolPushButton import ThreadPoolPushButton
+from silx.gui.hdf5.Hdf5TreeModel import Hdf5TreeModel
+
+
+class CustomTooltips(qt.QIdentityProxyModel):
+ """Custom the tooltip of the model by composition.
+
+ It is a very stable way to custom it cause it uses the Qt API. Then it will
+ not change according to the version of Silx.
+
+ But it is not well integrated if you only want to add custom fields to the
+ default tooltips.
+ """
+
+ def data(self, index, role=qt.Qt.DisplayRole):
+ if role == qt.Qt.ToolTipRole:
+
+ # Reach information from the node
+ sourceIndex = self.mapToSource(index)
+ sourceModel = self.sourceModel()
+ originalTooltip = sourceModel.data(sourceIndex, qt.Qt.ToolTipRole)
+ originalH5pyObject = sourceModel.data(sourceIndex, Hdf5TreeModel.H5PY_OBJECT_ROLE)
+
+ # We can filter according to the column
+ if sourceIndex.column() == Hdf5TreeModel.TYPE_COLUMN:
+ return super(CustomTooltips, self).data(index, role)
+
+ # Let's create our own tooltips
+ template = u"""<html>
+ <dl>
+ <dt><b>Original</b></dt><dd>{original}</dd>
+ <dt><b>Parent name</b></dt><dd>{parent_name}</dd>
+ <dt><b>Name</b></dt><dd>{name}</dd>
+ <dt><b>Power of 2</b></dt><dd>{pow_of_2}</dd>
+ </dl>
+ </html>
+ """
+
+ try:
+ data = originalH5pyObject[()]
+ if data.size <= 10:
+ result = data ** 2
+ else:
+ result = "..."
+ except Exception:
+ result = "NA"
+
+ info = dict(
+ original=originalTooltip,
+ parent_name=originalH5pyObject.parent.name,
+ name=originalH5pyObject.name,
+ pow_of_2=str(result)
+ )
+ return template.format(**info)
+
+ return super(CustomTooltips, self).data(index, role)
+
+
+_file_cache = {}
+
+
+def get_hdf5_with_all_types():
+ global _file_cache
+ ID = "alltypes"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+
+ g = h5.create_group("arrays")
+ g.create_dataset("scalar", data=10)
+ g.create_dataset("list", data=numpy.arange(10))
+ base_image = numpy.arange(10**2).reshape(10, 10)
+ images = [base_image,
+ base_image.T,
+ base_image.size - 1 - base_image,
+ base_image.size - 1 - base_image.T]
+ dtype = images[0].dtype
+ data = numpy.empty((10 * 10, 10, 10), dtype=dtype)
+ for i in range(10 * 10):
+ data[i] = images[i % 4]
+ data.shape = 10, 10, 10, 10
+ g.create_dataset("image", data=data[0, 0])
+ g.create_dataset("cube", data=data[0])
+ g.create_dataset("hypercube", data=data)
+ g = h5.create_group("dtypes")
+ g.create_dataset("int32", data=numpy.int32(10))
+ g.create_dataset("int64", data=numpy.int64(10))
+ g.create_dataset("float32", data=numpy.float32(10))
+ g.create_dataset("float64", data=numpy.float64(10))
+ g.create_dataset("string_", data=numpy.string_("Hi!"))
+ # g.create_dataset("string0",data=numpy.string0("Hi!\x00"))
+
+ g.create_dataset("bool", data=True)
+ g.create_dataset("bool2", data=False)
+ h5.close()
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+class Hdf5TreeViewExample(qt.QMainWindow):
+ """
+ This window show an example of use of a Hdf5TreeView.
+
+ The tree is initialized with a list of filenames. A panel allow to play
+ with internal property configuration of the widget, and a text screen
+ allow to display events.
+ """
+
+ def __init__(self, filenames=None):
+ """
+ :param files_: List of HDF5 or Spec files (pathes or
+ :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
+ instances)
+ """
+ qt.QMainWindow.__init__(self)
+ self.setWindowTitle("Silx HDF5 widget example")
+
+ self.__asyncload = False
+ self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
+ """Silx HDF5 TreeView"""
+
+ self.__sourceModel = self.__treeview.model()
+ """Store the source model"""
+
+ self.__text = qt.QTextEdit(self)
+ """Widget displaying information"""
+
+ self.__dataViewer = DataViewerFrame(self)
+ vSpliter = qt.QSplitter(qt.Qt.Vertical)
+ vSpliter.addWidget(self.__dataViewer)
+ vSpliter.addWidget(self.__text)
+ vSpliter.setSizes([10, 0])
+
+ spliter = qt.QSplitter(self)
+ spliter.addWidget(self.__treeview)
+ spliter.addWidget(vSpliter)
+ spliter.setStretchFactor(1, 1)
+
+ main_panel = qt.QWidget(self)
+ layout = qt.QVBoxLayout()
+ layout.addWidget(spliter)
+ layout.addWidget(self.createTreeViewConfigurationPanel(self, self.__treeview))
+ layout.setStretchFactor(spliter, 1)
+ main_panel.setLayout(layout)
+
+ self.setCentralWidget(main_panel)
+
+ # append all files to the tree
+ for file_name in filenames:
+ self.__treeview.findHdf5TreeModel().appendFile(file_name)
+
+ self.__treeview.activated.connect(self.displayData)
+
+ def displayData(self):
+ """Called to update the dataviewer with the selected data.
+ """
+ selected = list(self.__treeview.selectedH5Nodes())
+ if len(selected) == 1:
+ # Update the viewer for a single selection
+ data = selected[0]
+ # data is a hdf5.H5Node object
+ # data.h5py_object is a Group/Dataset object (from h5py, spech5, fabioh5)
+ # The dataviewer can display both
+ self.__dataViewer.setData(data)
+
+ def __fileCreated(self, filename):
+ if self.__asyncload:
+ self.__treeview.findHdf5TreeModel().insertFileAsync(filename)
+ else:
+ self.__treeview.findHdf5TreeModel().insertFile(filename)
+
+ def __hdf5ComboChanged(self, index):
+ function = self.__hdf5Combo.itemData(index)
+ self.__createHdf5Button.setCallable(function)
+
+ def __edfComboChanged(self, index):
+ function = self.__edfCombo.itemData(index)
+ self.__createEdfButton.setCallable(function)
+
+ def __useCustomLabel(self):
+ customModel = CustomTooltips(self.__treeview)
+ customModel.setSourceModel(self.__sourceModel)
+ self.__treeview.setModel(customModel)
+
+ def __useOriginalModel(self):
+ self.__treeview.setModel(self.__sourceModel)
+
+ def createTreeViewConfigurationPanel(self, parent, treeview):
+ """Create a configuration panel to allow to play with widget states"""
+ panel = qt.QWidget(parent)
+ panel.setLayout(qt.QHBoxLayout())
+
+ content = qt.QGroupBox("Create HDF5", panel)
+ content.setLayout(qt.QVBoxLayout())
+ panel.layout().addWidget(content)
+
+ combo = qt.QComboBox()
+ combo.addItem("Containing all types", get_hdf5_with_all_types)
+ combo.activated.connect(self.__hdf5ComboChanged)
+ content.layout().addWidget(combo)
+
+ button = ThreadPoolPushButton(content, text="Create")
+ button.setCallable(combo.itemData(combo.currentIndex()))
+ button.succeeded.connect(self.__fileCreated)
+ content.layout().addWidget(button)
+
+ self.__hdf5Combo = combo
+ self.__createHdf5Button = button
+
+ content.layout().addStretch(1)
+
+ option = qt.QGroupBox("Custom model", panel)
+ option.setLayout(qt.QVBoxLayout())
+ panel.layout().addWidget(option)
+
+ button = qt.QPushButton("Original model")
+ button.clicked.connect(self.__useOriginalModel)
+ option.layout().addWidget(button)
+
+ button = qt.QPushButton("Custom tooltips by composition")
+ button.clicked.connect(self.__useCustomLabel)
+ option.layout().addWidget(button)
+
+ option.layout().addStretch(1)
+
+ panel.layout().addStretch(1)
+ return panel
+
+
+def main(filenames):
+ """
+ :param filenames: list of file paths
+ """
+ app = qt.QApplication([])
+ sys.excepthook = qt.exceptionHandler
+ window = Hdf5TreeViewExample(filenames)
+ window.show()
+ result = app.exec_()
+ # remove ending warnings relative to QTimer
+ app.deleteLater()
+ sys.exit(result)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/examples/fftPlotAction.py b/examples/fftPlotAction.py
index e4d4081..66ecfbd 100755
--- a/examples/fftPlotAction.py
+++ b/examples/fftPlotAction.py
@@ -40,7 +40,7 @@ See shiftPlotAction.py for a simpler example with more basic comments.
"""
__authors__ = ["P. Knobel"]
__license__ = "MIT"
-__date__ = "12/01/2017"
+__date__ = "27/06/2017"
import numpy
import os
@@ -48,7 +48,7 @@ import sys
from silx.gui import qt
from silx.gui.plot import PlotWindow
-from silx.gui.plot.PlotActions import PlotAction
+from silx.gui.plot.actions import PlotAction
# Custom icon
# make sure there is a "fft.png" file saved in the same folder as this script
@@ -77,8 +77,8 @@ class FftAction(PlotAction):
def _rememberGraphLabels(self):
"""Store labels and title as attributes"""
self.original_title = self.plot.getGraphTitle()
- self.original_xlabel = self.plot.getGraphXLabel()
- self.original_ylabel = self.plot.getGraphYLabel()
+ self.original_xlabel = self.plot.getXAxis().getLabel()
+ self.original_ylabel = self.plot.getYAxis().getLabel()
def fftAllCurves(self, checked=False):
"""Get all curves from our PlotWindow, compute the amplitude spectrum
@@ -97,13 +97,13 @@ class FftAction(PlotAction):
self._rememberGraphLabels()
# change them
self.plot.setGraphTitle("Amplitude spectrum")
- self.plot.setGraphXLabel("Frequency")
- self.plot.setGraphYLabel("Amplitude")
+ self.plot.getXAxis().setLabel("Frequency")
+ self.plot.getYAxis().setLabel("Amplitude")
else:
# restore original labels
self.plot.setGraphTitle(self.original_title)
- self.plot.setGraphXLabel(self.original_xlabel)
- self.plot.setGraphYLabel(self.original_ylabel)
+ self.plot.getXAxis().setLabel(self.original_xlabel)
+ self.plot.getYAxis().setLabel(self.original_ylabel)
self.plot.clearCurves()
@@ -186,8 +186,8 @@ plotwin.addCurve(x, y2, legend="cos")
plotwin.addCurve(x, y3, legend="square wave")
plotwin.setGraphTitle("Original data")
-plotwin.setGraphYLabel("amplitude")
-plotwin.setGraphXLabel("time")
+plotwin.getYAxis().setLabel("amplitude")
+plotwin.getXAxis().setLabel("time")
plotwin.show()
app.exec_()
diff --git a/examples/icons.py b/examples/icons.py
index 0992cf4..a6f0ada 100644
--- a/examples/icons.py
+++ b/examples/icons.py
@@ -26,10 +26,10 @@
"""
Display available project icons using Qt.
"""
+import functools
+
from silx.gui import qt
import silx.gui.icons
-import pkg_resources
-import functools
class IconPreview(qt.QMainWindow):
@@ -74,9 +74,11 @@ class IconPreview(qt.QMainWindow):
self.tools = []
- icons = pkg_resources.resource_listdir("silx.resources", "gui/icons")
+ import silx.resources
+
+ icons = silx.resources.list_dir("gui/icons")
# filter out sub-directories
- icons = filter(lambda x: not pkg_resources.resource_isdir("silx.resources", "gui/icons/" + x), icons)
+ icons = filter(lambda x: not silx.resources.is_dir("gui/icons/" + x), icons)
# remove extension
icons = [i.split(".")[0] for i in icons]
# remove duplicated names
diff --git a/examples/plotContextMenu.py b/examples/plotContextMenu.py
new file mode 100644
index 0000000..3e9af1e
--- /dev/null
+++ b/examples/plotContextMenu.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""This script illustrates the addition of a context menu to a PlotWidget.
+
+This is done by adding a custom context menu to the plot area of PlotWidget:
+- set the context menu policy of the plot area to Qt.CustomContextMenu.
+- connect to the plot area customContextMenuRequested signal.
+
+The same method works with PlotWindow, Plot1D and Plot2D widgets as they
+inherit from PlotWidget.
+
+For more information on context menus, see Qt documentation.
+"""
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.plot import PlotWidget
+from silx.gui.plot.actions.control import ZoomBackAction, CrosshairAction
+from silx.gui.plot.actions.io import SaveAction, PrintAction
+
+
+class PlotWidgetWithContextMenu(PlotWidget):
+ """This class adds a custom context menu to PlotWidget's plot area."""
+
+ def __init__(self, *args, **kwargs):
+ super(PlotWidgetWithContextMenu, self).__init__(*args, **kwargs)
+ self.setWindowTitle('PlotWidget with a context menu')
+ self.setGraphTitle('Right-click on the plot to access context menu')
+
+ # Create QAction for the context menu once for all
+ self._zoomBackAction = ZoomBackAction(plot=self, parent=self)
+ self._crosshairAction = CrosshairAction(plot=self, parent=self)
+ self._saveAction = SaveAction(plot=self, parent=self)
+ self._printAction = PrintAction(plot=self, parent=self)
+
+ # Retrieve PlotWidget's plot area widget
+ plotArea = self.getWidgetHandle()
+
+ # Set plot area custom context menu
+ plotArea.setContextMenuPolicy(qt.Qt.CustomContextMenu)
+ plotArea.customContextMenuRequested.connect(self._contextMenu)
+
+ def _contextMenu(self, pos):
+ """Handle plot area customContextMenuRequested signal.
+
+ :param QPoint pos: Mouse position relative to plot area
+ """
+ # Create the context menu
+ menu = qt.QMenu(self)
+ menu.addAction(self._zoomBackAction)
+ menu.addSeparator()
+ menu.addAction(self._crosshairAction)
+ menu.addSeparator()
+ menu.addAction(self._saveAction)
+ menu.addAction(self._printAction)
+
+ # Displaying the context menu at the mouse position requires
+ # a global position.
+ # The position received as argument is relative to PlotWidget's
+ # plot area, and thus needs to be converted.
+ plotArea = self.getWidgetHandle()
+ globalPosition = plotArea.mapToGlobal(pos)
+ menu.exec_(globalPosition)
+
+
+# Start the QApplication
+app = qt.QApplication([]) # Start QApplication
+plot = PlotWidgetWithContextMenu() # Create the widget
+
+# Add content to the plot
+x = numpy.linspace(0, 2 * numpy.pi, 1000)
+plot.addCurve(x, numpy.sin(x), legend='sin')
+
+# Show the widget and start the application
+plot.show()
+app.exec_()
diff --git a/examples/colorbar.py b/examples/plotItemsSelector.py
index a4dc2d8..8f29457 100644..100755
--- a/examples/colorbar.py
+++ b/examples/plotItemsSelector.py
@@ -2,7 +2,7 @@
# coding: utf-8
# /*##########################################################################
#
-# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
+# Copyright (c) 2017 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -23,40 +23,34 @@
# THE SOFTWARE.
#
# ###########################################################################*/
+"""This example illustrates how to use a :class:`ItemsSelectionDialog` widget
+associated with a :class:`PlotWidget`.
"""
-Example to show the use of `ColorBarWidget` widget.
-It can be associated to a plot.
-In this exqmple the `ColorBarWidget` widget will display the colormap of the
-active image.
-
-To change the active image slick on the image you want to set active.
-"""
-
-__authors__ = ["H. Payno"]
+__authors__ = ["P. Knobel"]
__license__ = "MIT"
-__date__ = "03/05/2017"
-
+__date__ = "28/06/2017"
from silx.gui import qt
-import numpy
-from silx.gui.plot import Plot2D
-from silx.gui.plot.ColorBar import ColorBarWidget
-
-image = numpy.exp(numpy.random.rand(100, 100) * 10)
+from silx.gui.plot.PlotWidget import PlotWidget
+from silx.gui.plot.ItemsSelectionDialog import ItemsSelectionDialog
app = qt.QApplication([])
-plot = Plot2D()
-colorbar = ColorBarWidget(parent=None, plot=plot)
-colorbar.setLegend('my colormap')
-colorbar.show()
-plot.show()
-
-clm = plot.getDefaultColormap()
-clm['normalization'] = 'log'
-clm['name'] = 'viridis'
-plot.addImage(data=image, colormap=clm, legend='image')
-plot.setActiveImage('image')
+pw = PlotWidget()
+pw.addCurve([0, 1, 2], [3, 2, 1], "A curve")
+pw.addScatter([0, 1, 2.5], [3, 2.5, 0.9], [8, 9, 72], "A scatter")
+pw.addHistogram([0, 1, 2.5], [0, 1, 2, 3], "A histogram")
+pw.addImage([[0, 1, 2], [3, 2, 1]], "An image")
+pw.show()
+
+isd = ItemsSelectionDialog(plot=pw)
+isd.setItemsSelectionMode(qt.QTableWidget.ExtendedSelection)
+result = isd.exec_()
+if result:
+ for item in isd.getSelectedItems():
+ print(item.getLegend(), type(item))
+else:
+ print("Selection cancelled")
app.exec_()
diff --git a/examples/plotLimits.py b/examples/plotLimits.py
new file mode 100644
index 0000000..0a39bc6
--- /dev/null
+++ b/examples/plotLimits.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""This script is an example to illustrate how to use axis synchronization
+tool.
+"""
+
+from silx.gui import qt
+from silx.gui import plot
+import numpy
+import silx.test.utils
+
+
+class ConstrainedViewPlot(qt.QMainWindow):
+
+ def __init__(self):
+ qt.QMainWindow.__init__(self)
+ self.setWindowTitle("Plot with synchronized axes")
+ widget = qt.QWidget(self)
+ self.setCentralWidget(widget)
+
+ layout = qt.QGridLayout()
+ widget.setLayout(layout)
+
+ backend = "mpl"
+
+ data = numpy.arange(100 * 100)
+ data = (data % 100) / 5.0
+ data = numpy.sin(data)
+ data = silx.test.utils.add_gaussian_noise(data, mean=0.01)
+ data.shape = 100, 100
+
+ data1d = numpy.mean(data, axis=0)
+
+ self.plot2d = plot.Plot2D(parent=widget, backend=backend)
+ self.plot2d.setGraphTitle("A pixel can't be too big")
+ self.plot2d.setInteractiveMode('pan')
+ self.plot2d.addImage(data)
+ self.plot2d.getXAxis().setRangeConstraints(minRange=10)
+ self.plot2d.getYAxis().setRangeConstraints(minRange=10)
+
+ self.plot2d2 = plot.Plot2D(parent=widget, backend=backend)
+ self.plot2d2.setGraphTitle("The image can't be too small")
+ self.plot2d2.setInteractiveMode('pan')
+ self.plot2d2.addImage(data)
+ self.plot2d2.getXAxis().setRangeConstraints(maxRange=200)
+ self.plot2d2.getYAxis().setRangeConstraints(maxRange=200)
+
+ self.plot1d = plot.Plot1D(parent=widget, backend=backend)
+ self.plot1d.setGraphTitle("The curve is clamped into the view")
+ self.plot1d.addCurve(x=numpy.arange(100), y=data1d, legend="mean")
+ self.plot1d.getXAxis().setLimitsConstraints(minPos=0, maxPos=100)
+ self.plot1d.getYAxis().setLimitsConstraints(minPos=data1d.min(), maxPos=data1d.max())
+
+ self.plot1d2 = plot.Plot1D(parent=widget, backend=backend)
+ self.plot1d2.setGraphTitle("Only clamp y-axis")
+ self.plot1d2.setInteractiveMode('pan')
+ self.plot1d2.addCurve(x=numpy.arange(100), y=data1d, legend="mean")
+ self.plot1d2.getYAxis().setLimitsConstraints(minPos=data1d.min(), maxPos=data1d.max())
+
+ layout.addWidget(self.plot2d, 0, 0)
+ layout.addWidget(self.plot1d, 0, 1)
+ layout.addWidget(self.plot2d2, 1, 0)
+ layout.addWidget(self.plot1d2, 1, 1)
+
+
+if __name__ == "__main__":
+ app = qt.QApplication([])
+ window = ConstrainedViewPlot()
+ window.setVisible(True)
+ app.exec_()
diff --git a/examples/plotUpdateFromThread.py b/examples/plotUpdateFromThread.py
new file mode 100644
index 0000000..d36bc48
--- /dev/null
+++ b/examples/plotUpdateFromThread.py
@@ -0,0 +1,128 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""This script illustrates the update of a silx.gui.plot widget from a thread.
+
+The problem is that plot and GUI methods should be called from the main thread.
+To safely update the plot from another thread, one need to make the update
+asynchronously from the main thread.
+In this example, this is achieved through a Qt signal.
+
+In this example we create a subclass of :class:`silx.gui.plot.Plot1D`
+that adds a thread-safe method to add curves:
+:meth:`ThreadSafePlot1D.addCurveThreadSafe`.
+This thread-safe method is then called from a thread to update the plot.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/09/2017"
+
+
+import threading
+import time
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.plot import Plot1D
+
+
+class ThreadSafePlot1D(Plot1D):
+ """Add a thread-safe :meth:`addCurveThreadSafe` method to Plot1D.
+ """
+
+ _sigAddCurve = qt.Signal(tuple, dict)
+ """Signal used to perform addCurve in the main thread.
+
+ It takes args and kwargs as arguments.
+ """
+
+ def __init__(self, parent=None):
+ super(ThreadSafePlot1D, self).__init__(parent)
+ # Connect the signal to the method actually calling addCurve
+ self._sigAddCurve.connect(self.__addCurve)
+
+ def __addCurve(self, args, kwargs):
+ """Private method calling addCurve from _sigAddCurve"""
+ self.addCurve(*args, **kwargs)
+
+ def addCurveThreadSafe(self, *args, **kwargs):
+ """Thread-safe version of :meth:`silx.gui.plot.Plot.addCurve`
+
+ This method takes the same arguments as Plot.addCurve.
+
+ WARNING: This method does not return a value as opposed to Plot.addCurve
+ """
+ self._sigAddCurve.emit(args, kwargs)
+
+
+class UpdateThread(threading.Thread):
+ """Thread updating the curve of a :class:`ThreadSafePlot1D`
+
+ :param plot1d: The ThreadSafePlot1D to update."""
+
+ def __init__(self, plot1d):
+ self.plot1d = plot1d
+ self.running = False
+ super(UpdateThread, self).__init__()
+
+ def start(self):
+ """Start the update thread"""
+ self.running = True
+ super(UpdateThread, self).start()
+
+ def run(self):
+ """Method implementing thread loop that updates the plot"""
+ while self.running:
+ time.sleep(1)
+ self.plot1d.addCurveThreadSafe(
+ numpy.arange(1000), numpy.random.random(1000), resetzoom=False)
+
+ def stop(self):
+ """Stop the update thread"""
+ self.running = False
+ self.join(2)
+
+
+def main():
+ global app
+ app = qt.QApplication([])
+
+ # Create a ThreadSafePlot1D, set its limits and display it
+ plot1d = ThreadSafePlot1D()
+ plot1d.setLimits(0., 1000., 0., 1.)
+ plot1d.show()
+
+ # Create the thread that calls ThreadSafePlot1D.addCurveThreadSafe
+ updateThread = UpdateThread(plot1d)
+ updateThread.start() # Start updating the plot
+
+ app.exec_()
+
+ updateThread.stop() # Stop updating the plot
+
+
+if __name__ == '__main__':
+ main()
diff --git a/examples/plotWidget.py b/examples/plotWidget.py
new file mode 100644
index 0000000..698fe56
--- /dev/null
+++ b/examples/plotWidget.py
@@ -0,0 +1,121 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""This script shows how to subclass :class:`PlotWidget` to tune its tools.
+
+It subclasses a :class:`silx.gui.plot.PlotWidget` and adds toolbars and
+a colorbar by using pluggable widgets:
+
+- QAction from :mod:`silx.gui.plot.actions`
+- QToolButton from :mod:`silx.gui.plot.PlotToolButtons`
+- QToolBar from :mod:`silx.gui.plot.PlotTools`
+- :class:`ColorBarWidget` from :mod:`silx.gui.plot.ColorBar`.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/09/2017"
+
+import numpy
+
+from silx.gui import qt
+import silx.gui.plot
+
+from silx.gui.plot import actions # QAction to use with PlotWidget
+from silx.gui.plot import PlotToolButtons # QToolButton to use with PlotWidget
+from silx.gui.plot.PlotTools import LimitsToolBar
+from silx.gui.plot.ColorBar import ColorBarWidget
+
+class MyPlotWidget(silx.gui.plot.PlotWidget):
+ """PlotWidget with an ad hoc toolbar and a colorbar"""
+
+ def __init__(self, parent=None):
+ super(MyPlotWidget, self).__init__(parent)
+
+ # Add a tool bar to PlotWidget
+ toolBar = qt.QToolBar("Plot Tools", self)
+ self.addToolBar(toolBar)
+
+ # Add actions from silx.gui.plot.action to the toolbar
+ resetZoomAction = actions.control.ResetZoomAction(self, self)
+ toolBar.addAction(resetZoomAction)
+
+ # Add tool buttons from silx.gui.plot.PlotToolButtons
+ aspectRatioButton = PlotToolButtons.AspectToolButton(
+ parent=self, plot=self)
+ toolBar.addWidget(aspectRatioButton)
+
+ # Add limits tool bar from silx.gui.plot.PlotTools
+ limitsToolBar = LimitsToolBar(parent=self, plot=self)
+ self.addToolBar(qt.Qt.BottomToolBarArea, limitsToolBar)
+
+ self._initColorBar()
+
+ def _initColorBar(self):
+ """Create the ColorBarWidget and add it to the PlotWidget"""
+
+ # Add a colorbar on the right side
+ colorBar = ColorBarWidget(parent=self, plot=self)
+
+ # Make ColorBarWidget background white by changing its palette
+ colorBar.setAutoFillBackground(True)
+ palette = colorBar.palette()
+ palette.setColor(qt.QPalette.Background, qt.Qt.white)
+ palette.setColor(qt.QPalette.Window, qt.Qt.white)
+ colorBar.setPalette(palette)
+
+ # Add the ColorBarWidget by changing PlotWidget's central widget
+ gridLayout = qt.QGridLayout()
+ gridLayout.setSpacing(0)
+ gridLayout.setContentsMargins(0, 0, 0, 0)
+ plot = self.getWidgetHandle() # Get the widget rendering the plot
+ gridLayout.addWidget(plot, 0, 0)
+ gridLayout.addWidget(colorBar, 0, 1)
+ gridLayout.setRowStretch(0, 1)
+ gridLayout.setColumnStretch(0, 1)
+ centralWidget = qt.QWidget()
+ centralWidget.setLayout(gridLayout)
+ self.setCentralWidget(centralWidget)
+
+
+def main():
+ global app
+ app = qt.QApplication([])
+
+ # Create the ad hoc plot widget and change its default colormap
+ plot = MyPlotWidget()
+ plot.getDefaultColormap().setName('viridis')
+ plot.show()
+
+ # Add an image to the plot
+ x = numpy.outer(
+ numpy.linspace(-10, 10, 200), numpy.linspace(-10, 5, 150))
+ image = numpy.sin(x) / x
+ plot.addImage(image)
+
+ app.exec_()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/examples/printPreview.py b/examples/printPreview.py
new file mode 100755
index 0000000..187ad84
--- /dev/null
+++ b/examples/printPreview.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""This script illustrates how to add a print preview tool button to any plot
+widget inheriting :class:`PlotWidget`.
+
+Three plot widgets are instantiated. One of them uses a standalone
+:class:`PrintPreviewToolButton`, while the other two use a
+:class:`SingletonPrintPreviewToolButton` which allows them to send their content
+to the same print preview page.
+"""
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "25/07/2017"
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.plot import PlotWidget
+from silx.gui.plot import PrintPreviewToolButton
+
+app = qt.QApplication([])
+
+x = numpy.arange(1000)
+
+# first widget has a standalone print preview action
+pw1 = PlotWidget()
+pw1.setWindowTitle("Widget 1 with standalone print preview")
+toolbar1 = qt.QToolBar(pw1)
+toolbutton1 = PrintPreviewToolButton.PrintPreviewToolButton(parent=toolbar1,
+ plot=pw1)
+pw1.addToolBar(toolbar1)
+toolbar1.addWidget(toolbutton1)
+pw1.show()
+pw1.addCurve(x, numpy.tan(x * 2 * numpy.pi / 1000))
+
+# next two plots share a common print preview
+pw2 = PlotWidget()
+pw2.setWindowTitle("Widget 2 with shared print preview")
+toolbar2 = qt.QToolBar(pw2)
+toolbutton2 = PrintPreviewToolButton.SingletonPrintPreviewToolButton(
+ parent=toolbar2, plot=pw2)
+pw2.addToolBar(toolbar2)
+toolbar2.addWidget(toolbutton2)
+pw2.show()
+pw2.addCurve(x, numpy.sin(x * 2 * numpy.pi / 1000))
+
+
+pw3 = PlotWidget()
+pw3.setWindowTitle("Widget 3 with shared print preview")
+toolbar3 = qt.QToolBar(pw3)
+toolbutton3 = PrintPreviewToolButton.SingletonPrintPreviewToolButton(
+ parent=toolbar3, plot=pw3)
+pw3.addToolBar(toolbar3)
+toolbar3.addWidget(toolbutton3)
+pw3.show()
+pw3.addCurve(x, numpy.cos(x * 2 * numpy.pi / 1000))
+
+
+app.exec_()
diff --git a/examples/shiftPlotAction.py b/examples/shiftPlotAction.py
index ca48300..7cac08c 100755
--- a/examples/shiftPlotAction.py
+++ b/examples/shiftPlotAction.py
@@ -37,7 +37,7 @@ __date__ = "12/01/2017"
import sys
from silx.gui import qt
from silx.gui.plot import PlotWindow
-from silx.gui.plot.PlotActions import PlotAction
+from silx.gui.plot.actions import PlotAction
class ShiftUpAction(PlotAction):
diff --git a/examples/syncaxis.py b/examples/syncaxis.py
new file mode 100644
index 0000000..1033738
--- /dev/null
+++ b/examples/syncaxis.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""This script is an example to illustrate how to use axis synchronization
+tool.
+"""
+
+from silx.gui import qt
+from silx.gui import plot
+import numpy
+import silx.test.utils
+from silx.gui.plot.utils.axis import SyncAxes
+
+
+class SyncPlot(qt.QMainWindow):
+
+ def __init__(self):
+ qt.QMainWindow.__init__(self)
+ self.setWindowTitle("Plot with synchronized axes")
+ widget = qt.QWidget(self)
+ self.setCentralWidget(widget)
+
+ layout = qt.QGridLayout()
+ widget.setLayout(layout)
+
+ backend = "mpl"
+ self.plot2d = plot.Plot2D(parent=widget, backend=backend)
+ self.plot2d.setInteractiveMode('pan')
+ self.plot1d_x1 = plot.Plot1D(parent=widget, backend=backend)
+ self.plot1d_x2 = plot.PlotWidget(parent=widget, backend=backend)
+ self.plot1d_y1 = plot.Plot1D(parent=widget, backend=backend)
+ self.plot1d_y2 = plot.PlotWidget(parent=widget, backend=backend)
+
+ data = numpy.arange(100 * 100)
+ data = (data % 100) / 5.0
+ data = numpy.sin(data)
+ data = silx.test.utils.add_gaussian_noise(data, mean=0.01)
+ data.shape = 100, 100
+
+ self.plot2d.addImage(data)
+ self.plot1d_x1.addCurve(x=numpy.arange(100), y=numpy.mean(data, axis=0), legend="mean")
+ self.plot1d_x1.addCurve(x=numpy.arange(100), y=numpy.max(data, axis=0), legend="max")
+ self.plot1d_x1.addCurve(x=numpy.arange(100), y=numpy.min(data, axis=0), legend="min")
+ self.plot1d_x2.addCurve(x=numpy.arange(100), y=numpy.std(data, axis=0))
+
+ self.plot1d_y1.addCurve(y=numpy.arange(100), x=numpy.mean(data, axis=1), legend="mean")
+ self.plot1d_y1.addCurve(y=numpy.arange(100), x=numpy.max(data, axis=1), legend="max")
+ self.plot1d_y1.addCurve(y=numpy.arange(100), x=numpy.min(data, axis=1), legend="min")
+ self.plot1d_y2.addCurve(y=numpy.arange(100), x=numpy.std(data, axis=1))
+
+ self.constraint1 = SyncAxes([self.plot2d.getXAxis(), self.plot1d_x1.getXAxis(), self.plot1d_x2.getXAxis()])
+ self.constraint2 = SyncAxes([self.plot2d.getYAxis(), self.plot1d_y1.getYAxis(), self.plot1d_y2.getYAxis()])
+ self.constraint3 = SyncAxes([self.plot1d_x1.getYAxis(), self.plot1d_y1.getXAxis()])
+ self.constraint4 = SyncAxes([self.plot1d_x2.getYAxis(), self.plot1d_y2.getXAxis()])
+
+ layout.addWidget(self.plot2d, 0, 0)
+ layout.addWidget(self.createCenteredLabel(u"↓↑"), 1, 0)
+ layout.addWidget(self.plot1d_x1, 2, 0)
+ layout.addWidget(self.createCenteredLabel(u"↓↑"), 3, 0)
+ layout.addWidget(self.plot1d_x2, 4, 0)
+ layout.addWidget(self.createCenteredLabel(u"→\n←"), 0, 1)
+ layout.addWidget(self.plot1d_y1, 0, 2)
+ layout.addWidget(self.createCenteredLabel(u"→\n←"), 0, 3)
+ layout.addWidget(self.plot1d_y2, 0, 4)
+ layout.addWidget(self.createCenteredLabel(u"↗↙"), 2, 2)
+ layout.addWidget(self.createCenteredLabel(u"↗↙"), 4, 4)
+
+ def createCenteredLabel(self, text):
+ label = qt.QLabel(self)
+ label.setAlignment(qt.Qt.AlignCenter)
+ label.setText(text)
+ return label
+
+
+if __name__ == "__main__":
+ app = qt.QApplication([])
+ window = SyncPlot()
+ window.setVisible(True)
+ app.exec_()
diff --git a/examples/viewer3DVolume.py b/examples/viewer3DVolume.py
index 7a95d8a..82022f9 100644
--- a/examples/viewer3DVolume.py
+++ b/examples/viewer3DVolume.py
@@ -101,6 +101,19 @@ def load(filename):
return data
+def default_isolevel(data):
+ """Compute a default isosurface level: mean + 1 std
+
+ :param numpy.ndarray data: The data to process
+ :rtype: float
+ """
+ data = data[numpy.isfinite(data)]
+ if len(data) == 0:
+ return 0
+ else:
+ return numpy.mean(data) + numpy.std(data)
+
+
def main(argv=None):
# Parse input arguments
parser = argparse.ArgumentParser(
@@ -171,11 +184,11 @@ def main(argv=None):
else:
# Create dummy data
_logger.warning('Not data file provided, creating dummy data')
- size = 128
- z, y, x = numpy.mgrid[0:size, 0:size, 0:size]
- data = numpy.asarray(
- size**2 - ((x-size/2)**2 + (y-size/2)**2 + (z-size/2)**2),
- dtype='float32')
+ coords = numpy.linspace(-10, 10, 64)
+ z = coords.reshape(-1, 1, 1)
+ y = coords.reshape(1, -1, 1)
+ x = coords.reshape(1, 1, -1)
+ data = numpy.sin(x * y * z) / (x * y * z)
# Set ScalarFieldView data
window.setData(data)
@@ -195,9 +208,7 @@ def main(argv=None):
window.addIsosurface(args.level, '#FF0000FF')
else:
# Add an iso-surface from a function
- window.addIsosurface(
- lambda data: numpy.mean(data) + numpy.std(data),
- '#FF0000FF')
+ window.addIsosurface(default_isolevel, '#FF0000FF')
window.show()
return app.exec_()
diff --git a/examples/spectoh5.py b/examples/writetoh5.py
index f2f796b..5e89e48 100755..100644
--- a/examples/spectoh5.py
+++ b/examples/writetoh5.py
@@ -2,7 +2,7 @@
# coding: utf-8
# /*##########################################################################
#
-# Copyright (c) 2004-2016 European Synchrotron Radiation Facility
+# Copyright (c) 2004-2017 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
# THE SOFTWARE.
#
# ###########################################################################*/
-"""This script converts SPEC data files to HDF5 files.
+"""This script converts a supported data file (SPEC, EDF,...) to a HDF5 file.
By default, it creates a new output file or fails if the output file given
on the command line already exist, but the user can choose to overwrite
@@ -39,14 +39,14 @@ possible to specify a different target path.
__authors__ = ["P. Knobel"]
__license__ = "MIT"
-__date__ = "18/10/2016"
+__date__ = "12/09/2016"
import argparse
-from silx.io.spectoh5 import write_spec_to_h5
+from silx.io.convert import write_to_h5
parser = argparse.ArgumentParser(description=__doc__)
-parser.add_argument('spec_path',
- help='Path to input SPEC data file')
+parser.add_argument('input_path',
+ help='Path to input data file')
parser.add_argument('h5_path',
help='Path to output HDF5 file')
parser.add_argument('-t', '--target-path', default="/",
@@ -82,7 +82,7 @@ else:
# by default, use "write" mode and fail if file already exists
mode = "w-"
-write_spec_to_h5(args.spec_path, args.h5_path,
- h5path=args.target_path,
- mode=mode,
- overwrite_data=args.overwrite_data)
+write_to_h5(args.input_path, args.h5_path,
+ h5path=args.target_path,
+ mode=mode,
+ overwrite_data=args.overwrite_data)