Java高斯分布-钟形曲线

5
我已经计算了一组值的平均值和标准差。现在我需要使用这些值绘制钟形曲线,以显示JAVA Swing中的正态分布。我该如何处理这种情况?
列表: 204 297 348 528 681 684 785 957 1044 1140 1378 1545 1818
总计数: 13
平均值(Mean): 877.615384615385
标准偏差(SD): 477.272626245539
如果我能得到x和y坐标,我就可以做到,但是我怎么得到这些值?

你想使用什么方程或算法来绘制曲线?还是你只是想让别人告诉你要使用哪些点?你看过这个吗?http://en.wikipedia.org/wiki/Gaussian_function - James Black
你应该开始学习如何使用 Graphics 对象进行绘图。然后,你需要将空间映射到绘图空间中。一个简单的方法是使用图表库,比如 JFreeChart。 - David Oliván
你要找的词是“直方图”,但由于你所拥有的数据量有限,它会比较粗糙。另外请注意,能够计算出平均值和标准差并不保证数据呈正态分布。 - dmckee --- ex-moderator kitten
我认为这个方程不太容易在 SO 上书写,但这个方程应该会有所帮助:https://ccrma.stanford.edu/~jos/sasp/Gaussian_Probability_Density_Function.html - James Black
我知道如何在Java中绘制图形,但我需要绘制图形所需的坐标,即x和y坐标。例如(1,0) (2,5) (3,9) (4,5) (5,0)... - need_the_buzz
2个回答

10

首先您需要计算集合的方差。方差被计算为每个数字与其均值的平方偏差的平均值。

double variance(double[] population) {
        long n = 0;
        double mean = 0;
        double s = 0.0;

        for (double x : population) {
                n++;
                double delta = x – mean;
                mean += delta / n;
                s += delta * (x – mean);
        }
        // if you want to calculate std deviation

        return (s / n);
}

一旦你有了这个,你可以根据图形分辨率与值集散布之间的比较来选择x,并将其插入以下方程式中以获取y。

protected double stdDeviation, variance, mean; 

    public double getY(double x) { 

        return Math.pow(Math.exp(-(((x - mean) * (x - mean)) / ((2 * variance)))), 1 / (stdDeviation * Math.sqrt(2 * Math.PI))); 

    } 

显示结果集:假设您采用了您所布置的人口集,并且决定要在x分辨率为1000像素的图形上显示x=0到x=2000。那么您将插入一个循环(int x = 0; x <= 2000; x = 2),并将这些值提供给上述方程以获得该对的y值。由于您想要显示的y值是0-1,因此您可以将这些值映射到您想要的y分辨率上,同时保持适当的舍入行为,以使您的图形不会变得太过粗糙。例如,如果您希望您的y分辨率为500像素,则将0设置为0,将1设置为500,将.5设置为250等等。这是一个刻意的示例,您可能需要更多的灵活性,但我认为它阐明了这一点。大多数绘图库都会为您处理这些小事情。


谢谢您的回复,真的很有帮助。我已经成功获取了x和y坐标,哪个绘图库最适合创建钟形图?您有什么推荐吗? - need_the_buzz
JFreeChart 是一个很好的综合图表库。 - Ichorus

1
这里有一个使用XChart绘制高斯曲线的示例。代码可以在这里找到。免责声明:我是XChart Java图表库的创建者。
public class ThemeChart03 implements ExampleChart {

  public static void main(String[] args) {

    ExampleChart exampleChart = new ThemeChart03();
    Chart chart = exampleChart.getChart();
    new SwingWrapper(chart).displayChart();
  }

  @Override
  public Chart getChart() {

    // Create Chart
    Chart_XY chart = new ChartBuilder_XY().width(800).height(600).theme(ChartTheme.Matlab).title("Matlab Theme").xAxisTitle("X").yAxisTitle("Y").build();

    // Customize Chart
    chart.getStyler().setPlotGridLinesVisible(false);
    chart.getStyler().setXAxisTickMarkSpacingHint(100);

    // Series
    List<Integer> xData = new ArrayList<Integer>();
    for (int i = 0; i < 640; i++) {
      xData.add(i);
    }
    List<Double> y1Data = getYAxis(xData, 320, 60);
    List<Double> y2Data = getYAxis(xData, 320, 100);
    List<Double> y3Data = new ArrayList<Double>(xData.size());
    for (int i = 0; i < 640; i++) {
      y3Data.add(y1Data.get(i) - y2Data.get(i));
    }

    chart.addSeries("Gaussian 1", xData, y1Data);
    chart.addSeries("Gaussian 2", xData, y2Data);
    chart.addSeries("Difference", xData, y3Data);

    return chart;
  }

  private List<Double> getYAxis(List<Integer> xData, double mean, double std) {

    List<Double> yData = new ArrayList<Double>(xData.size());

    for (int i = 0; i < xData.size(); i++) {
      yData.add((1 / (std * Math.sqrt(2 * Math.PI))) * Math.exp(-(((xData.get(i) - mean) * (xData.get(i) - mean)) / ((2 * std * std)))));
    }
    return yData;
  }

}

生成的图表如下所示:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接