I have a dataset with 3 column, x, y, and value at (x,y). I want to plot map similar to bellow map. How to plot this type of figure in jfreechart or any library available for this kind of plot?
Asked
Active
Viewed 3,626 times
2
-
More discussion [here](http://www.jfree.org/forum/viewtopic.php?f=3&t=29588). – trashgod May 15 '16 at 04:17
3 Answers
3
Starting with this example and using this idea, you can use a SpectrumPaintScale
to get a palette of colors as shown below.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Paint;
import javax.swing.JFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.PaintScale;
import org.jfree.chart.renderer.xy.XYBlockRenderer;
import org.jfree.chart.title.PaintScaleLegend;
import org.jfree.data.xy.DefaultXYZDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYZDataset;
import org.jfree.chart.ui.RectangleEdge;
import org.jfree.chart.ui.RectangleInsets;
/**
* @see https://stackoverflow.com/a/37235165/230513
*/
public class XYZChartDemo {
private static final int N = 100;
public XYZChartDemo(String title) {
JFrame f = new JFrame(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ChartPanel chartPanel = new ChartPanel(createChart(createDataset())) {
@Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
};
chartPanel.setMouseZoomable(true, false);
f.add(chartPanel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static JFreeChart createChart(XYDataset dataset) {
NumberAxis xAxis = new NumberAxis("x Axis");
NumberAxis yAxis = new NumberAxis("y Axis");
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
XYBlockRenderer r = new XYBlockRenderer();
r.setDefaultToolTipGenerator(new StandardXYToolTipGenerator());
SpectrumPaintScale ps = new SpectrumPaintScale(0, N * N);
r.setPaintScale(ps);
plot.setRenderer(r);
JFreeChart chart = new JFreeChart("Title",
JFreeChart.DEFAULT_TITLE_FONT, plot, false);
NumberAxis scaleAxis = new NumberAxis("Scale");
scaleAxis.setAxisLinePaint(Color.white);
scaleAxis.setTickMarkPaint(Color.white);
PaintScaleLegend legend = new PaintScaleLegend(ps, scaleAxis);
legend.setSubdivisionCount(128);
legend.setAxisLocation(AxisLocation.TOP_OR_RIGHT);
legend.setPadding(new RectangleInsets(25, 10, 50, 10));
legend.setStripWidth(20);
legend.setPosition(RectangleEdge.RIGHT);
legend.setBackgroundPaint(Color.WHITE);
chart.addSubtitle(legend);
chart.setBackgroundPaint(Color.white);
return chart;
}
private static XYZDataset createDataset() {
DefaultXYZDataset dataset = new DefaultXYZDataset();
double[][] data = new double[3][N * N];
for (int i = 0; i < N * N; i++) {
var x = i % N;
var y = i / N;
data[0][i] = x;
data[1][i] = y;
data[2][i] = x * y;
}
dataset.addSeries("Series", data);
return dataset;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
XYZChartDemo demo = new XYZChartDemo("XYZ Demo");
});
}
private static class SpectrumPaintScale implements PaintScale {
private static final float H1 = 0f;
private static final float H2 = 1f;
private final double lowerBound;
private final double upperBound;
public SpectrumPaintScale(double lowerBound, double upperBound) {
this.lowerBound = lowerBound;
this.upperBound = upperBound;
}
@Override
public double getLowerBound() {
return lowerBound;
}
@Override
public double getUpperBound() {
return upperBound;
}
@Override
public Paint getPaint(double value) {
float scaledValue = (float) (value / (getUpperBound() - getLowerBound()));
float scaledH = H1 + scaledValue * (H2 - H1);
return Color.getHSBColor(scaledH, 1f, 1f);
}
}
}

trashgod
- 203,806
- 29
- 246
- 1,045
-
Instead of griding, can we create dataset something like dataset.add(array)? [data to be plotted](https://docs.google.com/spreadsheets/d/1jG9UZboPcU0kKRGD2OTHA_iViz9h49y_NEyXDj10KJ4/edit?usp=sharing) – Ranjeet May 15 '16 at 14:37
-
A related example using `XYLineAndShapeRenderer` with `XYZDataset` is shown [here](https://stackoverflow.com/a/54180207/230513). – trashgod Jan 26 '19 at 17:28
-
@trashgod What is the significance of H1 and H2 here? I want to create a rainbow pallet where the color values (Z) will be dynamic. I tried this implementation, but it doesn't make sufficient colors. – ACB Jul 04 '23 at 23:32
-
I agree; simple, linear interpolation isn't very flexible; a suitable `Paint` implementation will likely be more adaptable to a particular use case. – trashgod Jul 05 '23 at 17:07
2
An XYBlockRenderer
looks like a good match. You can use Color.getHSBColor()
, like they show here, to make the PaintScale
.

Community
- 1
- 1

Catalina Island
- 7,027
- 2
- 23
- 42
-
yes..tried this but output image is not smooth. I also tried different render width and height. – Ranjeet May 11 '16 at 16:49
-
What resolution did you use? The example looks like 100 x 100 blocks, – Catalina Island May 12 '16 at 10:25
1
You can use a BubbleChart to illustrate a dataset with 3 columns.
There are some android libs which contain some charts that look pretty well.
HelloCharts for Android: https://github.com/lecho/hellocharts-android
MPAndroidChart: https://github.com/PhilJay/MPAndroidChart
Hope this solve your problem.

hilzj
- 68
- 10