Integrating Data and Viewing
The goal of this lab is to bring together all of the elements--data, GUI, and viewing--into a single application that enables interactive visualization of data sets in the proper format. The result of this project should be an application that can read a data set and enable the user to interactively view it in up to 5 user-selected dimensions (3 spatial, color, and size).
In the lab, your goal should be to get data onto the screen and moving around correctly.
Give yourself a new working directory and copy your display, view, and
data python files into it. It's best to start with copies and modify
them from there. Integration often involves re-writing parts of your
code to make the process cleaner. From project 2, you should be able
to read one or more CSV data files in the proper format, and from
project 1 you should know how to create a dialog box and other screen
Based on feedback for project 2, you may want to update your Data class and Analysis class. In particular, you will be using your read method, your get_data method, and your normalize_columns_separately method in this project. Talk with a professor if your View class or axis viewing functions need improvement.
In your display class, create a method (e.g. handleOpen that
will use the tkFileDialog module to let the user select the
csv file they want to open.
- Use the file dialog to get a filename, e.g.
fn = tkFileDialog.askopenfilename( parent=self.root, title='Choose a data file', initialdir='.' )
- Bind your method to both a menu option (e.g. File/Open), and to Command-O (or Control-O).
- Make a Data object to read and hold the file's data. You will need to keep this around for plotting, so the Data object needs to be a field of your Display class. For now, your program needs to support having only one data file open at a time.
- Your handleOpen function should not plot the data, just create the Data object from the selected file..
It may seem convenient to put a call to handleOpen() in your __init__ method in your Display class. However, this will cause you headaches and nothing will work quite right because it will interefere with the proper initialization of your application. Using the normal Control-O binding to open files will be just as convenient and will save you headaches.
- Use the file dialog to get a filename, e.g.
- Create a button and/or menu item on your main window that begins the process of plotting data. The button should call a function (e.g. handlePlotData) that will enable the user to select which columns of data to plot on which axes and then builds the data.
Eventually, in this project you will need to design a dialog box that
lets the user select which columns of the data to plot, along with
other parameters. You will want to make that process a function, like
handleChooseAxes. For the lab, your handleChooseAxes function should
just return the headers of the first three columns as the x, y, and z
axes (assuming there are at least 3 axes in the data file).
After calling handleChooseAxes to determine which columns to plot, your handlePlotData function should pass those headers to the function buildPoints.
- Create a buildPoints function in your
display class that is analagous to your buildAxes
function. The buildPoints function should take in a list
of headers, delete any existing canvas objects
representing data (so not your axes), and then build a new
set of data points.
You probably want to follow the steps below in your buildPoints method.
- Delete any existing canvas objects used for plotting data. Delete them from the canvas and set your list of data graphics objects to the empty list.
- Get the spatial (x, y, z) columns specified by the argument headers to plot. Use your normalize_columns_separately function in analysis. If you are selecting only 2 columns to plot, add a column of 0's (z-value) and a column of 1's (homogeneous coordinate) to the data. If you are selecting 3 columns to plot, add a column of 1's (homogeneous coordinate). Each data point is now represented as a 4-column row in the spatial data matrix. Make sure this data is stored in a field of the display class. Do not change this matrix until the user clicks on plotData again.
- Calculate the VTM using the current view object.
Transform the data using the VTM (the following assumes each data point is a row).
pts = (vtm * data.T).T
- Create the canvas graphics objects, ovals/squares/crosses/points, for each data point using the X and Y (first two columns) of your transformed points. Be sure to save a reference to each data point object drawn on the screen (e.g. in self.objects). Letting the user specify the type of graphics object (circle, square, cross) to use in the plot is a nice extension.
- Make sure your program can read the file test data case 1 and display 3 spatial dimensions. Then try test data case 2, which has 5 dimensions, the first two of which are correlated.
When you are finished with the lab, go ahead and continue with the project.