I am using the Java HeatMap
library (http://www.mbeckler.org/heatMap/) to generate heatMap for my data.
I am working with a daatset which has NA values. So, basically I want no color (white color) for the pixels which have NA
value. But, unfortunately this library does not support data with NA value and what I get is a plan block of image with the base color. I tried looking into the source code, so as to make some changes. Within the code, the drawData()
method is used to color each pixel in the bufferedImage (possibly!). Can someone help me with how I can implement support for NA values and to show them with no color? I have little to no experience with BufferedImage
and Graphics2D
class.
Here is the drawData()
method from the source code of the library:
/**
* Creates a BufferedImage of the actual data plot.
*
* After doing some profiling, it was discovered that 90% of the drawing
* time was spend drawing the actual data (not on the axes or tick marks).
* Since the Graphics2D has a drawImage method that can do scaling, we are
* using that instead of scaling it ourselves. We only need to draw the
* data into the bufferedImage on startup, or if the data or gradient
* changes. This saves us an enormous amount of time. Thanks to
* Josh Hayes-Sheen ([email protected]) for the suggestion and initial code
* to use the BufferedImage technique.
*
* Since the scaling of the data plot will be handled by the drawImage in
* paintComponent, we take the easy way out and draw our bufferedImage with
* 1 pixel per data point. Too bad there isn't a setPixel method in the
* Graphics2D class, it seems a bit silly to fill a rectangle just to set a
* single pixel...
*
* This function should be called whenever the data or the gradient changes.
*/
private void drawData()
{
// System.out.println("Column: " + data.length + " row: " + data[0].length);
bufferedImage = new BufferedImage(data.length,data[0].length, BufferedImage.TYPE_INT_ARGB);
bufferedGraphics = bufferedImage.createGraphics();
for (int x = 0; x < data.length; x++)
{
for (int y = 0; y < data[0].length; y++)
{
bufferedGraphics.setColor(colors[dataColorIndices[x][y]]);
bufferedGraphics.fillRect(x, y, 1, 1);
}
}
}
sample data can be found at: http://www.filedropper.com/data_13
So, this is how it looks at the moment:
From Java:
From R:
Please ignore the orientation of the two images
As the BufferedImage
is created as ARGB, you could just not paint anything on those pixels that should be undefined, and they'll stay transparent. Something like:
public static int NA = ...;
private void drawData()
{
bufferedImage = new BufferedImage(data.length,data[0].length, BufferedImage.TYPE_INT_ARGB);
Graphics2D bufferedGraphics = bufferedImage.createGraphics();
try {
for (int x = 0; x < data.length; x++)
{
for (int y = 0; y < data[0].length; y++)
{
int colorIndex = dataColorIndices[x][y];
if (colorIndex != NA) {
bufferedGraphics.setColor(colors[colorIndex]);
bufferedGraphics.fillRect(x, y, 1, 1);
}
// Alternate flow, if you really want the pixels to be white
// else {
// bufferedGraphics.setColor(Color.WHITE);
// bufferedGraphics.fillRect(x, y, 1, 1);
// }
}
}
}
finally {
bufferedGraphics.dispose();
}
}
I also dispose the Graphics2D
instance, to avoid resource leaks.