csvoctave

Octave - Error creating plot from data read from file in csv format


I have a text file in CSV format as follows:

name,mi,km,sp
Aa,2.6,4.1843024285,3
Bb,12.7,20.4387080162,5
Cc,104,167.3720971402,9
Dd,8816,14188.0039268069,40
Ee,11669,18779.4711685469,39
Ff,77793,125195.93800795,84
Gg,103723,166926.307996846,76

The first column is of type string, the second and third are real numeric, and the fourth column is integer numeric.

I used the following script to read the data:

pkg load io
data = csv2cell("data.csv", 1)
sp = data(:,4) % Read 'sp' colunm

It looks to be read fine, but when I attempt to create a bar plot with the data in the 'sp' variable, using the command bar(sp) I got the error:

error: bar: Y must be numeric

Isn't the csv2cell function supposed to be able to read data from mixed types? But should the data be converted to their respective after reading? And if so, how can I do that?

Thanks in advance for any assistance you can provide.

EDIT: Trying something like

sn = str2num(sp) 

didn't help either, because in this case I received the message:

error: str2num: S must be a string or string array

I then tried using

datan = str2double(data)

which just returned a matrix of NaN's

At a loss still am I.


Solution

  • Looking at the data you're creating, I see:

    pkg load io
    data = csv2cell('data.csv',1)
    data =
    {
      [1,1] = Aa
      [2,1] = Bb
      [3,1] = Cc
      [4,1] = Dd
      [5,1] = Ee
      [6,1] = Ff
      [7,1] = Gg
      [1,2] = 2.6000
      [2,2] = 12.700
      [3,2] = 104
      [4,2] = 8816
      [5,2] = 11669
      [6,2] = 77793
      [7,2] = 103723
      [1,3] = 4.1843
      [2,3] = 20.439
      [3,3] = 167.37
      [4,3] = 1.4188e+04
      [5,3] = 1.8779e+04
      [6,3] = 1.2520e+05
      [7,3] = 1.6693e+05
      [1,4] = 3
      [2,4] = 5
      [3,4] = 9
      [4,4] = 40
      [5,4] = 39
      [6,4] = 84
      [7,4] = 76
    }
    
    sp = data(:,4)
    sp =
    {
      [1,1] = 3
      [2,1] = 5
      [3,1] = 9
      [4,1] = 40
      [5,1] = 39
      [6,1] = 84
      [7,1] = 76
    }
    

    Note that what you've created is not a numeric array. It's a cell array. See the curly braces. To convert sp to a numeric array you can use cell2mat:

    >> sp = cell2mat(sp)
    sp =
    
        3
        5
        9
       40
       39
       84
       76
    
    

    Now bar(sp) should work just fine.

    Also, if you don't actually need the text labels you can do what you needed without going through a cell array.

    using dlmread or csvread (csvread is really just a wrapper to dlmread):

     data2 = csvread('data.csv', 1, 1)  # the 1's skip first row and column
    data2 =
    
       2.6000e+00   4.1843e+00   3.0000e+00
       1.2700e+01   2.0439e+01   5.0000e+00
       1.0400e+02   1.6737e+02   9.0000e+00
       8.8160e+03   1.4188e+04   4.0000e+01
       1.1669e+04   1.8779e+04   3.9000e+01
       7.7793e+04   1.2520e+05   8.4000e+01
       1.0372e+05   1.6693e+05   7.6000e+01
    
    sp2 = data2(:,3)
    sp2 =
    
        3
        5
        9
       40
       39
       84
       76
    
    bar (data2(:,3))
    
    

    produces the same output. (If you didnt add the "1, 1" to csvread it would produce an array with zeros wherever there were strings. You could then just plot the subset with the actual data.)