From 5501903810bcbae487b12bc44d9cbedf29644d96 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Thu, 2 Dec 2004 05:52:51 +0000 Subject: [PATCH] Added histograms into examine. Revised the histogram API. Revised the piechart API. --- README.developer | 4 + po/en_GB.po | 158 +++++++++++++++++----------------- po/pspp.pot | 158 +++++++++++++++++----------------- src/ChangeLog | 19 +++++ src/cartesian.c | 38 --------- src/casefile.c | 1 - src/chart.c | 52 +++++++++++- src/chart.h | 36 +++++--- src/examine.q | 153 +++++++++++++++------------------ src/factor_stats.c | 26 ++++-- src/factor_stats.h | 4 +- src/frequencies.q | 165 +++++++++++++++++++++++++++++++++--- src/histogram.c | 207 ++++++++++++++++++--------------------------- src/piechart.c | 76 ++++++++--------- src/var.h | 42 --------- 15 files changed, 621 insertions(+), 518 deletions(-) diff --git a/README.developer b/README.developer index 4e4b6838..244c31b7 100644 --- a/README.developer +++ b/README.developer @@ -2,4 +2,8 @@ To build this project from the sources direct from the cvs archive use: make -f Smake +make + and to test it: + +make distcheck diff --git a/po/en_GB.po b/po/en_GB.po index 0767884d..2dbb8508 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PSPP 0.3.1\n" "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n" -"POT-Creation-Date: 2004-11-25 19:01+0800\n" +"POT-Creation-Date: 2004-12-02 13:38+0800\n" "PO-Revision-Date: 2004-01-23 13:04+0800\n" "Last-Translator: John Darrington \n" "Language-Team: John Darrington \n" @@ -957,7 +957,7 @@ msgstr "" msgid "Only USE ALL is currently implemented." msgstr "" -#: src/descript.c:99 src/examine.q:1281 src/frequencies.q:110 src/oneway.q:396 +#: src/descript.c:99 src/examine.q:1268 src/frequencies.q:112 src/oneway.q:396 #: src/t-test.q:683 src/t-test.q:706 src/t-test.q:829 src/t-test.q:1166 msgid "Mean" msgstr "" @@ -966,15 +966,15 @@ msgstr "" msgid "S E Mean" msgstr "" -#: src/descript.c:101 src/frequencies.q:114 +#: src/descript.c:101 src/frequencies.q:116 msgid "Std Dev" msgstr "" -#: src/descript.c:102 src/examine.q:1344 src/frequencies.q:115 +#: src/descript.c:102 src/examine.q:1331 src/frequencies.q:117 msgid "Variance" msgstr "" -#: src/descript.c:103 src/examine.q:1429 src/frequencies.q:116 +#: src/descript.c:103 src/examine.q:1416 src/frequencies.q:118 msgid "Kurtosis" msgstr "" @@ -982,7 +982,7 @@ msgstr "" msgid "S E Kurt" msgstr "" -#: src/descript.c:105 src/examine.q:1409 src/frequencies.q:118 +#: src/descript.c:105 src/examine.q:1396 src/frequencies.q:120 msgid "Skewness" msgstr "" @@ -990,21 +990,21 @@ msgstr "" msgid "S E Skew" msgstr "" -#: src/descript.c:107 src/examine.q:1392 src/frequencies.q:120 +#: src/descript.c:107 src/examine.q:1379 src/frequencies.q:122 msgid "Range" msgstr "" -#: src/descript.c:108 src/examine.q:1369 src/frequencies.q:121 +#: src/descript.c:108 src/examine.q:1356 src/frequencies.q:123 #: src/oneway.q:408 msgid "Minimum" msgstr "" -#: src/descript.c:109 src/examine.q:1380 src/frequencies.q:122 +#: src/descript.c:109 src/examine.q:1367 src/frequencies.q:124 #: src/oneway.q:409 msgid "Maximum" msgstr "" -#: src/descript.c:110 src/frequencies.q:123 +#: src/descript.c:110 src/frequencies.q:125 msgid "Sum" msgstr "" @@ -1574,64 +1574,64 @@ msgstr "" msgid "Unknown record type %g." msgstr "" -#: src/flip.c:78 +#: src/flip.c:81 msgid "" "FLIP ignores TEMPORARY. Temporary transformations will be made permanent." msgstr "" -#: src/flip.c:218 +#: src/flip.c:221 #, c-format msgid "Could not create acceptable variant for variable %s." msgstr "" -#: src/flip.c:234 +#: src/flip.c:237 msgid "Cannot create more than 99999 variable names." msgstr "" -#: src/flip.c:278 +#: src/flip.c:281 msgid "Could not create temporary file for FLIP." msgstr "" -#: src/flip.c:285 src/flip.c:353 +#: src/flip.c:288 src/flip.c:356 #, c-format msgid "Error writing FLIP file: %s." msgstr "" -#: src/flip.c:395 +#: src/flip.c:398 #, c-format msgid "Error rewinding FLIP file: %s." msgstr "" -#: src/flip.c:399 +#: src/flip.c:402 msgid "Error creating FLIP source file." msgstr "" -#: src/flip.c:408 +#: src/flip.c:411 #, c-format msgid "Error reading FLIP file: %s." msgstr "" -#: src/flip.c:425 +#: src/flip.c:432 #, c-format msgid "Error seeking FLIP source file: %s." msgstr "" -#: src/flip.c:430 +#: src/flip.c:437 #, c-format msgid "Error writing FLIP source file: %s." msgstr "" -#: src/flip.c:441 +#: src/flip.c:448 #, c-format msgid "Error rewind FLIP source file: %s." msgstr "" -#: src/flip.c:493 +#: src/flip.c:500 #, c-format msgid "Error reading FLIP temporary file: %s." msgstr "" -#: src/flip.c:496 +#: src/flip.c:503 msgid "Unexpected end of file reading FLIP temporary file." msgstr "" @@ -1990,6 +1990,14 @@ msgstr "" msgid "hash table:" msgstr "" +#: src/histogram.c:138 +msgid "HISTOGRAM" +msgstr "" + +#: src/histogram.c:140 src/frequencies.q:1135 +msgid "Frequency" +msgstr "" + #: src/html.c:66 #, c-format msgid "HTML driver initializing as `%s'..." @@ -3695,7 +3703,7 @@ msgstr "" #: src/sysfile-info.c:531 src/vfm.c:875 src/crosstabs.q:1099 #: src/crosstabs.q:1126 src/crosstabs.q:1146 src/crosstabs.q:1168 -#: src/examine.q:940 src/frequencies.q:1085 src/frequencies.q:1206 +#: src/examine.q:927 src/frequencies.q:1134 src/frequencies.q:1255 msgid "Value" msgstr "" @@ -3916,33 +3924,33 @@ msgstr "" msgid "Summary." msgstr "" -#: src/crosstabs.q:802 src/examine.q:724 +#: src/crosstabs.q:802 src/examine.q:711 msgid "Cases" msgstr "" -#: src/crosstabs.q:803 src/examine.q:658 src/frequencies.q:1083 -#: src/frequencies.q:1456 +#: src/crosstabs.q:803 src/examine.q:645 src/frequencies.q:1132 +#: src/frequencies.q:1505 msgid "Valid" msgstr "" -#: src/crosstabs.q:804 src/examine.q:659 src/frequencies.q:1151 -#: src/frequencies.q:1457 +#: src/crosstabs.q:804 src/examine.q:646 src/frequencies.q:1200 +#: src/frequencies.q:1506 msgid "Missing" msgstr "" #: src/crosstabs.q:805 src/crosstabs.q:1008 src/crosstabs.q:1722 -#: src/examine.q:660 src/frequencies.q:1160 src/oneway.q:307 src/oneway.q:486 +#: src/examine.q:647 src/frequencies.q:1209 src/oneway.q:307 src/oneway.q:486 msgid "Total" msgstr "" -#: src/crosstabs.q:815 src/examine.q:736 src/frequencies.q:1455 +#: src/crosstabs.q:815 src/examine.q:723 src/frequencies.q:1504 #: src/oneway.q:395 src/t-test.q:682 src/t-test.q:705 src/t-test.q:830 #: src/t-test.q:1365 msgid "N" msgstr "" -#: src/crosstabs.q:816 src/examine.q:739 src/frequencies.q:1087 -#: src/frequencies.q:1088 src/frequencies.q:1089 +#: src/crosstabs.q:816 src/examine.q:726 src/frequencies.q:1136 +#: src/frequencies.q:1137 src/frequencies.q:1138 msgid "Percent" msgstr "" @@ -3979,7 +3987,7 @@ msgid "adj. resid." msgstr "" #: src/crosstabs.q:1098 src/crosstabs.q:1125 src/crosstabs.q:1145 -#: src/crosstabs.q:1166 src/examine.q:1174 +#: src/crosstabs.q:1166 src/examine.q:1161 msgid "Statistic" msgstr "" @@ -4162,88 +4170,88 @@ msgstr "" msgid "%s Dependent" msgstr "" -#: src/examine.q:313 src/examine.q:325 +#: src/examine.q:300 src/examine.q:312 #, c-format msgid "%s and %s are mutually exclusive" msgstr "" -#: src/examine.q:718 +#: src/examine.q:705 msgid "Case Processing Summary" msgstr "" -#: src/examine.q:924 +#: src/examine.q:911 msgid "Extreme Values" msgstr "" -#: src/examine.q:941 +#: src/examine.q:928 msgid "Case Number" msgstr "" -#: src/examine.q:1029 +#: src/examine.q:1016 msgid "Highest" msgstr "" -#: src/examine.q:1034 +#: src/examine.q:1021 msgid "Lowest" msgstr "" -#: src/examine.q:1175 src/oneway.q:398 src/oneway.q:705 +#: src/examine.q:1162 src/oneway.q:398 src/oneway.q:705 msgid "Std. Error" msgstr "" -#: src/examine.q:1177 src/oneway.q:412 +#: src/examine.q:1164 src/oneway.q:412 msgid "Descriptives" msgstr "" -#: src/examine.q:1299 src/oneway.q:403 +#: src/examine.q:1286 src/oneway.q:403 #, c-format msgid "%g%% Confidence Interval for Mean" msgstr "" -#: src/examine.q:1305 src/oneway.q:405 +#: src/examine.q:1292 src/oneway.q:405 msgid "Lower Bound" msgstr "" -#: src/examine.q:1316 src/oneway.q:406 +#: src/examine.q:1303 src/oneway.q:406 msgid "Upper Bound" msgstr "" -#: src/examine.q:1328 +#: src/examine.q:1315 msgid "5% Trimmed Mean" msgstr "" -#: src/examine.q:1339 src/frequencies.q:112 +#: src/examine.q:1326 src/frequencies.q:114 msgid "Median" msgstr "" -#: src/examine.q:1356 src/oneway.q:397 src/t-test.q:684 src/t-test.q:707 +#: src/examine.q:1343 src/oneway.q:397 src/t-test.q:684 src/t-test.q:707 #: src/t-test.q:831 src/t-test.q:1167 msgid "Std. Deviation" msgstr "" -#: src/examine.q:1404 +#: src/examine.q:1391 msgid "Interquartile Range" msgstr "" -#: src/examine.q:1478 +#: src/examine.q:1459 #, c-format msgid "Normal Q-Q Plot of %s" msgstr "" -#: src/examine.q:1479 src/examine.q:1485 +#: src/examine.q:1460 src/examine.q:1466 msgid "Observed Value" msgstr "" -#: src/examine.q:1480 +#: src/examine.q:1461 msgid "Expected Normal" msgstr "" -#: src/examine.q:1483 +#: src/examine.q:1464 #, c-format msgid "Detrended Normal Q-Q Plot of %s" msgstr "" -#: src/examine.q:1486 +#: src/examine.q:1467 msgid "Dev from Normal" msgstr "" @@ -4290,92 +4298,88 @@ msgstr "" msgid "expecting a file name or handle name" msgstr "" -#: src/frequencies.q:111 +#: src/frequencies.q:113 msgid "S.E. Mean" msgstr "" -#: src/frequencies.q:113 +#: src/frequencies.q:115 msgid "Mode" msgstr "" -#: src/frequencies.q:117 +#: src/frequencies.q:119 msgid "S.E. Kurt" msgstr "" -#: src/frequencies.q:119 +#: src/frequencies.q:121 msgid "S.E. Skew" msgstr "" -#: src/frequencies.q:342 +#: src/frequencies.q:394 msgid "" "At most one of BARCHART, HISTOGRAM, or HBAR should be given. HBAR will be " "assumed. Argument values will be given precedence increasing along the " "order given." msgstr "" -#: src/frequencies.q:425 +#: src/frequencies.q:477 #, c-format msgid "" "MAX must be greater than or equal to MIN, if both are specified. However, " "MIN was specified as %g and MAX as %g. MIN and MAX will be ignored." msgstr "" -#: src/frequencies.q:749 +#: src/frequencies.q:798 msgid "" "Upper limit of integer mode value range must be greater than lower limit." msgstr "" -#: src/frequencies.q:762 +#: src/frequencies.q:811 #, c-format msgid "Variable %s specified multiple times on VARIABLES subcommand." msgstr "" -#: src/frequencies.q:768 +#: src/frequencies.q:817 #, c-format msgid "Integer mode specified, but %s is not a numeric variable." msgstr "" -#: src/frequencies.q:834 +#: src/frequencies.q:883 msgid "`)' expected after GROUPED interval list." msgstr "" -#: src/frequencies.q:846 +#: src/frequencies.q:895 #, c-format msgid "Variables %s specified on GROUPED but not on VARIABLES." msgstr "" -#: src/frequencies.q:853 +#: src/frequencies.q:902 #, c-format msgid "Variables %s specified multiple times on GROUPED subcommand." msgstr "" -#: src/frequencies.q:1084 src/frequencies.q:1176 src/frequencies.q:1177 -#: src/frequencies.q:1209 +#: src/frequencies.q:1133 src/frequencies.q:1225 src/frequencies.q:1226 +#: src/frequencies.q:1258 msgid "Cum" msgstr "" -#: src/frequencies.q:1086 -msgid "Frequency" -msgstr "" - -#: src/frequencies.q:1106 +#: src/frequencies.q:1155 msgid "Value Label" msgstr "" -#: src/frequencies.q:1207 +#: src/frequencies.q:1256 msgid "Freq" msgstr "" -#: src/frequencies.q:1208 src/frequencies.q:1210 +#: src/frequencies.q:1257 src/frequencies.q:1259 msgid "Pct" msgstr "" -#: src/frequencies.q:1429 +#: src/frequencies.q:1478 #, c-format msgid "No valid data for variable %s; statistics not displayed." msgstr "" -#: src/frequencies.q:1467 +#: src/frequencies.q:1516 msgid "Percentiles" msgstr "" diff --git a/po/pspp.pot b/po/pspp.pot index 32d94075..0f5739fe 100644 --- a/po/pspp.pot +++ b/po/pspp.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n" -"POT-Creation-Date: 2004-11-25 19:01+0800\n" +"POT-Creation-Date: 2004-12-02 13:38+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -958,7 +958,7 @@ msgstr "" msgid "Only USE ALL is currently implemented." msgstr "" -#: src/descript.c:99 src/examine.q:1281 src/frequencies.q:110 src/oneway.q:396 +#: src/descript.c:99 src/examine.q:1268 src/frequencies.q:112 src/oneway.q:396 #: src/t-test.q:683 src/t-test.q:706 src/t-test.q:829 src/t-test.q:1166 msgid "Mean" msgstr "" @@ -967,15 +967,15 @@ msgstr "" msgid "S E Mean" msgstr "" -#: src/descript.c:101 src/frequencies.q:114 +#: src/descript.c:101 src/frequencies.q:116 msgid "Std Dev" msgstr "" -#: src/descript.c:102 src/examine.q:1344 src/frequencies.q:115 +#: src/descript.c:102 src/examine.q:1331 src/frequencies.q:117 msgid "Variance" msgstr "" -#: src/descript.c:103 src/examine.q:1429 src/frequencies.q:116 +#: src/descript.c:103 src/examine.q:1416 src/frequencies.q:118 msgid "Kurtosis" msgstr "" @@ -983,7 +983,7 @@ msgstr "" msgid "S E Kurt" msgstr "" -#: src/descript.c:105 src/examine.q:1409 src/frequencies.q:118 +#: src/descript.c:105 src/examine.q:1396 src/frequencies.q:120 msgid "Skewness" msgstr "" @@ -991,21 +991,21 @@ msgstr "" msgid "S E Skew" msgstr "" -#: src/descript.c:107 src/examine.q:1392 src/frequencies.q:120 +#: src/descript.c:107 src/examine.q:1379 src/frequencies.q:122 msgid "Range" msgstr "" -#: src/descript.c:108 src/examine.q:1369 src/frequencies.q:121 +#: src/descript.c:108 src/examine.q:1356 src/frequencies.q:123 #: src/oneway.q:408 msgid "Minimum" msgstr "" -#: src/descript.c:109 src/examine.q:1380 src/frequencies.q:122 +#: src/descript.c:109 src/examine.q:1367 src/frequencies.q:124 #: src/oneway.q:409 msgid "Maximum" msgstr "" -#: src/descript.c:110 src/frequencies.q:123 +#: src/descript.c:110 src/frequencies.q:125 msgid "Sum" msgstr "" @@ -1574,64 +1574,64 @@ msgstr "" msgid "Unknown record type %g." msgstr "" -#: src/flip.c:78 +#: src/flip.c:81 msgid "" "FLIP ignores TEMPORARY. Temporary transformations will be made permanent." msgstr "" -#: src/flip.c:218 +#: src/flip.c:221 #, c-format msgid "Could not create acceptable variant for variable %s." msgstr "" -#: src/flip.c:234 +#: src/flip.c:237 msgid "Cannot create more than 99999 variable names." msgstr "" -#: src/flip.c:278 +#: src/flip.c:281 msgid "Could not create temporary file for FLIP." msgstr "" -#: src/flip.c:285 src/flip.c:353 +#: src/flip.c:288 src/flip.c:356 #, c-format msgid "Error writing FLIP file: %s." msgstr "" -#: src/flip.c:395 +#: src/flip.c:398 #, c-format msgid "Error rewinding FLIP file: %s." msgstr "" -#: src/flip.c:399 +#: src/flip.c:402 msgid "Error creating FLIP source file." msgstr "" -#: src/flip.c:408 +#: src/flip.c:411 #, c-format msgid "Error reading FLIP file: %s." msgstr "" -#: src/flip.c:425 +#: src/flip.c:432 #, c-format msgid "Error seeking FLIP source file: %s." msgstr "" -#: src/flip.c:430 +#: src/flip.c:437 #, c-format msgid "Error writing FLIP source file: %s." msgstr "" -#: src/flip.c:441 +#: src/flip.c:448 #, c-format msgid "Error rewind FLIP source file: %s." msgstr "" -#: src/flip.c:493 +#: src/flip.c:500 #, c-format msgid "Error reading FLIP temporary file: %s." msgstr "" -#: src/flip.c:496 +#: src/flip.c:503 msgid "Unexpected end of file reading FLIP temporary file." msgstr "" @@ -1990,6 +1990,14 @@ msgstr "" msgid "hash table:" msgstr "" +#: src/histogram.c:138 +msgid "HISTOGRAM" +msgstr "" + +#: src/histogram.c:140 src/frequencies.q:1135 +msgid "Frequency" +msgstr "" + #: src/html.c:66 #, c-format msgid "HTML driver initializing as `%s'..." @@ -3695,7 +3703,7 @@ msgstr "" #: src/sysfile-info.c:531 src/vfm.c:875 src/crosstabs.q:1099 #: src/crosstabs.q:1126 src/crosstabs.q:1146 src/crosstabs.q:1168 -#: src/examine.q:940 src/frequencies.q:1085 src/frequencies.q:1206 +#: src/examine.q:927 src/frequencies.q:1134 src/frequencies.q:1255 msgid "Value" msgstr "" @@ -3916,33 +3924,33 @@ msgstr "" msgid "Summary." msgstr "" -#: src/crosstabs.q:802 src/examine.q:724 +#: src/crosstabs.q:802 src/examine.q:711 msgid "Cases" msgstr "" -#: src/crosstabs.q:803 src/examine.q:658 src/frequencies.q:1083 -#: src/frequencies.q:1456 +#: src/crosstabs.q:803 src/examine.q:645 src/frequencies.q:1132 +#: src/frequencies.q:1505 msgid "Valid" msgstr "" -#: src/crosstabs.q:804 src/examine.q:659 src/frequencies.q:1151 -#: src/frequencies.q:1457 +#: src/crosstabs.q:804 src/examine.q:646 src/frequencies.q:1200 +#: src/frequencies.q:1506 msgid "Missing" msgstr "" #: src/crosstabs.q:805 src/crosstabs.q:1008 src/crosstabs.q:1722 -#: src/examine.q:660 src/frequencies.q:1160 src/oneway.q:307 src/oneway.q:486 +#: src/examine.q:647 src/frequencies.q:1209 src/oneway.q:307 src/oneway.q:486 msgid "Total" msgstr "" -#: src/crosstabs.q:815 src/examine.q:736 src/frequencies.q:1455 +#: src/crosstabs.q:815 src/examine.q:723 src/frequencies.q:1504 #: src/oneway.q:395 src/t-test.q:682 src/t-test.q:705 src/t-test.q:830 #: src/t-test.q:1365 msgid "N" msgstr "" -#: src/crosstabs.q:816 src/examine.q:739 src/frequencies.q:1087 -#: src/frequencies.q:1088 src/frequencies.q:1089 +#: src/crosstabs.q:816 src/examine.q:726 src/frequencies.q:1136 +#: src/frequencies.q:1137 src/frequencies.q:1138 msgid "Percent" msgstr "" @@ -3979,7 +3987,7 @@ msgid "adj. resid." msgstr "" #: src/crosstabs.q:1098 src/crosstabs.q:1125 src/crosstabs.q:1145 -#: src/crosstabs.q:1166 src/examine.q:1174 +#: src/crosstabs.q:1166 src/examine.q:1161 msgid "Statistic" msgstr "" @@ -4162,88 +4170,88 @@ msgstr "" msgid "%s Dependent" msgstr "" -#: src/examine.q:313 src/examine.q:325 +#: src/examine.q:300 src/examine.q:312 #, c-format msgid "%s and %s are mutually exclusive" msgstr "" -#: src/examine.q:718 +#: src/examine.q:705 msgid "Case Processing Summary" msgstr "" -#: src/examine.q:924 +#: src/examine.q:911 msgid "Extreme Values" msgstr "" -#: src/examine.q:941 +#: src/examine.q:928 msgid "Case Number" msgstr "" -#: src/examine.q:1029 +#: src/examine.q:1016 msgid "Highest" msgstr "" -#: src/examine.q:1034 +#: src/examine.q:1021 msgid "Lowest" msgstr "" -#: src/examine.q:1175 src/oneway.q:398 src/oneway.q:705 +#: src/examine.q:1162 src/oneway.q:398 src/oneway.q:705 msgid "Std. Error" msgstr "" -#: src/examine.q:1177 src/oneway.q:412 +#: src/examine.q:1164 src/oneway.q:412 msgid "Descriptives" msgstr "" -#: src/examine.q:1299 src/oneway.q:403 +#: src/examine.q:1286 src/oneway.q:403 #, c-format msgid "%g%% Confidence Interval for Mean" msgstr "" -#: src/examine.q:1305 src/oneway.q:405 +#: src/examine.q:1292 src/oneway.q:405 msgid "Lower Bound" msgstr "" -#: src/examine.q:1316 src/oneway.q:406 +#: src/examine.q:1303 src/oneway.q:406 msgid "Upper Bound" msgstr "" -#: src/examine.q:1328 +#: src/examine.q:1315 msgid "5% Trimmed Mean" msgstr "" -#: src/examine.q:1339 src/frequencies.q:112 +#: src/examine.q:1326 src/frequencies.q:114 msgid "Median" msgstr "" -#: src/examine.q:1356 src/oneway.q:397 src/t-test.q:684 src/t-test.q:707 +#: src/examine.q:1343 src/oneway.q:397 src/t-test.q:684 src/t-test.q:707 #: src/t-test.q:831 src/t-test.q:1167 msgid "Std. Deviation" msgstr "" -#: src/examine.q:1404 +#: src/examine.q:1391 msgid "Interquartile Range" msgstr "" -#: src/examine.q:1478 +#: src/examine.q:1459 #, c-format msgid "Normal Q-Q Plot of %s" msgstr "" -#: src/examine.q:1479 src/examine.q:1485 +#: src/examine.q:1460 src/examine.q:1466 msgid "Observed Value" msgstr "" -#: src/examine.q:1480 +#: src/examine.q:1461 msgid "Expected Normal" msgstr "" -#: src/examine.q:1483 +#: src/examine.q:1464 #, c-format msgid "Detrended Normal Q-Q Plot of %s" msgstr "" -#: src/examine.q:1486 +#: src/examine.q:1467 msgid "Dev from Normal" msgstr "" @@ -4290,92 +4298,88 @@ msgstr "" msgid "expecting a file name or handle name" msgstr "" -#: src/frequencies.q:111 +#: src/frequencies.q:113 msgid "S.E. Mean" msgstr "" -#: src/frequencies.q:113 +#: src/frequencies.q:115 msgid "Mode" msgstr "" -#: src/frequencies.q:117 +#: src/frequencies.q:119 msgid "S.E. Kurt" msgstr "" -#: src/frequencies.q:119 +#: src/frequencies.q:121 msgid "S.E. Skew" msgstr "" -#: src/frequencies.q:342 +#: src/frequencies.q:394 msgid "" "At most one of BARCHART, HISTOGRAM, or HBAR should be given. HBAR will be " "assumed. Argument values will be given precedence increasing along the " "order given." msgstr "" -#: src/frequencies.q:425 +#: src/frequencies.q:477 #, c-format msgid "" "MAX must be greater than or equal to MIN, if both are specified. However, " "MIN was specified as %g and MAX as %g. MIN and MAX will be ignored." msgstr "" -#: src/frequencies.q:749 +#: src/frequencies.q:798 msgid "" "Upper limit of integer mode value range must be greater than lower limit." msgstr "" -#: src/frequencies.q:762 +#: src/frequencies.q:811 #, c-format msgid "Variable %s specified multiple times on VARIABLES subcommand." msgstr "" -#: src/frequencies.q:768 +#: src/frequencies.q:817 #, c-format msgid "Integer mode specified, but %s is not a numeric variable." msgstr "" -#: src/frequencies.q:834 +#: src/frequencies.q:883 msgid "`)' expected after GROUPED interval list." msgstr "" -#: src/frequencies.q:846 +#: src/frequencies.q:895 #, c-format msgid "Variables %s specified on GROUPED but not on VARIABLES." msgstr "" -#: src/frequencies.q:853 +#: src/frequencies.q:902 #, c-format msgid "Variables %s specified multiple times on GROUPED subcommand." msgstr "" -#: src/frequencies.q:1084 src/frequencies.q:1176 src/frequencies.q:1177 -#: src/frequencies.q:1209 +#: src/frequencies.q:1133 src/frequencies.q:1225 src/frequencies.q:1226 +#: src/frequencies.q:1258 msgid "Cum" msgstr "" -#: src/frequencies.q:1086 -msgid "Frequency" -msgstr "" - -#: src/frequencies.q:1106 +#: src/frequencies.q:1155 msgid "Value Label" msgstr "" -#: src/frequencies.q:1207 +#: src/frequencies.q:1256 msgid "Freq" msgstr "" -#: src/frequencies.q:1208 src/frequencies.q:1210 +#: src/frequencies.q:1257 src/frequencies.q:1259 msgid "Pct" msgstr "" -#: src/frequencies.q:1429 +#: src/frequencies.q:1478 #, c-format msgid "No valid data for variable %s; statistics not displayed." msgstr "" -#: src/frequencies.q:1467 +#: src/frequencies.q:1516 msgid "Percentiles" msgstr "" diff --git a/src/ChangeLog b/src/ChangeLog index ec2863e8..3ff99082 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,22 @@ +Thu Dec 2 13:37:43 WST 2004 John Darrington + + * chart.h Updated to reflect many API changes. + + * cartesian.c chart.c Moved the definitions of chart_write_{xy}scale from + cartesian.c and into chart.c + + * factorstats.[ch] Added the histogram calculations + + * casefile.c Removed an unused variable. + + * frequencies.q examine.q histogram.c Reworked the API for + histograms. + + * piechart.c Revised the API for piecharts. + + * var.h Moved the definitions of freq_tab and freq out of var.h + and into frequencies.q where they belong. + Tue Nov 30 21:10:20 2004 Ben Pfaff * flip.c: (flip_file) Check for off_t separately from fseeko(), diff --git a/src/cartesian.c b/src/cartesian.c index a2e9fbff..cac18400 100644 --- a/src/cartesian.c +++ b/src/cartesian.c @@ -63,44 +63,6 @@ chart_write_xlabel(struct chart *ch, const char *label) } -/* Set the scale for the abscissa */ -void -chart_write_xscale(struct chart *ch, double min, double max, double tick) -{ - double x; - - ch->x_max = ceil( max / tick ) * tick ; - ch->x_min = floor ( min / tick ) * tick ; - - 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 ) - 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 min, double max, double tick) -{ - double y; - - ch->y_max = ceil( max / tick ) * tick ; - ch->y_min = floor ( min / tick ) * tick ; - - 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 ) - { - draw_tick (ch, TICK_ORDINATE, - (y - ch->y_min) * ch->ordinate_scale, "%g", y); - } - -} - /* Write the ordinate label */ diff --git a/src/casefile.c b/src/casefile.c index 6033427c..76de45dc 100644 --- a/src/casefile.c +++ b/src/casefile.c @@ -803,7 +803,6 @@ cmd_debug_casefile (void) static void test_casefile (int pattern, size_t value_cnt, size_t case_cnt) { - int zero = 0; struct casefile *cf; struct casereader *r1, *r2; struct ccase c; diff --git a/src/chart.c b/src/chart.c index 34527e41..3068f3e3 100644 --- a/src/chart.c +++ b/src/chart.c @@ -183,10 +183,12 @@ chart_finalise(struct chart *chart) +static double chart_rounded_tick(double tick); + /* Adjust tick to be a sensible value ie: ... 0.1,0.2,0.5, 1,2,5, 10,20,50 ... */ -double +static double chart_rounded_tick(double tick) { @@ -214,3 +216,51 @@ chart_rounded_tick(double tick) } + +/* 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); + } + +} + diff --git a/src/chart.h b/src/chart.h index d4a8dd74..d22c394f 100644 --- a/src/chart.h +++ b/src/chart.h @@ -23,6 +23,8 @@ #include #include +#include + #include "var.h" @@ -113,19 +115,26 @@ struct normal_curve }; -void draw_histogram(struct chart *ch, - const struct variable *v, - const struct freq_tab *frq_tab, - const char *title, - struct normal_curve *norm, - int show_normal); +void histogram_write_legend(struct chart *ch, const struct normal_curve *norm); + + +void histogram_plot(const gsl_histogram *hist, const char *factorname, + const struct normal_curve *norm, short show_normal); -double chart_rounded_tick(double tick); -void draw_piechart(struct chart *ch, const struct variable *v, - const struct freq_tab *); +struct slice { + const char *label; + double magnetude; +}; + + + + +/* Draw a piechart */ +void piechart_plot(const char *title, + const struct slice *slices, int n_slices); void draw_scatterplot(struct chart *ch); @@ -133,11 +142,16 @@ void draw_scatterplot(struct chart *ch); void draw_lineplot(struct chart *ch); +/* Set the scale on chart CH. + The scale extends from MIN to MAX . + TICK is the approximate number of tick marks. +*/ + void chart_write_xscale(struct chart *ch, - double min, double max, double tick); + double min, double max, int ticks); void chart_write_yscale(struct chart *ch, - double min, double max, double tick); + double min, double max, int ticks); void chart_datum(struct chart *ch, int dataset, double x, double y); diff --git a/src/examine.q b/src/examine.q index 4444f965..d426ecca 100644 --- a/src/examine.q +++ b/src/examine.q @@ -94,46 +94,6 @@ static struct factor *factors=0; static struct metrics *totals=0; -void -print_factors(void) -{ - struct factor *f = factors; - - while (f) - { - struct factor_statistics **fs = f->fs; - - printf("Factor: %s BY %s\n", - var_to_string(f->indep_var[0]), - var_to_string(f->indep_var[1]) ); - - - printf("Contains %d entries\n", hsh_count(f->fstats)); - - - while (*fs) - { - printf("Factor %g; %g\n", (*fs)->id[0].f, (*fs)->id[1].f); - - /* - printf("Factor %s; %s\n", - value_to_string(&(*fs)->id[0], f->indep_var[0]), - value_to_string(&(*fs)->id[1], f->indep_var[1])); - */ - - - printf("Mean is %g\n",(*fs)->m[0].mean); - - fs++ ; - } - - f = f->next; - } - - -} - - /* Parse the clause specifying the factors */ static int examine_parse_independent_vars(struct cmd_examine *cmd); @@ -157,7 +117,6 @@ void np_plot(const struct metrics *m, const char *factorname); - /* Per Split function */ static void run_examine(const struct casefile *cf, void *cmd_); @@ -224,13 +183,29 @@ output_examine(void) if ( cmd.sbc_plot) { + int v; if ( cmd.a_plot[XMN_PLT_NPPLOT] ) { - int v; + for ( v = 0 ; v < n_dependent_vars; ++v ) + np_plot(&totals[v], var_to_string(dependent_vars[v])); + } + if ( cmd.a_plot[XMN_PLT_HISTOGRAM] ) + { for ( v = 0 ; v < n_dependent_vars; ++v ) - np_plot(&totals[v], var_to_string(dependent_vars[v])); + { + struct normal_curve normal; + + normal.N = totals[v].n; + normal.mean = totals[v].mean; + normal.stddev = totals[v].stddev; + + histogram_plot(totals[v].histogram, + var_to_string(dependent_vars[v]), + &normal, 0); + } } + } @@ -254,47 +229,59 @@ output_examine(void) if ( cmd.sbc_plot) { - if ( cmd.a_plot[XMN_PLT_NPPLOT] ) + int v; + + struct factor_statistics **fs = fctr->fs ; + + for ( v = 0 ; v < n_dependent_vars; ++v ) { - int v; - for ( v = 0 ; v < n_dependent_vars; ++ v) + + for ( fs = fctr->fs ; *fs ; ++fs ) { - - struct factor_statistics **fs = fctr->fs ; - for ( fs = fctr->fs ; *fs ; ++fs ) - { - char buf1[100]; - char buf2[100]; - sprintf(buf1, "%s (", - var_to_string(dependent_vars[v])); + char buf1[100]; + char buf2[100]; + sprintf(buf1, "%s (", + var_to_string(dependent_vars[v])); + + snprintf(buf2, 100, "%s = %s", + var_to_string(fctr->indep_var[0]), + value_to_string(&(*fs)->id[0],fctr->indep_var[0])); - sprintf(buf2, "%s = %s", - var_to_string(fctr->indep_var[0]), - value_to_string(&(*fs)->id[0],fctr->indep_var[0])); + strcat(buf1, buf2); + if ( fctr->indep_var[1] ) + { + sprintf(buf2, "; %s = %s)", + var_to_string(fctr->indep_var[1]), + value_to_string(&(*fs)->id[1], + fctr->indep_var[1])); strcat(buf1, buf2); + } + else + { + strcat(buf1, ")"); + } - - if ( fctr->indep_var[1] ) - { - sprintf(buf2, "; %s = %s)", - var_to_string(fctr->indep_var[1]), - value_to_string(&(*fs)->id[1], - fctr->indep_var[1])); - strcat(buf1, buf2); - } - else - { - strcat(buf1, ")"); - } - - np_plot(&(*fs)->m[v],buf1); + if ( cmd.a_plot[XMN_PLT_NPPLOT] ) + np_plot(&(*fs)->m[v],buf1); + + if ( cmd.a_plot[XMN_PLT_HISTOGRAM] ) + { + struct normal_curve normal; + + normal.N = (*fs)->m[v].n; + normal.mean = (*fs)->m[v].mean; + normal.stddev = (*fs)->m[v].stddev; + + histogram_plot((*fs)->m[v].histogram, + buf1, &normal, 0); } - } + } /* for ( fs .... */ + + } /* for ( v = 0 ..... */ - } } fctr = fctr->next; @@ -1446,9 +1433,6 @@ populate_descriptives(struct tab_table *tbl, int col, int row, } - - - /* Plot the normal and detrended normal plots for m Label the plots with factorname */ void @@ -1485,6 +1469,7 @@ np_plot(const struct metrics *m, const char *factorname) yfirst = gsl_cdf_ugaussian_Pinv (m->wvp[0]->rank / ( m->n + 1)); ylast = gsl_cdf_ugaussian_Pinv (m->wvp[m->n_data-1]->rank / ( m->n + 1)); + { /* Need to make sure that both the scatter plot and the ideal fit into the plot */ @@ -1492,17 +1477,13 @@ np_plot(const struct metrics *m, const char *factorname) double x_upper = max(m->max, (ylast - intercept) / slope) ; double slack = (x_upper - x_lower) * 0.05 ; - chart_write_xscale(&np_chart, x_lower - slack, x_upper + slack, - chart_rounded_tick((m->max - m->min) / 5.0)); - + chart_write_xscale(&np_chart, x_lower - slack, x_upper + slack, 5); - chart_write_xscale(&dnp_chart, m->min, m->max, - chart_rounded_tick((m->max - m->min) / 5.0)); + chart_write_xscale(&dnp_chart, m->min, m->max, 5); } - chart_write_yscale(&np_chart, yfirst, ylast, - chart_rounded_tick((ylast - yfirst)/5.0) ); + chart_write_yscale(&np_chart, yfirst, ylast, 5); { /* We have to cache the detrended data, beacause we need to @@ -1522,9 +1503,7 @@ np_plot(const struct metrics *m, const char *factorname) if ( d_data[i] < d_min ) d_min = d_data[i]; if ( d_data[i] > d_max ) d_max = d_data[i]; } - - chart_write_yscale(&dnp_chart, d_min, d_max, - chart_rounded_tick((d_max - d_min) / 5.0)); + chart_write_yscale(&dnp_chart, d_min, d_max, 5); for ( i = 0 ; i < m->n_data; ++i ) chart_datum(&dnp_chart, 0, m->wvp[i]->v.f, d_data[i]); diff --git a/src/factor_stats.c b/src/factor_stats.c index b904d80c..2b9c48a6 100644 --- a/src/factor_stats.c +++ b/src/factor_stats.c @@ -34,24 +34,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA void -metrics_precalc(struct metrics *fs) +metrics_precalc(struct metrics *m) { - assert (fs) ; + assert (m) ; - fs->n_missing = 0; + m->n_missing = 0; - fs->min = DBL_MAX; - fs->max = -DBL_MAX; + m->min = DBL_MAX; + m->max = -DBL_MAX; - fs->moments = moments1_create(MOMENT_KURTOSIS); + m->moments = moments1_create(MOMENT_KURTOSIS); - fs->ordered_data = hsh_create(20, + m->ordered_data = hsh_create(20, (hsh_compare_func *) compare_values, (hsh_hash_func *) hash_value, (hsh_free_func *) weighted_value_free, (void *) 0); + m->histogram = gsl_histogram_alloc(10); + } @@ -189,6 +191,15 @@ metrics_postcalc(struct metrics *m) m->trimmed_mean += (m->wvp[k1 + 1]->cc - tc) * m->wvp[k1 + 1]->v.f ; m->trimmed_mean /= 0.9 * m->n ; + + gsl_histogram_set_ranges_uniform(m->histogram, m->min, m->max); + + for ( i = 0 ; i < m->n_data ; ++i ) + { + struct weighted_value **wv = (m->wvp) ; + gsl_histogram_accumulate(m->histogram, wv[i]->v.f, wv[i]->w); + } + } @@ -246,6 +257,7 @@ void factor_statistics_free(struct factor_statistics *f) { hsh_destroy(f->m->ordered_data); + gsl_histogram_free(f->m->histogram); free(f->m) ; free(f); } diff --git a/src/factor_stats.h b/src/factor_stats.h index 83c94931..d29ca4d8 100644 --- a/src/factor_stats.h +++ b/src/factor_stats.h @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "hash.h" #include "val.h" - +#include struct moments1; @@ -51,6 +51,8 @@ struct metrics struct moments1 *moments; + gsl_histogram *histogram; + double skewness; double kurtosis; diff --git a/src/frequencies.q b/src/frequencies.q index 649f09cd..1484776a 100644 --- a/src/frequencies.q +++ b/src/frequencies.q @@ -27,6 +27,8 @@ #include "error.h" #include #include +#include + #include "alloc.h" #include "bitvector.h" #include "case.h" @@ -188,6 +190,49 @@ static struct variable **v_variables; static struct pool *int_pool; /* Integer mode. */ static struct pool *gen_pool; /* General mode. */ +/* Frequency tables. */ + +/* Frequency table entry. */ +struct freq + { + union value v; /* The value. */ + double c; /* The number of occurrences of the value. */ + }; + +/* Types of frequency tables. */ +enum + { + FRQM_GENERAL, + FRQM_INTEGER + }; + +/* Entire frequency table. */ +struct freq_tab + { + int mode; /* FRQM_GENERAL or FRQM_INTEGER. */ + + /* General mode. */ + struct hsh_table *data; /* Undifferentiated data. */ + + /* Integer mode. */ + double *vector; /* Frequencies proper. */ + int min, max; /* The boundaries of the table. */ + double out_of_range; /* Sum of weights of out-of-range values. */ + double sysmis; /* Sum of weights of SYSMIS values. */ + + /* All modes. */ + struct freq *valid; /* Valid freqs. */ + int n_valid; /* Number of total freqs. */ + + struct freq *missing; /* Missing freqs. */ + int n_missing; /* Number of missing freqs. */ + + /* Statistics. */ + double total_cases; /* Sum of weights of all cases. */ + double valid_cases; /* Sum of weights of valid cases. */ + }; + + /* Per-variable frequency data. */ struct var_freqs { @@ -229,6 +274,13 @@ static hsh_compare_func compare_value_numeric_a, compare_value_alpha_a; static hsh_compare_func compare_value_numeric_d, compare_value_alpha_d; static hsh_compare_func compare_freq_numeric_a, compare_freq_alpha_a; static hsh_compare_func compare_freq_numeric_d, compare_freq_alpha_d; + + +static void do_piechart(const struct variable *var, + const struct freq_tab *frq_tab); + +void freq_tab_to_hist(const struct freq_tab *ft, gsl_histogram *hist); + /* Parser and outline. */ @@ -575,31 +627,28 @@ postcalc (void *aux UNUSED) if ( chart == GFT_HIST) { - struct chart ch; double d[frq_n_stats]; - struct normal_curve norm; + + gsl_histogram *hist = gsl_histogram_alloc(7); + norm.N = vf->tab.total_cases; calc_stats(v,d); norm.mean = d[frq_mean]; norm.stddev = d[frq_stddev]; - chart_initialise(&ch); - draw_histogram(&ch, v_variables[i], ft, "HISTOGRAM",&norm,normal); - chart_finalise(&ch); + freq_tab_to_hist(ft, hist); + + histogram_plot(hist, var_to_string(v), &norm, normal); + + gsl_histogram_free(hist); } if ( chart == GFT_PIE) { - struct chart ch; - - chart_initialise(&ch); - - draw_piechart(&ch, v_variables[i], ft); - - chart_finalise(&ch); + do_piechart(v_variables[i], ft); } @@ -1486,6 +1535,98 @@ dump_statistics (struct variable *v, int show_varname) tab_submit (t); } + + + +/* Populate a gsl_histogram from a freq_tab */ +void +freq_tab_to_hist(const struct freq_tab *ft, gsl_histogram *hist) +{ + int i; + double x_min = DBL_MAX; + double x_max = -DBL_MAX; + + struct hsh_iterator hi; + struct hsh_table *fh = ft->data; + struct freq *frq; + + gsl_histogram_reset(hist); + + /* Find out the extremes of the x value */ + + for ( frq = hsh_first(fh, &hi); + frq != 0; + frq = hsh_next(fh, &hi) ) + { + if ( frq->v.f < x_min ) x_min = frq->v.f ; + if ( frq->v.f > x_max ) x_max = frq->v.f ; + } + + + gsl_histogram_set_ranges_uniform(hist, x_min, x_max); + + for( i = 0 ; i < ft->n_valid ; ++i ) + { + frq = &ft->valid[i]; + gsl_histogram_accumulate(hist, frq->v.f, frq->c); + } + +} + +static struct slice * +freq_tab_to_slice_array(const struct freq_tab *frq_tab, + const struct variable *var, + int *n_slices); + + +/* Allocate an array of slices and fill them from the data in frq_tab + n_slices will contain the number of slices allocated. + The caller is responsible for freeing slices +*/ +static struct slice * +freq_tab_to_slice_array(const struct freq_tab *frq_tab, + const struct variable *var, + int *n_slices) +{ + int i; + struct slice *slices; + + *n_slices = frq_tab->n_valid; + + slices = xmalloc ( *n_slices * sizeof (struct slice ) ); + + for (i = 0 ; i < *n_slices ; ++i ) + { + const struct freq *frq = &frq_tab->valid[i]; + + slices[i].label = value_to_string(&frq->v, var); + + slices[i].magnetude = frq->c; + + } + + + return slices; +} + + + +static void +do_piechart(const struct variable *var, const struct freq_tab *frq_tab) +{ + struct slice *slices; + int n_slices; + + slices = freq_tab_to_slice_array(frq_tab, var, &n_slices); + + piechart_plot(var_to_string(var), slices, n_slices); + + free(slices); + +} + + + /* Local Variables: mode: c diff --git a/src/histogram.c b/src/histogram.c index 5429a903..0d90edd5 100644 --- a/src/histogram.c +++ b/src/histogram.c @@ -17,22 +17,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + #include #include -#include #include +#include +#include + #include "hash.h" #include "var.h" #include "chart.h" /* Number of bins in which to divide data */ -#define BINS 15 +#define BINS 7 /* The approximate no of ticks on the y axis */ #define YTICKS 10 +#ifndef M_PI #define M_PI ( 22.0 / 7.0 ) +#endif static double gaussian(double x, double mu, double sigma ) ; @@ -48,8 +54,8 @@ gaussian(double x, double mu, double sigma ) /* Write the legend of the chart */ -static void -write_legend(struct chart *ch, struct normal_curve *norm) +void +histogram_write_legend(struct chart *ch, const struct normal_curve *norm) { char buf[100]; pl_savestate_r(ch->lp); @@ -69,157 +75,110 @@ write_legend(struct chart *ch, struct normal_curve *norm) pl_restorestate_r(ch->lp); } +static void hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar); - -/* Draw a histogram. - If show_normal is non zero then superimpose a normal curve -*/ -void -draw_histogram(struct chart *ch, - const struct variable *var, - const struct freq_tab *frq_tab, - const char *title, - struct normal_curve *norm, - int show_normal) +static void +hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar) { + double upper; + double lower; + double height; - double d; - int count; - - double x_min = DBL_MAX; - double x_max = -DBL_MAX; - double y_min = DBL_MAX; - double y_max = -DBL_MAX; - - double y_tick ; - - - double ordinate_values[BINS]; - - struct hsh_iterator hi; - struct hsh_table *fh = frq_tab->data; - struct freq *frq; - - double interval_size = fabs(ch->data_right - ch->data_left) / ( BINS ); - - /* Find out the extremes of the x value - FIXME: These don't need to be calculated here, since the - calling routine should know them */ - - for ( frq = hsh_first(fh,&hi); frq != 0; frq = hsh_next(fh,&hi) ) - { - if ( frq->v.f < x_min ) x_min = frq->v.f ; - if ( frq->v.f > x_max ) x_max = frq->v.f ; - } - - double x_interval = fabs(x_max - x_min) / ( BINS - 1); - - - double abscissa_scale = - fabs( (ch->data_right - ch->data_left) / (x_max - x_min) ) ; - - - /* Find out the bin values */ - for ( count = 0, d = x_min; d <= x_max ; d += x_interval, ++count ) - { - - double y = 0; + 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 ; - for ( frq = hsh_first(fh,&hi); frq != 0; frq = hsh_next(fh,&hi) ) - { - if ( frq->v.f >= d && frq->v.f < d + x_interval ) - y += frq->c; - } - ordinate_values[count] = y ; + assert ( 0 == gsl_histogram_get_range(hist, bar, &lower, &upper)); - if ( y > y_max ) y_max = y ; - if ( y < y_min ) y_min = y; - } + assert( upper >= lower); - y_tick = chart_rounded_tick( ( y_max - y_min ) / (double) (YTICKS - 1)); - - - y_min = floor( y_min / y_tick ) * y_tick ; - y_max = ceil( y_max / y_tick ) * y_tick ; - - double ordinate_scale = - fabs(ch->data_top - ch->data_bottom) / fabs(y_max - y_min) ; - - - /* Move to data bottom-left */ - pl_move_r(ch->lp, ch->data_left, ch->data_bottom); + 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); - /* Draw the histogram */ - for ( count = 0, d = x_min; d <= x_max ; d += x_interval, ++count ) - { - const double x = count * interval_size ; - pl_savestate_r(ch->lp); - draw_tick (ch, TICK_ABSCISSA, x + (interval_size / 2.0 ), "%.1f",d); + pl_fboxrel_r(ch->lp, + x_pos, 0, + x_pos + width, height); - pl_fboxrel_r(ch->lp, x, 0, x + interval_size, - ordinate_values[count] * ordinate_scale ); + pl_restorestate_r(ch->lp); - 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); + } - } - pl_restorestate_r(ch->lp); - /* Put the y axis on */ - for ( d = y_min; d <= y_max ; d += y_tick ) - { - draw_tick (ch, TICK_ORDINATE, (d - y_min ) * ordinate_scale, "%g", d); - } +} - /* Write the abscissa label */ - pl_move_r(ch->lp,ch->data_left, ch->abscissa_top); - pl_alabel_r(ch->lp,0,'t',var->label ? var->label : var->name); - - /* Write the ordinate label */ - pl_savestate_r(ch->lp); - pl_move_r(ch->lp,ch->data_bottom, ch->ordinate_right); - pl_textangle_r(ch->lp,90); - pl_alabel_r(ch->lp,0,0,"Frequency"); - pl_restorestate_r(ch->lp); +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_write_title(ch, title); + chart_initialise(&ch); + chart_write_title(&ch, _("HISTOGRAM")); + chart_write_ylabel(&ch, _("Frequency")); + chart_write_xlabel(&ch, factorname); - /* Write the legend */ - write_legend(ch,norm); + 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; - - 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 - interval_size / 2.0 ) / - abscissa_scale + x_min ; + /* Draw the normal curve */ + + double d ; + double x_min, x_max, not_used ; + double abscissa_scale ; + double ordinate_scale ; + + + gsl_histogram_get_range(hist, 0, &x_min, ¬_used); + gsl_histogram_get_range(hist, bins - 1, &x_max, ¬_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 ; - pl_fcont_r(ch->lp, d, - ch->data_bottom + - norm->N * gaussian(x, norm->mean, norm->stddev) - * ordinate_scale); - + pl_fcont_r(ch.lp, d, + ch.data_bottom + norm->N * ordinate_scale * + gaussian(x, norm->mean, norm->stddev) + ); } - pl_endpath_r(ch->lp); - } + pl_endpath_r(ch.lp); + } + chart_finalise(&ch); } - diff --git a/src/piechart.c b/src/piechart.c index 4e0725e6..14115e4c 100644 --- a/src/piechart.c +++ b/src/piechart.c @@ -39,7 +39,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA /* Draw a single slice of the pie */ -void +static void draw_segment(struct chart *ch, double centre_x, double centre_y, double radius, @@ -47,47 +47,44 @@ draw_segment(struct chart *ch, const char *colour) ; -/* Draw a pie chart */ + +/* Draw a piechart */ void -draw_piechart(struct chart *ch, const struct variable *var, - const struct freq_tab *frq_tab) +piechart_plot(const char *title, const struct slice *slices, int n_slices) { int i; + double total_magnetude=0; + + struct chart ch; + + chart_initialise(&ch); - const int n_data = frq_tab->n_valid; - const double left_label = ch->data_left + - (ch->data_right - ch->data_left)/10.0; + const double left_label = ch.data_left + + (ch.data_right - ch.data_left)/10.0; - const double right_label = ch->data_right - - (ch->data_right - ch->data_left)/10.0; + const double right_label = ch.data_right - + (ch.data_right - ch.data_left)/10.0; - const double centre_x = (ch->data_right + ch->data_left ) / 2.0 ; - const double centre_y = (ch->data_top + ch->data_bottom ) / 2.0 ; + const double centre_x = (ch.data_right + ch.data_left ) / 2.0 ; + const double centre_y = (ch.data_top + ch.data_bottom ) / 2.0 ; const double radius = min( - 5.0 / 12.0 * (ch->data_top - ch->data_bottom), - 1.0 / 4.0 * (ch->data_right - ch->data_left) + 5.0 / 12.0 * (ch.data_top - ch.data_bottom), + 1.0 / 4.0 * (ch.data_right - ch.data_left) ); - chart_write_title(ch, var->label ? var->label: var->name); + chart_write_title(&ch, title); - - for (i = 0 ; i < n_data ; ++i ) + for (i = 0 ; i < n_slices ; ++i ) + total_magnetude += slices[i].magnetude; + + for (i = 0 ; i < n_slices ; ++i ) { static double angle=0.0; - const struct freq frq = frq_tab->valid[i]; const double segment_angle = - frq.c / frq_tab->valid_cases * 2 * M_PI ; - - char *label = val_labs_find (var->val_labs, frq.v ); - if ( !label ) - { - static char l[20]; - snprintf(l,20,"%g",frq.v.f); - label = l; - } + slices[i].magnetude / total_magnetude * 2 * M_PI ; const double label_x = centre_x - radius * sin(angle + segment_angle/2.0); @@ -96,7 +93,7 @@ draw_piechart(struct chart *ch, const struct variable *var, radius * cos(angle + segment_angle/2.0); /* Fill the segment */ - draw_segment(ch, + draw_segment(&ch, centre_x, centre_y, radius, angle, segment_angle, data_colour[i]); @@ -104,19 +101,19 @@ draw_piechart(struct chart *ch, const struct variable *var, /* Now add the labels */ if ( label_x < centre_x ) { - pl_line_r(ch->lp, label_x, label_y, + pl_line_r(ch.lp, label_x, label_y, left_label, label_y ); - pl_moverel_r(ch->lp,0,5); - pl_alabel_r(ch->lp,0,0,label); + pl_moverel_r(ch.lp,0,5); + pl_alabel_r(ch.lp,0,0,slices[i].label); } else { - pl_line_r(ch->lp, + pl_line_r(ch.lp, label_x, label_y, right_label, label_y ); - pl_moverel_r(ch->lp,0,5); - pl_alabel_r(ch->lp,'r',0,label); + pl_moverel_r(ch.lp,0,5); + pl_alabel_r(ch.lp,'r',0,slices[i].label); } angle += segment_angle; @@ -124,14 +121,13 @@ draw_piechart(struct chart *ch, const struct variable *var, } /* Draw an outline to the pie */ - pl_filltype_r(ch->lp,0); - pl_fcircle_r (ch->lp, centre_x, centre_y, radius); + pl_filltype_r(ch.lp,0); + pl_fcircle_r (ch.lp, centre_x, centre_y, radius); + chart_finalise(&ch); } - - -void +static void fill_segment(struct chart *ch, double x0, double y0, double radius, @@ -139,7 +135,7 @@ fill_segment(struct chart *ch, /* Fill a segment with the current fill colour */ -void +static void fill_segment(struct chart *ch, double x0, double y0, double radius, @@ -185,7 +181,7 @@ fill_segment(struct chart *ch, /* Draw a single slice of the pie */ -void +static void draw_segment(struct chart *ch, double x0, double y0, double radius, diff --git a/src/var.h b/src/var.h index 46a0efc5..0bca760e 100644 --- a/src/var.h +++ b/src/var.h @@ -24,48 +24,6 @@ #include "format.h" #include "val.h" -/* Frequency tables. */ - -/* Frequency table entry. */ -struct freq - { - union value v; /* The value. */ - double c; /* The number of occurrences of the value. */ - }; - -/* Types of frequency tables. */ -enum - { - FRQM_GENERAL, - FRQM_INTEGER - }; - -/* Entire frequency table. */ -struct freq_tab - { - int mode; /* FRQM_GENERAL or FRQM_INTEGER. */ - - /* General mode. */ - struct hsh_table *data; /* Undifferentiated data. */ - - /* Integer mode. */ - double *vector; /* Frequencies proper. */ - int min, max; /* The boundaries of the table. */ - double out_of_range; /* Sum of weights of out-of-range values. */ - double sysmis; /* Sum of weights of SYSMIS values. */ - - /* All modes. */ - struct freq *valid; /* Valid freqs. */ - int n_valid; /* Number of total freqs. */ - - struct freq *missing; /* Missing freqs. */ - int n_missing; /* Number of missing freqs. */ - - /* Statistics. */ - double total_cases; /* Sum of weights of all cases. */ - double valid_cases; /* Sum of weights of valid cases. */ - }; - /* Script variables. */ /* Variable type. */ -- 2.30.2