We are monitoring the score of an evolution with
constantly adding data to an XYSeries and repainting
the chart. As soon as the Y-Value reaches a constant
level, we get a spike in the direction of the X-Axis. I
have attached a file with the screenshot.
Note that, with the series below, the behaviour starts
popping up at generation 30, where the Y value of
137.40161 is repeated in generation 35.
[java] Adding score for generation number 5
[java] score is: 106.18773
[java] Adding score for generation number 10
[java] score is: 121.51716
[java] Adding score for generation number 15
[java] score is: 124.19476
[java] Adding score for generation number 20
[java] score is: 129.50732
[java] Adding score for generation number 25
[java] score is: 132.03752
[java] Adding score for generation number 30
[java] score is: 137.40161
[java] Adding score for generation number 35
[java] score is: 137.40161
[java] Adding score for generation number 40
[java] score is: 137.42336
[java] Adding score for generation number 45
[java] score is: 137.42336
[java] Adding score for generation number 50
[java] score is: 137.42336
A screen shot showing the reported spiking in an XY plot
Logged In: YES
user_id=112975
Can you post some sample code that shows this problem? I
ran the following program (an adaptation of the
DynamicDataDemo1.java demo), and it seems to work OK:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
/**
* A demonstration application showing a time series chart
where you can dynamically add
* (random) data by clicking on a button.
*/
public class DynamicDataDemo1 extends ApplicationFrame {
/**
* Constructs a new demonstration application.
*
* @param title the frame title.
*/
public DynamicDataDemo1(String title) {
super(title);
DemoPanel demoPanel = new DemoPanel();
setContentPane(demoPanel);
}
static class DemoPanel extends JPanel implements
ActionListener {
private double[] x = {5, 10, 15, 20, 25, 30, 35, 40,
45, 50};
private double[] y = {106.18773, 121.51716,
124.19476, 129.50732, 132.03752, 137.40161,
137.40161, 137.42336,
137.42336, 137.42336};
private int index = 0;
/** The time series data. */
private XYSeries series;
/** The most recent value added. */
private double lastValue = 100.0;
/**
* Creates a new instance.
*/
public DemoPanel() {
super(new BorderLayout());
this.series = new XYSeries("Series 1");
XYSeriesCollection dataset = new
XYSeriesCollection();
dataset.addSeries(this.series);
ChartPanel chartPanel = new
ChartPanel(createChart(dataset));
chartPanel.setPreferredSize(new
java.awt.Dimension(500, 270));
JPanel buttonPanel = new JPanel();
buttonPanel.setBorder(BorderFactory.createEmptyBorder(4, 4,
4, 4));
JButton button = new JButton("Add New Data Item");
button.setActionCommand("ADD_DATA");
button.addActionListener(this);
buttonPanel.add(button);
add(chartPanel);
add(buttonPanel, BorderLayout.SOUTH);
}
/**
* Creates a sample chart.
*
* @param dataset the dataset.
*
* @return A sample chart.
*/
private JFreeChart createChart(XYDataset dataset) {
JFreeChart result = ChartFactory.createXYLineChart(
"Dynamic Data Demo",
"Time",
"Value",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false
);
XYPlot plot = (XYPlot) result.getPlot();
NumberAxis rangeAxis = (NumberAxis)
plot.getRangeAxis();
rangeAxis.setAutoRangeIncludesZero(false);
return result;
}
/**
* Handles a click on the button by adding new
(random) data.
*
* @param e the action event.
*/
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("ADD_DATA")) {
if (this.index < 10) {
this.series.add(this.x[this.index],
this.y[this.index]);
this.index++;
}
}
}
}
/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createDemoPanel() {
return new DynamicDataDemo1.DemoPanel();
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(String[] args) {
DynamicDataDemo1 demo = new
DynamicDataDemo1("Dynamic Data Demo");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
Regards,
Dave Gilbert
JFreeChart Project Leader
Logged In: YES
user_id=54358
Hi David,
thanks for getting back to us.
I'm on vacation at the moment and can't find the time for a
runnable demo. Here is what we do:
xySeriesCollection =
(XYSeriesCollection)monitoringChartPanel.getChart().getXYPlot().getDataset();
xySeries = xySeriesCollection.getSeries(0);
xySeries.add(((FloatScore)best.getScore()).getValue(),
generationNumber);
monitoringChartPanel.repaint();
This basically adds a floating point value on the y axis and
an integer on the x axis. The x axis values are added in
intervals of 5. (5, 10, 15, etc.)
Logged In: YES
user_id=112975
My initial thought was that you might be running into a bug
that has been fixed in CVS:
http://cvs.sourceforge.net/viewcvs.py/jfreechart/jfreechart/source/org/jfree/data/xy/XYSeries.java?r1=1.2&r2=1.3
However, this only affects duplicate x-values, and I assumed
that you had duplicate y-values. But then your call to the
add() method specifies the score as the x-value, and the
generationNumber as the y-value. But for that to work, you
would need to change the orientation of the plot to
horizontal - maybe your other code does that.
The other alternative is that you are somehow adding more
than one observation for generationNumber = 30, but I can't
tell that without seeing more code.
Regards,
Dave Gilbert
JFreeChart Project Leader