我无法正确填充直方图。
我得到了一个大的数据文件,里面充满了代表GPA的双打,其中大约有5500个。我创建了一种方法来计算数据的计数,均值和标准偏差,但是我的最后一个问题是对数据进行图形处理。
我要为每个可能的等级(其中12个等级)制作一个直方图,并用图形绘制每个等级的总和。
我认为我已经正确编码了每个年级的总和,但是在实际绘制直方图时,我无法弄清楚fillRect所需的4个参数。
我一直在研究不同的变量,但是似乎没有什么能让我接近。
感谢您的帮助。
private static int[] gradeCounts(double[] stats) throws Exception{
double stdv = 0;
double sum = 0;
double sum2 = 0;
double variance = 0;
Scanner fsc = new Scanner(new File("introProgGrades.txt"));
while (!fsc.hasNextDouble())
fsc.nextLine();
int[] binCounts = new int[NUM_OF_GRADE_CATEGORIES];
double x = 0;
while (fsc.hasNextDouble()){
stats[2]++;
x = fsc.nextDouble();
sum += x;
sum2 += x * x;
if (x == 0.0)
binCounts[0]++;
else if (x == 0.6666667)
binCounts[1]++;
else if (x == 1.0)
binCounts[2]++;
else if (x == 1.3333333)
binCounts[3]++;
else if (x == 1.6666667)
binCounts[4]++;
else if (x == 2.0)
binCounts[5]++;
else if (x == 2.3333333)
binCounts[6]++;
else if (x == 2.6666667)
binCounts[7]++;
else if (x == 3.0)
binCounts[8]++;
else if (x == 3.3333333)
binCounts[9]++;
else if (x == 3.6666667)
binCounts[10]++;
else
binCounts[11]++;
}
stats[0] = sum/stats[2];
variance = (stats[2] * sum2 - sum * sum) / (stats[2]*(stats[2]-1));
stdv = Math.sqrt(variance);
stats[1] = stdv;
return binCounts;
}
我遇到的麻烦:
private static void plotHistogram(int[] binCounts){
int max = Arrays.stream(binCounts).max().getAsInt();
DrawingPanel panel = new DrawingPanel (800,800);
Graphics2D g = panel.getGraphics();
g.fillRect(0, 0, 800/binCounts.length,max);
}
我认为我必须使用for循环来遍历数据,但这是我毫无头绪的fillRect参数。
答案 0 :(得分:0)
但是在实际绘制直方图时,我无法找出fillRect所需的4个参数。
JavaDocs在属性及其含义上非常明确,它只是一个具有位置(x / y)和大小(宽度/高度)的盒子
public abstract void fillRect((int x, 诠释 整数宽度 int高度)
填充指定的矩形。矩形的左右边缘分别位于x和x + 宽度-1。顶部和底部边缘位于y和y +高度-1。 产生的矩形覆盖一个区域宽度像素宽度高度像素 高。使用图形上下文的当前填充矩形 颜色。
参数:
x-要填充的矩形的x坐标。
y-要填充的矩形的y坐标。
width-宽度
height-要填充的矩形的高度 充满。我一直在研究不同的变量,但是似乎没有什么能让我接近。
因此,我想到了两件事,第一件事来自上面的JavaDocs ...
使用图形上下文的当前填充矩形 颜色
这是容易忘记的事情
第二个是您似乎误解了绘画在Swing中的工作方式。
Swing中的绘画有一个非常具体且有据可查的工作流程。您应该做的第一件事是阅读Performing Custom Painting和Painting in AWT and Swing,以更好地了解绘画的工作方式以及应该如何使用它。
除了能够返回JComponent#getGraphics
之外,没有充分的理由调用null
,这只是最后一次绘制循环的快照,在下一次绘制过程中将被清除干净(可能出于多种原因随时发生)。
相反,您将需要一个自定义组件并替代其paintComponent
方法。
然后,您应该通读2D Graphics线索,以更好地了解API的工作方式以及可以提供的功能/功能。
例如。...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Random rnd = new Random();
int[] binCounts = new int[10];
for (int index = 0; index < binCounts.length; index++) {
binCounts[index] = rnd.nextInt(100);
}
JFrame frame = new JFrame();
frame.add(new DrawingPanel(binCounts));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawingPanel extends JPanel {
private int[] binCounts;
private int max;
public DrawingPanel(int[] binCounts) {
this.binCounts = binCounts;
max = Arrays.stream(binCounts).max().getAsInt();
System.out.println(max);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 800);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int barWidth = 800 / binCounts.length;
for (int i = 0; i < binCounts.length; i++) {
int barHeight = (int)((binCounts[i] / (double)max) * getHeight());
// I personally would cache this until the state of the component
// changes, but for brevity
Rectangle rect = new Rectangle(i * barWidth, getHeight() - barHeight, barWidth, barHeight);
g2d.setColor(Color.BLUE);
g2d.fill(rect);
g2d.setColor(Color.BLACK);
g2d.draw(rect);
}
g2d.dispose();
}
}
}