def imshow(self): """Generate an image from a data set in the workspace.""" logger = logging.getLogger(__name__ +".VtImageViewer.imshow") indexes = vitables.utils.getSelectedIndexes() if len(indexes) != 1: msg = translate( _defaults["PLUGIN_CLASS"], "Only one node can be viewed as an image at a time!", "Plugin error message" ) logger.error(msg) return dbg = vitables.utils.getGui().dbs_tree_model leaf = dbg.nodeFromIndex(indexes[0]) node = leaf.node if node.dtype.kind not in "iuf": msg = translate( _defaults["PLUGIN_CLASS"], "Node must be a numeric type array!", "Plugin error message" ) logger.error(msg) return if not (node.ndim == 2 and 1 not in node.shape) \ and node.ndim not in (3,4): msg = translate( _defaults["PLUGIN_CLASS"], "Node must be 2D, 3D or 4D.", "Plugin error message" ) logger.error(msg) return workspace = vitables.utils.getGui().workspace window = ImageWindow(leaf, parent=workspace)
def helpAbout(self, parent): """Full description of the plugin. The help about page needed by ViTables to recognize a plug-in. This has been adapted from the code used in :class:`ImportCSV` distributed with ViTables. Parameters ---------- parent : :class:`PyQt4.QtGui.QWidget` The parent object provided by ViTables """ from .aboutpage import AboutPage desc = { "version" : _defaults["VERSION"], "module_name" : _defaults["MODULE_NAME"], "folder" : _defaults["FOLDER"], "author" : "{0:s} <{1:s}>".format( _defaults["AUTHOR"], _defaults["AUTHOR_EMAIL"] ), "comment" : translate( _defaults["PLUGIN_CLASS"], """ <qt> <p>View 2D data set as an image.</p> <p> If the data set is simply 2D, view it as an image. If the dataset is 3D of dimension (N,M,K), view each (N,M) slice [0,K) as an image with a slider. </p> </qt> """, "Text of an About plugin message box" ) } about_page = AboutPage(desc, parent) return about_page
def __init__(self, leaf, parent): """Load the data set and display it as an image. Parameters ---------- leaf : :class:`vitables.h5db.leafnode` The leaf tree node to view parent : :class:`PyQt4.QtGui.QMdiArea` The workspace from ViTables """ logger = logging.getLogger(__name__ +".ImageWindow") if leaf.node.ndim in (2,3,4): data = leaf.node.read() else: msg = translate( _defaults["PLUGIN_CLASS"], "Array must be 2D, 3D, or 4D", "Plugin error message" ) logger.error(msg) raise RuntimeError(msg) super(ImageWindow, self).__init__(parent) config = Preferences() if leaf.node.ndim == 2: self.data = data.transpose(( int(config["2D"]["Height"]), int(config["2D"]["Width"]) )) elif leaf.node.ndim == 3: if data.shape[int(config["2D"]["RGB(A)"])] in (3,4): self.data = data.transpose(( int(config["2D"]["Height"]), int(config["2D"]["Width"]), int(config["2D"]["RGB(A)"]) )) else: self.data = data.transpose(( int(config["3D"]["Depth"]), int(config["3D"]["Height"]), int(config["3D"]["Width"]) )) else: self.data = data.transpose(( int(config["4D"]["Depth"]), int(config["4D"]["Height"]), int(config["4D"]["Width"]), int(config["4D"]["RGB(A)"]) )) self.image = pyqtgraph.ImageView() self.image.setImage(self.data) self.setWidget(self.image) self.image.show() self.pindex = None self.dbt_leaf = leaf self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle(self.dbt_leaf.name) if self.image.menu is None: self.image.buildMenu() action = QtGui.QAction("Reshape", self.image.menu) vitables.utils.addToMenu(self.image.menu, action) action.triggered.connect(self.reshape)
def reshape(self): """Select different axis for displaying the image.""" logger = logging.getLogger(__name__ +".ImageWindow.reshape") dims = SetDims(self.data) if dims.exec() == dims.Rejected: return # Prepare the image array W = dims.get_width() logger.debug("Width : {0!s}".format(W)) H = dims.get_height() logger.debug("Height : {0!s}".format(H)) D = dims.get_depth() logger.debug("Depth : {0!s}".format(D)) R = dims.get_rgba() logger.debug("RGBA : {0!s}".format(R)) if D is None and R is None: data = self.data.transpose((W.dim, H.dim))[ W.start:W.end:W.stride, H.start:H.end:H.stride ] elif D is not None and R is None: if len(self.data.shape) != 3: msg = translate( _defaults["PLUGIN_CLASS"], "Either Depth or RGBA can be set! Not both.", "Plugin error message" ) logger.error(msg) return data = self.data.transpose((D.dim, W.dim, H.dim))[ D.start:D.end:D.stride, W.start:W.end:W.stride, H.start:H.end:H.stride ] elif D is None and R is not None: if len(self.data.shape) != 3: msg = translate( _defaults["PLUGIN_CLASS"], "Either Depth or RGBA can be set! Not both.", "Plugin error message" ) logger.error(msg) return data = self.data.transpose((W.dim, H.dim, R.dim))[ W.start:W.end:W.stride, H.start:H.end:H.stride, : ] elif D is not None and R is not None: data = self.data.transpose((D.dim, W.dim, H.dim, R.dim))[ D.start:D.end:D.stride, W.start:W.end:W.stride, H.start:H.end:H.stride, : ] else: raise RuntimeError("This should never be possible") self.image.setImage(data) self.image.show() return