The table has no column named '' ''

I just started out in Processing and need to create an interactive data visualization as my main assignment. I'm having a lot of trouble since the teacher won't help us,and the data I put into my program works fine,but it keeps saying that the table has no column named ''MovieTitle'' even though I know it does. It is the very first cell in my Excel file,and I've already checked for any spaces that I might have missed - nothing. If anyone could help me with this and some other things,it would be greatly appreciated!

Answers

  • Answer ✓

    There are many helpful people here, but first you have to post your code. Without it, we have NO IDEA where or what the problem is.

    https://forum.processing.org/two/discussion/15473/readme-how-to-format-code-and-text#latest

  • I don't have any code yet because I integrated my data into a class draft that we all did. I was thinking of using that as a starting point,but it keeps bugging. I'll attach my CSV file and the class code that we did. I know what I want my data to look like,but I don't know the proper code. I've watched tutorials multiple times,but they don't seem to be helping since they aren't very practical.2 3 data

  • So you have a CSV file and no code. So write some code. Start by loading the CSV file and parsing it. Load it with loadStrings(). You'll need to make sure that the CSV file is in the right folder for Processing to find it. Once you have it loaded into an array of Strings, you will probably want to iterate over each String and parse it, using a for(){} loop and split(). Then you will have the information for one of your movies, which you can then store either in an ArrayList of Movie objects (which I recommend you do - just write a class for your Movie object!), or in several arrays of various types (not recommended).

    That alone is probably a lot to get you started. We can draw things later. For now, just try loading your file and printing the data from it to the console with println().

  • edited October 2017
    /* sample.csv:
    
    SchfiftyName, SchfiftyNumber
    Shwam, 1
    Doo, 2
    Two And Heif, 2.5
    Scheven, 7
    Schfourteen-teen, 14.14
    Schwenty One, 21
    Shwenty Seven Heif, 27.5
    Twenty Seven, 27
    Thirty Seven, 37
    Schfifty Five, 55
    
    */
    
    class KnownNumber {
      String s;
      float v;
      KnownNumber(String name, float value){
        s = name;
        v = value;
      }
      void tell(){
        println("" + s + " is " + v );
      }
    }
    
    ArrayList<KnownNumber> numbers = new ArrayList(); 
    
    void setup(){
      size(400,400);
      String[] data = loadStrings("sample.csv");
      for( int i = 1; i < data.length; i++){
        String[] line = data[i].split(",");
        numbers.add( new KnownNumber( line[0], float(line[1]) ) );   
      }
    }
    
    void draw(){
      background(0);
    }
    
    int w = 0;
    void mousePressed(){
      if( w < numbers.size() ){ 
        numbers.get(w++).tell();
      } 
    }
    

    Here, have a look at this.

  • edited October 2017

    We can't copy & paste code from pictures. Also it's hard to read them! [-(

    https://Forum.Processing.org/two/discussion/15473/readme-how-to-format-code-and-text

    Having access to your ".csv" file (or some sample of it) woulda helped a lot too. 8-|
    For my own example I did this 1 named as "movies.csv": :ar!

    "movies.csv":

    MovieTitle,AverageRating
    It,7.9
    Mother!,6.9
    

    As you can notice, in my own ".csv" file, the numbers are using a dot . instead of a comma ,. L-)
    Dunno whether when Excel saves a ".csv" file, it auto-replaces , w/ . though. :-??

    In my solution I'm also relying on loadTable(): https://Processing.org/reference/loadTable_.html

    Although it's not hard at all to access the resultant Table container via its many methods, I also find it's much easier to create a class to represent all columns of an individual TableRow, and then have an array container to store all instances of that class. *-:)

    Here's my attempt solution below. Any doubt about it, just ask again! O:-)

    "MovieTitles.pde":

    /**
     * Movie Titles (v1.0)
     * GoToLoop (2017-Oct-02)
     *
     * Forum.Processing.org/two/discussion/24337/
     * the-table-has-no-column-named#Item_5
     */
    
    static final String FILE = "movies";
    static final String EXT = ".csv";
    
    Film[] films;
    
    void setup() {
      final Table t = loadTable(FILE + EXT, "header");
      final int rows = t.getRowCount();
    
      films = new Film[rows];
    
      for (int i = 0; i < rows; ++i) {
        final TableRow tr = t.getRow(i);
        final String title = tr.getString("MovieTitle");
        final float rate = tr.getFloat("AverageRating");
    
        films[i] = new Film(title, rate);
      }
    
      printArray(films);
      exit();
    }
    
    static final class Film {
      final String title;
      final float rate;
    
      Film(final String t, final float r) {
        title = t;
        rate = r;
      }
    
      @ Override String toString() {
        return "Title: " + title + " \tRating: " + rate;
      }
    }
    
  • Hi,guys! Thank you so much for helping! I know this probably isn't right,even though the code runs smoothly,I could probably have trouble with it down the road,but I started out like this:

    Table table;
    TableRow row;
    String[] MovieTitle = {"Kingsman: The Golden Circle", "It", "The LEGO Ninjago Movie", 
      "American Assassin", "Mother!", "Home Again", "Friend Request", "Stronger", 
      "The Hitman's Bodyguard", "Wind River"};
    String[] AverageRating = {"7,3", "7,9", "6,3", "6,7", "6,9", "5,8", "5,4", "7,6", 
      "7", "8"};
    
    
    void setup() {
      size(700, 500);
      loadStrings("Book.csv");
      //println("Wind River");
    }
    

    This is the data from my csv file.

    MovieTitle  AverageRating
    Kingsman: The Golden Circle 7,3
    It  7,9
    The LEGO Ninjago Movie  6,3
    American Assassin   6,7
    Mother! 6,9
    Home Again  5,8
    Friend Request  5,4
    Stronger    7,6
    The Hitman's Bodyguard  7
    Wind River  8
    

    Thanks again! P.S. I had to use commas because when I save the document as a csv. file,it registers the numbers as dates,i.e. 7.3=7.mar,even when I put it down as Text of General.

  • String[] MovieTitle = {"Kingsman: The Golden Circle", "It", "The LEGO Ninjago Movie", 
      "American Assassin", "Mother!", "Home Again", "Friend Request", "Stronger", 
      "The Hitman's Bodyguard", "Wind River"};
    String[] AverageRating = {"7,3", "7,9", "6,3", "6,7", "6,9", "5,8", "5,4", "7,6", 
      "7", "8"};
    

    If you already have the data in your code, why try to load it from a file?

    You would do well to convert the numbers to actual numbers, with periods instead of commas.

  • I did GoToLoop's style of code and everything is working great! Now I need to visualize my data. Should I try and do that by void draw()?

  • edited October 2017

    I've created an extra helper function called makeArrayPrintable(), which turns each array's element as a line of text, all joined together as 1 String via StringBuilder, ready to be used by text(). \m/

    /**
     * Movie Titles (v2.2.1)
     * GoToLoop (2017-Oct-02)
     *
     * Forum.Processing.org/two/discussion/24337/
     * the-table-has-no-column-named#Item_9
     */
    
    static final color FG = #FFFF00, BG = #0000FF;
    static final int TXT_SIZE = 24, TXT_MARGIN = 50;
    static final String FILE = "movies", EXT = ".csv";
    
    Film[] films;
    String filmListing;
    
    void setup() {
      size(900, 700);
      smooth(3);
      noLoop();
    
      fill(FG);
      textMode(MODEL);
      textAlign(LEFT, BASELINE);
      textSize(TXT_SIZE);
    
      films = loadFilmCSVTable();
      printArray(films);
    
      filmListing = makeArrayPrintable(films);
    }
    
    void draw() {
      background(BG);
      text(filmListing, TXT_MARGIN, TXT_MARGIN);
    }
    
    Film[] loadFilmCSVTable() {
      final Table t = loadTable(FILE + EXT, "header");
      final int rows = t.getRowCount();
      final Film[] films = new Film[rows];
    
      for (int i = 0; i < rows; ++i) {
        final TableRow tr = t.getRow(i);
        final String title = tr.getString("MovieTitle");
        final float rate = tr.getFloat("AverageRating");
        films[i] = new Film(title, rate);
      }
    
      return films;
    }
    
    @ SafeVarargs static final String makeArrayPrintable(final Object... arr) {
      if (arr == null || arr.length == 0)  return "";
      final StringBuilder sb = new StringBuilder();
    
      for (final Object obj : arr)  sb.append(obj).append(ENTER);
      return sb.substring(0, sb.length() - 1);
    }
    
    static final class Film {
      final String title;
      final float rate;
    
      Film(final String t, final float r) {
        title = t;
        rate = r;
      }
    
      @ Override String toString() {
        return "Title: " + title + "  -  Rating: " + rate;
      }
    }
    
  • Hi! I tried your code,but it didn't really work because we've never done most of the commands you've shown me so far. :(( I was thinking of using the ratings for a ring graph,where the highest rating would have the most space, and outside of the ring graph,there would be the movie title corresponding to the rating. I also created this: sketch I didn't send the code because all I did was insert the images and correctly position them. I was wondering if it's possible to make them slightly enlarge when I hover over them with the mouse,and when I click on them for them to show some pop-up text? How can I do that?

    Thanks in advance!

  • please show your code - makes it much easier

    to check hover check mouseX and mouseY against position of images, so

    if(mouseX>imgX && mouseY>imgY &&.....

    then resize the image or better still use a secondary image array you enlarged in setup() using resize

    similar when you mouse click : in function mouse pressed check with if as shown, store id of movie and select text

  • My code so far:

    Table t;
    TableRow row;
    PImage img;
    PImage img1;
    PImage img2;
    PImage img3;
    PImage img4;
    PImage img5;
    PImage img6;
    PImage img7;
    PImage img8;
    PImage img9;
    Film[] films;
    
    void setup() {
      size(910, 536);
      background(#F2EFEA);
      smooth();
      noStroke();
      img = loadImage("ha.jpg");
      img1 = loadImage("wr.jpg");
      img2 = loadImage("mother.jpg");
      img3 = loadImage("it.jpg");
      img4 = loadImage("aa.jpg");
      img5 = loadImage("lnm.jpg");
      img6 = loadImage("hb.jpg");
      img7 = loadImage("str.jpg");
      img8 = loadImage("kgs.jpg");
      img9 = loadImage("fr.jpg");
    
      //loadStrings("Book1.csv");
      //println("Wind River");
      Table t = loadTable("Book1.csv", "header");
      int rows = t.getRowCount();
    
      films = new Film[rows];
    
      for (int i = 0; i < rows; ++i) {
        TableRow tr = t.getRow(i);
        String title = tr.getString("MovieTitle");
        float rate = tr.getFloat("AverageRating");
    
        films[i] = new Film(title, rate);
      }
    
      //printArray(films);
    }
    
    void draw() {
      //rectMode(CENTER);
      //rect(125,200,50,50);
      //rect(275,200,50,50);
      //rect(425,200,50,50);
      //rect(575,200,50,50);
      //fill(#84A59D);
      image(img, 0, 0);
      image(img1, 182, 0);
      image(img2, 364, 0);
      image(img3, 546, 0);
      image(img4, 728, 0);
      image(img5, 0, 268);
      image(img6, 182,268);
      image(img7, 364,268);
      image(img8, 546,268);
      image(img9, 728,268);
    }
    
    
    class Film {
      String title;
      float rate;
    
      Film (String t, float r) {
        title = t;
        rate = r;
      }
      String toString() {
        return "Title:"+title+"\tRating:"+ rate;
      }
    }
    
  • But I don't know how to visualize my data in question. How can I use my data and create a ring graph,for example?

  • edited October 2017

    If you want to display data visualization modules rather than write them yourself, you could try grafica:

    ...although I don't think a ring graph is one of its options.

    Here is a simple pie chart to give you an idea of what writing it yourself looks like.

    /**
     * SimplePieChart
     * Draw a piechart of arbitrary values using cumulative arcs
     * 2017-10-06 Jeremy Douglass - Processing 3.3.6
     * forum.processing.org/two/discussion/24337/the-table-has-no-column-named#latest
     */
    int[] values;
    int total;
    
    void setup() {
      colorMode(HSB);
      frameRate(1);
    }
    
    void draw(){
      background(0);
      translate(width/2,height/2); // centered
    
      getData();
      drawArcs();
    }
    
    void getData(){
      // random number of slices
      values = new int[(int)random(3,9)];
      // random values for each slice, and total
      total = 0;
      for (int i=0; i<values.length; i++) {
        values[i] = (int)random(10);
        total += values[i];
        println(i, values[i]);
      }
    }
    
    void drawArcs(){
      strokeWeight(2);
      float lastangle=0;
      float angle=0;
      for (int i=0; i<values.length; i++) {
        // angle as a ratio of total values
        angle = TWO_PI * values[i]/(float)total;
        // draw
        fill(random(255),255,255);
        arc(0, 0, 90, 90, lastangle, lastangle+angle, PIE);
        fill(0,0,255);
        // next arc begins where last one ended
        lastangle+=angle;
      }
      fill(0);
      ellipse(0,0,60,60);
    }
    

    It uses the arc() function:

    Edit: added a final ellipse to make the pie a "ring" graph

  • edited October 2017

    Nice example -- and drawing the ellipse on top at the end is also a good quick way to turn the pie chart into a "ring chart" -- especially as I don't believe that arc() has a two-radius version. I added two lines to my example above to to copy the effect.

  • Why full code? What did she learn now?

  • https://processing.org/examples/piechart.html

    How do I make this example colorful? Thank you for your examples,but I'm just starting out and I can't really use code that we haven't done and I don't really understand yet.

  • I'd like to use the upper one as an example of what I want my final data visualization to look like, and the one where I sent the images put together as a second example. I want the images to zoom in and display text when I hover over them. How can I do that? I have the code with the images in one of my previous comments above.

  • I just need a really rough sketch that WORKS by tonight. I'd like to use the one with images;if you click them,text pops up. Nothing fancy,I just need to know how to do that.

  • I tried to explain the process above....

    Did you try it...?

  • ok, here is my version

    The file Book1.csv must look like this, it's with commata !!! And no spaces around the commata:

    MovieTitle,AverageRating
    Kingsman: The Golden Circle,7.3
    It,7.9
    The LEGO Ninjago Movie,6.3
    American Assassin,6.7
    Mother!,6.9
    Home Again,5.8
    Friend Request,5.4
    Stronger,7.6
    The Hitman's Bodyguard,7
    Wind River,8
    

    the program:

    // list of films 
    Film[] films;
    
    // array of images 
    PImage[] images = new PImage[10];
    
    // when a movie is clicked we store the grid position x,y (e.g. 0,1), not a screen position 
    boolean foundOverForMousePressed=false; // yes/no
    int foundOverForMousePressedX=0, 
      foundOverForMousePressedY=0;
    int foundOverForMousePressedImgNumber=0;
    
    void setup() {
    
      size(910, 536);
    
      background(#F2EFEA);
      smooth();
      noStroke();
      images[0] = loadImage("ha.jpg");
      images[1] = loadImage("wr.jpg");
      images[2] = loadImage("mother.jpg");
      images[3] = loadImage("it.jpg");
      images[4] = loadImage("aa.jpg");
      images[5] = loadImage("lnm.jpg");
      images[6] = loadImage("hb.jpg");
      images[7] = loadImage("str.jpg");
      images[8] = loadImage("kgs.jpg");
      images[9] = loadImage("fr.jpg");
    
      for (int i=0; i<images.length; i++) {
        images[i].resize(199, 0);
      }
    
      Table t = loadTable("Book1.csv", "header");
      int rows = t.getRowCount();
    
      films = new Film[rows];
    
      for (int i = 0; i < rows; ++i) {
        TableRow tr = t.getRow(i);
        String title = tr.getString("MovieTitle");
        float rate = tr.getFloat("AverageRating");
    
        films[i] = new Film(title, rate);
      }
    }
    
    void draw() {
      background(255);
    
      showImages();
    }
    
    // -----------------------
    
    void mousePressed() {
      // when mouse is pressed, we store data and show text later  
      int k=0;
      for (int x=0; x<4; x++) {
        for (int y=0; y<2; y++) {
          // is the mouse over this image? 
          if (mouseOverImage(x, y)) {
            // we store the data to display the text later 
            foundOverForMousePressed=true;
            foundOverForMousePressedX=x; 
            foundOverForMousePressedY=y;
            foundOverForMousePressedImgNumber=k;
            //
          }//if
          k++;
        }//for
      }//for
    }//func 
    
    void showImages() {
    
      int k=0;
      boolean foundOver=false; 
      int foundImg=-1, foundX=0, foundY=0; 
    
      // -1 means we haven't found any
      foundImg=-1;
    
      for (int x=0; x<4; x++) {
        for (int y=0; y<2; y++) {
          // is the mouse over this image? 
          if (mouseOverImage(x, y) && (foundOver==false)) {
            // mouse is over - we don't show the image,
            // we just store the data needed to display it later
            foundOver=true;
            foundX=x;
            foundY=y; 
            foundImg=k;
            // when the mouse is over, we check the text box
            if (foundOverForMousePressedX!=x || foundOverForMousePressedY!=y) {
              // when the image is not the image of text box anymore, we close the text box
              foundOverForMousePressed=false;
            }
          } else {
            // mouse is not over - normal
            image(images[k], x*200, y*268);
          }
          k++;
        }
      }
    
      // show the bigger image after all other images
      if (foundImg>-1 && (foundOver!=false)) {
        image(images[foundImg], foundX*200-22, foundY*268-22, 310, 310);
      }
    
      // text output 
      if (foundOverForMousePressed==true) {
        String text1 = films[foundOverForMousePressedImgNumber].toString();
        stroke(0);
        fill(255, 248, 10);
        rect (foundOverForMousePressedX*200+19, 
          foundOverForMousePressedY*268+19, 
          textWidth(text1)+12, 
          45);
        fill(0); 
        text(films[foundOverForMousePressedImgNumber].toString(), 
          foundOverForMousePressedX*200+19+3, 
          foundOverForMousePressedY*268+19+19);
      }
    }
    
    boolean mouseOverImage(int x, int y) {
      // checks if mouse over image in grod at pos x,y (0,3 e.g.)
    
      // when we leave the window with the mouse we don't want a image to be selected 
      if (mouseX<3||mouseY<3||
        mouseX>width-10||mouseY>height-10)
        return false; 
    
      // test the mouse against image pos - must be the same 
      // values like we use when drawing images 
      if ( mouseX > x*200 && 
        mouseX < x*200 + 200 && 
        mouseY > y*268 && 
        mouseY < y*268 + 268 ) 
        return true; 
      else 
      return false;
    }
    
    // ---------------------------------------------------
    
    class Film {
    
      String title;
      float rate;
    
      Film (String t, float r) {
        // constructor 
        title = t;
        rate = r;
      }
    
      String toString() {
        return 
          "Title:"+title
          +"\nRating:"+ rate;
      }
    }
    //
    
  • edited October 2017 Answer ✓

    Please read the code I provided carefully and understand it. Come back with questions. I tried to write it simply and a bit like a beginner would do it...

    Unfortunately I don't have the images of the movies.

    Some explanations:

    The grid

    Now, the idea is that the images are in a grid, you did that in your code. I just changed your img1,img2 etc, to an array. Since the grid has two rows, I use a double for loop to show them.

      for (int x=0; x<4; x++) {
        for (int y=0; y<2; y++) {
    

    So x says in which column we are in the grid and y in which row.

    To show an image we calculate the screen position as

    x*200 AND y*268
    

    so we get

    image(images[k], x*200, y*268);
    

    to display an image.

    We use the grid of course also to check whether the mouse is over an image.

    So we check mouseX and mouseY against the position of the image.

    The position of the image is like above x*200, y*268 so we get:

      if ( mouseX > x*200 && 
        mouseX < x*200 + 200 && 
        mouseY > y*268 && 
        mouseY < y*268 + 268 ) 
    

    I put this into a function boolean mouseOverImage(int x, int y) {which returns true or false.

    When mouse is pressed / clicked we need to find out on which image, so in the function mousePressed() I do a double for loop over the grid, check if mouse is on this image and store the position of the clicked image / movie to display the text.

    Some Details

    As always, the little details matter.

    I wanted to display one image bigger. But it looked crappy: Imagine image number 3 in the first row is hovered. This image is bigger now. But now the image next to it (to the right) and the image under it (in the 2nd row) are drawn after the big image and they overlap the big image. Looks bad. So I decided to store the data of the image I want to enlarge and draw it after all small images are drawn (after the double / nested for-loop). So I made sure that the big image is always on top. But it makes the code a little more complicate. Look at function showImages() to see what I mean.

    Similar with the text. We detect a mouse Click in mousePressed(). But when we use text() there, the text would just flash briefly. So I decided to store the data of the image that has been clicked and display the text later, at the end of showImages(). Also, we want to have the text on top of all images, so the text output must be at the end of showImages(), after the images are shown.

    Also, when you have the text displayed and you move the mouse away, you want the text to disappear. I also did that.

    Remark

    As you can see, we have two arrays / lists now, one for films, one for the images. This is unfortunate since the image would in theory belong into the class (because it is the image of the film).

    Since we have two separate lists, you need to make sure that the image in array images have the same order as in you Book1.csv (which is the order in the array films).

    So, let's look at this line: images[4] = loadImage("aa.jpg");. This is the image for movie aa. It is image number 4. We need to have the movie in line 4 (or 5/6 since we start counting with 0) in the file Book1.csv !!!!!!!!!!!! OK?

    So correct the image names in these lines accordingly to the order in the csv please:

      images[0] = loadImage("ha.jpg");
      images[1] = loadImage("wr.jpg");
      images[2] = loadImage("mother.jpg");
      images[3] = loadImage("it.jpg");
      images[4] = loadImage("aa.jpg");
      images[5] = loadImage("lnm.jpg");
      images[6] = loadImage("hb.jpg");
      images[7] = loadImage("str.jpg");
      images[8] = loadImage("kgs.jpg");
      images[9] = loadImage("fr.jpg");
    

    Improvements

    Since you don't have much time I suggest you just play with the code a little and understand it.

    If you want to show more movies just make a bigger window. The grid size must be equal or smaller than the number of images and lines in the .csv file.

    I just did a resize() on the images in setup(). This must be improved, e.g. when we have an image in portrait or landscape format I think the resize should be different (line 32 above).

    Of course the .csv file could just contain the image names

    MovieTitle,AverageRating
    Kingsman: The Golden Circle,7.3,kgs.jpg
    

    As you can see, the film data just contains the image that belongs to that film. Much better.

    Then we could load the images in the normal loop where we build the array films from the table in setup(). Also the image could be part of the class Film of one film. Then we wouldn't need the array image anymore.

    If we have more than 8 images / films, we would be able to scroll to the next / previous 8 films.

    When we had a longer text for each film, a click on the small text box could bring up a new screen with longer text for that specific film.

    The handling of the grid and where we check the mouse can be improved.

  • Thank you so very much! You have no idea how much I appreciate this! And the explanation really helps!!!

This discussion has been closed.