~ubuntu-branches/ubuntu/trusty/guiqwt/trusty

« back to all changes in this revision

Viewing changes to guiqwt/builder.py

  • Committer: Bazaar Package Importer
  • Author(s): Picca Frédéric-Emmanuel
  • Date: 2011-04-07 22:41:50 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110407224150-kkhppnq7rp2c8b3c
Tags: 2.1.0-1
* Imported Upstream version 2.1.0
* debian/patches/
  - 0001-features-01_bts614083.patch (delete)
  - 0001-feature-fix-the-documentation-build.patch (new)
* add and install the sift desktop file
* recommends python-dicom (Closes: #621421)
  thanks Junqian Gordon Xu for the report

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# -*- coding: utf-8 -*-
2
2
#
3
3
# Copyright © 2009-2010 CEA
4
 
# Pierre Raybaut <pierre.raybaut@cea.fr>
 
4
# Pierre Raybaut
5
5
# Licensed under the terms of the CECILL License
6
6
# (see guiqwt/__init__.py for details)
7
7
 
56
56
 
57
57
from numpy import arange, array, zeros, meshgrid, ndarray
58
58
 
59
 
from PyQt4.Qwt5 import QwtPlot
60
 
 
61
59
# Local imports
62
60
from guiqwt.config import _, CONF, make_title
 
61
from guiqwt.baseplot import BasePlot
63
62
from guiqwt.curve import CurveItem, ErrorBarCurveItem, GridItem
64
 
from guiqwt.histogram import HistogramItem
 
63
from guiqwt.histogram import HistogramItem, lut_range_threshold
65
64
from guiqwt.image import (ImageItem, QuadGridItem, TrImageItem, XYImageItem,
66
 
                          Histogram2DItem)
 
65
                          Histogram2DItem, RGBImageItem, MaskedImageItem)
67
66
from guiqwt.shapes import (XRangeSelection, RectangleShape, EllipseShape,
68
 
                           SegmentShape)
 
67
                           SegmentShape, VerticalCursor, HorizontalCursor)
69
68
from guiqwt.annotations import (AnnotatedRectangle, AnnotatedEllipse,
70
 
                                AnnotatedSegment)
 
69
                                AnnotatedSegment, AnnotatedVCursor)
71
70
from guiqwt.styles import (update_style_attr, CurveParam, ErrorBarParam,
72
71
                           style_generator, LabelParam, LegendParam, ImageParam,
73
72
                           TrImageParam, HistogramParam, Histogram2DParam,
 
73
                           RGBImageParam, MaskedImageParam, XYImageParam,
74
74
                           ImageFilterParam, MARKERS, COLORS, GridParam,
75
75
                           LineStyleParam, AnnotationParam,
76
76
                           LabelParamWithContents)
77
77
from guiqwt.label import (LabelItem, LegendBoxItem, RangeComputation,
78
 
                          RangeComputation2d, DataInfoLabel,
 
78
                          RangeComputation2d, DataInfoLabel, CursorComputation,
79
79
                          SelectedLegendBoxItem)
80
80
from guiqwt.io import imagefile_to_array
81
81
import os.path as osp
103
103
    This is just a bare class used to regroup
104
104
    a set of factory functions in a single object
105
105
    """
106
 
    AXES = {
107
 
            'bottom': QwtPlot.xBottom,
108
 
            'left'  : QwtPlot.yLeft,
109
 
            'top'   : QwtPlot.xTop,
110
 
            'right' : QwtPlot.yRight,
111
 
            }
112
 
    
113
106
    def __init__(self):
114
107
        self.style = style_generator()
115
108
        
162
155
                                   major_style, minor_style)
163
156
        return GridItem(gridparam)
164
157
    
165
 
    def __set_axes(self, curve, xaxis, yaxis):
 
158
    def __set_curve_axes(self, curve, xaxis, yaxis):
166
159
        """Set curve axes"""
167
160
        for axis in (xaxis, yaxis):
168
 
            if axis not in self.AXES:
 
161
            if axis not in BasePlot.AXIS_NAMES:
169
162
                raise RuntimeError("Unknown axis %s" % axis)
170
 
        curve.setXAxis(self.AXES[xaxis])
171
 
        curve.setYAxis(self.AXES[yaxis])
 
163
        curve.setXAxis(BasePlot.AXIS_NAMES[xaxis])
 
164
        curve.setYAxis(BasePlot.AXIS_NAMES[yaxis])
172
165
 
173
166
    def __set_param(self, param, title, color, linestyle, linewidth,
174
167
                    marker, markersize, markerfacecolor, markeredgecolor,
322
315
        curve = CurveItem(param)
323
316
        curve.set_data(x, y)
324
317
        curve.update_params()
325
 
        self.__set_axes(curve, xaxis, yaxis)
 
318
        self.__set_curve_axes(curve, xaxis, yaxis)
326
319
        return curve
327
320
 
328
321
    def curve(self, x, y, title=u"",
420
413
        curve = ErrorBarCurveItem(curveparam, errorbarparam)
421
414
        curve.set_data(x, y, dx, dy)
422
415
        curve.update_params()
423
 
        self.__set_axes(curve, xaxis, yaxis)
 
416
        self.__set_curve_axes(curve, xaxis, yaxis)
424
417
        return curve
425
418
        
426
419
    def error(self, x, y, dx, dy, title=u"",
482
475
        return self.perror(x, y, dx, dy, curveparam, errorbarparam,
483
476
                           xaxis, yaxis)
484
477
    
485
 
    def histogram(self, data, bins=None, logscale=None, remove_first_bin=None,
 
478
    def histogram(self, data, bins=None, logscale=None,
486
479
                  title=u"", color=None, xaxis="bottom", yaxis="left"):
487
480
        """
