Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

- JMP User Community
- :
- Discussions
- :
- adding graphic to a graph box using a for-loop

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

Highlighted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Jul 17, 2020 2:47 AM
(753 views)

Hi,

I'm trying to add graphics (rectangles) to a graph box by using a for-loop. The expected outcome is a cross made of 31 rectangles. I have a working script where I wrote the code out line by line but would like to make it shorter and more scalable.

The script below is running but only the last rectangle will be displayed in the graph box.

When I write the script with 2 lines of "`Add Graphics Script`

" (commented out at the bottom of the script) instead of the for-loop it does add 2 rectangles. I would have expected a for-loop to do the same. How can I get it do do so?

```
Names default to here(1);
//dt that holds the parameters for the rectangles
dt_loc = open (momo_dir || "rectangle_locations.csv" );
//create a graphic box
base_box = graph Box(
Frame Size( 400, 400 ),
XName(""), XScale(19,81), yScale(19,91), SuppressAxes, Pen Color( 1 );
);
//define the frame box in which the rectangles will e displayed
framebox = base_box[frame box( 1 )];
//ran a for loop for all 31 rectangles to be added to the Base_box
For( f = 1, f <= N Rows(dt_loc), f++,
//f=1;
//location/sizes of each box is defined here based on a csv file
rec_left = dt_loc:left[f];
rec_top = dt_loc:top[f];
rec_right = dt_loc:right[f];
rec_bottom = dt_loc:bottom[f];
//add the graphic script to the base_box for each row (aka rectangle) in the table
framebox << Add Graphics Script(Rect(rec_left, rec_top, rec_right, rec_bottom, fill = 0););
); //end f for loop
try(close(dt_loc, no save));
//Running the following 2 lines will add 2 rectangles
//framebox << Add Graphics Script(Rect(40,75,50,70, fill = 0););
//framebox << Add Graphics Script(Rect(40,70,50,65, fill = 0););
cross_rep = New window ("Cross", vlistbox(base_box));
```

2 ACCEPTED SOLUTIONS

Accepted Solutions

Highlighted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

You have made the script far more complex than it needs to be. Below are 2 reworks of your script. The first one is taking your flow, and just converting it into a working model. The second is making it very concise(small) as you also requested.

```
Names Default To Here( 1 );
//dt that holds the parameters for the rectangles
dt_loc = Open( momo_dir || "rectangle_locations.csv" );
//create a graphic box
base_box = Graph Box(
Frame Size( 400, 400 ),
XName( "" ),
X Scale( 19, 81 ),
Y Scale( 19, 91 ),
SuppressAxes,
Pen Color( 1 );
//ran a for loop for all 31 rectangles to be added to the Base_box
For( f = 1, f <= N Rows( dt_loc ), f++,
// location/sizes of each box is defined here based on a csv file
rec_left = dt_loc:left[f];
rec_top = dt_loc:top[f];
rec_right = dt_loc:right[f];
rec_bottom = dt_loc:bottom[f];
// Draw the rectangle
Rect( rec_left, rec_top, rec_right, rec_bottom, fill = 0 );
);
);
Try( Close( dt_loc, no save ) );
cross_rep = New Window( "Cross", V List Box( base_box ) );
```

```
Names Default To Here( 1 );
//dt that holds the parameters for the rectangles
dt_loc = Open( momo_dir || "rectangle_locations.csv" );
cross_rep = New Window( "Cross",
//create a graphic box
base_box = Graph Box(
Frame Size( 400, 400 ),
XName( "" ),
X Scale( 19, 81 ),
Y Scale( 19, 91 ),
SuppressAxes,
Pen Color( 1 );
//ran a for loop for all 31 rectangles to be added to the Base_box
For( f = 1, f <= N Rows( dt_loc ), f++,
// location/sizes of each box is defined here based on a csv file
Rect( dt_loc:left[f], dt_loc:top[f], dt_loc:right[f], dt_loc:bottom[f] );
);
)
);
Try( Close( dt_loc, no save ) );
```

Jim

Highlighted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Created:
Jul 17, 2020 3:54 AM
| Last Modified: Jul 17, 2020 3:58 AM
(741 views)
| Posted in reply to message from Ole 07-17-2020

