Create a text wave histogram

On the Igor Pro mailing list someone once asked for advice on how to create a wave that can be used to create a histogram of values in a text wave.

You can use TextWaveHistogram1D() to create such a histogram. See the comments above the code for details on the parameters the function takes. You may want to remove or comment out the code at the end that prints the time it took to execute the function, since that code is primarily for testing purposes.

The second function below, MakeBigTextWave(), can be used to create some fake data to test the first function. For my testing, I copied the list of countries at http://openconcept.ca/blog/mgifford/text_list_all_countries onto my clipboard and then executed the following from the Igor Pro command line:

String listOfCountries = GetScrapText() Make/T fake_data Make/T histo MakeBigTextWave(listOfCountries, fake_data, 10000) TextWaveHistogram1D(fake_data, histo) It took 3.33 s to compute a histogram with 10000 data points and 223 unique categories.

//**
// Creates a wave containing the number of rows in textInputWave that have each of the possible values in textInputWave.
// Basically, this gives you the data that you can use to plot a histogram with a text label on the x axis and
// # (count) on the y axis.
//
// NOTE:    This function discards any rows in textInputWave that are blank (ie. the string value = "").
//      Furthermore, matching of text values is for the complete string, but is case insensitive.
//
// @param textInputWave
//  A 1D text wave which contains the text values that should be counted.  For example,
//  each row might contain the name of a country.
// @param outWave
//  A numerical wave where the output of this function will be stored.  This wave must exist.
//  The format of this wave will be for each row dimension label to have the text value of a category
//  and the corresponding row will contain the number of times that the item appeares in textInputWave.
// @return No value is returned
//*
Function TextWaveHistogram1D(textInputWave, outWave)
    WAVE/T textInputWave
    WAVE outWave
    Variable start, stop   
    start = StopMsTimer(-2)
    Duplicate/O/T textInputWave, textInputWaveCopy
    Redimension/N=0 outWave
   
    // Sort the input wave
    Sort/A textInputWaveCopy, textInputWaveCopy
   
    Variable n, numRows = numpnts(textInputWaveCopy)
    Variable numOutRows
    String currentTextString = "", lastTextString = ""
    For (n=0; n<numRows; n+=1)
        currentTextString = textInputWaveCopy[n]
        if (strlen(currentTextString) > 0 && cmpstr(currentTextString, lastTextString) != 0)
            Redimension/N=(numOutRows + 1) outWave
            SetDimLabel 0, numOutRows, $(currentTextString), outWave
           
            // Count the number of rows in textInputWaveCopy that have this value
            Extract/O/INDX/T textInputWaveCopy, extractedWave, cmpstr(textInputWaveCopy[p], currentTextString) == 0
            outWave[numOutRows] = numpnts(extractedWave)
            numOutRows += 1
        endif
       
        lastTextString = currentTextString
    EndFor
    KillWaves textInputWaveCopy, extractedWave
    stop = StopMsTimer(-2)
    printf "It took %.2W1Ps to compute a histogram with %d data points and %d unique categories.\r", (stop - start)/1E6, numRows, numOutRows
End

//**
// This function is used to create some fake data to test the main function above.
//
// @param labelsString
//  This is a carriage-return (\r) separated list of labels that will be used to create the
//  fake data.  For testing purposes I copied the list of countries to my clipboard from this site:
//  <http://openconcept.ca/blog/mgifford/text_list_all_countries&gt;
//  After copying to the clipboard, I issued the following command from the Igor command line:
//  String/G listOfCountries = GetScrapText()
// @param outWave
//  A 1D text wave that will contain one item from labelsString in each row.  This wave must exist
//  when the function is called but it will be redimensioned as appropriate by this function.
// @param numPoints
//  Number of points to make outWave
// @return No value is returned
//*
Function MakeBigTextWave(labelsString, outWave, numPoints)
    String labelsString
    WAVE/T outWave
    Variable numPoints
   
    Redimension/N=(numPoints) outWave
   
    Make/O/N=(numPoints) randomWave
   
    randomWave = abs(round(enoise(ItemsInList(labelsString, "\r"))))
    outWave[] = RemoveEnding(StringFromList(randomWave[p], labelsString, "\r"), "\r")
    KillWaves randomWave   
End

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More