Skip to content

Commit ea80229

Browse files
authored
Merge pull request #99 from CEGRcode/heatmap-trace
Heatmap trace (#66)
2 parents accf3ff + 5ea57ad commit ea80229

6 files changed

Lines changed: 71 additions & 39 deletions

File tree

src/cli/Figure_Generation/ThreeColorHeatMapCLI.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static class MaxGroup {
7676
@Option(names = {"-0", "--include-zeros"}, description = "used with `-p` flag, indicating exclusion of zero values when calculating percentile thresholds")
7777
private boolean includeZeros = false;
7878

79-
@ArgGroup(multiplicity = "0..1", heading = "%nSelect heatmap colors:%n")
79+
@ArgGroup(multiplicity = "0..1", exclusive=false, heading = "%nSelect heatmap colors:%n")
8080
private ColorGroup color = new ColorGroup();
8181
static class ColorGroup {
8282
@Option(names = {"-cn", "--color-min"}, description = "Color indicating minimum values (default=YELLOW) For custom color: type hexadecimal string to represent colors (e.g. \"FF0000\" is hexadecimal for red).\n See <http://www.javascripter.net/faq/rgbtohex.htm> for some color options with their corresponding hex strings.\n")
@@ -88,7 +88,20 @@ static class ColorGroup {
8888
@Option(names = {"-ca", "--color-nan"}, description = "Color indicating not-a-number values (default=GRAY) For custom color: type hexadecimal string to represent colors (e.g. \"FF0000\" is hexadecimal for red).\n See <http://www.javascripter.net/faq/rgbtohex.htm> for some color options with their corresponding hex strings.\n")
8989
private String nan = null;
9090
}
91-
91+
92+
@ArgGroup(multiplicity = "0..1", exclusive=false, heading = "%nSelect transparency of heatmap colors (alpha channel):%n")
93+
private AlphaGroup alpha = new AlphaGroup();
94+
static class AlphaGroup {
95+
@Option(names = {"-tn", "--transparent-min"}, description = "Value indicating transparency of minimum values, 0 to 255 (default=255)\n")
96+
private int min = 255;
97+
@Option(names = {"-td", "--transparent-mid"}, description = "Value indicating transparency of middle values, 0 to 255 (default=255)\n")
98+
private int mid = 255;
99+
@Option(names = {"-tx", "--transparent-max"}, description = "Value indicating transparency of maximum values, 0 to 255 (default=255)\n")
100+
private int max = 255;
101+
@Option(names = {"-ta", "--transparent-nan"}, description = "Value indicating transparency of not-a-number values, 0 to 255 (default=255)\n")
102+
private int nan = 255;
103+
}
104+
92105
String scaleType = "treeview";
93106
//Colors from JavaTreeview microarray software
94107
Color CMAX = new Color(254,255,0,255);
@@ -217,6 +230,16 @@ private String validateInput() throws IOException {
217230
System.err.println("Decoding NaN color: 0x" + color.nan);
218231
CNAN = Color.decode("0x" + color.nan);
219232
}
233+
// check that Alpha channel/transparency values are formatted properly and decode/assign colors
234+
if (alpha.max<0 || alpha.max>255) { r += "(!)Alpha/transparency value for higher values (max) must be a numeric 0 to 255\n"; }
235+
else { CMAX = new Color(CMAX.getRed(), CMAX.getGreen(), CMAX.getBlue(), alpha.max); }
236+
if (alpha.mid<0 || alpha.mid>255) { r += "(!)Alpha/transparency value for middling values (mid) must be a numeric 0 to 255\n"; }
237+
else { CMID = new Color(CMID.getRed(), CMID.getGreen(), CMID.getBlue(), alpha.mid); }
238+
if (alpha.min<0 || alpha.min>255) { r += "(!)Alpha/transparency value for lower values(min) must be a numeric 0 to 255\n"; }
239+
else { CMIN = new Color(CMIN.getRed(), CMIN.getGreen(), CMIN.getBlue(), alpha.min); }
240+
if (alpha.nan<0 || alpha.nan>255) { r += "(!)Alpha/transparency value for invalid/non-numeric values(NaN) must be a numeric 0 to 255\n"; }
241+
else { CNAN = new Color(CNAN.getRed(), CNAN.getGreen(), CNAN.getBlue(), alpha.nan); }
242+
220243
// assign vals for contrast thresholds and set bools
221244
if(maxGroup.percentile!=null) {
222245
MAX = maxGroup.percentile;

src/cli/Figure_Generation/TwoColorHeatMapCLI.java

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ public class TwoColorHeatMapCLI implements Callable<Integer> {
5656

5757
@ArgGroup(exclusive = true, multiplicity = "0..1", heading = "%nSelect heatmap color:%n\t@|fg(red) (select no more than one of these options)|@%n")
5858
private ColorGroup color = new ColorGroup();
59-
6059
static class ColorGroup {
6160
@Option(names = { "--black" }, description = "Use the color black for generating the heatmap (default)")
6261
private boolean black = false;
@@ -68,6 +67,12 @@ static class ColorGroup {
6867
"--color" }, description = "For custom color: type hexadecimal string to represent colors (e.g. \"FF0000\" is hexadecimal for red).\n See <http://www.javascripter.net/faq/rgbtohex.htm> for some color options with their corresponding hex strings.\n")
6968
private String custom = null;
7069
}
70+
@Option(names = { "-t", "--transparent" }, description = "Value indicating transparency of heatmap, 0 to 255 (default=255)\n")
71+
private int alpha = 255;
72+
73+
@Option(names = { "-b", "--background" }, description = "Set a transparent background for the heatmap minimum values (default=white)\n")
74+
private boolean transparentBackground = false;
75+
7176

7277
String scaleType = "treeview";
7378
Color MAXCOLOR = Color.BLACK;
@@ -84,7 +89,7 @@ public Integer call() throws Exception {
8489

8590
// Generate HeatMap
8691
TwoColorHeatMap script_object = new TwoColorHeatMap(CDT, MAXCOLOR, startROW, startCOL, pixelHeight, pixelWidth,
87-
scaleType, absolute, percentile, output, true);
92+
scaleType, absolute, percentile, output, true, transparentBackground);
8893
script_object.run();
8994

9095
System.err.println("Image Generated.");
@@ -114,16 +119,6 @@ private String validateInput() throws IOException {
114119
output = new File(NAME + "_" + scaleType + ".png");
115120
// check output filename is valid
116121
} else {
117-
// check ext
118-
try {
119-
if (!"png".equals(ExtensionFileFilter.getExtension(output))) {
120-
r += "(!)Use PNG extension for output filename. Try: " + ExtensionFileFilter.stripExtension(output)
121-
+ ".png\n";
122-
}
123-
} catch (NullPointerException e) {
124-
r += "(!)Output filename must have extension: use PNG extension for output filename. Try: " + output
125-
+ ".png\n";
126-
}
127122
// check directory
128123
if (output.getParent() == null) {
129124
// System.err.println("default to current directory");
@@ -136,14 +131,7 @@ private String validateInput() throws IOException {
136131
if (compression < 1 || compression > 4) {
137132
r += "(!)Compression must be integer 1-4. Please select from the available compression types.";
138133
}
139-
// check that hex string is formatted properly
140-
if (color.custom != null) {
141-
Pattern hexColorPat = Pattern.compile("[0-9A-Fa-f]{6}");
142-
Matcher m = hexColorPat.matcher(color.custom);
143-
if (!m.matches()) {
144-
r += "(!)Color must be formatted as a hexidecimal String!\n\tExpected input string format: \"[0-9A-Fa-f]{6}\"";
145-
}
146-
}
134+
147135
// check scaling is valid input
148136
if (absolute == -999 && percentile == -999) {
149137
absolute = 10;
@@ -165,8 +153,16 @@ private String validateInput() throws IOException {
165153
MAXCOLOR = Color.BLUE;
166154
} else if (color.custom != null) {
167155
System.err.println("Decoding color: 0x" + color.custom);
168-
MAXCOLOR = Color.decode("0x" + color.custom);
156+
// check that hex string is formatted properly
157+
Pattern hexColorPat = Pattern.compile("[0-9A-Fa-f]{6}");
158+
Matcher m = hexColorPat.matcher(color.custom);
159+
if (!m.matches()) {
160+
r += "(!)Color must be formatted as a hexidecimal String!\n\tExpected input string format: \"[0-9A-Fa-f]{6}\"";
161+
} else { MAXCOLOR = Color.decode("0x" + color.custom); }
169162
}
163+
// check that Alpha channel/transparency values are formatted properly and decode/assign colors
164+
if (alpha<0 || alpha>255) { r += "(!)Alpha/transparency value for higher values (max) must be a numeric 0 to 255\n"; }
165+
else { MAXCOLOR = new Color(MAXCOLOR.getRed(), MAXCOLOR.getGreen(), MAXCOLOR.getBlue(), alpha); }
170166

171167
return (r);
172168
}

src/scripts/Figure_Generation/ThreeColorHeatMap.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public static BufferedImage generateHeatMap(ArrayList<double[]> matrix) throws F
175175
BufferedImage im = new BufferedImage(pixwidth, pixheight, BufferedImage.TYPE_INT_ARGB);
176176
Graphics g = im.getGraphics();
177177
Graphics2D g2 = (Graphics2D) g;
178-
g2.setColor(new Color(255, 255, 255));
178+
g2.setColor(new Color(255, 255, 255, 0));
179179
g2.fillRect(0, 0, pixwidth, pixheight);
180180

181181
int count = 0;
@@ -196,7 +196,8 @@ public static BufferedImage generateHeatMap(ArrayList<double[]> matrix) throws F
196196
int red = (int) (MAXCOLOR.getRed() * sVal + MIDCOLOR.getRed() * (1 - sVal));
197197
int green = (int) (MAXCOLOR.getGreen() * sVal + MIDCOLOR.getGreen() * (1 - sVal));
198198
int blue = (int) (MAXCOLOR.getBlue() * sVal + MIDCOLOR.getBlue() * (1 - sVal));
199-
g.setColor(new Color(red, green, blue));
199+
int alpha = (int) (MAXCOLOR.getAlpha() * sVal + MIDCOLOR.getAlpha() * (1 - sVal));
200+
g.setColor(new Color(red, green, blue, alpha));
200201
} else if (IDj < MIDVAL) {
201202
double v = (MIDVAL - IDj) / LOWER_RATIO;
202203
double sVal = v > 1 ? 1 : v;
@@ -206,7 +207,8 @@ public static BufferedImage generateHeatMap(ArrayList<double[]> matrix) throws F
206207
int red = (int) (MINCOLOR.getRed() * sVal + MIDCOLOR.getRed() * (1 - sVal));
207208
int green = (int) (MINCOLOR.getGreen() * sVal + MIDCOLOR.getGreen() * (1 - sVal));
208209
int blue = (int) (MINCOLOR.getBlue() * sVal + MIDCOLOR.getBlue() * (1 - sVal));
209-
g.setColor(new Color(red, green, blue));
210+
int alpha = (int) (MINCOLOR.getAlpha() * sVal + MIDCOLOR.getAlpha() * (1 - sVal));
211+
g.setColor(new Color(red, green, blue, alpha));
210212
} else {
211213
g.setColor(MIDCOLOR);
212214
}

src/scripts/Figure_Generation/TwoColorHeatMap.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class TwoColorHeatMap {
4949
private JLabel picLabel = null;
5050

5151
public TwoColorHeatMap(File in, Color c, int startR, int startC, int pHeight, int pWidth, String scale, double abs,
52-
double quant, File output, boolean outstatus) {
52+
double quant, File output, boolean outstatus, boolean trans) {
5353

5454
SAMPLE = in;
5555
MAXCOLOR = c;
@@ -64,6 +64,10 @@ public TwoColorHeatMap(File in, Color c, int startR, int startC, int pHeight, in
6464

6565
OUTFILE = output;
6666
OUTPUTSTATUS = outstatus;
67+
MINCOLOR = new Color(255, 255, 255, 255);
68+
if (trans) {
69+
MINCOLOR = new Color(MAXCOLOR.getRed(), MAXCOLOR.getGreen(), MAXCOLOR.getBlue(), 0);
70+
}
6771
}
6872

6973
public void run() throws IOException {
@@ -122,7 +126,7 @@ public static BufferedImage generateHeatMap(ArrayList<double[]> matrix) throws F
122126
BufferedImage im = new BufferedImage(pixwidth, pixheight, BufferedImage.TYPE_INT_ARGB);
123127
Graphics g = im.getGraphics();
124128
Graphics2D g2 = (Graphics2D) g;
125-
g2.setColor(new Color(255, 255, 255));
129+
g2.setColor(MINCOLOR);
126130
g2.fillRect(0, 0, pixwidth, pixheight);
127131

128132
int count = 0;
@@ -136,9 +140,10 @@ public static BufferedImage generateHeatMap(ArrayList<double[]> matrix) throws F
136140
int red = (int) (MAXCOLOR.getRed() * sVal + MINCOLOR.getRed() * (1 - sVal));
137141
int green = (int) (MAXCOLOR.getGreen() * sVal + MINCOLOR.getGreen() * (1 - sVal));
138142
int blue = (int) (MAXCOLOR.getBlue() * sVal + MINCOLOR.getBlue() * (1 - sVal));
139-
g.setColor(new Color(red, green, blue));
143+
int alpha = (int) (MAXCOLOR.getAlpha() * sVal + MINCOLOR.getAlpha() * (1 - sVal));
144+
g.setColor(new Color(red, green, blue, alpha));
140145
} else {
141-
g.setColor(Color.WHITE);
146+
g.setColor(MINCOLOR);
142147
}
143148
g.fillRect(j * width, count * height, width, height);
144149
}
@@ -354,7 +359,7 @@ public static double getQuantile(ArrayList<double[]> matrix, double percent) {
354359
ArrayList<Double> nonZero = new ArrayList<Double>();
355360
for (int x = 0; x < matrix.size(); x++) {
356361
for (int y = 0; y < matrix.get(x).length; y++) {
357-
if (matrix.get(x)[y] != 0) {
362+
if (matrix.get(x)[y] != 0 && !Double.isNaN(matrix.get(x)[y])) {
358363
nonZero.add(Double.valueOf(matrix.get(x)[y]));
359364
}
360365
}

src/window_interface/Figure_Generation/TwoColorHeatMapOutput.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public class TwoColorHeatMapOutput extends JFrame {
2828
protected static double quantile = 0.9;
2929
protected static double absolute = -999;
3030

31-
public static Color MINCOLOR = new Color(255, 255, 255);
3231
public static Color MAXCOLOR = new Color(255, 0, 0);
32+
public boolean transparentBackground = false;
3333

3434
protected static boolean OUTPUTSTATUS = false;
3535
protected static File OUT_DIR = null;
@@ -39,7 +39,7 @@ public class TwoColorHeatMapOutput extends JFrame {
3939
JTabbedPane newpane;
4040

4141
public TwoColorHeatMapOutput(ArrayList<File> in, Color c, int startR, int startC, int pHeight, int pWidth,
42-
String scale, double abs, double quant, File out_dir, boolean outstatus) {
42+
String scale, double abs, double quant, File out_dir, boolean outstatus, boolean trans) {
4343
setTitle("Heatmap");
4444
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
4545
setBounds(150, 150, 600, 800);
@@ -49,6 +49,7 @@ public TwoColorHeatMapOutput(ArrayList<File> in, Color c, int startR, int startC
4949

5050
SAMPLE = in;
5151
MAXCOLOR = c;
52+
transparentBackground = trans;
5253
startROW = startR;
5354
startCOL = startC;
5455
pixelHeight = pHeight;
@@ -60,7 +61,6 @@ public TwoColorHeatMapOutput(ArrayList<File> in, Color c, int startR, int startC
6061

6162
OUT_DIR = out_dir;
6263
OUTPUTSTATUS = outstatus;
63-
System.out.println(OUTPUTSTATUS);
6464
}
6565

6666
public void run() throws IOException {
@@ -72,7 +72,7 @@ public void run() throws IOException {
7272

7373
// Execute script
7474
TwoColorHeatMap script_object = new TwoColorHeatMap(SAMPLE.get(x), MAXCOLOR, startROW, startCOL,
75-
pixelHeight, pixelWidth, scaleType, absolute, quantile, OUTPUT, OUTPUTSTATUS);
75+
pixelHeight, pixelWidth, scaleType, absolute, quantile, OUTPUT, OUTPUTSTATUS, transparentBackground);
7676
script_object.run();
7777
JLabel picLabel = script_object.getImg();
7878

src/window_interface/Figure_Generation/TwoColorHeatMapWindow.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public class TwoColorHeatMapWindow extends JFrame implements ActionListener, Pro
6060
private JTextField txtHeight;
6161
private JTextField txtWidth;
6262
private JButton btnColor;
63+
private JCheckBox chckbxTransparentBackground;
6364
private JRadioButton rdbtnAbsoluteValue;
6465
private JRadioButton rdbtnPercentileValue;
6566
private JRadioButton rdbtnTreeview;
@@ -125,7 +126,7 @@ public Void doInBackground() throws IOException {
125126
double quantile = Double.parseDouble(txtPercent.getText());
126127

127128
TwoColorHeatMapOutput heat = new TwoColorHeatMapOutput(txtFiles, COLOR, startR, startC, pHeight, pWidth,
128-
scaletype, absolute, quantile, OUT_DIR, chckbxOutputHeatmap.isSelected());
129+
scaletype, absolute, quantile, OUT_DIR, chckbxOutputHeatmap.isSelected(), chckbxTransparentBackground.isSelected());
129130

130131
heat.addPropertyChangeListener("heat", new PropertyChangeListener() {
131132
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
@@ -333,9 +334,14 @@ public void itemStateChanged(ItemEvent e) {
333334
}
334335
});
335336

337+
chckbxTransparentBackground = new JCheckBox("Use transparent background");
338+
sl_contentPane.putConstraint(SpringLayout.NORTH, chckbxTransparentBackground, 8, SpringLayout.SOUTH, lblSelectColor);
339+
sl_contentPane.putConstraint(SpringLayout.WEST, chckbxTransparentBackground, 10, SpringLayout.WEST, lblSelectColor);
340+
contentPane.add(chckbxTransparentBackground);
341+
336342
JLabel lblPixelHeight = new JLabel("Image Height:");
337-
sl_contentPane.putConstraint(SpringLayout.NORTH, lblPixelHeight, 20, SpringLayout.SOUTH, btnColor);
338-
sl_contentPane.putConstraint(SpringLayout.WEST, lblPixelHeight, 0, SpringLayout.WEST, lblSelectColor);
343+
sl_contentPane.putConstraint(SpringLayout.NORTH, lblPixelHeight, 8, SpringLayout.SOUTH, chckbxTransparentBackground);
344+
sl_contentPane.putConstraint(SpringLayout.WEST, lblPixelHeight, 15, SpringLayout.WEST, contentPane);
339345
contentPane.add(lblPixelHeight);
340346

341347
JLabel lblPixelWidth = new JLabel("Image Width:");
@@ -425,7 +431,7 @@ public void itemStateChanged(ItemEvent e) {
425431
});
426432

427433
JLabel lblImageCompression = new JLabel("Image Compression:");
428-
sl_contentPane.putConstraint(SpringLayout.NORTH, lblImageCompression, 10, SpringLayout.SOUTH, txtAbsolute);
434+
sl_contentPane.putConstraint(SpringLayout.NORTH, lblImageCompression, 5, SpringLayout.SOUTH, txtAbsolute);
429435
sl_contentPane.putConstraint(SpringLayout.WEST, lblImageCompression, 10, SpringLayout.WEST, contentPane);
430436
contentPane.add(lblImageCompression);
431437

0 commit comments

Comments
 (0)