running vpython without the visualisation - sounds crazy!

257 views
Skip to first unread message

Tom Griffiths

unread,
Apr 28, 2022, 5:42:58 AM4/28/22
to VPython-users
I have created a simple ball on slope model using vpython with some inputs and outputs. I have used pandas to read the csv of inputs and written an output csv too.

Currently it works with one set of inputs - such as slope angle, ball radius etc - to produce one set of outputs - such as final KE, final acceleration. 

However, I now want to upscale the model by using multiple inputs from a dataset I have created (at the moment the dataset is small, for simplicity) in order to create a distribution of outputs. 

I wonder if there is a way of running my model without running the visualisation? For obvious reasons this is not very efficient and I am wondering if I need to try a different method of creating the model without using vpython at all? I would rather not do this because it is useful to see if my model is actually working! 

Many thanks, 

Bruce Sherwood

unread,
Apr 28, 2022, 2:49:44 PM4/28/22
to VPython-users
You can of course put any or all aspects of the visualization inside if statements, so perhaps you need to be more explicit about what the issue is. Another approach is to leave all of the visualization intact but create the objects with "visible=visualization", where  visualization is a global variable set to True or False.

Bruce

John

unread,
May 3, 2022, 3:58:50 PM5/3/22
to VPython-users
I think it can be done if you are willing to make a few changes to the vpython.py file in your installation of the vpython package.


My idea is to pass a parameter to the vpython  canvas() object to indicate if the scene should be visualized like in this sample program.

from vpython import *
scene = canvas(visualize=False)
b = box()

If visualize is False then the scene is not visualized, if it is true then it is visualized. 

The first thing to do is to add a class variable called "visualize" to the baseObj class with a default value of True at line 179 in the vpython.py file

class baseObj(object):
    glow = None
    visualize = True 
    objCnt = 0

All vpython classes inherit from baseObj. Then update the baseObj class methods appendcmd,  addmethod, addattr at around line 273 in the file to check if visualize is True otherwise do nothing if visualize is False. These methods send data to the javascript front end so if you block the data from being sent then the front end will not receive any commands to process.  

    def appendcmd(self,cmd):
        if(self.visualize):
            # The following code makes sure that constructors are sent to the front end first.
            cmd['idx'] = self.idx
            while not baseObj.sent: # baseObj.sent is always True in the notebook case
                time.sleep(0.001)
            baseObj.updates['cmds'].append(cmd) # this is an "atomic" (uninterruptable) operation

    def addmethod(self, method, data):
        if(self.visualize):
            while not baseObj.sent: # baseObj.sent is always True in the notebook case
                time.sleep(0.001)
            baseObj.updates['methods'].append((self.idx, method, data)) # this is an "atomic" (uninterruptable) operation

    def addattr(self, attr):
        if(self.visualize):
            while not baseObj.sent: # baseObj.sent is always True in the notebook case
                time.sleep(0.001)
            baseObj.attrs.add((self.idx, attr)) # this is an "atomic" (uninterruptable) operation

Then update the canvas class around line number 2926  to check if visualize was passed as an argument and if so set the baseObj.visualize class variable. Since all vpython objects inherit from baseObj, by having the baseObj.visualize class variable set to False then no objects will send data to the javascript front end.

     if "visualize" in args:
            baseObj.visualize = args["visualize"]
       
    # set values of user-defined attributes
        for key, value in args.items(): # Assign all other properties
            setattr(self, key, value)


With these modifications to vpython.py file you should be able to accomplish what you are looking for. I tried it in a jupyter notebook and it seemed to work. Attached is a version of vpython.py from vpython release 7.6.3 with the above changes.

John
vpython.py

Bruce Sherwood

unread,
May 3, 2022, 7:04:21 PM5/3/22
to VPython-users
Here are a couple of other possible approaches:

1) After creating all of the 3D objects, for scene (or whatever is the name of the canvas) set scene.visible = False, in which case the WebGL renderer won't have any work to do.

2) Set scene.width = scene.height = 1, so you don't see the display. However, in the case the WebGL renderer will presumably make a display even if you can't see it.

Bruce

Tom Griffiths

