/** * Plot the results produced by the testing methods in this class. * * @param results The results of one or more tests. They must all have the same type {@link TYPE}. * If more than one result is to be plotted then only {@link TYPE#STDP} or {@link * TYPE#STDP_1D} are supported, and it is assumed that they all have the same pre- and * post-synaptic spike patterns. * @param singlePlot If plotting more than one TestResult then whether to show the results on a * single plot (true) or separate plots (false). * @param timeResolution The time resolution which the simulation was run at. * @param logSpikesAndStateVariables Whether to include pre- and post-synaptic spikes and any * state variables exposed by the synapse model in the plot. This is ignored if more than one * result is to be plotted. * @param showInFrame Whether to display the result in a frame. */ public static JFreeChart createChart( TestResults[] results, boolean singlePlot, int timeResolution, boolean logSpikesAndStateVariables, boolean showInFrame, String title) { JFreeChart resultsPlot = null; int resultsCount = results.length; // Make sure they're all the same type. for (int ri = 0; ri < results.length; ri++) { if (ri < resultsCount - 1 && results[ri].getProperty("type") != results[ri + 1].getProperty("type")) { throw new IllegalArgumentException("All results must have the same type."); } if (resultsCount > 1 && results[ri].getProperty("type") != TYPE.STDP && results[ri].getProperty("type") != TYPE.STDP_1D) { throw new IllegalArgumentException( "Multiple results can only be plotted for types STDP or STDP_1D."); } } TYPE type = (TYPE) results[0].getProperty("type"); XYLineAndShapeRenderer xyRenderer; XYToolTipGenerator tooltipGen = new StandardXYToolTipGenerator(); if (type == TYPE.STDP) { CombinedDomainXYPlot combinedPlot = new CombinedDomainXYPlot(new NumberAxis("t (s)")); if (singlePlot) { // Plot all result sets together. DefaultXYDataset efficacyData = new DefaultXYDataset(); for (TestResults result : results) { String efficacyLabel = (resultsCount == 1) ? "Efficacy" : "" + result.getProperty("label"); efficacyData.addSeries(efficacyLabel, result.getResult("Time", "Efficacy")); } xyRenderer = new XYLineAndShapeRenderer(true, false); xyRenderer.setBaseToolTipGenerator(tooltipGen); combinedPlot.add(new XYPlot(efficacyData, null, new NumberAxis("Efficacy"), xyRenderer), 4); } else { // Plot each result set separately. for (TestResults result : results) { DefaultXYDataset efficacyData = new DefaultXYDataset(); String efficacyLabel = (resultsCount == 1) ? "Efficacy" : "" + result.getProperty("label"); efficacyData.addSeries(efficacyLabel, result.getResult("Time", "Efficacy")); xyRenderer = new XYLineAndShapeRenderer(true, false); xyRenderer.setBaseToolTipGenerator(tooltipGen); combinedPlot.add( new XYPlot(efficacyData, null, new NumberAxis("Efficacy"), xyRenderer), 4); } } // Don't plot trace data for multiple tests. if (resultsCount == 1 && logSpikesAndStateVariables) { DefaultXYDataset traceData = new DefaultXYDataset(); for (String label : results[0].getResultLabels()) { if (!label.startsWith("Time") && !label.startsWith("Efficacy") && !label.equals("Pre-synaptic spikes") && !label.equals("Post-synaptic spikes")) { traceData.addSeries(label, results[0].getResult("Time", label)); } } xyRenderer = new XYLineAndShapeRenderer(true, false); xyRenderer.setBaseToolTipGenerator(tooltipGen); combinedPlot.add(new XYPlot(traceData, null, new NumberAxis("State"), xyRenderer), 3); DefaultXYDataset spikeData = new DefaultXYDataset(); spikeData.addSeries( "Pre-synaptic spikes", results[0].getResult("Time", "Pre-synaptic spikes")); spikeData.addSeries( "Post-synaptic spikes", results[0].getResult("Time", "Post-synaptic spikes")); xyRenderer = new XYLineAndShapeRenderer(true, false); xyRenderer.setBaseToolTipGenerator(tooltipGen); combinedPlot.add( new XYPlot(spikeData, null, new NumberAxis("Pre/post potential"), xyRenderer), 3); } resultsPlot = new JFreeChart(title, null, combinedPlot, true); resultsPlot.setBackgroundPaint(Color.WHITE); resultsPlot.getPlot().setBackgroundPaint(Color.WHITE); ((XYPlot) resultsPlot.getPlot()).setRangeGridlinePaint(Color.LIGHT_GRAY); ((XYPlot) resultsPlot.getPlot()).setDomainGridlinePaint(Color.LIGHT_GRAY); } else if (type == TYPE.STDP_1D) { DecimalFormat timeFormatter = new DecimalFormat(); timeFormatter.setMultiplier(1000); NumberAxis domainAxis = new NumberAxis("\u0394t (ms)"); domainAxis.setNumberFormatOverride(timeFormatter); CombinedDomainXYPlot combinedPlot = new CombinedDomainXYPlot(domainAxis); if (singlePlot) { // Plot all result sets together. DefaultXYDataset efficacyData = new DefaultXYDataset(); for (TestResults result : results) { String efficacyLabel = (resultsCount == 1) ? "Efficacy" : "" + result.getProperty("label"); efficacyData.addSeries(efficacyLabel, result.getResult("Time delta", "Efficacy")); } xyRenderer = new XYLineAndShapeRenderer(true, false); xyRenderer.setBaseToolTipGenerator(tooltipGen); combinedPlot.add(new XYPlot(efficacyData, null, new NumberAxis("Efficacy"), xyRenderer), 4); } else { // Plot each result set separately. for (TestResults result : results) { DefaultXYDataset efficacyData = new DefaultXYDataset(); String efficacyLabel = (resultsCount == 1) ? "Efficacy" : "" + result.getProperty("label"); efficacyData.addSeries(efficacyLabel, result.getResult("Time delta", "Efficacy")); xyRenderer = new XYLineAndShapeRenderer(true, false); xyRenderer.setBaseToolTipGenerator(tooltipGen); combinedPlot.add( new XYPlot(efficacyData, null, new NumberAxis("Efficacy"), xyRenderer), 4); } } resultsPlot = new JFreeChart(title, null, combinedPlot, true); resultsPlot.setBackgroundPaint(Color.WHITE); resultsPlot.getPlot().setBackgroundPaint(Color.WHITE); ((XYPlot) resultsPlot.getPlot()).setRangeGridlinePaint(Color.LIGHT_GRAY); ((XYPlot) resultsPlot.getPlot()).setDomainGridlinePaint(Color.LIGHT_GRAY); } else if (type == TYPE.STDP_2D) { double[][] data = results[0].getResult("Time delta 1", "Time delta 2", "Efficacy"); DefaultXYZDataset plotData = new DefaultXYZDataset(); plotData.addSeries("Efficacy", data); // Set up paint scale, and convert domain axes from seconds to // milliseconds (XYBlockRenderer won't deal with fractional values // in the domain axes) double min = Double.MAX_VALUE, max = -min; double[] efficacy = data[2]; for (int i = 0; i < data[0].length; i++) { if (efficacy[i] < min) min = efficacy[i]; if (efficacy[i] > max) max = efficacy[i]; data[0][i] = Math.round(data[0][i] * 1000); data[1][i] = Math.round(data[1][i] * 1000); } XYBlockRenderer renderer = new XYBlockRenderer(); double range = Math.max(Math.abs(min), Math.abs(max)); double rangeBase = 0; if (min < 0) min = -range; if (max > 0) max = range; // If the value range does not cross the zero point, don't use a zero-based range. if ((min > 0) || (max < 0)) { range = Math.abs(max - min); rangeBase = Math.min(Math.abs(min), Math.abs(max)); } if (min >= max) { max = min + Double.MIN_VALUE * 10; } LookupPaintScale scale = new LookupPaintScale(min, max, Color.WHITE); if (min < 0) { for (int ci = 0; ci <= 255; ci++) { double v = -(ci / 255.0) * range - rangeBase; scale.add(v, new Color(0, ci, ci)); } } if (max > 0) { for (int ci = 0; ci <= 255; ci++) { double v = (ci / 255.0) * range + rangeBase; scale.add(v, new Color(ci, ci, 0)); } } renderer.setPaintScale(scale); renderer.setSeriesToolTipGenerator(0, new StandardXYZToolTipGenerator()); int displayResolution = ((Integer) results[0].getProperty("display time resolution")).intValue(); renderer.setBlockWidth(1000.0 / displayResolution); renderer.setBlockHeight(1000.0 / displayResolution); NumberAxis xAxis = new NumberAxis("\u0394t1 (ms)"); NumberAxis yAxis = new NumberAxis("\u0394t2 (ms)"); XYPlot plot = new XYPlot(plotData, xAxis, yAxis, renderer); plot.setDomainGridlinesVisible(false); resultsPlot = new JFreeChart(title, plot); resultsPlot.removeLegend(); NumberAxis valueAxis = new NumberAxis(); valueAxis.setLowerBound(scale.getLowerBound()); valueAxis.setUpperBound(scale.getUpperBound()); PaintScaleLegend legend = new PaintScaleLegend(scale, valueAxis); legend.setPosition(RectangleEdge.RIGHT); legend.setMargin(5, 5, 5, 5); resultsPlot.addSubtitle(legend); } if (showInFrame) { JFrame plotFrame = new JFrame(title); plotFrame.add(new ChartPanel(resultsPlot)); plotFrame.setExtendedState(plotFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH); plotFrame.pack(); plotFrame.setVisible(true); } return resultsPlot; }