示例#1
0
  /**
   * 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;
  }