As an example, let us tackle a statistical query on a dataset. We will play with the Hair Eye Color dataset which looks like this:

"" , "Hair" , "Eye" , "Sex" , "Freq" "1" , "Black" , "Brown" , "Male" ,32 "2" , "Brown" , "Brown" , "Male" ,53 "3" , "Red" , "Brown" , "Male" ,10 "4" , "Blond" , "Brown" , "Male" ,3 "5" , "Black" , "Blue" , "Male" ,11

Before we query, let us import the data which is a good exercise for CSV parsing in Emacs:

( setq csv-dataset-file ( expand-file-name "HairEyeColor.csv" "~/Downloads" ) ) ( defun read-lines ( file ) ;; Take your pick: custom, find-file, f-read-text ( with-temp-buffer ( insert-file-contents-literally file ) ( split-string ( decode-coding-region ( point-min ) ( point-max ) 'utf-8 t ) "

" t ) ) ) ( defun read-csv-field ( field ) ;; Remove the pesky enclosed double quoting ( cond ( ( zerop ( length field ) ) "" ) ( ( and ( string-equal ( substring-no-properties field 0 1 ) "\"" ) ( string-equal ( substring-no-properties field -1 ) "\"" ) ) ( substring-no-properties field 1 -1 ) ) ( t ( string-to-number field ) ) ) ) ( defun read-csv-line ( line ) ( let ( ( raw-fields ;; This assumes no rogue commas need escaping ( split-string line "," ) ) ) ( mapcar #'read-csv-field raw-fields ) ) ) ( defun read-csv-file ( file ) ( mapcar #'read-csv-line ( read-lines file ) ) ) ( setq dataset ( read-csv-file csv-dataset-file ) ) ;; Generated output ( ( "" "Hair" "Eye" "Sex" "Freq" ) ( "1" "Black" "Brown" "Male" 32 ) ( "2" "Brown" "Brown" "Male" 53 ) ( "3" "Red" "Brown" "Male" 10 ) ( "4" "Blond" "Brown" "Male" 3 ) )

Libraries exist for this purpose such as csv , el-csv or parse-csv and utilities like f or parsec but doing it yourself is an occasional opportunity to review the basics. With that handled, what can we ask of the data? What is the frequency of eye colors? Before that, we need to group the data:

( setq headers ( car dataset ) ;; Only mentioned, not needed records ( cdr dataset ) ) ( defun group-by ( f xs ) ;; A quick write on -group-by ( let ( ( groups ( list ) ) ) ( mapc ( lambda ( x ) ( let* ( ( key ( funcall f x ) ) ( key-group ( assoc key groups ) ) ) ( unless key-group ( push ( cons key ( list ) ) groups ) ( setq key-group ( assoc key groups ) ) ) ( setcdr key-group ( cons x ( cdr key-group ) ) ) ) ) xs ) groups ) ) ( defun group-records-by-eye-color ( records ) ( let* ( ( raw-eye-groups ( group-by ( apply-partially #'nth 2 ) records ) ) ( eye-groups ( mapcar ( lambda ( eye-group ) ( pcase-let ( ( ` ( ,eye-color . ,eye-records ) eye-group ) ) ( let ( ( eye-frequencies ;; Extract frequencies and collect it ( mapcar ( apply-partially #'nth 4 ) eye-records ) ) ) ( cons eye-color ( apply #'+ eye-frequencies ) ;; Shiv for sum ) ) ) ) raw-eye-groups ) ) ) eye-groups ) ) ( setq eye-color-groups ( group-records-by-eye-color records ) ) ;; Generated output ( ( "Green" . 64 ) ( "Hazel" . 93 ) ( "Blue" . 215 ) ( "Brown" . 220 ) )

After writing the extraction, getting the bar chart is straightforward.

( chart-bar-quickie 'horizontal "Eye Colors" ( mapcar #'car eye-color-groups ) "Colors" ( mapcar #'cdr eye-color-groups ) "Frequency" )

Neat but let's arrange it by descending order:

( defun on ( f op ) ;; Haskell's on operator ( lexical-let ( ( f f ) ;; Sad that parameters aren't lexically scoped here ( op op ) ) ( lambda ( left right ) ( funcall op ( funcall f left ) ( funcall f right ) ) ) ) ) ( chart-bar-quickie 'horizontal "Eye Colors - Descending" ( mapcar #'car eye-color-groups ) "Colors" ( mapcar #'cdr eye-color-groups ) "Frequency" nil ( on #'cdr #'> ) ;; A comparator lambda also works but done for variety )

Looking at it, brown and blue eye colors are quite frequent. Nothing groundbreaking or epic. How about applying the same process with hair color? We get the following chart:

With hair color as the variable, brown and blonds are many. Nothing fancy. We could change the variable into gender but nothing more would be gained. The real question for any visualization is what does it mean? Rather, what insights can we interpret from the data? Since it is a sample, it might not mean anything nor does it have to. This is a library exploration, not a statistical lesson that is beyond scope.