Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ttools: add example code for programmatic use of new STILTS plots
A new class ttools.example.SinePlot runs an animated live plot in a window. It comes with a couple of associated source files that give two alternative ways to set the plot up. All commented in what I hope is a didactic fasion.
- Loading branch information
Showing
3 changed files
with
450 additions
and
0 deletions.
There are no files selected for viewing
164 changes: 164 additions & 0 deletions
164
ttools/src/main/uk/ac/starlink/ttools/example/ApiPlanePlotter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package uk.ac.starlink.ttools.example; | ||
|
||
import java.awt.Color; | ||
import java.awt.Dimension; | ||
import java.io.IOException; | ||
import javax.swing.Icon; | ||
import javax.swing.JComponent; | ||
import uk.ac.starlink.table.StarTable; | ||
import uk.ac.starlink.ttools.plot.MarkShape; | ||
import uk.ac.starlink.ttools.plot.Range; | ||
import uk.ac.starlink.ttools.plot2.BasicCaptioner; | ||
import uk.ac.starlink.ttools.plot2.Captioner; | ||
import uk.ac.starlink.ttools.plot2.DataGeom; | ||
import uk.ac.starlink.ttools.plot2.Navigator; | ||
import uk.ac.starlink.ttools.plot2.PlotLayer; | ||
import uk.ac.starlink.ttools.plot2.ShadeAxis; | ||
import uk.ac.starlink.ttools.plot2.config.StyleKeys; | ||
import uk.ac.starlink.ttools.plot2.data.DataSpec; | ||
import uk.ac.starlink.ttools.plot2.data.DataStore; | ||
import uk.ac.starlink.ttools.plot2.data.DataStoreFactory; | ||
import uk.ac.starlink.ttools.plot2.data.SimpleDataStoreFactory; | ||
import uk.ac.starlink.ttools.plot2.geom.PlaneAspect; | ||
import uk.ac.starlink.ttools.plot2.geom.PlaneNavigator; | ||
import uk.ac.starlink.ttools.plot2.geom.PlanePlotType; | ||
import uk.ac.starlink.ttools.plot2.geom.PlaneSurfaceFactory; | ||
import uk.ac.starlink.ttools.plot2.layer.MarkForm; | ||
import uk.ac.starlink.ttools.plot2.layer.Outliner; | ||
import uk.ac.starlink.ttools.plot2.layer.ShapeMode; | ||
import uk.ac.starlink.ttools.plot2.layer.ShapePlotter; | ||
import uk.ac.starlink.ttools.plot2.layer.ShapeStyle; | ||
import uk.ac.starlink.ttools.plot2.layer.Stamper; | ||
import uk.ac.starlink.ttools.plot2.paper.Compositor; | ||
import uk.ac.starlink.ttools.plot2.task.ColumnDataSpec; | ||
import uk.ac.starlink.ttools.plot2.task.PlotDisplay; | ||
|
||
/** | ||
* PlanePlotter implementation that sets up a plot explicitly. | ||
* There's a lot to do, it's quite complicated, even for a simple plot. | ||
* If you don't like this approach, see the much more straightforward | ||
* {@link EnvPlanePlotter} implementation instead. | ||
* This approach however gives compile-time type-checking of the | ||
* plot parameters. | ||
* | ||
* @author Mark Taylor | ||
* @since 12 Jun 2014 | ||
*/ | ||
public class ApiPlanePlotter implements SinePlot.PlanePlotter { | ||
|
||
public JComponent createPlotComponent( StarTable table, | ||
boolean dataMayChange ) | ||
throws InterruptedException, IOException { | ||
|
||
/* It's a 2d plot. */ | ||
PlanePlotType plotType = PlanePlotType.getInstance(); | ||
DataGeom geom = plotType.getPointDataGeoms()[ 0 ]; | ||
|
||
/* Create the Profile for the plot surface. This encapsulates | ||
* those things about the geometry and appearance of the plot | ||
* axes which will not change with window resizing, zooming etc. */ | ||
PlaneSurfaceFactory surfFact = new PlaneSurfaceFactory(); | ||
boolean xlog = false; | ||
boolean ylog = false; | ||
boolean xflip = false; | ||
boolean yflip = false; | ||
String xlabel = "X axis"; | ||
String ylabel = "Y axis"; | ||
Captioner captioner = new BasicCaptioner(); | ||
double xyfactor = Double.NaN; | ||
boolean grid = false; | ||
double xcrowd = 1; | ||
double ycrowd = 1; | ||
boolean minor = true; | ||
Color gridColor = Color.BLACK; | ||
Color axlabelColor = Color.BLACK; | ||
PlaneSurfaceFactory.Profile profile = | ||
new PlaneSurfaceFactory.Profile( xlog, ylog, xflip, yflip, | ||
xlabel, ylabel, captioner, | ||
xyfactor, grid, xcrowd, ycrowd, | ||
minor, gridColor, axlabelColor ); | ||
|
||
/* Set up a plot Aspect. This is the initial data range, | ||
* and is subject to change by user navigation. */ | ||
double[] xlimits = new double[] { 0, 1 }; | ||
double[] ylimits = new double[] { -1.2, 1.2 }; | ||
PlaneAspect aspect = new PlaneAspect( xlimits, ylimits ); | ||
|
||
/* Set up a Navigator which determines what mouse gestures are | ||
* available to the user for plot pan/zoom etc. Note that | ||
* anisotropic pan/zoom are available with wheel/drag gestures | ||
* outside the plot axes. */ | ||
double zoomFactor = StyleKeys.ZOOM_FACTOR.getDefaultValue(); | ||
boolean xZoom = true; | ||
boolean yZoom = true; | ||
boolean xPan = true; | ||
boolean yPan = true; | ||
double xAnchor = Double.NaN; | ||
double yAnchor = Double.NaN; | ||
Navigator<PlaneAspect> navigator = | ||
new PlaneNavigator( zoomFactor, | ||
xZoom, yZoom, xPan, yPan, xAnchor, yAnchor ); | ||
|
||
/* We will not use optional decorations for this plot. */ | ||
Icon legend = null; | ||
float[] legPos = null; | ||
ShadeAxis shadeAxis = null; | ||
Range shadeFixRange = null; | ||
boolean surfaceAuxRange = false; | ||
|
||
/* Prepare the list of plot layers; in this case there is only one. */ | ||
PlotLayer[] layers = { createScatterLayer( geom, table), }; | ||
|
||
/* Prepare the data cache. */ | ||
int nl = layers.length; | ||
DataSpec[] dataSpecs = new DataSpec[ nl ]; | ||
for ( int il = 0; il < nl; il++ ) { | ||
dataSpecs[ il ] = layers[ il ].getDataSpec(); | ||
} | ||
DataStoreFactory storeFact = new SimpleDataStoreFactory(); | ||
DataStore dataStore = storeFact.readDataStore( dataSpecs, null ); | ||
boolean caching = ! dataMayChange; | ||
|
||
/* Finally construct, size and return the plot component. */ | ||
Compositor compositor = Compositor.SATURATION; | ||
JComponent comp = | ||
new PlotDisplay<PlaneSurfaceFactory.Profile,PlaneAspect> | ||
( plotType, layers, surfFact, profile, aspect, | ||
legend, legPos, shadeAxis, shadeFixRange, | ||
dataStore, surfaceAuxRange, navigator, | ||
compositor, caching ); | ||
comp.setPreferredSize( new Dimension( 500, 400 ) ); | ||
return comp; | ||
} | ||
|
||
/** | ||
* Returns a plot layer plotting the first two columns of a given table | ||
* against each other. | ||
* | ||
* @param geom data geom | ||
* @param table data table | ||
* @return new layer | ||
*/ | ||
private PlotLayer createScatterLayer( DataGeom geom, StarTable table ) { | ||
|
||
/* Prepare the data for the scatter plot layer: use the first | ||
* two columns of the supplied table as X and Y.*/ | ||
DataSpec dataSpec = | ||
new ColumnDataSpec( table, geom.getPosCoords(), | ||
new int[][] { { 0 }, { 1 } } ); | ||
|
||
/* Prepare the graphical style of the scatter plot layer: | ||
* it's a scatter plot with single-position markers, plotted | ||
* in a single fixed colour. */ | ||
ShapePlotter plotter = | ||
ShapePlotter.createFlat2dPlotter( MarkForm.SINGLE ); | ||
MarkShape shape = MarkShape.OPEN_CIRCLE; | ||
int size = 2; | ||
Outliner outliner = MarkForm.createMarkOutliner( shape, size ); | ||
Stamper stamper = new ShapeMode.FlatStamper( Color.RED ); | ||
ShapeStyle style = new ShapeStyle( outliner, stamper ); | ||
|
||
/* Combine the data and style to generate a plot layer. */ | ||
return plotter.createLayer( geom, dataSpec, style ); | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
ttools/src/main/uk/ac/starlink/ttools/example/EnvPlanePlotter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package uk.ac.starlink.ttools.example; | ||
|
||
import java.io.IOException; | ||
import javax.swing.JComponent; | ||
import uk.ac.starlink.table.StarTable; | ||
import uk.ac.starlink.task.TaskException; | ||
import uk.ac.starlink.ttools.plot2.task.Plot2Task; | ||
import uk.ac.starlink.ttools.task.MapEnvironment; | ||
|
||
/** | ||
* PlanePlotter implementation that uses the name/value pairs in the | ||
* same way as the STILTS application command-line interface to set | ||
* up a plot. | ||
* | ||
* This is much easier to do than the alternative, since the large | ||
* majority of the options will assume sensible defaults if not set. | ||
* It allows pretty much the same capabilities. However, it does | ||
* not offer compile-time safety: there is no guarantee that a plot | ||
* set up like this will not generate a run-time error. | ||
* | ||
* @author Mark Taylor | ||
* @since 12 Jun 2014 | ||
*/ | ||
public class EnvPlanePlotter implements SinePlot.PlanePlotter { | ||
public JComponent createPlotComponent( StarTable table, | ||
boolean dataMayChange ) | ||
throws InterruptedException, IOException, TaskException { | ||
|
||
/* Create an execution environment for the stilts plot task. */ | ||
MapEnvironment env = new MapEnvironment(); | ||
|
||
/* Populate the environment with parameter name/value pairs. | ||
* For the available parameters and their values, see the user | ||
* documentation of the corresponding STILTS command-line task. | ||
* At time of writing, this documentation does not exist :-[. | ||
* | ||
* Some general points: | ||
* | ||
* - In most cases the values are strings. | ||
* | ||
* - For some parameters non-String objects of a relevant type | ||
* are also allowed. In particular parameters accepting | ||
* tables will take StarTable objects. | ||
* | ||
* - Most parameters are optional, and will assume sensible | ||
* defaults if not set. There are several tens of parameters | ||
* available, allowing detailed setup if you want to do it. | ||
* In the example below, the required parameters are so marked, | ||
* the others can be omitted if you want to accept default values. | ||
*/ | ||
|
||
/* Global parameters for the plot. */ | ||
env.setValue( "type", "plane" ); // required | ||
env.setValue( "insets", "10,30,30,8" ); | ||
|
||
/* Parameters for the first (in this case, only) layer; | ||
* the parameter names have a trailing (arbitrary) label "1". | ||
* The values of the x1/y1 parameters, giving the data coordinates, | ||
* are names of the columns in the input table. */ | ||
env.setValue( "layer1", "mark-flat" ); // required | ||
env.setValue( "in1", table ); // required | ||
env.setValue( "x1", "x" ); // required | ||
env.setValue( "y1", "y" ); // required | ||
env.setValue( "shape1", "open circle" ); | ||
env.setValue( "size1", "2" ); | ||
|
||
/* You could add more layers here. */ | ||
|
||
/* Pass the populated environment to the Plot2Task object, | ||
* which can turn it into a JComponent containing the plot. */ | ||
boolean caching = ! dataMayChange; | ||
return new Plot2Task().createPlotComponent( env, caching ); | ||
} | ||
} |
Oops, something went wrong.