X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fcharts%2Fplot-hist.c;h=5925df6d1a35af5d0122f75312b497bc01e68eb8;hb=dfd1972f7bcb550a4fc3b05dbe7e71d12334b0a7;hp=4b11618a2f1a409fa3d92a9071a456131ce8485a;hpb=8af5c0889486280ecb843d9ceec6e8bb8a6e20d2;p=pspp-builds.git diff --git a/src/output/charts/plot-hist.c b/src/output/charts/plot-hist.c index 4b11618a..5925df6d 100644 --- a/src/output/charts/plot-hist.c +++ b/src/output/charts/plot-hist.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,179 +18,52 @@ #include #include -#include #include -#include #include #include #include -#include +#include -#include -#include -#include +#include #include #include #include "gettext.h" #define _(msgid) gettext (msgid) -/* Write the legend of the chart */ -static void -histogram_write_legend (struct chart *ch, double n, double mean, double stddev) +/* Plots a histogram of the data in HIST with the given LABEL. + Labels the histogram with each of N, MEAN, and STDDEV that is + not SYSMIS. If all three are not SYSMIS and SHOW_NORMAL is + true, also draws a normal curve on the histogram. */ +struct chart_item * +histogram_chart_create (const gsl_histogram *hist, const char *label, + double n, double mean, double stddev, + bool show_normal) { - char buf[100]; - - if (!ch) - return ; - - pl_savestate_r (ch->lp); - - sprintf (buf, "N = %.2f", n); - pl_move_r (ch->lp, ch->legend_left, ch->data_bottom); - pl_alabel_r (ch->lp, 0, 'b', buf); - - sprintf (buf, "Mean = %.1f", mean); - pl_fmove_r (ch->lp,ch->legend_left,ch->data_bottom + ch->font_size * 1.5); - pl_alabel_r (ch->lp, 0, 'b', buf); - - sprintf (buf, "Std. Dev = %.2f", stddev); - pl_fmove_r (ch->lp, ch->legend_left, ch->data_bottom + ch->font_size * 1.5 * 2); - pl_alabel_r (ch->lp, 0, 'b', buf); - - pl_restorestate_r (ch->lp); + struct histogram_chart *h; + + h = xmalloc (sizeof *h); + chart_item_init (&h->chart_item, &histogram_chart_class, label); + h->gsl_hist = hist != NULL ? gsl_histogram_clone (hist) : NULL; + h->n = n; + h->mean = mean; + h->stddev = stddev; + h->show_normal = show_normal; + return &h->chart_item; } -static void hist_draw_bar (struct chart *ch, const struct histogram *hist, int bar); - - static void -hist_draw_bar (struct chart *ch, const struct histogram *hist, int bar) -{ - if (!ch) - return ; - - { - double upper; - double lower; - double height; - - const size_t bins = gsl_histogram_bins (hist->gsl_hist); - const double x_pos = (ch->data_right - ch->data_left) * bar / (double) bins ; - const double width = (ch->data_right - ch->data_left) / (double) bins ; - - assert ( 0 == gsl_histogram_get_range (hist->gsl_hist, bar, &lower, &upper)); - - assert ( upper >= lower); - - height = gsl_histogram_get (hist->gsl_hist, bar) * - (ch->data_top - ch->data_bottom) / gsl_histogram_max_val (hist->gsl_hist); - - pl_savestate_r (ch->lp); - pl_move_r (ch->lp,ch->data_left, ch->data_bottom); - pl_fillcolorname_r (ch->lp, ch->fill_colour); - pl_filltype_r (ch->lp,1); - - - pl_fboxrel_r (ch->lp, - x_pos, 0, - x_pos + width, height); - - pl_restorestate_r (ch->lp); - - { - char buf[5]; - snprintf (buf,5,"%g", (upper + lower) / 2.0); - draw_tick (ch, TICK_ABSCISSA, - x_pos + width / 2.0, buf); - } - } -} - - - -void -histogram_plot (const struct histogram *hist, - const char *label, - const struct moments1 *m) -{ - double mean, var, n; - - moments1_calculate (m, &n, &mean, &var, NULL, NULL); - - histogram_plot_n (hist, label, n, mean, sqrt(var), m); -} - - -/* This function is deprecated. Don't use it in new code */ -void -histogram_plot_n (const struct histogram *hist, - const char *label, - double n, double mean, double stddev, - bool show_normal) +histogram_chart_destroy (struct chart_item *chart_item) { - int i; - int bins; - - struct chart *ch = chart_create (); - - chart_write_title (ch, _("HISTOGRAM")); - - chart_write_ylabel (ch, _("Frequency")); - chart_write_xlabel (ch, label); - - if ( ! hist ) /* If this happens, probably all values are SYSMIS */ - { - chart_submit (ch); - return; - } - else - { - bins = gsl_histogram_bins (hist->gsl_hist); - } - - chart_write_yscale (ch, 0, gsl_histogram_max_val (hist->gsl_hist), 5); - - for ( i = 0 ; i < bins ; ++i ) - hist_draw_bar (ch, hist, i); - - histogram_write_legend (ch, n, mean, stddev); - - if (show_normal) - { - /* Draw the normal curve */ - - double d ; - double x_min, x_max, not_used ; - double abscissa_scale ; - double ordinate_scale ; - double range ; - - gsl_histogram_get_range (hist->gsl_hist, 0, &x_min, ¬_used); - range = not_used - x_min; - gsl_histogram_get_range (hist->gsl_hist, bins - 1, ¬_used, &x_max); - - abscissa_scale = (ch->data_right - ch->data_left) / (x_max - x_min); - ordinate_scale = (ch->data_top - ch->data_bottom) / - gsl_histogram_max_val (hist->gsl_hist) ; - - pl_move_r (ch->lp, ch->data_left, ch->data_bottom); - for ( d = ch->data_left; - d <= ch->data_right ; - d += (ch->data_right - ch->data_left) / 100.0) - { - const double x = (d - ch->data_left) / abscissa_scale + x_min ; - const double y = n * range * - gsl_ran_gaussian_pdf (x - mean, stddev); - - pl_fcont_r (ch->lp, d, ch->data_bottom + y * ordinate_scale); - - } - pl_endpath_r (ch->lp); - } - - chart_submit (ch); + struct histogram_chart *h = UP_CAST (chart_item, struct histogram_chart, + chart_item); + if (h->gsl_hist != NULL) + gsl_histogram_free (h->gsl_hist); + free (h); } - +const struct chart_item_class histogram_chart_class = + { + histogram_chart_destroy + };