the graphics script runs later, whenever the graph needs to update (zooming, etc). You've specified variables in one case, and hard coded numbers in the other. You can convert the variables to numbers in a bunch of ways. The way I usually do this looks something like this:

```
eval(evalexpr(
framebox << Add Graphics Script(Rect(expr(rec_left), expr(rec_top), expr(rec_right), expr(rec_bottom), fill = 0););
));
```

which wraps the variables with expr(...), uses evalexpr(...) to replace expr(...) with actual value, and uses eval(...) to evaluate the expression returned by evalexpr(...). Likely other people will show their preferred ways. <edit> I like @txnelson 2nd answer.

Craige

5 REPLIES 5

Highlighted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

You have made the script far more complex than it needs to be. Below are 2 reworks of your script. The first one is taking your flow, and just converting it into a working model. The second is making it very concise(small) as you also requested.

```
Names Default To Here( 1 );
//dt that holds the parameters for the rectangles
dt_loc = Open( momo_dir || "rectangle_locations.csv" );
//create a graphic box
base_box = Graph Box(
Frame Size( 400, 400 ),
XName( "" ),
X Scale( 19, 81 ),
Y Scale( 19, 91 ),
SuppressAxes,
Pen Color( 1 );
//ran a for loop for all 31 rectangles to be added to the Base_box
For( f = 1, f <= N Rows( dt_loc ), f++,
// location/sizes of each box is defined here based on a csv file
rec_left = dt_loc:left[f];
rec_top = dt_loc:top[f];
rec_right = dt_loc:right[f];
rec_bottom = dt_loc:bottom[f];
// Draw the rectangle
Rect( rec_left, rec_top, rec_right, rec_bottom, fill = 0 );
);
);
Try( Close( dt_loc, no save ) );
cross_rep = New Window( "Cross", V List Box( base_box ) );
```

```
Names Default To Here( 1 );
//dt that holds the parameters for the rectangles
dt_loc = Open( momo_dir || "rectangle_locations.csv" );
cross_rep = New Window( "Cross",
//create a graphic box
base_box = Graph Box(
Frame Size( 400, 400 ),
XName( "" ),
X Scale( 19, 81 ),
Y Scale( 19, 91 ),
SuppressAxes,
Pen Color( 1 );
//ran a for loop for all 31 rectangles to be added to the Base_box
For( f = 1, f <= N Rows( dt_loc ), f++,
// location/sizes of each box is defined here based on a csv file
Rect( dt_loc:left[f], dt_loc:top[f], dt_loc:right[f], dt_loc:bottom[f] );
);
)
);
Try( Close( dt_loc, no save ) );
```

Jim

Highlighted
##

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Re: adding graphic to a graph box using a for-loop

I agree. The 2nd script is really concise and to the point. I tried the for-loop in the graph box as well but must have had an error in the script that prevented it from working.

Thanks a lot.

Ole

Highlighted
##

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Re: adding graphic to a graph box using a for-loop

*One follow up question/comment. *

*The dt_loc variable is not passed into the graph box. I found two options to get it to work:*

*- open the dt_loc table inside the graph box (which works if I only use the table at that part of the script)*

*- make dt_loc a global variable (::dt_loc)*

*Is there any other way to make the dt_loc variable available inside the graph box?*

*Thanks*

*Ole*

Highlighted

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Created:
Jul 17, 2020 3:54 AM
| Last Modified: Jul 17, 2020 3:58 AM
(742 views)
| Posted in reply to message from Ole 07-17-2020

the graphics script runs later, whenever the graph needs to update (zooming, etc). You've specified variables in one case, and hard coded numbers in the other. You can convert the variables to numbers in a bunch of ways. The way I usually do this looks something like this:

```
eval(evalexpr(
framebox << Add Graphics Script(Rect(expr(rec_left), expr(rec_top), expr(rec_right), expr(rec_bottom), fill = 0););
));
```

which wraps the variables with expr(...), uses evalexpr(...) to replace expr(...) with actual value, and uses eval(...) to evaluate the expression returned by evalexpr(...). Likely other people will show their preferred ways. <edit> I like @txnelson 2nd answer.

Craige

Highlighted
##

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Email to a Friend
- Report Inappropriate Content

Re: adding graphic to a graph box using a for-loop

Perfect. That worked. Thank you very much.

Ole