Quickstart Visualization¶
Visualization implies to have a GUI, which will help to display many things: graphs, text, 3D representations, … This software provides a clean interface to PyQt. PyQt works that way:
- A QMainWindow that includes layouts, (ex: horizontal, vertical, grid, …)
- Layouts can include widgets.
- Widgets can be anything: buttons, menu, opengl 3D representation, graphs, … Several high-level widgets are proposed, check
optimeed.visualize.gui.widgets
.
Simple gui using OpenGL:¶
This example shows how to create a simple gui that contains an openGL widget. First define the imports:
from optimeed.visualize.gui.widgets.widget_openGL import widget_openGL
from optimeed.visualize.gui.gui_mainWindow import gui_mainWindow
from optimeed.visualize.gui.widgets.openGLWidget.DeviceDrawerInterface import DeviceDrawerInterface
from optimeed.core.interfaceDevice import InterfaceDevice
from optimeed.visualize.gui.widgets.openGLWidget.OpenGlFunctions_Library import *
from optimeed.visualize.gui.widgets.openGLWidget.Materials_visual import *
Define the device to draw
class Cone(InterfaceDevice):
def __init__(self):
self.radius_base = 1
self.height = 1.5
Define the drawer
class ConeDrawer(DeviceDrawerInterface):
def __init__(self):
self.theCone = None
def draw(self, theCone): # How to draw the cone
self.theCone = theCone
glPushMatrix() # Remove the previous matrices transformations
glTranslate(0, 0, -theCone.height/2) # Move the cone
Bronze_material.activateMaterialProperties() # Change colour aspect of the cones
draw_disk(0, theCone.radius_base, 50, translate=theCone.height) # Draw the base
gluCylinder(gluNewQuadric(), 0, theCone.radius_base, theCone.height, 50, 10) # Draw the cylinder
glPopMatrix() # Push back previous matrices transformations
def get_init_camera(self, theDevice):
tipAngle = 10
viewAngle = 10
zoomLevel = 0.5
return tipAngle, viewAngle, zoomLevel
def keyboard_push_action(self, theKey):
if theKey == ord(b'H'):
self.theCone.radius_base += 0.2 # Change the radius length when h is pressed
Instantiates objects and run the code
openGlWidget = widget_openGL()
theDrawer = ConeDrawer()
theCone = Cone()
openGlWidget.set_deviceDrawer(theDrawer)
openGlWidget.set_deviceToDraw(theCone)
myWindow = gui_mainWindow([openGlWidget], keep_alive=True)
myWindow.run()
Advanced visualization:¶
This example truly shows the potential of this tool, by linking saved data to graphs.
First, define the imports:
from optimeed.core import Collection
# Visuals imports
from optimeed.core.linkDataGraph import LinkDataGraph, HowToPlotGraph
from optimeed.visualize.gui.gui_mainWindow import gui_mainWindow
# Graph visuals imports
from optimeed.visualize.gui.widgets.widget_graphs_visual import widget_graphs_visual
from optimeed.visualize.gui.widgets.graphsVisualWidget.examplesActionOnClick import *
from optimeed.visualize.gui.widgets.graphsVisualWidget.smallGui import guiPyqtgraph
# OpenGL imports
from optimeed.visualize.gui.widgets.widget_openGL import widget_openGL
from optimeed.visualize.gui.widgets.openGLWidget.DeviceDrawerInterface import DeviceDrawerInterface
from optimeed.visualize.gui.widgets.openGLWidget.OpenGlFunctions_Library import *
from optimeed.visualize.gui.widgets.openGLWidget.Materials_visual import *
import os
Then, define an openGL drawer:
class Drawer(DeviceDrawerInterface):
def __init__(self):
self.theDevice = None
def draw(self, theDevice):
self.theDevice = theDevice
glPushMatrix()
Bronze_material.activateMaterialProperties()
draw_simple_rectangle(theDevice.x, theDevice.y)
glPopMatrix()
def get_init_camera(self, theDevice):
return 0, 0, 0.5
Load data files. Path is relative to this directory __file__:
collection_devices = Collection.load(os.path.join(os.path.dirname(__file__), 'resources/autosaved.col'), doCoherence=False)
collection_logOpti = Collection.load(os.path.join(os.path.dirname(__file__), 'resources/logopti.col'), doCoherence=False)
Instantiates high level module that links the data contained in collections to graphs (that will be later created):
theDataLink = LinkDataGraph()
id_logOpti = theDataLink.add_collection(collection_logOpti)
id_devices = theDataLink.add_collection(collection_devices)
The attributes to plots on x and y axis, and additional kwargs.:
howToPlot = HowToPlotGraph('objectives[0]', 'objectives[1]', {'x_label': "Objective 1", 'y_label': "Objective 2", 'is_scattered': True})
The trick here is that the objective functions is not directly stocked in collection_devices but in collection_logOpti. So we display the objectives coming from collection_logOpti but we link collection_devices from it:
howToPlot.exclude_col(id_devices)
theDataLink.link_collection_to_graph_collection(id_logOpti, id_devices) # Link the devices to the logopti
Generate the graphs:
theDataLink.add_graph(howToPlot)
theGraphs = theDataLink.createGraphs()
Add additional actions to perform when the graph is clicked. This is what makes this software extremely powerful.:
theActionsOnClick = list()
openGlDrawing = widget_openGL()
openGlDrawing.set_deviceDrawer(Drawer())
theActionsOnClick.append(on_graph_click_showAnim(theDataLink, DataAnimationOpenGL(openGlDrawing)))
theActionsOnClick.append(on_graph_click_showInfo(theDataLink, visuals=[Repr_opengl(Drawer())]))
theActionsOnClick.append(on_click_extract_pareto(theDataLink, max_x=False, max_y=False))
theActionsOnClick.append(on_graph_click_delete(theDataLink))
Create the widget of the graphs, and the associated GUI:
myWidgetGraphsVisuals = widget_graphs_visual(theGraphs, highlight_last=True, refresh_time=-1)
guiPyqtgraph(myWidgetGraphsVisuals, actionsOnClick=theActionsOnClick) # Add GUI to change action easily and export graphs
myWidgetGraphsVisuals = myWidgetGraphsVisuals
Launch the window:
myWindow = gui_mainWindow([myWidgetGraphsVisuals], keep_alive=True)
myWindow.run()