117
117
from guiqwt.config import _
118
from guiqwt.baseplot import EnhancedQwtPlot
118
from guiqwt.baseplot import BasePlot
119
119
from guiqwt.curve import CurvePlot, PlotItemList
120
120
from guiqwt.image import ImagePlot
121
from guiqwt.tools import (SelectTool, RectZoomTool, ColormapTool,
122
ReverseYAxisTool, BasePlotMenuTool, HelpTool,
123
ItemListTool, AntiAliasingTool, PrintTool,
121
from guiqwt.tools import (SelectTool, RectZoomTool, ColormapTool, HelpTool,
122
ReverseYAxisTool, BasePlotMenuTool, DeleteItemTool,
123
ItemListPanelTool, AntiAliasingTool, PrintTool,
124
124
DisplayCoordsTool, AxisScaleTool, SaveAsTool,
125
AspectRatioTool, ContrastTool, DummySeparatorTool,
126
XCrossSectionTool, YCrossSectionTool, SnapshotTool,
127
CrossSectionTool, AverageCrossSectionTool)
125
AspectRatioTool, ContrastPanelTool, XCSPanelTool,
126
YCSPanelTool, SnapshotTool, DummySeparatorTool,
127
CrossSectionTool, AverageCrossSectionTool,
128
129
from guiqwt.interfaces import IPlotManager
129
130
from guiqwt.signals import (SIG_ITEMS_CHANGED, SIG_ACTIVE_ITEM_CHANGED,
130
SIG_VISIBILITY_CHANGED)
131
SIG_VISIBILITY_CHANGED, SIG_PLOT_AXIS_CHANGED)
133
134
class DefaultPlotID(object):
171
175
if plot_id is DefaultPlotID:
172
176
plot_id = id(plot)
173
177
assert plot_id not in self.plots
174
assert isinstance(plot, EnhancedQwtPlot)
178
assert isinstance(plot, BasePlot)
175
179
assert not self.tools, "tools must be added after plots"
176
180
assert not self.panels, "panels must be added after plots"
177
181
self.plots[plot_id] = plot
178
182
if len(self.plots) == 1:
179
183
self.default_plot = plot
180
plot.set_manager(self)
184
plot.set_manager(self, id)
181
185
# Connecting signals
182
186
plot.connect(plot, SIG_ITEMS_CHANGED, self.update_tools_status)
183
187
plot.connect(plot, SIG_ACTIVE_ITEM_CHANGED, self.update_tools_status)
188
plot.connect(plot, SIG_PLOT_AXIS_CHANGED, self.plot_axis_changed)
185
190
def set_default_plot(self, plot):
494
523
self.add_tool(ReverseYAxisTool)
495
524
self.add_tool(AspectRatioTool)
496
525
if self.get_contrast_panel():
497
self.add_tool(ContrastTool)
526
self.add_tool(ContrastPanelTool)
527
self.add_tool(SnapshotTool)
528
self.add_tool(ImageStatsTool)
498
529
if self.get_xcs_panel() and self.get_ycs_panel():
499
self.add_tool(XCrossSectionTool)
500
self.add_tool(YCrossSectionTool)
530
self.add_tool(XCSPanelTool)
531
self.add_tool(YCSPanelTool)
501
532
self.add_tool(CrossSectionTool)
502
533
self.add_tool(AverageCrossSectionTool)
503
self.add_tool(SnapshotTool)
505
535
def register_other_tools(self):
552
583
self.register_image_tools()
553
584
self.add_separator_tool()
554
585
self.register_other_tools()
586
self.add_separator_tool()
555
587
self.get_default_tool().activate()
589
def synchronize_axis(self, axis, plots):
590
for plot_id in plots:
591
synclist = self.synchronized_plots.setdefault(plot_id, [])
592
for plot2_id in plots:
593
if plot_id==plot2_id:
595
item = (axis,plot2_id)
596
if item not in synclist:
597
synclist.append(item)
599
def plot_axis_changed(self, plot):
600
plot_id = plot.plot_id
601
if plot_id not in self.synchronized_plots:
603
for (axis, other_plot_id) in self.synchronized_plots[plot_id]:
604
scalediv = plot.axisScaleDiv(axis)
605
map = plot.canvasMap(axis)
606
other = self.get_plot(other_plot_id)
607
lb = scalediv.lowerBound()
608
ub = scalediv.upperBound()
609
other.setAxisScale(axis, lb, ub)
557
612
assert_interfaces_valid(PlotManager)
572
627
qsplit.setStretchFactor(1, 1)
573
628
qsplit.setSizes([1, 2])
630
class SubplotWidget(QSplitter):
631
def __init__(self, parent=None, title=None, xlabel=None, ylabel=None,
632
section="plot", show_itemlist=False, gridparam=None):
633
QSplitter.__init__(self, Qt.Horizontal, parent)
635
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
640
self.plotlayout = QGridLayout()
641
parent.setLayout(self.plotlayout)
642
self.addWidget(parent)
644
self.itemlist = PlotItemList(self)
645
self.itemlist.setVisible(show_itemlist)
646
self.addWidget(self.itemlist)
648
def add_subplot(self, plot, i=0, j=0, plot_id=None):
649
"""Add a plot to the grid of plots"""
650
self.plotlayout.addWidget(plot, i, j)
651
self.plots.append(plot)
654
self.manager.add_plot(plot, plot_id)
657
self.manager.add_panel(self.itemlist)
658
configure_plot_splitter(self)
575
660
class BaseCurveWidget(QSplitter):
577
662
Construct a BaseCurveWidget object, which includes:
605
690
* title: plot title
606
691
* xlabel: (bottom axis title, top axis title) or bottom axis title only
607
692
* ylabel: (left axis title, right axis title) or left axis title only
693
* panels (optional): additionnal panels (list, tuple)
609
695
def __init__(self, parent=None, title=None, xlabel=None, ylabel=None,
610
section="plot", show_itemlist=False, gridparam=None):
696
section="plot", show_itemlist=False, gridparam=None,
611
698
BaseCurveWidget.__init__(self, parent, title, xlabel, ylabel,
612
699
section, show_itemlist, gridparam)
613
700
PlotManager.__init__(self, main=self)
615
702
# Configuring plot manager
616
703
self.add_plot(self.plot)
617
704
self.add_panel(self.itemlist)
619
class CurveDialog(QDialog, PlotManager):
621
Construct a CurveDialog object: plotting dialog box with integrated
623
* wintitle: window title
625
* edit: editable state
626
* toolbar: show/hide toolbar
627
* options: options sent to the :py:class:`guiqwt.curve.CurvePlot` object
629
* parent: parent widget
705
if panels is not None:
707
self.add_panel(panel)
709
class CurveWidgetMixin(PlotManager):
631
710
def __init__(self, wintitle="guiqwt plot", icon="guiqwt.png",
632
edit=False, toolbar=False, options=None, parent=None):
633
QDialog.__init__(self, parent)
711
toolbar=False, options=None, panels=None):
634
712
PlotManager.__init__(self, main=self)
714
self.plot_layout = QGridLayout()
718
self.plot_widget = None
719
self.create_plot(options)
721
if panels is not None:
723
self.add_panel(panel)
725
self.toolbar = QToolBar(_("Tools"))
729
# Configuring widget layout
730
self.setup_widget_properties(wintitle=wintitle, icon=icon)
731
self.setup_widget_layout()
733
# Configuring plot manager
734
self.add_toolbar(self.toolbar, "default")
735
self.register_tools()
737
def setup_widget_layout(self):
738
raise NotImplementedError
740
def setup_widget_properties(self, wintitle, icon):
637
741
self.setWindowTitle(wintitle)
638
742
if isinstance(icon, basestring):
639
743
icon = get_icon(icon)
640
744
self.setWindowIcon(icon)
641
745
self.setMinimumSize(320, 240)
642
746
self.resize(640, 480)
748
def register_tools(self):
750
Register the plotting dialog box tools: the base implementation
751
provides standard, curve-related and other tools - i.e. calling
752
this method is exactly the same as calling
753
:py:meth:`guiqwt.plot.CurveDialog.register_all_curve_tools`
755
This method may be overriden to provide a fully customized set of tools
757
self.register_all_curve_tools()
759
def create_plot(self, options):
761
Create the plotting widget (which is an instance of class
762
:py:class:`guiqwt.plot.BaseCurveWidget`), add it to the dialog box
763
main layout (:py:attr:`guiqwt.plot.CurveDialog.plot_layout`) and
764
then add the `item list` panel
766
May be overriden to customize the plot layout
767
(:py:attr:`guiqwt.plot.CurveDialog.plot_layout`)
769
self.plot_widget = BaseCurveWidget(self, **options)
770
self.plot_layout.addWidget(self.plot_widget, 0, 0)
772
# Configuring plot manager
773
self.add_plot(self.plot_widget.plot)
774
self.add_panel(self.plot_widget.itemlist)
776
class CurveDialog(QDialog, CurveWidgetMixin):
778
Construct a CurveDialog object: plotting dialog box with integrated
780
* wintitle: window title
782
* edit: editable state
783
* toolbar: show/hide toolbar
784
* options: options sent to the :py:class:`guiqwt.curve.CurvePlot` object
786
* parent: parent widget
787
* panels (optional): additionnal panels (list, tuple)
789
def __init__(self, wintitle="guiqwt plot", icon="guiqwt.png", edit=False,
790
toolbar=False, options=None, parent=None, panels=None):
791
QDialog.__init__(self, parent)
793
self.button_box = None
794
CurveWidgetMixin.__init__(self, wintitle=wintitle, icon=icon,
795
toolbar=toolbar, options=options,
643
797
self.setWindowFlags(Qt.Window)
645
self.plot_layout = QGridLayout()
650
self.create_plot(options)
652
self.vlayout = QVBoxLayout(self)
654
self.toolbar = QToolBar(_("Tools"))
657
self.vlayout.addWidget(self.toolbar)
659
self.setLayout(self.vlayout)
660
self.vlayout.addLayout(self.plot_layout)
799
def setup_widget_layout(self):
800
vlayout = QVBoxLayout(self)
801
vlayout.addWidget(self.toolbar)
802
vlayout.addLayout(self.plot_layout)
803
self.setLayout(vlayout)
663
805
self.button_layout = QHBoxLayout()
664
806
self.install_button_layout()
665
self.vlayout.addLayout(self.button_layout)
667
# Configuring plot manager
668
self.add_toolbar(self.toolbar, "default")
669
self.register_tools()
807
vlayout.addLayout(self.button_layout)
671
809
def install_button_layout(self):
679
817
self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
680
818
self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
681
819
self.button_layout.addWidget(bbox)
683
def register_tools(self):
685
Register the plotting dialog box tools: the base implementation
686
provides standard, curve-related and other tools - i.e. calling
687
this method is exactly the same as calling
688
:py:meth:`guiqwt.plot.CurveDialog.register_all_curve_tools`
690
This method may be overriden to provide a fully customized set of tools
692
self.register_all_curve_tools()
694
def create_plot(self, options):
696
Create the plotting widget (which is an instance of class
697
:py:class:`guiqwt.plot.BaseCurveWidget`), add it to the dialog box
698
main layout (:py:attr:`guiqwt.plot.CurveDialog.plot_layout`) and
699
then add the `item list` panel
701
May be overriden to customize the plot layout
702
(:py:attr:`guiqwt.plot.CurveDialog.plot_layout`)
704
widget = BaseCurveWidget(self, **options)
705
self.plot_layout.addWidget(widget, 0, 0)
707
# Configuring plot manager
708
self.add_plot(widget.plot)
709
self.add_panel(widget.itemlist)
820
self.button_box = bbox
822
class CurveWindow(QMainWindow, CurveWidgetMixin):
824
Construct a CurveWindow object: plotting window with integrated plot manager
825
* wintitle: window title
827
* toolbar: show/hide toolbar
828
* options: options sent to the :py:class:`guiqwt.curve.CurvePlot` object
830
* parent: parent widget
831
* panels (optional): additionnal panels (list, tuple)
833
def __init__(self, wintitle="guiqwt plot", icon="guiqwt.png",
834
toolbar=False, options=None, parent=None, panels=None):
835
QMainWindow.__init__(self, parent)
836
CurveWidgetMixin.__init__(self, wintitle=wintitle, icon=icon,
837
toolbar=toolbar, options=options,
840
def setup_widget_layout(self):
841
self.addToolBar(self.toolbar)
843
widget.setLayout(self.plot_layout)
844
self.setCentralWidget(widget)
846
def closeEvent(self, event):
847
# Closing panels (necessary if at least one of these panels has no
848
# parent widget: otherwise, this panel will stay open after the main
849
# window has been closed which is not the expected behavior)
850
for panel in self.panels:
851
self.get_panel(panel).close()
852
QMainWindow.closeEvent(self, event)
712
855
#===============================================================================
756
900
self.connect(self.xcsw, SIG_VISIBILITY_CHANGED, self.xcsw_is_visible)
758
xcsw_splitter = QSplitter(Qt.Vertical, self)
902
self.xcsw_splitter = QSplitter(Qt.Vertical, self)
759
903
if xsection_pos == "top":
760
self.ycsw_spacer = self.ycsw.spacer1
761
xcsw_splitter.addWidget(self.xcsw)
762
xcsw_splitter.addWidget(self.plot)
904
self.xcsw_splitter.addWidget(self.xcsw)
905
self.xcsw_splitter.addWidget(self.plot)
764
self.ycsw_spacer = self.ycsw.spacer2
765
xcsw_splitter.addWidget(self.plot)
766
xcsw_splitter.addWidget(self.xcsw)
767
self.connect(xcsw_splitter, SIGNAL('splitterMoved(int,int)'),
907
self.xcsw_splitter.addWidget(self.plot)
908
self.xcsw_splitter.addWidget(self.xcsw)
909
self.connect(self.xcsw_splitter, SIGNAL('splitterMoved(int,int)'),
768
910
lambda pos, index: self.adjust_ycsw_height())
770
ycsw_splitter = QSplitter(Qt.Horizontal, self)
912
self.ycsw_splitter = QSplitter(Qt.Horizontal, self)
771
913
if ysection_pos == "left":
772
ycsw_splitter.addWidget(self.ycsw)
773
ycsw_splitter.addWidget(xcsw_splitter)
914
self.ycsw_splitter.addWidget(self.ycsw)
915
self.ycsw_splitter.addWidget(self.xcsw_splitter)
775
ycsw_splitter.addWidget(xcsw_splitter)
776
ycsw_splitter.addWidget(self.ycsw)
917
self.ycsw_splitter.addWidget(self.xcsw_splitter)
918
self.ycsw_splitter.addWidget(self.ycsw)
778
configure_plot_splitter(xcsw_splitter,
920
configure_plot_splitter(self.xcsw_splitter,
779
921
decreasing_size=xsection_pos == "bottom")
780
configure_plot_splitter(ycsw_splitter,
922
configure_plot_splitter(self.ycsw_splitter,
781
923
decreasing_size=ysection_pos == "right")
783
self.sub_splitter.addWidget(ycsw_splitter)
925
self.sub_splitter.addWidget(self.ycsw_splitter)
785
927
self.itemlist = PlotItemList(self)
786
928
self.itemlist.setVisible(show_itemlist)
829
969
(string: "top", "bottom")
830
970
* ysection_pos: y-axis cross section plot position
831
971
(string: "left", "right")
972
* panels (optional): additionnal panels (list, tuple)
833
974
def __init__(self, parent=None, title="",
834
975
xlabel=("", ""), ylabel=("", ""), zlabel=None, yreverse=True,
835
976
colormap="jet", aspect_ratio=1.0, lock_aspect_ratio=True,
836
977
show_contrast=False, show_itemlist=False, show_xsection=False,
837
978
show_ysection=False, xsection_pos="top", ysection_pos="right",
979
gridparam=None, panels=None):
839
980
BaseImageWidget.__init__(self, parent, title, xlabel, ylabel,
840
981
zlabel, yreverse, colormap, aspect_ratio, lock_aspect_ratio,
841
982
show_contrast, show_itemlist, show_xsection, show_ysection,
848
989
self.add_panel(self.xcsw)
849
990
self.add_panel(self.ycsw)
850
991
self.add_panel(self.contrast)
852
class ImageDialog(CurveDialog):
854
Construct a ImageDialog object: plotting dialog box with integrated
856
* wintitle: window title
858
* edit: editable state
859
* toolbar: show/hide toolbar
860
* options: options sent to the :py:class:`guiqwt.image.ImagePlot` object
862
* parent: parent widget
864
def __init__(self, wintitle="guiqwt imshow", icon="guiqwt.png",
865
edit=False, toolbar=False, options=None, parent=None):
866
CurveDialog.__init__(self, wintitle=wintitle, icon=icon, edit=edit,
867
toolbar=toolbar, options=options,
992
if panels is not None:
994
self.add_panel(panel)
996
class ImageWidgetMixin(CurveWidgetMixin):
870
997
def register_tools(self):
872
999
Register the plotting dialog box tools: the base implementation
889
1016
May be overriden to customize the plot layout
890
1017
(:py:attr:`guiqwt.plot.CurveDialog.plot_layout`)
892
widget = BaseImageWidget(self, **options)
893
self.plot_layout.addWidget(widget, row, column, rowspan, columnspan)
1019
self.plot_widget = BaseImageWidget(self, **options)
1020
self.plot_layout.addWidget(self.plot_widget,
1021
row, column, rowspan, columnspan)
895
1023
# Configuring plot manager
896
self.add_plot(widget.plot)
897
self.add_panel(widget.itemlist)
898
self.add_panel(widget.xcsw)
899
self.add_panel(widget.ycsw)
900
self.add_panel(widget.contrast)
1024
self.add_plot(self.plot_widget.plot)
1025
self.add_panel(self.plot_widget.itemlist)
1026
self.add_panel(self.plot_widget.xcsw)
1027
self.add_panel(self.plot_widget.ycsw)
1028
self.add_panel(self.plot_widget.contrast)
1030
class ImageDialog(CurveDialog, ImageWidgetMixin):
1032
Construct a ImageDialog object: plotting dialog box with integrated
1034
* wintitle: window title
1036
* edit: editable state
1037
* toolbar: show/hide toolbar
1038
* options: options sent to the :py:class:`guiqwt.image.ImagePlot` object
1040
* parent: parent widget
1041
* panels (optional): additionnal panels (list, tuple)
1045
class ImageWindow(CurveWindow, ImageWidgetMixin):
1047
Construct a ImageWindow object: plotting window with integrated plot manager
1048
* wintitle: window title
1050
* toolbar: show/hide toolbar
1051
* options: options sent to the :py:class:`guiqwt.image.ImagePlot` object
1053
* parent: parent widget
1054
* panels (optional): additionnal panels (list, tuple)
903
1059
#===============================================================================