+Fri Jan 7 08:01:02 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+ * configure.ac pref.h.orig: Compilation with libplot is now optional
+ by sacrificing the chart features.
+
Sun Nov 28 19:24:02 2004 Ben Pfaff <blp@gnu.org>
* Smake: Change -a to -pR in cp invocations for SUSv3 compliance.
AC_SYS_LARGEFILE
AC_FUNC_FSEEKO
AC_CHECK_LIB(m, sin)
+AC_ARG_WITH(libplot, [ --without-libplot don't compile in support of charts (using libplot)])
+
+if test x"$with_libplot" != x"no" ; then
+ AC_CHECK_LIB(plot, pl_newpl_r,,
+ AC_MSG_ERROR([You must install libplot (or use --without-libplot)])
+ )
+fi
+AM_CONDITIONAL(WITHCHARTS, test x"$with_libplot" != x"no")
+
+
AC_CHECK_LIB(gmp, mpf_get_str,,
AC_CHECK_LIB(gmp, __gmpf_get_str,,
AC_MSG_ERROR([You must install libgmp])
msgstr ""
"Project-Id-Version: PSPP 0.3.1\n"
"Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2005-01-05 22:50+0800\n"
+"POT-Creation-Date: 2005-01-06 13:08+0800\n"
"PO-Revision-Date: 2004-01-23 13:04+0800\n"
"Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
"Language-Team: John Darrington <john@darrington.wattle.id.au>\n"
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2005-01-05 22:50+0800\n"
+"POT-Creation-Date: 2005-01-06 13:08+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
#define GLOBAL_DEBUGGING 1
#endif
+#if !HAVE_LIBPLOT
+#define NO_CHARTS 1
+#endif
+
/* Define these if DEBUGGING is off and you want to make certain
additional optimizations. */
#if !DEBUGGING
+Fri Jan 7 08:00:05 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+ * Makefile.am chart.[ch] histogram.[ch] piechart.c (Modified);
+ plot-hist.c plot-chart.c (Added) Reorganised these files in an
+ attempt to seperate the creation and processing of charts from their
+ actuall renedering.
+
+ * examine.q frequencies.q generated charts conditional upon the NO_CHARTS
+ macro.
+
Thu Jan 6 18:48:58 WST 2005 John Darrington <john@darrington.wattle.id.au>
* main.c Added a signal handler for SIGFPE
q_sources_q = correlations.q crosstabs.q examine.q file-handle.q \
frequencies.q list.q means.q oneway.q set.q t-test.q
-pspp_SOURCES = $(q_sources_c) aggregate.c algorithm.c algorithm.h \
+if WITHCHARTS
+chart_sources = barchart.c \
+ box-whisker.c \
+ cartesian.c \
+ plot-chart.c \
+ plot-hist.c \
+ piechart.c
+endif
+
+pspp_SOURCES = $(q_sources_c) $(chart_sources) \
+aggregate.c algorithm.c algorithm.h \
alloc.c alloc.h apply-dict.c ascii.c autorecode.c bitvector.h \
-case.c case.h \
-casefile.c casefile.h cmdline.c cmdline.h command.c command.def \
+case.c case.h casefile.c casefile.h chart.c chart.h \
+cmdline.c cmdline.h command.c command.def \
command.h compute.c copyleft.c copyleft.h count.c data-in.c data-in.h \
data-list.c data-list.h data-out.c date.c debug-print.h descript.c \
devind.c devind.h dfm-read.c dfm-read.h dfm-write.c dfm-write.h \
file-type.c filename.c filename.h flip.c font.h format.c format.def \
format.h formats.c get.c getline.c getline.h glob.c glob.h \
groff-font.c group.c group.h group_proc.h \
-hash.c hash.h html.c htmlP.h include.c inpt-pgm.c lexer.c \
+hash.c hash.h histogram.c histogram.h \
+html.c htmlP.h include.c inpt-pgm.c lexer.c \
lexer.h levene.c levene.h log.h loop.c magic.c magic.h main.c main.h \
matrix-data.c mis-val.c misc.c misc.h modify-vars.c \
moments.c moments.h numeric.c output.c output.h \
sysfile-info.c tab.c tab.h temporary.c stat.h \
title.c val.h val-labs.c value-labels.c value-labels.h \
var-labs.c var.h vars-atr.c vars-prs.c vector.c version.c version.h \
-vfm.c vfm.h vfmP.h weight.c \
-barchart.c \
-box-whisker.c \
-cartesian.c \
-chart.c \
-chart.h \
-histogram.c \
-piechart.c
+vfm.c vfm.h vfmP.h weight.c
+
pspp_LDADD = ../lib/julcal/libjulcal.a \
../lib/misc/libmisc.a \
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include <config.h>
-#include <stdio.h>
-#include <plot.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdio.h>
-#include <float.h>
-#include <assert.h>
+
#include <math.h>
+#include <float.h>
#include "chart.h"
-#include "str.h"
-
-
-const char *data_colour[] = {
- "brown",
- "red",
- "orange",
- "yellow",
- "green",
- "blue",
- "violet",
- "grey",
- "pink"
-};
-
-
-
-int
-chart_initialise(struct chart *chart)
-{
-
- chart->pl_params = pl_newplparams();
-
- chart->lp = pl_newpl_r ("X",0,stdout,stderr,chart->pl_params);
-
- if (pl_openpl_r (chart->lp) < 0) /* open Plotter */
- return 1;
-
- pl_fspace_r (chart->lp, 0.0, 0.0, 1000.0, 1000.0); /* set coordinate system */
- pl_flinewidth_r (chart->lp, 0.25); /* set line thickness */
- pl_pencolorname_r (chart->lp, "black");
-
- pl_erase_r (chart->lp); /* erase graphics display */
- pl_filltype_r(chart->lp,0);
-
-
-
- pl_savestate_r(chart->lp);
-
- /* Set default chartetry */
- chart->data_top = 900;
- chart->data_right = 800;
- chart->data_bottom = 120;
- chart->data_left = 150;
- chart->abscissa_top = 70;
- chart->ordinate_right = 120;
- chart->title_bottom = 920;
- chart->legend_left = 810;
- chart->legend_right = 1000;
- chart->font_size = 0;
- strcpy(chart->fill_colour,"red");
-
-
- /* Get default font size */
- if ( !chart->font_size)
- chart->font_size = pl_fontsize_r(chart->lp, -1);
-
- /* Draw the data area */
- pl_box_r(chart->lp,
- chart->data_left, chart->data_bottom,
- chart->data_right, chart->data_top);
-
- return 0;
-
-}
-
-
-
-/* Draw a tick mark at position
- If label is non zero, then print it at the tick mark
-*/
-void
-draw_tick(struct chart *chart,
- enum tick_orientation orientation,
- double position,
- const char *label, ...)
-{
- const int tickSize = 10;
-
- pl_savestate_r(chart->lp);
-
- pl_move_r(chart->lp, chart->data_left, chart->data_bottom);
-
- if ( orientation == TICK_ABSCISSA )
- pl_flinerel_r(chart->lp, position, 0, position, -tickSize);
- else if (orientation == TICK_ORDINATE )
- pl_flinerel_r(chart->lp, 0, position, -tickSize, position);
- else
- assert(0);
-
- if ( label ) {
- char buf[10];
- va_list ap;
- va_start(ap,label);
- vsnprintf(buf,10,label,ap);
-
- if ( orientation == TICK_ABSCISSA )
- pl_alabel_r(chart->lp, 'c','t', buf);
- else if (orientation == TICK_ORDINATE )
- {
- if ( fabs(position) < DBL_EPSILON )
- pl_moverel_r(chart->lp, 0, 10);
-
- pl_alabel_r(chart->lp, 'r','c', buf);
- }
-
- va_end(ap);
- }
-
- pl_restorestate_r(chart->lp);
-}
-
-
-
-
-/* Write the title on a chart*/
-void
-chart_write_title(struct chart *chart, const char *title, ...)
-{
- va_list ap;
- char buf[100];
-
- pl_savestate_r(chart->lp);
- pl_ffontsize_r(chart->lp,chart->font_size * 1.5);
- pl_move_r(chart->lp,chart->data_left, chart->title_bottom);
-
- va_start(ap,title);
- vsnprintf(buf,100,title,ap);
- pl_alabel_r(chart->lp,0,0,buf);
- va_end(ap);
-
- pl_restorestate_r(chart->lp);
-}
-
-
-
-void
-chart_finalise(struct chart *chart)
-{
- pl_restorestate_r(chart->lp);
-
- if (pl_closepl_r (chart->lp) < 0) /* close Plotter */
- {
- fprintf (stderr, "Couldn't close Plotter\n");
- }
-
-
- pl_deletepl_r(chart->lp);
-
- pl_deleteplparams(chart->pl_params);
-
-}
-
-
/* Adjust tick to be a sensible value
ie: ... 0.1,0.2,0.5, 1,2,5, 10,20,50 ... */
}
-
-/* Set the scale for the abscissa */
-void
-chart_write_xscale(struct chart *ch, double min, double max, int ticks)
-{
- double x;
-
- const double tick_interval =
- chart_rounded_tick( (max - min) / (double) ticks);
-
- ch->x_max = ceil( max / tick_interval ) * tick_interval ;
- ch->x_min = floor ( min / tick_interval ) * tick_interval ;
-
- ch->abscissa_scale = fabs(ch->data_right - ch->data_left) /
- fabs(ch->x_max - ch->x_min);
-
- for(x = ch->x_min ; x <= ch->x_max; x += tick_interval )
- {
- draw_tick (ch, TICK_ABSCISSA,
- (x - ch->x_min) * ch->abscissa_scale, "%g", x);
- }
-
-}
-
-
-/* Set the scale for the ordinate */
-void
-chart_write_yscale(struct chart *ch, double smin, double smax, int ticks)
-{
- double y;
-
- const double tick_interval =
- chart_rounded_tick( (smax - smin) / (double) ticks);
-
- ch->y_max = ceil ( smax / tick_interval ) * tick_interval ;
- ch->y_min = floor ( smin / tick_interval ) * tick_interval ;
-
- ch->ordinate_scale =
- fabs(ch->data_top - ch->data_bottom) / fabs(ch->y_max - ch->y_min) ;
-
- for(y = ch->y_min ; y <= ch->y_max; y += tick_interval )
- {
- draw_tick (ch, TICK_ORDINATE,
- (y - ch->y_min) * ch->ordinate_scale, "%g", y);
- }
-
-}
-
#ifndef CHART_H
#define CHART_H
+#include <config.h>
#include <stdio.h>
-#include <plot.h>
#include <gsl/gsl_histogram.h>
-
#include "var.h"
+#ifndef NO_CHARTS
+#include <plot.h>
+#endif
+
/* Array of standard colour names */
extern const char *data_colour[];
struct chart {
+#ifndef NO_CHARTS
plPlotter *lp ;
plPlotterParams *pl_params;
+#endif
/* The geometry of the chart
See diagram at the foot of this file.
cmd.v_id);
}
+#ifndef NO_CHARTS
if ( cmd.a_plot[XMN_PLT_HISTOGRAM] )
{
for ( v = 0 ; v < n_dependent_vars; ++v )
&normal, 0);
}
}
+#endif
}
if ( cmd.a_plot[XMN_PLT_NPPLOT] )
np_plot(&(*fs)->m[v], s);
+#ifndef NO_CHARTS
if ( cmd.a_plot[XMN_PLT_HISTOGRAM] )
{
struct normal_curve normal;
histogram_plot((*fs)->m[v].histogram,
s, &normal, 0);
}
+#endif
} /* for ( fs .... */
struct variable **vars, int n_vars,
const struct variable *id)
{
+#ifndef NO_CHARTS
int i;
struct factor_statistics **fs ;
chart_finalise(&ch);
}
-
+#endif
}
int n_vars,
const struct variable *id)
{
+#ifndef NO_CHARTS
int i;
for ( i = 0 ; i < n_vars ; ++i )
chart_finalise(&ch);
}
-
+#endif
}
void
np_plot(const struct metrics *m, const char *factorname)
{
+#ifndef NO_CHARTS
int i;
double yfirst=0, ylast=0;
chart_finalise(&np_chart);
chart_finalise(&dnp_chart);
-
+#endif
}
dump_statistics (v, !dumped_freq_tab);
+#ifndef NO_CHARTS
if ( chart == GFT_HIST)
{
double d[frq_n_stats];
{
do_piechart(v_variables[i], ft);
}
+#endif
cleanup_freq_tab (v);
+#ifndef NO_CHARTS
static void
do_piechart(const struct variable *var, const struct freq_tab *frq_tab)
{
free(slices);
}
+#endif
/*
Local Variables:
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include <config.h>
-
-#include <stdio.h>
-#include <plot.h>
#include <math.h>
#include <gsl/gsl_histogram.h>
-#include <gsl/gsl_randist.h>
#include <assert.h>
-
-#include "hash.h"
-
-#include "var.h"
+#include "histogram.h"
#include "chart.h"
-/* Write the legend of the chart */
-void
-histogram_write_legend(struct chart *ch, const struct normal_curve *norm)
-{
- char buf[100];
- pl_savestate_r(ch->lp);
-
- sprintf(buf,"N = %.2f",norm->N);
- pl_move_r(ch->lp, ch->legend_left, ch->data_bottom);
- pl_alabel_r(ch->lp,0,'b',buf);
-
- sprintf(buf,"Mean = %.1f",norm->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",norm->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);
-}
-
-static void hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar);
-
-
-static void
-hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar)
-{
- double upper;
- double lower;
- double height;
-
- const size_t bins = gsl_histogram_bins(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, bar, &lower, &upper));
-
- assert( upper >= lower);
-
- height = gsl_histogram_get(hist, bar) *
- (ch->data_top - ch->data_bottom) / gsl_histogram_max_val(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 gsl_histogram *hist,
- const char *factorname,
- const struct normal_curve *norm, short show_normal)
-{
- int i;
- int bins;
-
- struct chart ch;
-
- bins = gsl_histogram_bins(hist);
-
- chart_initialise(&ch);
- chart_write_title(&ch, _("HISTOGRAM"));
-
- chart_write_ylabel(&ch, _("Frequency"));
- chart_write_xlabel(&ch, factorname);
-
- chart_write_yscale(&ch, 0, gsl_histogram_max_val(hist), 5);
-
- for ( i = 0 ; i < bins ; ++i )
- hist_draw_bar(&ch, hist, i);
-
- histogram_write_legend(&ch, norm);
-
- 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, 0, &x_min, ¬_used);
- range = not_used - x_min;
- gsl_histogram_get_range(hist, bins - 1, ¬_used, &x_max);
- assert(range == x_max - not_used);
-
- 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) ;
-
- 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 = norm->N * range *
- gsl_ran_gaussian_pdf(x - norm->mean, norm->stddev);
-
- pl_fcont_r(ch.lp, d, ch.data_bottom + y * ordinate_scale);
-
- }
- pl_endpath_r(ch.lp);
-
- }
- chart_finalise(&ch);
-}
-
gsl_histogram *
histogram_create(double bins, double x_min, double x_max)
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Written by John Darrington <john@darrington.wattle.id.au>
+
+ 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 the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef HISTOGRAM_H
+#define HISTOGRAM_H
+
+#include <gsl/gsl_histogram.h>
+
+
+gsl_histogram * histogram_create(double bins, double x_min, double x_max);
+
+#endif
02111-1307, USA. */
-#include <config.h>
+#include "config.h"
#include "chart.h"
#include <float.h>
#include <assert.h>
+#ifndef NO_CHARTS
+
/* Draw a piechart */
void
piechart_plot(const char *title, const struct slice *slices, int n_slices)
pl_restorestate_r(ch->lp);
}
+
+#else
+
+
+void
+piechart_plot(const char *title, const struct slice *slices, int n_slices)
+{
+}
+
+#endif
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Written by John Darrington <john@darrington.wattle.id.au>
+
+ 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 the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <config.h>
+#include <stdio.h>
+#include <plot.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <float.h>
+#include <assert.h>
+#include <math.h>
+
+#include "chart.h"
+#include "str.h"
+
+
+const char *data_colour[] = {
+ "brown",
+ "red",
+ "orange",
+ "yellow",
+ "green",
+ "blue",
+ "violet",
+ "grey",
+ "pink"
+};
+
+
+
+int
+chart_initialise(struct chart *chart)
+{
+
+ chart->pl_params = pl_newplparams();
+
+ chart->lp = pl_newpl_r ("X",0,stdout,stderr,chart->pl_params);
+
+ if (pl_openpl_r (chart->lp) < 0) /* open Plotter */
+ return 1;
+
+ pl_fspace_r (chart->lp, 0.0, 0.0, 1000.0, 1000.0); /* set coordinate system */
+ pl_flinewidth_r (chart->lp, 0.25); /* set line thickness */
+ pl_pencolorname_r (chart->lp, "black");
+
+ pl_erase_r (chart->lp); /* erase graphics display */
+ pl_filltype_r(chart->lp,0);
+
+
+
+ pl_savestate_r(chart->lp);
+
+ /* Set default chartetry */
+ chart->data_top = 900;
+ chart->data_right = 800;
+ chart->data_bottom = 120;
+ chart->data_left = 150;
+ chart->abscissa_top = 70;
+ chart->ordinate_right = 120;
+ chart->title_bottom = 920;
+ chart->legend_left = 810;
+ chart->legend_right = 1000;
+ chart->font_size = 0;
+ strcpy(chart->fill_colour,"red");
+
+
+ /* Get default font size */
+ if ( !chart->font_size)
+ chart->font_size = pl_fontsize_r(chart->lp, -1);
+
+ /* Draw the data area */
+ pl_box_r(chart->lp,
+ chart->data_left, chart->data_bottom,
+ chart->data_right, chart->data_top);
+
+ return 0;
+
+}
+
+
+
+/* Draw a tick mark at position
+ If label is non zero, then print it at the tick mark
+*/
+void
+draw_tick(struct chart *chart,
+ enum tick_orientation orientation,
+ double position,
+ const char *label, ...)
+{
+ const int tickSize = 10;
+
+ pl_savestate_r(chart->lp);
+
+ pl_move_r(chart->lp, chart->data_left, chart->data_bottom);
+
+ if ( orientation == TICK_ABSCISSA )
+ pl_flinerel_r(chart->lp, position, 0, position, -tickSize);
+ else if (orientation == TICK_ORDINATE )
+ pl_flinerel_r(chart->lp, 0, position, -tickSize, position);
+ else
+ assert(0);
+
+ if ( label ) {
+ char buf[10];
+ va_list ap;
+ va_start(ap,label);
+ vsnprintf(buf,10,label,ap);
+
+ if ( orientation == TICK_ABSCISSA )
+ pl_alabel_r(chart->lp, 'c','t', buf);
+ else if (orientation == TICK_ORDINATE )
+ {
+ if ( fabs(position) < DBL_EPSILON )
+ pl_moverel_r(chart->lp, 0, 10);
+
+ pl_alabel_r(chart->lp, 'r','c', buf);
+ }
+
+ va_end(ap);
+ }
+
+ pl_restorestate_r(chart->lp);
+}
+
+
+
+
+/* Write the title on a chart*/
+void
+chart_write_title(struct chart *chart, const char *title, ...)
+{
+ va_list ap;
+ char buf[100];
+
+ pl_savestate_r(chart->lp);
+ pl_ffontsize_r(chart->lp,chart->font_size * 1.5);
+ pl_move_r(chart->lp,chart->data_left, chart->title_bottom);
+
+ va_start(ap,title);
+ vsnprintf(buf,100,title,ap);
+ pl_alabel_r(chart->lp,0,0,buf);
+ va_end(ap);
+
+ pl_restorestate_r(chart->lp);
+}
+
+
+
+void
+chart_finalise(struct chart *chart)
+{
+ pl_restorestate_r(chart->lp);
+
+ if (pl_closepl_r (chart->lp) < 0) /* close Plotter */
+ {
+ fprintf (stderr, "Couldn't close Plotter\n");
+ }
+
+
+ pl_deletepl_r(chart->lp);
+
+ pl_deleteplparams(chart->pl_params);
+
+}
+
+
+/* Set the scale for the abscissa */
+void
+chart_write_xscale(struct chart *ch, double min, double max, int ticks)
+{
+ double x;
+
+ const double tick_interval =
+ chart_rounded_tick( (max - min) / (double) ticks);
+
+ ch->x_max = ceil( max / tick_interval ) * tick_interval ;
+ ch->x_min = floor ( min / tick_interval ) * tick_interval ;
+
+ ch->abscissa_scale = fabs(ch->data_right - ch->data_left) /
+ fabs(ch->x_max - ch->x_min);
+
+ for(x = ch->x_min ; x <= ch->x_max; x += tick_interval )
+ {
+ draw_tick (ch, TICK_ABSCISSA,
+ (x - ch->x_min) * ch->abscissa_scale, "%g", x);
+ }
+
+}
+
+
+/* Set the scale for the ordinate */
+void
+chart_write_yscale(struct chart *ch, double smin, double smax, int ticks)
+{
+ double y;
+
+ const double tick_interval =
+ chart_rounded_tick( (smax - smin) / (double) ticks);
+
+ ch->y_max = ceil ( smax / tick_interval ) * tick_interval ;
+ ch->y_min = floor ( smin / tick_interval ) * tick_interval ;
+
+ ch->ordinate_scale =
+ fabs(ch->data_top - ch->data_bottom) / fabs(ch->y_max - ch->y_min) ;
+
+ for(y = ch->y_min ; y <= ch->y_max; y += tick_interval )
+ {
+ draw_tick (ch, TICK_ORDINATE,
+ (y - ch->y_min) * ch->ordinate_scale, "%g", y);
+ }
+
+}
+
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Written by John Darrington <john@darrington.wattle.id.au>
+
+ 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 the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <plot.h>
+#include <math.h>
+#include <gsl/gsl_histogram.h>
+#include <gsl/gsl_randist.h>
+#include <assert.h>
+
+#include "hash.h"
+
+#include "var.h"
+#include "chart.h"
+
+/* Write the legend of the chart */
+void
+histogram_write_legend(struct chart *ch, const struct normal_curve *norm)
+{
+ char buf[100];
+ pl_savestate_r(ch->lp);
+
+ sprintf(buf,"N = %.2f",norm->N);
+ pl_move_r(ch->lp, ch->legend_left, ch->data_bottom);
+ pl_alabel_r(ch->lp,0,'b',buf);
+
+ sprintf(buf,"Mean = %.1f",norm->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",norm->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);
+}
+
+static void hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar);
+
+
+static void
+hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar)
+{
+ double upper;
+ double lower;
+ double height;
+
+ const size_t bins = gsl_histogram_bins(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, bar, &lower, &upper));
+
+ assert( upper >= lower);
+
+ height = gsl_histogram_get(hist, bar) *
+ (ch->data_top - ch->data_bottom) / gsl_histogram_max_val(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 gsl_histogram *hist,
+ const char *factorname,
+ const struct normal_curve *norm, short show_normal)
+{
+ int i;
+ int bins;
+
+ struct chart ch;
+
+ bins = gsl_histogram_bins(hist);
+
+ chart_initialise(&ch);
+ chart_write_title(&ch, _("HISTOGRAM"));
+
+ chart_write_ylabel(&ch, _("Frequency"));
+ chart_write_xlabel(&ch, factorname);
+
+ chart_write_yscale(&ch, 0, gsl_histogram_max_val(hist), 5);
+
+ for ( i = 0 ; i < bins ; ++i )
+ hist_draw_bar(&ch, hist, i);
+
+ histogram_write_legend(&ch, norm);
+
+ 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, 0, &x_min, ¬_used);
+ range = not_used - x_min;
+ gsl_histogram_get_range(hist, bins - 1, ¬_used, &x_max);
+ assert(range == x_max - not_used);
+
+ 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) ;
+
+ 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 = norm->N * range *
+ gsl_ran_gaussian_pdf(x - norm->mean, norm->stddev);
+
+ pl_fcont_r(ch.lp, d, ch.data_bottom + y * ordinate_scale);
+
+ }
+ pl_endpath_r(ch.lp);
+
+ }
+ chart_finalise(&ch);
+}
+