Как заполнить гистограмму массивом данных? - PullRequest
0 голосов
/ 23 января 2019

У меня проблемы с получением правильной гистограммы.

Мне дали большой файл данных, полный двойных чисел, представляющих GPA, около 5500 из них. Я создал метод для подсчета количества, среднего значения и стандартного отклонения данных, однако моя последняя проблема - это график данных.

Я должен составить гистограмму для каждого из возможных классов (12 из них) и составить график их общего количества для каждого класса.

Я думаю, что правильно закодировал итоговую оценку для каждой оценки, но когда дело доходит до фактического построения гистограммы, я не могу определить 4 аргумента, необходимых для fillRect.

Я играл с разными переменными, но, кажется, ничто не может приблизить меня.

Любая помощь приветствуется.

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.

1 Ответ

0 голосов
/ 23 января 2019

, но когда дело доходит до рисования гистограммы, я не могу определить 4 аргумента, необходимых для fillRect.

JavaDocs довольно явно указаны в свойствах иих значения, это просто поле, с позицией (x / y) и размером (ширина / высота)

public abstract void fillRect (int x, int y, int width, int height)

Заполняет указанный прямоугольник.Левый и правый края прямоугольника имеют размеры x и x + width - 1. Верхний и нижний края имеют значения y и y + height - 1. Получившийся прямоугольник охватывает область шириной в пиксели шириной и высотой пикселя в высоту.Прямоугольник заполняется с использованием текущего цвета графического контекста.

Параметры:
x - координата x прямоугольника, который нужно заполнить.
y - координата y прямоугольника, который нужно заполнить.
width - ширина прямоугольника, который будетзаполнено.
высота - высота прямоугольника, который будет заполнен.

Я играл с различными переменными, но, кажется, ничто не может приблизить меня.

Итакна ум приходят две вещи, первая из приведенных выше JavaDocs ...

Прямоугольник заполняется с использованием текущего цвета графического контекста

Это легкозабыть

Во-вторых, кажется, вы неправильно поняли, как рисование работает в Swing.

Живопись в Swing имеет очень специфический и хорошо документированный рабочий процесс.Первое, что вы должны сделать, это прочитать Выполнение пользовательской живописи и Рисование в AWT и Swing , чтобы лучше понять, как работает живопись и как с ней работать.

Нет веских причин для вызова JComponent#getGraphics, кроме возможности возврата null, это всего лишь снимок последнего цикла рисования и будет очищен при следующем проходе (который может произойти прив любое время по любому количеству причин).

Вместо этого вам потребуется пользовательский компонент и вместо него переопределить его метод paintComponent.

После этого вы должны прочитать 2DГрафика позволяет лучше понять, как работает API и какие функции / функциональные возможности он может предоставить.

Например ....

Example

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();

        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...