public void addValue(long x, double y) {
      // calculate the bar in which this value should go
      int bar = (int) (x / barsize);

      double Y = y;
      if (ysum.containsKey(bar)) {

        double newyvalue = Y + ysum.get(bar);
        long newxvalue = x + xsum.get(bar);

        Integer newcount = count.get(bar) + 1;

        ysum.put(bar, newyvalue);
        xsum.put(bar, newxvalue);
        count.put(bar, newcount);
        Vector<Double> barvalues = values.get(bar);
        barvalues.add(Y);
        values.put(bar, barvalues);

      } else {
        ysum.put(bar, Y);
        xsum.put(bar, x);
        count.put(bar, 1);
        Vector<Double> barvalues = new Vector<Double>();
        barvalues.add(Y);
        values.put(bar, barvalues);
      }
    }
 public YIntervalSeries getYIntervalSeries(String rowname, long factor) {
   YIntervalSeries mydataset = new YIntervalSeries(rowname);
   double sdcount = 0;
   double total = 0;
   Vector<Double> totalvalues = new Vector<Double>();
   double avgtotal = 0;
   double minus = 0;
   double plus = 0;
   double zero = 0;
   for (Integer key : ysum.keySet()) {
     Double value = ysum.get(key) / (double) count.get(key);
     Double point = (double) xsum.get(key) / (double) count.get(key);
     Vector<Double> listofvalues = values.get(key);
     double sumofdiff = 0.0;
     for (Double onevalue : listofvalues) {
       sumofdiff += Math.pow(onevalue - value, 2);
       sdcount++;
       total += Math.pow(onevalue, 2);
       avgtotal += onevalue;
       totalvalues.add(onevalue);
       if (onevalue == 1) {
         plus++;
       }
       ;
       if (onevalue == -1) {
         minus++;
       }
       ;
       if (onevalue == 0) {
         zero++;
       }
       ;
     }
     double sd = Math.sqrt(sumofdiff / count.get(key));
     // mydataset.add(point/factor, value,value+sd,value-sd);
     // mydataset.add(point/factor, value,value,value);
     mydataset.add(
         point / factor,
         value,
         value + 1.96 * (sd / Math.sqrt(count.get(key))),
         value - 1.96 * (sd / Math.sqrt(count.get(key))));
   }
   double sdtotal = 0;
   double avgsd = total / sdcount;
   double test = 0;
   for (Double onevalue : totalvalues) {
     sdtotal += Math.pow(Math.pow(onevalue, 2) - (total / sdcount), 2);
     test += onevalue;
   }
   // System.out.println(rowname+" mean square: "+avgsd+"
   // +/-95%:"+1.96*Math.sqrt(sdtotal/sdcount)/Math.sqrt(sdcount));
   // System.out.println("total -1:"+minus+" total +1:"+plus+" zero: "+zero
   // +" total:"+sdcount);
   return mydataset;
 }
  /**
   * The constructor.
   *
   * @param logFileName The experiment log file to analyze.
   * @param samplingInterval The interval at which to calculate the heading error in milliseconds.
   * @param saveToFile whether to save the error calculations to a file.
   */
  public VisualizeHeadingError(String logFileName, long samplingInterval, boolean saveToFile) {
    this.logFileName = logFileName;
    robotData = new RobotExpData(logFileName);

    long startTime = robotData.getExpStartTime();

    // Calculate heading divergence every sampling interval
    for (long time = startTime; time < robotData.getExpStopTime(); time += samplingInterval) {

      // Only do the calculation if the robot has started to move.
      if (time >= robotData.getPathEdge(0).getStartTime())
        divergenceData.add(getHeadingError(time));
    }

    if (saveToFile) saveToFile();
    showPlot();
  }