Gráfico de dispersión con múltiples “líneas de dispersión”
-
19-09-2019 - |
Pregunta
Ok, conozco JFreeChart y otros, pero estoy codificando mi propio gráfico de dispersión simple.Ya tengo un gráfico de cuadros (sin etiquetas del eje y, pero eso no debería ser un gran problema cuando lo explique en mi informe).
Tengo una clase de gráfico de dispersión básica, sin embargo, intenté cambiarla para poder agregar diferentes valores de dispersión.
Funciona, pero sólo acepta la primera matriz de dispersión y no dibuja el resto.Aunque dibuja la primera matriz de dispersión en el color de la última matriz de dispersión...entonces es semi-funcionante.
Aquí está mi clase ScatterPanel completa:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JPanel;
public class ScatterPanel extends JPanel {
private TwoArray[] values;
private String title;
private String[] color_list;
// Constructor for ScatterPanel
public ScatterPanel(TwoArray[] v, String t, String[] c) {
values = v;
title = t;
color_list = c;
}
/* This will paint the scatter chart
* using the values from the above variables:
* "values", "title" and "color_list"
*/
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
// Initialize the titleFont
Font titleFont = new Font("Verdana", Font.BOLD, 16);
FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
// Get the width of the JPanel
Dimension d = getSize();
int clientWidth = d.width;
//int clientHeight = d.height;
// Setup the title position and size
int titleWidth = titleFontMetrics.stringWidth(title);
int title_y = titleFontMetrics.getAscent();
int title_x = (clientWidth - titleWidth) / 2;
// Set the font for the title
g.setFont(titleFont);
// Draw the title
g.drawString(title, title_x, title_y);
// Initialise min and max display scale
double min = -0.5;
double max = 5;
// Iterate through each different algorithm we are comparing
for(int point = 0; point < values.length; point++) {
// Iterate through each algorithm's size array and timing array
for (int i = 0; i < values[point].array_time.length; i++) {
// Find the overall max and min for x and y
double x = (double) values[point].array_size[i];
double y = (double) values[point].array_time[i];
// Adjust max and min to include x and y.
if (x < min)
min = x - 0.5;
if (x > max)
max = x + 0.5;
if (y < min)
min = y - 0.5;
if (y > max)
max = y + 0.5;
}
}
g2.translate(getWidth()/2,getHeight()/2);
g2.scale(getWidth()/(max-min), -getHeight()/(max-min));
g2.translate(-(max+min)/2, -(max+min)/2);
// Horizontal size of a pixel in new coords.
double pixelWidth = (max-min)/getWidth();
// Vertical size of a pixel in new coord.
double pixelHeight = (max-min)/getHeight();
g2.setStroke(new BasicStroke(0));
// Draw the x and y axis
g2.setColor(Color.BLUE);
g2.draw( new Line2D.Double(min,0,max,0));
g2.draw( new Line2D.Double(0,min,0,max));
for(int point = 0; point < values.length; point++) {
if(point % 3 == 0)
g2.setColor(Color.decode(color_list[0]));
else if(point % 3 == 1)
g2.setColor(Color.decode(color_list[4]));
else if(point % 3 == 2)
g2.setColor(Color.decode(color_list[8]));
for (int i = 0; i < values[point].array_time.length; i++) {
long x = values[point].array_size[i];
long y = values[point].array_time[i];
// Plot the x-y co-ords
g2.draw(new Line2D.Double(x-3*pixelWidth,y,x+3*pixelWidth,y));
g2.draw(new Line2D.Double(x,y-3*pixelHeight,x,y+3*pixelHeight));
}
}
}
}
TwoArray solo se usa para almacenar dos matrices largas.
Dentro de mi clase de interfaz principal, dibujo un gráfico de dispersión como este:
for(int i = 0; i < scat_size.length; i++)
scat_size[i] = i;
for(int i = 0; i < scat_times.length; i++)
scat_times[i] = i;
// This should be 1,1 2,2 3,3 etc. in Red
scatter_values[0] = new TwoArray(scat_size, scat_times);
// Trying to test a large co-ord so this should be green
scat_size[2] = 70;
scat_times[2] = 20;
scatter_values[1] = new TwoArray(scat_size, scat_times);
// Trying to test another different co-ord so this should be blue
scat_size[2] = 3;
scat_times[2] = 7;
scatter_values[2] = new TwoArray(scat_size, scat_times);
myScatter = new ScatterPanel(scatter_values, scat_title, color_list);
Un JPanel está configurado en myScatter.Funciona y dibuja la dispersión muy bien, pero no la dibuja con puntos de diferentes colores, sino que dibuja la "dispersión roja" en el color azul.
Animo amigos.
PDSé que todavía no tengo ningún código que dibuje una línea curva a través de la dispersión, trabajaré en eso después de terminar esta parte =)
Solución
scatter_values[] contendrá un puntero a las matrices scat_size y scat_times.Está cambiando los valores en estas matrices, por lo que el cambio se aplicará a todos los elementos de la matriz scatter_values.Por lo tanto, dibujará el tercer gráfico tres veces uno encima del otro.
Necesita agregar una dimensión a las matrices:
for(int j = 0; j < 3; j++) {
for(int i = 0; i < scat_size.length; i++)
scat_size[j][i] = i;
for(int i = 0; i < scat_times.length; i++)
scat_times[j][i] = i;
}
// This should be 1,1 2,2 3,3 etc. in Red
scatter_values[0] = new TwoArray(scat_size[0], scat_times[0]);
// Trying to test a large co-ord so this should be green
scat_size[1][2] = 70;
scat_times[1][2] = 20;
scatter_values[1] = new TwoArray(scat_size[1], scat_times[1]);
// Trying to test another different co-ord so this should be blue
scat_size[2][2] = 3;
scat_times[2][2] = 7;
scatter_values[2] = new TwoArray(scat_size[2], scat_times[2]);
myScatter = new ScatterPanel(scatter_values, scat_title, color_list);