488
481
        Make 1D Histogram `plot item` 
506
499
            histparam.n_bins = bins
507
500
        if logscale is not None:
508
501
            histparam.logscale = logscale
509
 
        if remove_first_bin is not None:
510
 
            histparam.remove_first_bin = remove_first_bin
511
502
        return self.phistogram(data, curveparam, histparam, xaxis, yaxis)
512
503
        
513
504
    def phistogram(self, data, curveparam, histparam,
523
514
        hist = HistogramItem(curveparam, histparam)
524
515
        hist.update_params()
525
516
        hist.set_hist_data(data)
526
 
        self.__set_axes(hist, xaxis, yaxis)
 
517
        self.__set_curve_axes(hist, xaxis, yaxis)
527
518
        return hist
528
519
 
529
 
    def __set_image_param(self, param, title, background_color,
530
 
                          alpha_mask, alpha, colormap, **kwargs):
 
520
    def __set_image_param(self, param, title, alpha_mask, alpha, interpolation,
 
521
                          **kwargs):
531
522
        if title:
532
523
            param.label = title
533
524
        else:
534
525
            global IMAGE_COUNT
535
526
            IMAGE_COUNT += 1
536
527
            param.label = make_title(_("Image"), IMAGE_COUNT)
537
 
        if background_color is not None:
538
 
            param.background = background_color
539
528
        if alpha_mask is not None:
 
529
            assert isinstance(alpha_mask, bool)
540
530
            param.alpha_mask = alpha_mask
541
531
        if alpha is not None:
 
532
            assert (0.0 <= alpha <= 1.0)
542
533
            param.alpha = alpha
543
 
        if colormap is not None:
544
 
            param.colormap = colormap
 
534
        interp_methods = {'nearest': 0, 'linear': 1, 'antialiasing': 5}
 
535
        param.interpolation = interp_methods[interpolation]
545
536
        for key, val in kwargs.items():
546
 
            setattr(param, key, val)
 
537
            if val is not None:
 
538
                setattr(param, key, val)
547
539
 
548
 
    def _get_image_data(self, data, filename, title, cmap):
 
540
    def _get_image_data(self, data, filename, title, to_grayscale):
549
541
        if data is None:
550
542
            assert filename is not None
551
 
            data = imagefile_to_array(filename)
 
543
            data = imagefile_to_array(filename, to_grayscale=to_grayscale)
552
544
        if title is None and filename is not None:
553
545
            title = osp.basename(filename)
554
 
        return data, filename, title, cmap
 
546
        return data, filename, title
555
547
 
556
 
    def image(self, data=None, filename=None, title=None, background_color=None,
557
 
              alpha_mask=None, alpha=None, colormap=None,
558
 
              xaxis="bottom", yaxis="left", zaxis="right"):
 
548
    @staticmethod
 
549
    def compute_bounds(data, pixel_size):
 
550
        """Return image bounds from *pixel_size* (scalar or tuple)"""
 
551
        if not isinstance(pixel_size, (tuple, list)):
 
552
            pixel_size = [pixel_size, pixel_size]
 
553
        dx, dy = pixel_size
 
554
        xmin, ymin = 0., 0.
 
555
        xmax, ymax = data.shape[1]*dx, data.shape[0]*dy
 
556
        return xmin, xmax, ymin, ymax
 
557
        
 
558
    def image(self, data=None, filename=None, title=None, alpha_mask=None,
 
559
              alpha=None, background_color=None, colormap=None,
 
560
              xdata=[None, None], ydata=[None, None], pixel_size=None,
 
561
              interpolation='linear', eliminate_outliers=None,
 
562
              xformat='%.1f', yformat='%.1f', zformat='%.1f'):
559
563
        """
560
564
        Make an image `plot item` from data
561
 
        (:py:class:`guiqwt.image.ImageItem` object)
 
565
        (:py:class:`guiqwt.image.ImageItem` object or 
 
566
        :py:class:`guiqwt.image.RGBImageItem` object if data has 3 dimensions)
562
567
        """
 
568
        assert isinstance(xdata, (tuple, list)) and len(xdata) == 2
 
569
        assert isinstance(ydata, (tuple, list)) and len(ydata) == 2
563
570
        param = ImageParam(title=_("Image"), icon='image.png')
564
 
        params = self._get_image_data(data, filename, title, colormap)
565
 
        data, filename, title, colormap = params
566
 
        self.__set_image_param(param, title, background_color,
567
 
                               alpha_mask, alpha, colormap)
 
571
        data, filename, title = self._get_image_data(data, filename, title,
 
572
                                                     to_grayscale=True)
 
573
        if data.ndim == 3:
 
574
            return self.rgbimage(data=data, filename=filename, title=title,
 
575
                                 alpha_mask=alpha_mask, alpha=alpha)
 
576
        assert data.ndim == 2, "Data must have 2 dimensions"
 
577
        if pixel_size is None:
 
578
            xmin, xmax = xdata
 
579
            ymin, ymax = ydata
 
580
        else:
 
581
            xmin, xmax, ymin, ymax = self.compute_bounds(data, pixel_size)
 
582
        self.__set_image_param(param, title, alpha_mask, alpha, interpolation,
 
583
                               background=background_color,
 
584
                               colormap=colormap,
 
585
                               xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
 
586
                               xformat=xformat, yformat=yformat,
 
587
                               zformat=zformat)
568
588
        image = ImageItem(data, param)
569
589
        image.set_filename(filename)
 
590
        if eliminate_outliers is not None:
 
591
            image.set_lut_range(lut_range_threshold(image, 256,
 
592
                                                    eliminate_outliers))
 
593
        return image
 
594
 
 
595
    def maskedimage(self, data=None, mask=None, filename=None, title=None,
 
596
                    alpha_mask=False, alpha=1.0,
 
597
                    xdata=[None, None], ydata=[None, None], pixel_size=None,
 
598
                    background_color=None, colormap=None,
 
599
                    show_mask=False, fill_value=None, interpolation='linear',
 
600
                    eliminate_outliers=None,
 
601
                    xformat='%.1f', yformat='%.1f', zformat='%.1f'):
 
602
        """
 
603
        Make a masked image `plot item` from data
 
604
        (:py:class:`guiqwt.image.MaskedImageItem` object)
 
605
        """
 
606
        assert isinstance(xdata, (tuple, list)) and len(xdata) == 2
 
607
        assert isinstance(ydata, (tuple, list)) and len(ydata) == 2
 
608
        param = MaskedImageParam(title=_("Image"), icon='image.png')
 
609
        data, filename, title = self._get_image_data(data, filename, title,
 
610
                                                     to_grayscale=False)
 
611
        assert data.ndim == 2, "Data must have 2 dimensions"
 
612
        if pixel_size is None:
 
613
            xmin, xmax = xdata
 
614
            ymin, ymax = ydata
 
615
        else:
 
616
            xmin, xmax, ymin, ymax = self.compute_bounds(data, pixel_size)
 
617
        self.__set_image_param(param, title, alpha_mask, alpha, interpolation,
 
618
                               background=background_color,
 
619
                               colormap=colormap,
 
620
                               xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
 
621
                               show_mask=show_mask, fill_value=fill_value,
 
622
                               xformat=xformat, yformat=yformat,
 
623
                               zformat=zformat)
 
624
        image = MaskedImageItem(data, mask, param)
 
625
        image.set_filename(filename)
 
626
        if eliminate_outliers is not None:
 
627
            image.set_lut_range(lut_range_threshold(image, 256,
 
628
                                                    eliminate_outliers))
 
629
        return image
 
630
 
 
631
    def rgbimage(self, data=None, filename=None, title=None,
 
632
                 alpha_mask=False, alpha=1.0,
 
633
                 xdata=[None, None], ydata=[None, None], pixel_size=None,
 
634
                 interpolation='linear'):
 
635
        """
 
636
        Make a RGB image `plot item` from data
 
637
        (:py:class:`guiqwt.image.RGBImageItem` object)
 
638
        """
 
639
        assert isinstance(xdata, (tuple, list)) and len(xdata) == 2
 
640
        assert isinstance(ydata, (tuple, list)) and len(ydata) == 2
 
641
        param = RGBImageParam(title=_("Image"), icon='image.png')
 
642
        data, filename, title = self._get_image_data(data, filename, title,
 
643
                                                     to_grayscale=False)
 
644
        assert data.ndim == 3, "RGB data must have 3 dimensions"
 
645
        if pixel_size is None:
 
646
            xmin, xmax = xdata
 
647
            ymin, ymax = ydata
 
648
        else:
 
649
            xmin, xmax, ymin, ymax = self.compute_bounds(data, pixel_size)
 
650
        self.__set_image_param(param, title, alpha_mask, alpha, interpolation,
 
651
                               xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
 
652
        image = RGBImageItem(data, param)
 
653
        image.set_filename(filename)
570
654
        return image
571
655
        
572
 
    def quadgrid(self, X, Y, Z, filename=None, title=None,
573
 
                 background_color=None, alpha_mask=None, alpha=None,
574
 
                 colormap=None, xaxis="bottom", yaxis="left", zaxis="right"):
 
656
    def quadgrid(self, X, Y, Z, filename=None, title=None, alpha_mask=None,
 
657
                 alpha=None, background_color=None, colormap=None,
 
658
                 interpolation='linear'):
575
659
        """
576
660
        Make a pseudocolor `plot item` of a 2D array
577
661
        (:py:class:`guiqwt.image.QuadGridItem` object)
578
662
        """
579
663
        param = ImageParam(title=_("Image"), icon='image.png')
580
 
        self.__set_image_param(param, title, background_color,
581
 
                               alpha_mask, alpha, colormap)
 
664
        self.__set_image_param(param, title, alpha_mask, alpha, interpolation,
 
665
                               background=background_color, colormap=colormap)
582
666
        image = QuadGridItem(X, Y, Z, param)
583
667
        return image
584
668
 
602
686
            raise RuntimeError("1 or 3 non-keyword arguments expected")
603
687
        return self.quadgrid(X, Y, Z, **kwargs)
604
688
 
605
 
    def trimage(self, data=None, filename=None, title=None,
606
 
                background_color=None, alpha_mask=None, alpha=None,
607
 
                colormap=None, xaxis="bottom", yaxis="left", zaxis="right",
 
689
    def trimage(self, data=None, filename=None, title=None, alpha_mask=None,
 
690
                alpha=None, background_color=None, colormap=None,
608
691
                x0=0.0, y0=0.0, angle=0.0, dx=1.0, dy=1.0,
609
 
                interpolation='linear'):
 
692
                interpolation='linear', eliminate_outliers=None,
 
693
                xformat='%.1f', yformat='%.1f', zformat='%.1f'):
610
694
        """
611
695
        Make a transformable image `plot item` (image with an arbitrary 
612
696
        affine transform)
620
704
            * interpolation: 'nearest', 'linear' (default), 'antialiasing' (5x5)
621
705
        """
622
706
        param = TrImageParam(title=_("Image"), icon='image.png')
623
 
        params = self._get_image_data(data, filename, title, colormap)
624
 
        data, filename, title, colormap = params
625
 
        self.__set_image_param(param, title, background_color,
626
 
                               alpha_mask, alpha, colormap,
627
 
                               x0=x0, y0=y0, angle=angle, dx=dx, dy=dy)
628
 
        interp_methods = {'nearest': 0, 'linear': 1, 'antialiasing': 5}
629
 
        param.interpolation = interp_methods[interpolation]
 
707
        data, filename, title = self._get_image_data(data, filename, title,
 
708
                                                     to_grayscale=True)
 
709
        self.__set_image_param(param, title, alpha_mask, alpha, interpolation,
 
710
                               background=background_color, colormap=colormap,
 
711
                               x0=x0, y0=y0, angle=angle, dx=dx, dy=dy,
 
712
                               xformat=xformat, yformat=yformat,
 
713
                               zformat=zformat)
630
714
        image = TrImageItem(data, param)
631
715
        image.set_filename(filename)
 
716
        if eliminate_outliers is not None:
 
717
            image.set_lut_range(lut_range_threshold(image, 256,
 
718
                                                    eliminate_outliers))
632
719
        return image
633
720
 
634
 
    def xyimage(self, x, y, data, title=None, background_color=None,
635
 
                alpha_mask=None, alpha=None, colormap=None,
636
 
                xaxis="bottom", yaxis="left", zaxis="right"):
 
721
    def xyimage(self, x, y, data, title=None, alpha_mask=None, alpha=None,
 
722
                background_color=None, colormap=None,
 
723
                interpolation='linear', eliminate_outliers=None,
 
724
                xformat='%.1f', yformat='%.1f', zformat='%.1f'):
637
725
        """
638
726
        Make an xyimage `plot item` (image with non-linear X/Y axes) from data
639
727
        (:py:class:`guiqwt.image.XYImageItem` object)
641
729
            * y: 1D NumPy array
642
730
            * data: 2D NumPy array (image pixel data)
643
731
            * title: image title (optional)
 
732
            * interpolation: 'nearest', 'linear' (default), 'antialiasing' (5x5)
644
733
        """
645
 
        param = ImageParam(title=_("Image"), icon='image.png')
646
 
        self.__set_image_param(param, title, background_color,
647
 
                               alpha_mask, alpha, colormap)
648
 
        return XYImageItem(x, y, data, param)
 
734
        param = XYImageParam(title=_("Image"), icon='image.png')
 
735
        self.__set_image_param(param, title, alpha_mask, alpha, interpolation,
 
736
                               background=background_color, colormap=colormap,
 
737
                               xformat=xformat, yformat=yformat,
 
738
                               zformat=zformat)
 
739
        image = XYImageItem(x, y, data, param)
 
740
        if eliminate_outliers is not None:
 
741
            image.set_lut_range(lut_range_threshold(image, 256,
 
742
                                                    eliminate_outliers))
 
743
        return image
649
744
    
650
745
    def imagefilter(self, xmin, xmax, ymin, ymax,
651
746
                    imageitem, filter, title=None):
760
855
    def range(self, xmin, xmax):
761
856
        return XRangeSelection(xmin, xmax)
762
857
        
 
858
    def vcursor(self, position):
 
859
        """
 
860
        Make a vertical cursor `plot item`
 
861
        (:py:class:`guiqwt.shapes.VerticalCursor` object)
 
862
        """
 
863
        return VerticalCursor(position)
 
864
 
 
865
    def hcursor(self, position):
 
866
        """
 
867
        Make an horizontal cursor `plot item`
 
868
        (:py:class:`guiqwt.shapes.HorizontalCursor` object)
 
869
        """
 
870
        return HorizontalCursor(position)
 
871
        
763
872
    def __shape(self, shapeclass, x0, y0, x1, y1, title=None):
764
873
        shape = shapeclass(x0, y0, x1, y1)
765
874
        shape.set_style("plot", "shape/drag")
865
974
        """
866
975
        return self.__annotated_shape(AnnotatedSegment,
867
976
                                      x0, y0, x1, y1, title, subtitle)
 
977
                                      
 
978
    def annotated_vcursor(self, pos, title=None, subtitle=None,
 
979
                          infos_format="value = %.2f", moveable=True):
 
980
        """
 
981
        Make an annotated vertical cursor `plot item` 
 
982
        (:py:class:`guiqwt.annotations.AnnotatedVCursor` object)
 
983
            * pos: cursor x coordinate
 
984
            * title, subtitle: strings
 
985
        """
 
986
        param = self.__get_annotationparam(title, subtitle)
 
987
        param.format = infos_format
 
988
        return AnnotatedVCursor(pos, param, moveable)
868
989
 
869
990
    def info_label(self, anchor, comps, title=""):
870
991
        """
886
1007
        c = ANCHOR_OFFSETS[anchor]
887
1008
        param.xc, param.yc = c
888
1009
        return DataInfoLabel(param, comps)
 
1010
        
 
1011
    def info_cursor(self, cursor, anchor, label=None, func=None):
 
1012
        if func is None:
 
1013
                func = lambda x: x        
 
1014
        if label is None:
 
1015
            if isinstance(cursor, VerticalCursor):
 
1016
                label = 'x = %s'
 
1017
            else:
 
1018
                label = 'y = %s'
 
1019
        comp = CursorComputation(label, cursor, func)
 
1020
        return self.info_label(anchor, [comp])
889
1021
 
890
1022
    def computation(self, range, anchor, label, curve, function):
891
1023
        """