def __init__(self, parent = None): QtGui.QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.renWinList = [] # data_file = askopenfilename() data_file = '/Users/emonson/Data/Fodava/EMoGWDataSets/mnist1_5c_20100324.mat' # self.openFilesDefaultPath = QtCore.QDir.homePath() # data_file = QtGui.QFileDialog.getOpenFileName(self, # "Load Saved Matlab File", # self.openFilesDefaultPath, # "All Files (*);;Matlab Files (*.mat)") # DataSource loads .mat file and can generate data from it for other views self.ds = DataSource(str(data_file)) # All view classes have access to an instance of that data source for internal queries # Note that the only view which will pull and display data right away is the icicle view # the other views need to be able to initialize without any data and only pull and show # upon the first AnnotationChanged event... # View #0 -- Icicle View # Set up a 2D scene, add an XY chart to it self.chartView = vtk.vtkContextView() self.chartView.GetRenderer().SetBackground(1.0, 1.0, 1.0) self.renWinList.append(self.chartView.GetRenderWindow()) self.chart = vtkvtg.vtkMyChartXY() self.chartView.GetScene().AddItem(self.chart) # View #1 -- AxisImageView self.axisView = vtk.vtkContextView() self.axisView.GetRenderer().SetBackground(1.0, 1.0, 1.0) self.renWinList.append(self.axisView.GetRenderWindow()) self.ai = vtkvtg.vtkAxisImageItem() self.axisView.GetScene().AddItem(self.ai) # Set up all the render windows in the GUI self.ui.setupUi(self, self.renWinList) # Now need to get all the interactors working properly # XY style0 = vtk.vtkInteractorStyleRubberBand2D() self.chartView.GetInteractor().SetInteractorStyle(style0) self.chartView.GetScene().SetInteractorStyle(style0) # Axis images style1 = vtk.vtkInteractorStyleRubberBand2D() self.axisView.GetInteractor().SetInteractorStyle(style1) self.axisView.GetScene().SetInteractorStyle(style1) # Set sizes for veritcal splitters self.ui.splitter.setSizes([200,400]) # Connect signals and slots QtCore.QObject.connect(self.ui.actionExit, QtCore.SIGNAL("triggered()"), self.fileExit) # CORE setting up chart and axis images test_id = 68 self.table = self.ds.GetNodeOneScaleCoeffTable(test_id) line1 = vtkvtg.vtkMyPlotPoints() # line1.DebugOn() self.chart.AddPlot(line1) # POINTS line1.SetInput(self.table, 0, 1) line1.SetMarkerStyle(2) line1.SetColor(0, 0, 0, 255) # Tooltip image stack will now be owned by the tooltip, so need to do that differently... id_list = self.ds.PIN[test_id] image_stack = self.ds.GetProjectedImages(id_list) self.chart.SetTooltipImageStack(image_stack) self.chart.SetTooltipShowImage(True) # self.chart.SetTooltipImageScalingFactor(2.0) self.chart.SetTooltipImageTargetSize(40) axis_images = self.ds.GetNodeBasisImages(test_id) center_image = self.ds.GetNodeCenterImage(test_id) self.ai.SetAxisImagesHorizontal() self.ai.SetChartXY(self.chart) self.ai.SetChartXYView(self.chartView) self.ai.SetAxisImageStack(axis_images) self.ai.SetCenterImage(center_image) # Set up annotation link which will carry indices to parallel coordinates chart # for highlighting outside selections (e.g. back from image_flow) # This needs to carry indices, while image_flow link outputs pedigree ids # so conversion happens in HighlightSelectionCallback # data_col_idxs = vtk.vtkAnnotationLink() # data_col_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point # data_col_idxs.GetCurrentSelection().GetNode(0).SetContentType(4) # 2 = PedigreeIds, 4 = Indices # self.chart.SetDataColumnsLink(data_col_idxs) # self.ai.SetDataColumnsLink(data_col_idxs) # Create a annotation link to access selection in XY chart annotationLink = vtk.vtkAnnotationLink() annotationLink.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point annotationLink.GetCurrentSelection().GetNode(0).SetContentType(4) # Indices # Connect the annotation link to the parallel coordinates representation self.chart.SetAnnotationLink(annotationLink) self.chart.GetAnnotationLink().AddObserver("AnnotationChangedEvent", self.IcicleSelectionCallback) # Set up annotation link which will carry indices to parallel coordinates chart # for highlighting outside selections (e.g. back from image_flow) # This needs to carry indices, while image_flow link outputs pedigree ids # so conversion happens in HighlightSelectionCallback highlight_link_idxs = vtk.vtkAnnotationLink() highlight_link_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point highlight_link_idxs.GetCurrentSelection().GetNode(0).SetContentType(4) # 2 = PedigreeIds, 4 = Indices self.chart.SetHighlightLink(highlight_link_idxs) # Fill selection link with dummy IDs id_array = N.array([0],dtype='int64') id_list = VN.numpy_to_vtkIdTypeArray(id_array, deep=True) highlight_link_idxs.GetCurrentSelection().GetNode(0).SetSelectionList(id_list) highlight_link_idxs.InvokeEvent("AnnotationChangedEvent") # self.updater = vtk.vtkViewUpdater() # self.updater.AddAnnotationLink(data_col_idxs) # self.updater.AddView(self.axisView) # self.updater.AddView(self.chartView) # col_array = N.array([0,1],dtype='int64') # col_vtk = VN.numpy_to_vtkIdTypeArray(col_array, deep=True) # data_col_idxs.GetCurrentSelection().GetNode(0).SetSelectionList(col_vtk) # data_col_idxs.InvokeEvent("AnnotationChangedEvent") self.chart.RecalculateBounds() # Only need to Start() interactor for one view # self.pc_class.GetView().GetInteractor().Start() # Shouldn't have to do this render... for rw in self.renWinList: rw.Render()
def InputSelectionCallback(self, caller, event): """This is the callback that tracks changes in the icicle view and sets the input table for the parallel coordinates chart accordingly. Note: This can only handle a single input nodeID for now...""" annSel = caller.GetCurrentSelection() # Note: When selection is cleared, the current selection does NOT contain any nodes if annSel.GetNumberOfNodes() > 0: idxVtk = annSel.GetNode(0).GetSelectionList() idxArr = VN.vtk_to_numpy(idxVtk) print "ice input to XY ", idxArr # Here is where I'm limiting the selection to _one_ nodeID for now... node_id = idxArr[0] # If this is the same icicle node as before same_ice_node = False if node_id == self.input_link_idx: same_ice_node = True self.table = self.ds.GetNodeOneScaleCoeffTable(node_id) id_list = self.ds.PointsInNet[node_id] # Directly accessing member variable self.axis_images = self.ds.GetNodeBasisImages(node_id, True) if not same_ice_node: if self.ds.hasDocTitles: self.text_stack = self.ds.GetDocTitles(id_list) else: self.image_stack = self.ds.GetProjectedImages(id_list, True, True) self.center_image = self.ds.GetNodeCenterImage(node_id, True) # Get the axis image XY indices in case resetting to those values # and the number of dimensions has changed, and xI or yI are over the limit xI = self.ai.GetXAxisIndex() yI = self.ai.GetYAxisIndex() if yI > xI: y_bigger = 1 else: y_bigger = 0 # Check whether they're out of range for the new data (dX,dY,dZ) = self.axis_images.GetDimensions() max_dim = dZ - 1 if yI > max_dim: yI = max_dim if xI > max_dim: xI = max_dim if xI == yI: if y_bigger: xI = yI-1 else: yI = xI-1 if xI < 0: xI = 0 if yI < 0: yI = 0 # Deal with the case where go from 1D to mutipleD on wav/scal switchover if (max_dim > 0) and (xI == 0) and (yI == 0): yI = 1 # DEBUG # print "__ Axis image max_dim, xI, yI: ", max_dim, xI, yI self.chart.ClearPlots() self.ai.ClearAxisImages() line1 = vtkvtg.vtkMyPlotPoints() # Count number of non-_ids column names num_real_cols = len([self.table.GetColumnName(ii) for ii in range(self.table.GetNumberOfColumns()) if not self.table.GetColumnName(ii).endswith('_ids')]) if (num_real_cols > 1): line1.SetInput(self.table, 0, 1) else: line1.SetInput(self.table, 0, 0) line1.SetMarkerStyle(vtkvtg.vtkMyPlotPoints.CIRCLE) # Adding plot must happen after plot.SetInput or rendering crashes... self.chart.AddPlot(line1) # POINTS self.SetColorByArray(self.color_array_name) # Need to set the image stack for the plot which will get resliced if not same_ice_node: if self.ds.hasDocTitles: self.chart.GetTooltip().SetTextStack(self.text_stack) else: self.chart.SetTooltipImageStack(self.image_stack) # self.chart.SetTooltipShowImage(True) # self.chart.SetTooltipImageScalingFactor(0.5) self.chart.SetTooltipImageTargetSize(60) self.chart.Update() # If this is the same icicle node as before, then reset to original XY indices # before view is updated if same_ice_node: self.chart.SetPlotColumnIndices(xI,yI) self.ai.SetAxisImagesHorizontal() self.ai.SetAxisImageStack(self.axis_images) if not same_ice_node: self.ai.SetCenterImage(self.center_image) # If this is the same icicle node as before, then reset to original XY indices # before view is updated if same_ice_node: self.ai.SetAxisIndices(xI,yI) self.ai.Update() self.PedIdToIndexSelection() # self.chartView.ResetCamera() self.input_link_idx = node_id self.chartView.Render() self.axisView.Render() else: self.chart.ClearPlots() self.table = None # self.chart.Update() # self.chartView.ResetCamera() self.chartView.Render() self.ai.ClearAxisImages() self.axisView.Render()
def __init__(self, parent = None): QtGui.QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Set up a 2D scene (later we'll add a pcoords chart to it) self.view = vtk.vtkContextView() # self.view.GetRenderer().SetBackground(1.0, 1.0, 1.0) # // QVTKWidget *widget = new QVTKWidget; # // vtkContextView *view = vtkContextView::New(); # // view->SetInteractor(widget->GetInteractor()); # // widget->SetRenderWindow(view->GetRenderWindow()); # Necessary for RenderView types self.view.SetInteractor(self.ui.vtkWidget.GetInteractor()) self.ui.vtkWidget.SetRenderWindow(self.view.GetRenderWindow()) data_file = '/Users/emonson/Data/Fodava/EMoGWDataSets/mnist12_1k_20101119.mat' # DataSource loads .mat file and can generate data from it for other views ds = DataSource(data_file) # Testing my custom chart class which has image hover tooltips chart = vtkvtg.vtkMyChartXY() chart.SetActionToButton(vtk.vtkChart.PAN, 2) chart.SetActionToButton(vtk.vtkChart.ZOOM, 4) chart.SetActionToButton(vtk.vtkChart.SELECT, 1) self.view.GetScene().AddItem(chart) # Create a annotation link to access selection in parallel coordinates view annotationLink = vtk.vtkAnnotationLink() # If you don't set the FieldType explicitly it ends up as UNKNOWN (as of 21 Feb 2010) # See vtkSelectionNode doc for field and content type enum values annotationLink.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point annotationLink.GetCurrentSelection().GetNode(0).SetContentType(4) # Indices # Connect the annotation link to the parallel coordinates representation chart.SetAnnotationLink(annotationLink) test_id = 3 table = ds.GetNodeOneScaleCoeffTable(test_id) chart.ClearPlots() line1 = vtkvtg.vtkMyPlotPoints() chart.AddPlot(line1) # POINTS line1.SetInput(table, 0, 1) line1.SetMarkerStyle(2) line1.SetColor(0, 0, 0, 255) # Tooltip image stack will now be owned by the tooltip, so need to do that differently... id_list = ds.PointsInNet[test_id] image_stack = ds.GetProjectedImages(id_list) chart.SetTooltipImageStack(image_stack) chart.SetTooltipShowImage(True) # chart.SetTooltipImageScalingFactor(2.0) chart.SetTooltipImageTargetSize(40) # Set up annotation link which will carry indices to parallel coordinates chart # for highlighting outside selections (e.g. back from image_flow) # This needs to carry indices, while image_flow link outputs pedigree ids # so conversion happens in HighlightSelectionCallback highlight_link_idxs = vtk.vtkAnnotationLink() highlight_link_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point highlight_link_idxs.GetCurrentSelection().GetNode(0).SetContentType(4) # 2 = PedigreeIds, 4 = Indices chart.SetHighlightLink(highlight_link_idxs) # Finally render the scene and compare the image to a reference image # view.GetRenderWindow().SetMultiSamples(0) annotationLink.AddObserver("AnnotationChangedEvent", self.selectionCallback) # view.ResetCamera() # view.Render() # Fill selection link with dummy IDs id_array = N.array([0],dtype='int64') id_list = VN.numpy_to_vtkIdTypeArray(id_array) highlight_link_idxs.GetCurrentSelection().GetNode(0).SetSelectionList(id_list) highlight_link_idxs.InvokeEvent("AnnotationChangedEvent") # Set up annotation link which will carry indices to parallel coordinates chart # for highlighting outside selections (e.g. back from image_flow) # This needs to carry indices, while image_flow link outputs pedigree ids # so conversion happens in HighlightSelectionCallback data_col_idxs = vtk.vtkAnnotationLink() data_col_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point data_col_idxs.GetCurrentSelection().GetNode(0).SetContentType(4) # 2 = PedigreeIds, 4 = Indices chart.SetDataColumnsLink(data_col_idxs) # Fill selection link with dummy IDs col_array = N.array([1,2],dtype='int64') col_list = VN.numpy_to_vtkIdTypeArray(col_array) data_col_idxs.GetCurrentSelection().GetNode(0).SetSelectionList(col_list) data_col_idxs.InvokeEvent("AnnotationChangedEvent") # Start interaction event loop self.ui.vtkWidget.show()
# Create a annotation link to access selection in parallel coordinates view annotationLink = vtk.vtkAnnotationLink() # If you don't set the FieldType explicitly it ends up as UNKNOWN (as of 21 Feb 2010) # See vtkSelectionNode doc for field and content type enum values annotationLink.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point annotationLink.GetCurrentSelection().GetNode(0).SetContentType(4) # Indices # Connect the annotation link to the parallel coordinates representation chart.SetAnnotationLink(annotationLink) test_id = 3 table = ds.GetNodeOneScaleCoeffTable(test_id) chart.ClearPlots() line1 = vtkvtg.vtkMyPlotPoints() chart.AddPlot(line1) # POINTS line1.SetInput(table, 0, 1) line1.SetMarkerStyle(2) line1.SetColor(0, 0, 0, 255) # Tooltip image stack will now be owned by the tooltip, so need to do that differently... id_list = ds.PointsInNet[test_id] image_stack = ds.GetProjectedImages(id_list) # DEBUG writer = vtk.vtkXMLImageDataWriter() writer.SetFileName('out.vti') writer.SetInput(image_stack) writer.Write()