#! /bin/bash # Last edited on 2022-10-22 11:32:42 by stolfi # Reads from stdin a file with least two numeric variables {X,Y}. # Creates a FNI (float-valued) image file with a histogram of those variables. # Writes the image to stdout, and displays it with {fni_view}. # Usage: # # $0 [-noex] [-norm x|y|xy] {XCOL} {XMIN} {XMAX} {XNUM} {YCOL} {YMIN} {YMAX} {YNUM} # # where # # {XCOL,YCOL} = indices (from 1) of the columns with {X} and {Y} values. # {XNUM,YNUM} = bin counts for {X} and {Y} # # The "-noex" option rejects pairs outside the given ranges; otherwise such # points are mapepd to the nearest bin. # # The "-norm" option specifies that bin values should be normalized # to unit sum along each row ("x"), each column ("y") or in the whole # histogram ("xy"). In any case, the denominator includes points outside of # the given ranges, even if "-noex" is specified. noex=0 norm='' while [[ ( $# -gt 1 ) && ( "/$1" =~ /-.* ) ]]; do if [[ "/$1" == "/-noex" ]]; then noex=1; shift; elif [[ ( "/$1" == "/-norm" ) && ( $# -gt 2 ) ]]; then norm="$2"; shift; shift; else echo "** invalid option \"$1\"" 1>&2; exit 1 fi done xcol="$1"; shift; # Index (from 1) of column in file with {X} values (hor axis). xmin="$1"; shift; # Min value of {X} to plot. xmax="$1"; shift; # Max value of {X} to plot. xnum="$1"; shift; # Number of histogram bins for {X}. ycol="$1"; shift; # Index (from 1) of column in file with {Y} values (ver axis). ymin="$1"; shift; # Min value of {Y} to plot. ymax="$1"; shift; # Max value of {Y} to plot. ynum="$1"; shift; # Number of histogram bins for {Y}. tmp="/tmp/$$" pfile="${tmp}-r.fni" dfile="${tmp}-d.dat" cat | sed -e '/^[ ]*\([#]|$\)/d' > ${dfile} dnum="`cat ${dfile} | wc -l`" export GDFONTPATH=${STOLFILOCAL}/ttf ${STOLFIHOME}/bin/build_2d_histogram_image.gawk \ -f ${STOLFIHOME}/lib/write_fni_image.gawk \ -v xcol=${xcol} -v xmin=${xmin} -v xmax=${xmax} -v xnum=${xnum} \ -v ycol=${ycol} -v ymin=${ymin} -v ymax=${ymax} -v ynum=${ynum} \ -v noex=${noex} \ -v norm=${norm} \ < ${dfile} \ > ${pfile} if [[ -s ${pfile} ]]; then # Choose a scale value for display: # if [[ ${xnum} -gt ${ynum} ]]; then mnum=${xnum}; else mnum=${ynum}; fi # if [[ "/${norm}" == "/" ]]; then # zscale=`echo "0.5*(${mnum}*${xnum}*${ynum})/(${dnum})" | bc -lq`; # elif [[ "/${norm}" == "/x" ]]; then # zscale=`echo "(${mnum})*(${ynum})" | bc -lq` # elif [[ "/${norm}" == "/y" ]]; then # zscale=`echo "(${mnum})*(${xnum})" | bc -lq`; # elif [[ "/${norm}" == "/xy" ]]; then # zscale=${mnum}; # else # echo "** invalid option \"-norm ${norm}\"" 1>&2; exit 1 # fi zscale=`echo "0.5*sqrt((${xnum})^2 + (${ynum})^2)" | bc -lq`; echo "zscale = ${zscale}" 1>&2 cat ${pfile} fni_view \ -hist 1 \ -range auto \ -scale ${zscale} \ < ${pfile} rm -f ${pfile} else echo "** plot failed" 1>&2 rm -f ${pfile} # In case it exists but is empty. exit 1 fi