How to: make x and y axis have the same autogen tick marks

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
AndrewC
Posts: 2
Joined: Mon Apr 03, 2017 2:12 am
antibot: No, of course not.

How to: make x and y axis have the same autogen tick marks

Post by AndrewC » Mon Apr 03, 2017 2:31 am

Hello

We are using JFreeChart to generate an xy plot. The plot is always made "square", so the min and max range of the x and y axis is always set the same.

We do not know before hand what the data will look like, so we don't have any guesses as to what the tick mark intervals should be. The automatic tick marks that are produced are pretty good, so we want to keep relying on that.
Our issue is that sometimes, but not always, it sets different tick marks on the x axis than the y axis. For example the tick mark interval may be every 0.1 on the x-axis, but every 0.05 on the y-axis. We would like them to be the same.

We think that because we are using the auto generated tick marks that these are not available until the plot is rendered, and as such we have some code that seems to work (posted below).
Our Question: But maybe this isn't the case and we can get access to the tick marks earlier. Or maybe there a better way.

Snips of our code is shown below:

Code: Select all

// Generate the data series
dataset = generateData();

// Create the scatter plot
JFreeChart xyChart = ChartFactory.createScatterPlot(
                title,
                xAxisLabel,
                yAxisLabel,
                dataset,
                orientation,
                showLegend,generateToolTips,generateURLs);

// Do some minor chart formatting here
XYPlot plot = xyChart.getXYPlot();
doChartFormatting(plot);

// make the x and y domain axis symmetric.  Find the largest x or y point and make the domains just a bit larger than that figure.
double maxDomain = Math.max(maxAbsX, maxAbsY) * 1.10;
double minDomain = -1 * maxDomain;
plot.getDomainAxis().setRange(minDomain, maxDomain);
plot.getRangeAxis().setRange(minDomain, maxDomain);

// Make x and y axis have same tick marks.  Need to do this in a round about way as the automatic tick marks are
// not generated until the chart is finally rendered (we think).
// Add an event listener that fires once the chart has finished drawing, at this stage the auto tick marks will have
// been determined.  Copy the x tick marks to the y axis.  Next time the chart is drawn it will use these matching
// tick marks.
// The trick is to do a dummy draw of the chart first so we can get the tick marks, and then do the real draw
// to file after that.
xyChart.addProgressListener(chartProgressEvent -> {
            if (chartProgressEvent.getType() == ChartProgressEvent.DRAWING_FINISHED) {
                NumberAxis domainNumberAxis = (NumberAxis) plot.getDomainAxis();
                NumberAxis rangeNumberAxis = (NumberAxis) plot.getRangeAxis();
                NumberTickUnit domainTickUnit = domainNumberAxis.getTickUnit();
                // Set the auto tick marks from the x axis onto the y axis.  Set onto the x axis again as well just
                // in to guarantee that the auto tick mark drawing wont change between renders.
                rangeNumberAxis.setTickUnit(domainTickUnit);
                domainNumberAxis.setTickUnit(domainTickUnit);
            }
        });
try {
       // Write the chart to an output stream that gets thrown away, this will trigger the DRAWING_FINISHED event
       ChartUtilities.writeChartAsPNG(new ByteArrayOutputStream(), xyChart, 500, 500);
} catch (IOException e) {
       // do something here
}

// Do  the real save of the chart
File chartFile = filename.toFile();
try {
      ChartUtilities.saveChartAsPNG(chartFile, xyChart, 500, 500);
      return chartFile;
} catch (Exception e) {
      // do something here
}
All help appreciated

Cheers
AndrewC

Locked