unread,
May 4, 2022, 4:32:17 AM5/4/22
to VPython-users
Thanks to both of you for your help. I will give them a try and let you know how I get on with it! 
All the best,
Tom

Tom Griffiths

unread,
May 4, 2022, 5:34:00 AM5/4/22
to VPython-users

When running the model with a single set of inputs:
- By implementing both 1) and 2) from Bruce's response, I now cannot see the visualisation in the web-browser - great. 
- However, the web-browser tab still opens and I would like to stop this from happening as well if possible?

When running the model using a dataset of inputs:
- I have placed the model in a function so that I can call it in other scripts, and loop over it for multiple inputs
- At the moment I am getting this error when trying to run the program: "TypeError: cannot convert the series to <class 'float'>"
- It seems to be arising when the program is running the function and coming across the various vector inputs. I am wondering if I need to convert my datasets from series into floats? However when I test the dataframes to see the datatype they are already floats, so this is confusing so me. 

Please help! 
Thanks,
Tom

John

unread,
May 4, 2022, 1:09:13 PM5/4/22
to VPython-users
I modified the code in vpython.py of my suggested solution so that the web-browser tab doesn't open. Attached is my updated version of vpython.py. I made the following change at line 241 of the file vpython.py

Replaced lines 241, 242

            else:
                from .no_notebook import _

With

            elif baseObj.visualize:
                from .no_notebook import _

With this change the browser tab doesn't open when set visualize to False when the canvas is created in your vpython program. e.g.

from vpython import *
scene = canvas(visualize=False)
b = box()

You can copy the attached vpython.py file and overwrite the version of this file in the vpython installed location on your system  if you are using vpython 7.6.3  and you want to try it out this proposed fix. Be sure to make a backup copy of the original vpython.py file before you overwrite it that way you can undo this proposed solution after trying it out.

John
vpython.py

Tom Griffiths

unread,
Jul 21, 2022, 5:55:10 AM7/21/22
to VPython-users
Hi, back again trying to get this working. 

I have compiled the model into some functions that I am calling in a separate script, and I am getting this error: 

ball_on_slope
    'value': [ball.pos.mag, ball_v.x, ball_v.x, k_e],

AttributeError: 'vpython.cyvector.vector' object has no attribute 'pos'

This error does not occur when I run the model with single input parameters, but with multiple ones it seems to kick up this error. 

Thanks

Bruce Sherwood

unread,
Jul 21, 2022, 1:06:16 PM7/21/22
to VPython-users
The error message states that "ball" is an ordinary vector, not an object that has a "pos" attribute. I suggest inserting a print statement just before the reference to ball.pos to see what kind of thing "ball" is.

Bruce

Tom Griffiths

unread,
Jul 22, 2022, 10:45:14 AM7/22/22
to VPython-users
Hi Bruce, 

Many thanks I seem to have solved the issue. 

Can you help me with something else? 

I want to run the model I have made multiple times with different input parameters from a dataset of numpy arrays. An obvious place to start is for loops, and I have done this already. However I am aware that this is an inefficient way of doing and and keep coming across this term "vectorization". Is this method compatible with v.python?

Thanks, 
Tom

Bruce Sherwood

unread,
Jul 22, 2022, 1:27:01 PM7/22/22
to VPython-users
What numpy is about is vectorization, that instead of looping over a list to take the square root of all the items, one item at a time, you put all the items in a numpy array and with a single statement you take the square root of all the items, at machine speed. 

If the processing of each of your cases (using numpy) is extensive, you can ignore the small additional cost of a loop over the cases.

Bruce

Alex Herrera

unread,
Apr 12, 2023, 11:46:33 PM4/12/23
to VPython-users
Hi John,

Just wanted to say thank you for sharing your solution! I know it would have taken me a long time to figure this out and it was exactly what I needed.

Best,
Alex

Alex Herrera

unread,
Apr 13, 2023, 1:04:24 AM4/13/23
to VPython-users
I would also add that I commented out the "atexit.register(Exit)" line (line 28), which I found allows me to run code to completion gracefully. Specifically, this prevents the

"in Exit
    a = 1.0/zero
ZeroDivisionError: float division by zero"

error I usually got when running VPython code without the visualization component.

Reply all
Reply to author
Forward
0 new messages