Forte Tutorial 5b: Forte's pythreejs Renderer


In this tutorial we are going to explore the 3D renderer avaiable in forte.

Let's import the psi4 and forte modules, including the forte.utils submodule


In [ ]:
import psi4
import forte
import forte.utils

Next, we will define some colors


In [ ]:
red = '#E4413C'
orange = '#E98E34'
yellow = '#F5E34C'
lime = '#B1CB44'
green = '#5BB13B'
emerald = '#41936B'
teal = '#2F6E83'
prussian = '#274F92'
blue = '#282F99'
violet = '#533498'
purple = '#94258C'
magenta = '#C12858'

colors = {'red' : '#E4413C',
'orange' : '#E98E34',
'yellow' : '#F5E34C',
'lime' : '#B1CB44',
'green' : '#5BB13B',
'emerald' : '#41936B',
'teal' : '#2F6E83',
'prussian' : '#274F92',
'blue' : '#282F99',
'violet' : '#533498',
'purple' :'#94258C',
'magenta' : '#C12858'}

Creating a renderer object

We will start by creating a renderer object and set the dimensions


In [ ]:
renderer = forte.utils.Py3JSRenderer(width=400, height=400)

To visualize the renderer we call the display() function


In [ ]:
renderer.display()

After we execute this command you should see an empty white are of dimension 400 x 400 pixels.


Py3JSRenderer basic elements

The Py3JSRenderer class can visualize molecule, cube files, and some simple elements like arrows, planes, spheres. Here is the class specification


In [ ]:
help(renderer)

Arrows

Let's take a look at arrows first. The next three commands add arrows to the rendering. An arrow is created with the add_arrow function. This requires a starting point (xyz1) and ending point (xyz2) and a color (in hexadecimal code)

The following code creates three arrows pointing in the x, y, z directions coded in red, green, blue, respectively. In this tutorial we will stay consistent and so the arrows will be color coded x <-> red, y <-> green, z <-> blue as in RGB. After executing this code, scroll up to see the output


In [ ]:
help(renderer.add_arrow)

In [ ]:
renderer.add_arrow((0,0,0),(1,0,0),red)
renderer.add_arrow((0,0,0),(0,1,0),green)
renderer.add_arrow((0,0,0),(0,0,1),blue)

Planes

The second type of element supported by Py3JSRenderer is a plane. The following code plots three planes lying on the yz, xz, and xy planes and their respective normal unit vectors.


In [ ]:
help(renderer.add_plane)

In [ ]:
renderer2 = forte.utils.Py3JSRenderer(width=400, height=400)

renderer2.add_arrow((0,0,0),(1,0,0),red)
renderer2.add_arrow((0,0,0),(0,1,0),green)
renderer2.add_arrow((0,0,0),(0,0,1),blue)

renderer2.add_plane(position=(0,0,0),color=red,plane='yz')
renderer2.add_plane(position=(0,0,0),color=green,plane='xz')
renderer2.add_plane(position=(0,0,0),color=blue,plane='xy')
renderer2.display()

It is also possible to make square planes and specify the plane by passing a vector orthogonal to the plane


In [ ]:
renderer3 = forte.utils.Py3JSRenderer(width=400, height=400)

renderer3.add_arrow((0,0,0),(1,0,0),red)
renderer3.add_arrow((0,0,0),(0,1,0),green)
renderer3.add_arrow((0,0,0),(0,0,1),blue)

renderer3.add_plane(position=(0,0,0),width=5,height=5,color=magenta,normal=(0,1,1),type='square')
renderer3.display()

Boxes

We can also plot general boxes oriented in space


In [ ]:
help(renderer.add_box)

In [ ]:
renderer4 = forte.utils.Py3JSRenderer(width=400, height=400)

# these arrows have length = 2
renderer4.add_arrow((0,0,0),(2,0,0),red)
renderer4.add_arrow((0,0,0),(0,2,0),green)
renderer4.add_arrow((0,0,0),(0,0,2),blue)

# add a box with dimensions: width (x) = 4, height (y) = 2, depth (z) = 1
renderer4.add_box(position=(0,0,0),width=2,height=1,depth=0.25,color=purple)
renderer4.display()

We can also rotate boxes, by specifying a vector normal to the width-heigth plane


In [ ]:
renderer5 = forte.utils.Py3JSRenderer(width=400, height=400)

# these arrows have length = 3
renderer5.add_arrow((0,0,0),(3,0,0),red)
renderer5.add_arrow((0,0,0),(0,3,0),green)
renderer5.add_arrow((0,0,0),(0,0,3),blue)

# add a box with dimensions: width (x) = 3, height (y) = 3, depth (z) = 0.25 with the
# width-height plane normal to the (1,1,0) vector
renderer5.add_box(position=(0,0,0),width=3,height=3,depth=0.25,color=orange,normal=(1,1,0))
renderer5.display()

Spheres

Spheres can be added with the add_sphere function. This is not designed for making molecules because it is not efficient for more than a couple elements


In [ ]:
help(renderer.add_sphere)

In [ ]:
renderer6 = forte.utils.Py3JSRenderer(width=400, height=400)

renderer6.add_arrow((0,0,0),(1,0,0),red)
renderer6.add_arrow((0,0,0),(0,1,0),green)
renderer6.add_arrow((0,0,0),(0,0,1),blue)

# add a box with dimensions: width (x) = 4, height (y) = 2, depth (z) = 1
renderer6.add_sphere(position=(1,1,1),radius=0.5,color=lime)
renderer6.add_sphere(position=(2,0,0),radius=0.5,color=red)
renderer6.add_sphere(position=(0,3,0),radius=0.25,color=green)
renderer6.add_sphere(position=(0,0,1.5),radius=0.5,color=blue)
renderer6.display()

Cylinders (tubes)

Cylinders with different radii at the two ends can be drawn using the add_cylinder function


In [ ]:
help(renderer.add_cylinder)

In [ ]:
renderer7 = forte.utils.Py3JSRenderer(width=400, height=400)

renderer7.add_arrow((0,0,0),(1,0,0),red)
renderer7.add_arrow((0,0,0),(0,1,0),green)
renderer7.add_arrow((0,0,0),(0,0,1),blue)

# add a box with dimensions: width (x) = 4, height (y) = 2, depth (z) = 1
renderer7.add_cylinder(xyz1=(0,0,0),xyz2=(1,1,1), radius=0.125,color=teal)
renderer7.add_cylinder(xyz1=(1.5,1.5,1),xyz2=(2,2,1), radius=0.5,color=emerald)
for x in range(1,8):
    renderer7.add_cylinder(xyz1=(2 - x * 0.5,0,0),xyz2=(2 - x* 0.5,0,1), radius=0.25 /x,color=prussian)
    
renderer7.display()

To specify that the two ends have different radii pass a tuple or list with two elements


In [ ]:
renderer8 = forte.utils.Py3JSRenderer(width=400, height=400)

renderer8.add_arrow((0,0,0),(1,0,0),red)
renderer8.add_arrow((0,0,0),(0,1,0),green)
renderer8.add_arrow((0,0,0),(0,0,1),blue)

# add a box with dimensions: width (x) = 4, height (y) = 2, depth (z) = 1
renderer8.add_cylinder(xyz1=(2,2,1),xyz2=(2,2,0), radius=(0.25,0.5),color=yellow)
renderer8.add_cylinder(xyz1=(1,1,1),xyz2=(1,1,2), radius=[0.5,0.0],color=violet)
renderer8.display()

That's all!