From 270d5ddc31c26b62379e3caa9044dd75ccc71847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Picca=20Fr=C3=A9d=C3=A9ric-Emmanuel?= Date: Sun, 4 Mar 2018 10:20:27 +0100 Subject: New upstream version 0.7.0+dfsg --- doc/source/modules/gui/plot/getting_started.rst | 259 +++++++++--------------- 1 file changed, 100 insertions(+), 159 deletions(-) (limited to 'doc/source/modules/gui/plot/getting_started.rst') diff --git a/doc/source/modules/gui/plot/getting_started.rst b/doc/source/modules/gui/plot/getting_started.rst index 484d3f7..bfea8f2 100644 --- a/doc/source/modules/gui/plot/getting_started.rst +++ b/doc/source/modules/gui/plot/getting_started.rst @@ -1,3 +1,7 @@ + +.. role:: python(code) + :language: python + .. currentmodule:: silx.gui Getting started with plot widgets @@ -5,30 +9,40 @@ Getting started with plot widgets This introduction to :mod:`silx.gui.plot` covers the following topics: -- `Use silx.gui.plot from the console`_ +- `Use silx.gui.plot from (I)Python console`_ - `Use silx.gui.plot from a script`_ - `Plot curves in a widget`_ - `Plot images in a widget`_ -- `Control plot axes`_ +- `Configure plot axes`_ For a complete description of the API, see :mod:`silx.gui.plot`. -Use :mod:`silx.gui.plot` from the console ------------------------------------------ +Use :mod:`silx.gui.plot` from (I)Python console +----------------------------------------------- + +The simplest way is to import the :mod:`silx.sx` module: + +>>> from silx import sx -From IPython -++++++++++++ +The :mod:`silx.sx` module initialises Qt and provides access to :mod:`silx.gui.plot` widgets and extra plot functions. -To run :mod:`silx.gui.plot` widgets from `IPython `_, IPython must be set to use Qt (and in case of using PyQt4 and Python 2.7, PyQt must be set ti use API version 2, see Explanation_ below). +.. note:: The :mod:`silx.sx` module does NOT initialise Qt and does NOT expose silx widget in a notebook. -As *silx* is performing some configuration of the Qt binding and `matplotlib `_, the safest way to use *silx* from IPython is to import :mod:`silx.gui.plot` first and then run either `%gui `_ qt or `%pylab `_ qt:: +Compatibility with IPython +++++++++++++++++++++++++++ + +To run :mod:`silx.gui` widgets from `IPython `_, +IPython must be set to use Qt (and in case of using PyQt4 and Python 2.7, +PyQt must be set to use API version 2, see note below for explanation). + +As *silx* is configuring the Qt binding and `matplotlib `_, the safest way to use *silx* from IPython is to import :mod:`silx.gui.plot` first and then run either `%gui `_ qt or `%pylab `_ qt:: In [1]: from silx.gui.plot import * In [2]: %pylab qt Alternatively, when using Python 2.7 and PyQt4, you can start IPython with the ``QT_API`` environment variable set to ``pyqt``. -On Linux and MacOS X, run:: +On Linux and MacOS X, run from the command line:: QT_API=pyqt ipython @@ -37,100 +51,33 @@ On Windows, run from the command line:: set QT_API=pyqt&&ipython -Explanation -........... - -PyQt4 used from Python 2.x provides 2 incompatible versions of QString and QVariant: - -- version 1, the legacy which is the default, and -- version 2, a more pythonic one, which is the only one supported by *silx*. +.. note:: PyQt4 used from Python 2.x provides 2 incompatible versions of QString and QVariant: -All other configurations (i.e., PyQt4 on Python 3.x, PySide, PyQt5, IPython QtConsole widget) uses version 2 only or as the default. + - version 1, the legacy version which is also the default, and + - version 2, a more pythonic one, which is the only one supported by *silx*. -For more information, see `IPython, PyQt and PySide `_. + All other configurations (i.e., PyQt4 on Python 3.x, PySide, PyQt5, IPython QtConsole widget) uses version 2. + For more information, see `IPython, PyQt and PySide `_. -From Python -+++++++++++ - -The :mod:`silx.sx` package is a convenient module to use silx from the console. -It sets-up Qt and provides functions for the main features of silx. - ->>> from silx import sx - -Alternatively, you can create a QApplication before using silx widgets: - ->>> from silx.gui import qt # Import Qt binding and do some set-up ->>> qapp = qt.QApplication([]) - ->>> from silx.gui.plot import * # Import plot widgets and set-up matplotlib - -.. currentmodule:: silx.sx Plot functions ++++++++++++++ -The :mod:`silx.sx` package provides 2 functions to plot curves and images from the (I)Python console in a widget with a set of tools: - -- :func:`plot`, and -- :func:`imshow`. - -For more features, use widgets directly (see `Plot curves in a widget`_ and `Plot images in a widget`_). - - -Curve: :func:`plot` -................... - -The following examples must run with a Qt QApplication initialized (see `Use silx.gui.plot from the console`_). - -First import :mod:`sx` function: - ->>> from silx import sx ->>> import numpy - -Plot a single curve given some values: - ->>> values = numpy.random.random(100) ->>> plot_1curve = sx.plot(values, title='Random data') - -Plot a single curve given the x and y values: - ->>> angles = numpy.linspace(0, numpy.pi, 100) ->>> sin_a = numpy.sin(angles) ->>> plot_sinus = sx.plot(angles, sin_a, -... xlabel='angle (radian)', ylabel='sin(a)') - -Plot many curves by giving a 2D array, provided xn, yn arrays: - ->>> plot_curves = sx.plot(x0, y0, x1, y1, x2, y2, ...) - -Plot curve with style giving a style string: - ->>> plot_styled = sx.plot(x0, y0, 'ro-', x1, y1, 'b.') - -See :func:`plot` for details. +The :mod:`silx.sx` module provides functions to plot curves and images with :mod:`silx.gui.plot` widgets: +- :func:`~silx.sx.plot` for curves, e.g., :python:`sx.plot(y)` or :python:`sx.plot(x, y)` +- :func:`~silx.sx.imshow` for images, e.g., :python:`sx.imshow(image)` -Image: :func:`imshow` -..................... +See :mod:`silx.sx` for documentation and how to use it. -This example plot a single image. - -First, import :mod:`silx.sx`: - ->>> from silx import sx ->>> import numpy - ->>> data = numpy.random.random(1024 * 1024).reshape(1024, 1024) ->>> plt = sx.imshow(data, title='Random data') - -See :func:`imshow` for more details. +For more features, use widgets directly (see `Plot curves in a widget`_ and `Plot images in a widget`_). Use :mod:`silx.gui.plot` from a script -------------------------------------- -A Qt GUI script must have a QApplication initialized before creating widgets: +A Qt GUI script must have a QApplication initialised before creating widgets: .. code-block:: python @@ -146,27 +93,22 @@ A Qt GUI script must have a QApplication initialized before creating widgets: [...] qapp.exec_() -Unless a Qt binding has already been loaded, :mod:`silx.gui.qt` uses the first Qt binding it founds by probing in the following order: PyQt5, PyQt4 and finally PySide. +Unless a Qt binding has already been loaded, :mod:`silx.gui.qt` uses one of the supported Qt bindings (PyQt4, PySide or PyQt5). If you prefer to choose the Qt binding yourself, import it before importing a module from :mod:`silx.gui`: .. code-block:: python - import PySide # Importing PySide will force silx to use it + import PyQt5.QtCore # Importing PyQt5 will force silx to use it from silx.gui import qt -.. warning:: - - :mod:`silx.gui.plot` widgets are not thread-safe. - All calls to :mod:`silx.gui.plot` widgets must be made from the main thread. - Plot curves in a widget ----------------------- -The :class:`Plot1D` widget provides a plotting area and a toolbar with tools useful for curves such as setting logarithmic scale or defining region of interest. +The :class:`~silx.gui.plot.PlotWindow.Plot1D` widget provides a plotting area and a toolbar with tools useful for curves such as setting a logarithmic scale or defining a region of interest. -First, create a :class:`Plot1D` widget: +First, create a :class:`~silx.gui.plot.PlotWindow.Plot1D` widget: .. code-block:: python @@ -183,15 +125,17 @@ To display a single curve, use the :meth:`.PlotWidget.addCurve` method: .. code-block:: python - plot.addCurve(x=(1, 2, 3), y=(3, 2, 1)) # Add a curve with default style + plot.addCurve(x=(1, 2, 3), y=(3, 2, 1), legend='curve') # Add a curve named 'curve' -When you need to update this curve, call :meth:`.PlotWidget.addCurve` again with the new values to display: +When you need to update this curve, first get the curve invoking :meth:`.PlotWidget.getCurve` and +update its points invoking the curve's :meth:`~silx.gui.plot.items.Curve.setData` method: .. code-block:: python - plot.addCurve(x=(1, 2, 3), y=(1, 2, 3)) # Replace the existing curve + mycurve = plot.getCurve('curve') # Retrieve the curve + mycurve.setData(x=(1, 2, 3), y=(1, 2, 3)) # Update its data -To clear the plotting area, call :meth:`.PlotWidget.clear`: +To clear the plot, call :meth:`.PlotWidget.clear`: .. code-block:: python @@ -201,7 +145,7 @@ To clear the plotting area, call :meth:`.PlotWidget.clear`: Multiple curves +++++++++++++++ -In order to display multiple curves at the same time, you need to provide a different ``legend`` string for each of them: +In order to display multiple curves in a frame, you need to provide a different ``legend`` string for each of them: .. code-block:: python @@ -213,14 +157,15 @@ In order to display multiple curves at the same time, you need to provide a diff plot.addCurve(x, numpy.random.random(len(x)), legend='random') -To update a curve, call :meth:`.PlotWidget.addCurve` with the ``legend`` of the curve you want to udpdate. -By default, the new curve will keep the same color (and style) as the curve it is updating: +To update a curve, call :meth:`.PlotWidget.getCurve` with the ``legend`` of the curve you want to update, +and update its data through :meth:`~silx.gui.plot.items.Curve.setData`: .. code-block:: python - plot.addCurve(x, numpy.random.random(len(x)) - 1., legend='random') + curve = plot.getCurve('random') + curve.setData(x, numpy.random.random(len(x)) - 1.) -To remove a curve from the plot, call :meth:`.PlotWidget.remove` with the ``legend`` of the curve you want to remove from the plot: +To remove a curve from the plot, call :meth:`.PlotWidget.remove` with the ``legend`` of the curve you want to remove: .. code-block:: python @@ -235,9 +180,9 @@ To clear the plotting area, call :meth:`.PlotWidget.clear`: Curve style +++++++++++ -By default, different curves will automatically use different styles to render, and keep the same style when updated. +By default, different curves will automatically be displayed using different styles, and keep the same style when updating the plot. -It is possible to specify the ``color`` of the curve, its ``linewidth`` and ``linestyle`` as well as the ``symbol`` to use as markers for data points (See :meth:`.PlotWidget.addCurve` for more details): +It is possible to specify the ``color`` of the curve, its ``linewidth`` and ``linestyle`` as well as the ``symbol`` to use as marker for data points (See :meth:`.PlotWidget.addCurve` for more details): .. code-block:: python @@ -262,24 +207,32 @@ It is possible to specify the ``color`` of the curve, its ``linewidth`` and ``li Histogram +++++++++ -Data can be displayed as an histogram. This must be specified when calling the the addCurve function. (using ``histogram``, See :meth:`.PlotWidget.addCurve` for more details ). +To display histograms, use :meth:`.PlotWidget.addHistogram`: -Histogram steps can be centered on x values or set at the left or the right of the given x values. +.. code-block:: python + + import numpy + values = numpy.arange(20) # Values of the histogram + edges = numpy.arange(21) # Edges of the bins (number of values + 1) + plot.addHistogram(values, edges, legend='histo1', fill=True, color='green') + +Alternatively, :meth:`.PlotWidget.addCurve` can be used to display histograms with the ``histogram`` argument. +(See :meth:`.PlotWidget.addCurve` for more details). .. code-block:: python import numpy x = numpy.arange(0, 20, 1) - plot.addCurve(x, x+1, histogram='center', fill=True, color='green') + plot.addCurve(x, x+1, legend='histo2', histogram='center', fill=False, color='black') -.. note:: You can also give x as edges. For this you must have len(x) = len(y) + 1 +Histogram bins can be centred on x values or set on the left hand side or the right hand side of the given x values. Plot images in a widget ----------------------- -The :class:`Plot2D` widget provides a plotting area and a toolbar with tools useful for images, such as keeping aspect ratio, changing the colormap or defining a mask. +The :class:`~silx.gui.plot.PlotWindow.Plot2D` widget provides a plotting area and a toolbar with tools useful for images, such as keeping the aspect ratio, changing the colormap or defining a mask. -First, create a :class:`Plot2D` widget: +First, create a :class:`~silx.gui.plot.PlotWindow.Plot2D` widget: .. code-block:: python @@ -288,7 +241,6 @@ First, create a :class:`Plot2D` widget: plot = Plot2D() # Create the plot widget plot.show() # Make the plot widget visible - One image +++++++++ @@ -299,46 +251,36 @@ To display a single image, use the :meth:`.PlotWidget.addImage` method: import numpy data = numpy.random.random(512 * 512).reshape(512, -1) # Create 2D image - plot.addImage(data) # Plot the 2D data set with default colormap - + plot.addImage(data, legend='image') # Plot the 2D data set with default colormap -To update this image, call :meth:`.PlotWidget.addImage` again with the new image to display: +To update this image, call :meth:`.PlotWidget.getImage` with its ``legend`` and +update its data with :meth:`~silx.gui.plot.items.Image.setData`: .. code-block:: python - # Create a RGB image - rgb_image = (numpy.random.random(512*512*3) * 255).astype(numpy.uint8) - rgb_image.shape = 512, 512, 3 + data2 = numpy.arange(512*512).reshape(512, 512) - plot.addImage(rgb_image) # Plot the RGB image instead of the previous data + image = plot.getImage('image') # Retrieve the image + image.setData(data2) # Update the displayed data +:meth:`.PlotWidget.addImage` supports both 2D arrays of data displayed with a colormap and RGB(A) images as 3D arrays of shape (height, width, color channels). -To clear the plotting area, call :meth:`.PlotWidget.clear`: +To clear the plot area, call :meth:`.PlotWidget.clear`: .. code-block:: python plot.clear() - Origin and scale ++++++++++++++++ -:meth:`.PlotWidget.addImage` supports both 2D arrays of data displayed with a colormap and RGB(A) images as 3D arrays of shape (height, width, color channels). -When displaying an image, it is possible to specify the ``origin`` and the ``scale`` of the image array in the plot area coordinates: +When displaying an image, it is possible to define the ``origin`` and the ``scale`` of the image array in the plot area coordinates: .. code-block:: python data = numpy.random.random(512 * 512).reshape(512, -1) - plot.addImage(data, origin=(100, 100), scale=(0.1, 0.1)) - -When updating an image, if ``origin`` and ``scale`` are not provided, the previous values will be used: - -.. code-block:: python - - data = numpy.random.random(512 * 512).reshape(512, -1) - plot.addImage(data) # Keep previous origin and scale - + plot.addImage(data, legend='image', origin=(100, 100), scale=(0.1, 0.1)) Colormap ++++++++ @@ -347,6 +289,8 @@ A ``colormap`` is described with a :class:`.Colormap` class as follows: .. code-block:: python + from silx.gui.plot.Colormap import Colormap + colormap = Colormap(name='gray', # Name of the colormap normalization='linear', # Either 'linear' or 'log' vmin=0.0, # If not autoscale, data value to bind to min of colormap @@ -354,7 +298,7 @@ A ``colormap`` is described with a :class:`.Colormap` class as follows: ) -At least the following colormap names are guaranteed to be available, but any colormap name from `matplotlib `_ (see `Choosing Colormaps `_) should work: +The following colormap names are guaranteed to be available: - gray - reversed gray @@ -367,14 +311,18 @@ At least the following colormap names are guaranteed to be available, but any co - inferno - plasma -It is possible to change the default colormap of :meth:`.PlotWidget.addImage` for the plot widget with :meth:`.PlotWidget.setDefaultColormap` (and to get it with :meth:`.PlotWidget.getDefaultColormap`): +Yet, any colormap name from `matplotlib `_ (see `Choosing Colormaps `_) should work. + +It is possible to change the default colormap of the plot widget by :meth:`.PlotWidget.setDefaultColormap` (and to get it with :meth:`.PlotWidget.getDefaultColormap`): .. code-block:: python + from silx.gui.plot.Colormap import Colormap + colormap = Colormap(name='viridis', normalization='linear', vmin=0.0, - vmax=1.0) + vmax=10000.0) plot.setDefaultColormap(colormap) data = numpy.arange(512 * 512.).reshape(512, -1) @@ -386,25 +334,18 @@ It is also possible to provide a :class:`.Colormap` to :meth:`.PlotWidget.addIma colormap = Colormap(name='magma', normalization='log', - vmin=1.2, - vmax=1.8) + vmin=1.8, + vmax=2.2) data = numpy.random.random(512 * 512).reshape(512, -1) + 1. plot.addImage(data, colormap=colormap) -As for `Origin and scale`_, when updating an image, if ``colormap`` is not provided, the previous colormap will be used: - -.. code-block:: python - - data = numpy.random.random(512 * 512).reshape(512, -1) + 1. - plot.addImage(data) # Keep previous colormap - The colormap can be changed by the user from the widget's toolbar. Multiple images +++++++++++++++ -In order to display multiple images at the same time, you need to provide a different ``legend`` string for each of them and to set the ``replace`` argument to ``False``: +In order to display multiple images in a frame, you need to provide a different ``legend`` string for each of them and to set the ``replace`` argument to ``False``: .. code-block:: python @@ -415,27 +356,27 @@ In order to display multiple images at the same time, you need to provide a diff plot.addImage(data, legend='arange', replace=False, origin=(512, 512)) -To update an image, call :meth:`.PlotWidget.addImage` with the ``legend`` of the curve you want to udpdate. -By default, the new image will keep the same colormap, origin and scale as the image it is updating: +To update an image, call :meth:`.PlotWidget.getImage` with the ``legend`` to get the corresponding curve. +Update its data values using :meth:`~silx.gui.plot.items.setData`. .. code-block:: python data = (512 * 512. - numpy.arange(512 * 512.)).reshape(512, -1) - plot.addImage(data, legend='arange', replace=False) # Beware of replace=False - + arange_image = plot.getImage('arange') + arange_image.setData(data) -To remove an image from the plot, call :meth:`.PlotWidget.remove` with the ``legend`` of the image you want to remove: +To remove an image from a plot, call :meth:`.PlotWidget.remove` with the ``legend`` of the image you want to remove: .. code-block:: python plot.remove('random') -Control plot axes ------------------ +Configure plot axes +------------------- -The following examples illustrate the API to control the plot axes. -:meth:`.PlotWidget.getXAxis` and :meth:`.PlotWidget.getYAxis` give access to each plot axis (:class:`.items.Axis`) in order to control them. +The following examples illustrate the API to configure the plot axes. +:meth:`.PlotWidget.getXAxis` and :meth:`.PlotWidget.getYAxis` give access to each plot axis (:class:`.items.Axis`) in order to configure them. Labels and title ++++++++++++++++ @@ -453,7 +394,7 @@ Use :meth:`.PlotWidget.getXAxis` and :meth:`.PlotWidget.getYAxis` to get the axe Axes limits +++++++++++ -Different methods allows to get and set the data limits displayed on each axis. +Different methods allow to retrieve and set the data limits displayed on each axis. The following code moves the visible plot area to the right: @@ -463,7 +404,7 @@ The following code moves the visible plot area to the right: offset = 0.1 * (xmax - xmin) plot.getXAxis().setLimits(xmin + offset, xmax + offset) -:meth:`.PlotWidget.resetZoom` set the plot limits to the bounds of the data: +:meth:`.PlotWidget.resetZoom` set the plot limits to the upper and lower bounds of the data: .. code-block:: python @@ -475,7 +416,7 @@ See :meth:`.PlotWidget.resetZoom`, :meth:`.PlotWidget.setLimits`, :meth:`.PlotWi Axes ++++ -Different methods allow plot axes modifications: +The axes of a plot can be modified via different methods: .. code-block:: python -- cgit v1.2.3