org.biojava.nbio.survival.kaplanmeier.figure.ExpressionFigure Maven / Gradle / Ivy
The newest version!
/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package org.biojava.nbio.survival.kaplanmeier.figure;
import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
import org.biojava.nbio.survival.cox.SurvivalInfo;
import org.biojava.nbio.survival.cox.comparators.SurvivalInfoValueComparator;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
/**
*
* @author Scooter Willis
*/
public class ExpressionFigure extends JPanel {
private static final long serialVersionUID = 1L;
ArrayList title = new ArrayList<>();
/**
*
*/
public int top;
/**
*
*/
public int bottom;
/**
*
*/
public int left;
/**
*
*/
public int right;
int titleHeight;
int xAxisLabelHeight;
int labelWidth;
Double maxTime = null;
Double minX = 0.0;
Double maxX = 10.0;
Double minY = 0.0;
Double maxY = 1.0;
Double mean = 0.0;
FontMetrics fm;
KMFigureInfo kmfi = new KMFigureInfo();
// LinkedHashMap> survivalData = new LinkedHashMap>();
ArrayList lineInfoList = new ArrayList<>();
ArrayList siList = new ArrayList<>();
String variable = "";
private String fileName = "";
/**
*
*/
public ExpressionFigure() {
super();
setSize(500, 400);
setBackground(Color.WHITE);
}
/**
* The data used to draw the graph
* @return
*/
public ArrayList getSurvivalInfoList(){
return siList;
}
/**
*
* @param kmfi
*/
public void setKMFigureInfo(KMFigureInfo kmfi) {
this.kmfi = kmfi;
if (kmfi.width != null && kmfi.height != null) {
this.setSize(kmfi.width, kmfi.height);
}
}
/**
*
* @param lineInfoList
*/
public void setFigureLineInfo(ArrayList lineInfoList) {
this.lineInfoList = lineInfoList;
this.repaint();
}
/**
*
* @param title
* @param _siList
* @param variable
*/
public void setSurvivalInfo(ArrayList title, ArrayList _siList, String variable) {
this.siList = new ArrayList<>();
this.title = title;
this.variable = variable;
minX = 0.0;
maxX = (double) _siList.size();
minY = 0.0;
maxY = null;
DescriptiveStatistics ds = new DescriptiveStatistics();
for (SurvivalInfo si : _siList) {
this.siList.add(si);
String v = si.getOriginalMetaData(variable);
Double value = Double.parseDouble(v);
ds.addValue(value);
if (maxTime == null || maxTime < si.getTime()) {
maxTime = si.getTime();
}
}
SurvivalInfoValueComparator sivc = new SurvivalInfoValueComparator(variable);
Collections.sort(this.siList, sivc);
mean = ds.getMean();
minY = ds.getMin();
maxY = ds.getMax();
minY = (double) Math.floor(minY);
maxY = (double) Math.ceil(maxY);
this.repaint();
}
DecimalFormat df = new DecimalFormat("#.#");
private void setRenderingHints(Graphics2D g) {
RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
rh.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHints(rh);
}
@Override
public void paintComponent(Graphics g) // draw graphics in the panel
{
//int width = getWidth(); // width of window in pixels
//int height = getHeight(); // height of window in pixels
setFigureDimensions();
super.paintComponent(g); // call superclass to make panel display correctly
Graphics2D g2 = (Graphics2D)g;
setRenderingHints(g2);
drawExpressionLevels(g);
drawFigureLineInfo(g);
drawLegend(g);
// Drawing code goes here
}
private void drawFigureLineInfo(Graphics g) {
g.setColor(Color.BLACK);
Font font = g.getFont();
Font f = new Font(font.getFontName(), Font.BOLD, font.getSize());
g.setFont(f);
fm = getFontMetrics(getFont());
int yoffset = fm.getHeight() * lineInfoList.size();
int x = getX(kmfi.figureLineInfoLowerPercentX * maxX);
int y = getY(kmfi.figureLineInfoLowerPercentY) - yoffset;
for (String line : lineInfoList) {
g.drawString(line, x, y);
y = y + fm.getHeight();
}
}
private void drawExpressionLevels(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(kmfi.kmStroke);
g2.setColor(Color.blue);
Double py = null;
for (int x = 0; x < siList.size(); x++) {
SurvivalInfo si = siList.get(x);
String v = si.getOriginalMetaData(variable);
Double y = Double.parseDouble(v);
if (si.getStatus() == 1) {
g2.setColor(Color.RED);
} else {
g2.setColor(Color.LIGHT_GRAY);
}
g2.drawLine(getX(x), getY((maxY - minY)), getX(x), getY(maxY - y));
if (py == null) {
py = y;
}
if (mean >= py && mean <= y) {
g2.setColor(Color.green);
g2.drawLine(getX(x), getY(maxY - minY), getX(x), getY(maxY - y));
g2.drawLine(getX(x - 1), getY(maxY - minY), getX(x - 1), getY(maxY - y));
}
py = y;
// g2.setColor(Color.black);
// double yt = getYFromPercentage(1.0 - ((double)x)/((double)siList.size()) );
// g2.drawOval(getX(x) - 2, ((int)yt) - 2, 4, 4);
}
}
// private int getYFromPercentage(double percentage) {
// double d = top + (((bottom - top) * percentage));
// return (int) d;
// }
private int getX(double value) {
double d = left + (((right - left) * value) / (maxX - minX));
return (int) d;
}
private int getY(double value) {
double d = top + (((bottom - top) * value) / (maxY - minY));
return (int) d;
}
/**
* @return the fileName
*/
public String getFileName() {
return fileName;
}
private void drawLegend(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Font font = g2.getFont();
font = new Font(font.getFontName(), Font.BOLD, font.getSize());
g2.setFont(font);
fm = getFontMetrics(font);
int fontHeight = fm.getHeight();
for (int i = 0; i < title.size(); i++) {
if (fm.stringWidth(title.get(i)) > .8 * this.getWidth()) {
Font f = new Font(font.getFontName(), Font.BOLD, 10);
g2.setFont(f);
fm = getFontMetrics(f);
}
g2.drawString(title.get(i), (getSize().width - fm.stringWidth(title.get(i))) / 2, ((i + 1) * fontHeight));
g2.setFont(font);
}
// draw the maxY and minY values
g2.drawString(df.format(minY), left - fm.stringWidth(df.format(minY)) - 20, bottom + titleHeight / 6);
g2.drawLine(left - 5, bottom, left, bottom);
double ySize = maxY - minY;
double increment = kmfi.yaxisPercentIncrement * ySize;
increment = Math.ceil(increment);
// increment = increment * 10.0;
double d = minY + increment;
//double graphHeight = top - bottom;
String label = "";
while (d < maxY) {
int yvalue = getY(maxY - d);
label = df.format(d);
g2.drawString(label, left - (fm.stringWidth(label)) - 20, yvalue + titleHeight / 6); //
g2.drawLine(left - 5, yvalue, left, yvalue);
d = d + (increment);
}
label = df.format(maxY);
g2.drawString(label, left - (fm.stringWidth(label)) - 20, top + (titleHeight) / 6);
g2.drawLine(left - 5, top, left, top);
double timeDistance = maxX - minX;
double timeIncrement = timeDistance * kmfi.xaxisPercentIncrement;
double timeInt = (int) timeIncrement;
if (timeInt < 1.0) {
timeInt = 1.0;
}
double adjustedPercentIncrement = timeInt / timeDistance;
d = adjustedPercentIncrement; //kmfi.xaxisPercentIncrement;
while (d <= 1.0) {
label = df.format((minX * kmfi.timeScale) + d * ((maxX - minX) * kmfi.timeScale)); //
if (d + adjustedPercentIncrement > 1.0) { //if this is the last one then adjust
g2.drawString(label, left + (int) (d * (right - left)) - (int) (.5 * fm.stringWidth(label)), bottom + fm.getHeight() + 5);
} else {
g2.drawString(label, left + (int) (d * (right - left)) - (fm.stringWidth(label) / 2), bottom + fm.getHeight() + 5);
}
g2.drawLine(left + (int) (d * (right - left)), bottom, left + (int) (d * (right - left)), bottom + 5);
d = d + adjustedPercentIncrement; //kmfi.xaxisPercentIncrement;
}
// draw the vertical and horizontal lines
g2.setStroke(kmfi.axisStroke);
g2.drawLine(left, top, left, bottom);
g2.drawLine(left, bottom, right, bottom);
}
private void setFigureDimensions() {
fm = getFontMetrics(getFont());
titleHeight = kmfi.titleHeight;//fm.getHeight();
xAxisLabelHeight = titleHeight;
labelWidth = Math.max(fm.stringWidth(df.format(minY)),
fm.stringWidth(df.format(maxY))) + 5;
top = kmfi.padding + titleHeight;
bottom = this.getHeight() - kmfi.padding - xAxisLabelHeight;
left = kmfi.padding + labelWidth;
right = this.getWidth() - kmfi.padding;
}
/**
*
* @param fileName
*/
public void savePNG(String fileName) {
if (fileName.startsWith("null")) {
return;
}
this.fileName = fileName;
BufferedImage image = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = image.createGraphics();
this.paint(graphics2D);
try {
ImageIO.write(image, "png", new File(fileName));
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try {
ExpressionFigure expressionFigure = new ExpressionFigure();
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(expressionFigure);
expressionFigure.setSize(500, 400);
application.setSize(500, 400); // window is 500 pixels wide, 400 high
application.setVisible(true);
ArrayList titles = new ArrayList<>();
titles.add("Line 1");
titles.add("line 2");
ArrayList figureInfo = new ArrayList<>();
ArrayList survivalInfoList = new ArrayList<>();
for (int i = 0; i < 600; i++) {
double r = Math.random();
double v = r * 10000;
double t = Math.random() * 5.0;
r = Math.random();
int e = 0;
if (r < .3) {
e = 1;
}
SurvivalInfo si = new SurvivalInfo(t, e);
si.addContinuousVariable("META_GENE", v);
survivalInfoList.add(si);
}
expressionFigure.setSurvivalInfo(titles, survivalInfoList, "META_GENE");
expressionFigure.setFigureLineInfo(figureInfo);
expressionFigure.savePNG("/Users/Scooter/Downloads/test.png");
} catch (Exception e) {
e.printStackTrace();
}
}
}