def __init__(self, data_source, input_link=None, highlight_link=None): """Parallel coordinates view constructor needs a valid DataSource plus and external annotation link (from the icicle view). """ self.ds = data_source self.input_link = None if input_link is not None: self.SetInputAnnotationLink(input_link) # Set up a 2D scene, add an XY chart to it # Relies on changes to VTK (drawimage branch) that allow DrawImage() scaling factor self.chartView = vtk.vtkContextView() self.chartView.GetRenderer().SetBackground(1.0, 1.0, 1.0) # vtkChart:: # PAN # ZOOM # SELECT # vtkContextMouseEvent: # enum # { NO_BUTTON = 0, LEFT_BUTTON = 1, MIDDLE_BUTTON = 2, RIGHT_BUTTON = 4 } self.chart = vtkvtg.vtkMyChartXY() # self.chart.SetMouseMoveSelectZoomButtons(2,1,4) self.chart.SetActionToButton(vtk.vtkChart.PAN, 2) self.chart.SetActionToButton(vtk.vtkChart.ZOOM, 4) self.chart.SetActionToButton(vtk.vtkChart.SELECT, 1) self.chartView.GetScene().AddItem(self.chart) self.axisView = vtk.vtkContextView() self.axisView.GetRenderer().SetBackground(1.0, 1.0, 1.0) self.ai = vtkvtg.vtkAxisImageItem() self.axisView.GetScene().AddItem(self.ai) # Create a BrBg7 lookup table self.lut = self.ds.GetDivergingLUT('BrBg') self.ai.SetAxisImagesLookupTable(self.lut) # Create a greyscale lookup table self.lutBW = self.ds.GetGrayscaleLUT('gray') self.ai.SetCenterImageLookupTable(self.lutBW) self.highlight_link = None if highlight_link is not None: self.SetHighlightAnnotationLink(highlight_link) # Set up callback to listen for changes in IcicleView selections self.highlight_link.AddObserver("AnnotationChangedEvent", self.HighlightSelectionCallback) # 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 self.highlight_link_idxs = vtk.vtkAnnotationLink() self.highlight_link_idxs.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point self.highlight_link_idxs.GetCurrentSelection().GetNode(0).SetContentType(4) # 2 = PedigreeIds, 4 = Indices self.chart.SetHighlightLink(self.highlight_link_idxs) # Create a annotation link to access selection in parallel coordinates view self.link = 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 self.link.GetCurrentSelection().GetNode(0).SetFieldType(1) # Point # The chart seems to force INDEX selection, so I'm using vtkConvertSelection below to get # out PedigreeIds... self.link.GetCurrentSelection().GetNode(0).SetContentType(4) # 2 = PedigreeIds, 4 = Indices # Connect the annotation link to the parallel coordinates representation self.chart.SetAnnotationLink(self.link) # Set up callback for ID -> Pedigree ID conversion & copy to output link # self.link.AddObserver("AnnotationChangedEvent", self.PCoordsSelectionCallback) # Set up output annotation link which will carry pedigree ids to image flow view # Type and field will be set during conversion to pedigree ids in PCoordsSelectionCallback # self.output_link = vtk.vtkAnnotationLink() # self.chartView.ResetCamera() # self.chartView.Render() # Want to keep track of whether the node coming in on the input_link # is new or not self.input_link_idx = 0 # TODO: Should check the menu to see which is checked so default is # set by GUI self.SetColorByArray("None")
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()
chartScene.AddItem(chart) chartActor.SetScene(chartScene) # both needed chartRen.AddActor(chartActor) chartScene.SetRenderer(chartRen) chartScene.SetInteractorStyle(istyle) # AXIS IMAGES aiRen = vtk.vtkRenderer() aiRen.SetBackground(1.0,1.0,1.0) aiRen.SetViewport(viewports[0]) renwin.AddRenderer(aiRen) # Testing my custom chart class which has image hover tooltips ai = vtkvtg.vtkAxisImageItem() aiScene = vtk.vtkContextScene() aiActor = vtk.vtkContextActor() aiScene.AddItem(ai) aiActor.SetScene(aiScene) # both needed aiRen.AddActor(aiActor) aiScene.SetRenderer(aiRen) aiScene.SetInteractorStyle(istyle) # 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)