Table of Contents
Python Scripting in GeoGebra
Note: the version of Python used in GeoGebra is 2.5 (the technical reason for this is that this is the latest version of Jython, the Java implementation of Python). You will not be able to use features of Python 2.6 or Python 2.7. When reading online docs, look out for notices such as new in version 2.6.
The Python Window
- Run GeoGebra 5 Beta Webstart
- Select Python Window in the View menu to open the Python window (a few seconds wait may be needed the first time round).
- The Python Window contains three panes:
- Interactive
- Here you can enter python statements and see their effect immediately. With Alt+UP / Alt+DOWN you can navigate the history of commands you have entered
- Script
- Here you can write the script that will be executed when the .ggb file is loaded. You can also execute this script at any point
- Events
- Here you can select any GeoGebra object and enter the Python code that will be executed when this object is clicked or updated. Within this script, the object that is the target of the event can be referred to as self
Demo
Copy and paste this script into the interactive pane
geo.A = (1,2) # Create some random points import random xcoords = [random.uniform(-2, 5) for i in range(8)] ycoords = [random.uniform(-2, 5) for i in range(8)] points = [Point(x, y) for x, y in zip(xcoords, ycoords)] # Join them all to A segments = [Segment(p, geo.A) for p in points] # Make a function that shows only the shortest segment def show_shortest(moved_point): for s in segments: s.visible = False shortest = min(segments, key=float) shortest.visible = True # Invoke this every time A is updated geo.A.onupdate = show_shortest # Now move A around in the Euclidian view!
The Python and GeoGebra namespaces
Since both Python and GeoGebra deal with objects which have names, it is important to be able to access easily the GeoGebra objects from Python but not to mix up both kinds of objects. GeoGebra objects can be accessed (and created) in Python by prefixing their name with $ or geo.. So if there is a point called A, it can be referred as $A or geo.A from Python. All other names are only accessible from Python.
As the above only allows ASCII names, there is a syntax for accessing non-ASCII name which may be common in other languages. The following will all return the GeoGebra object named A:
$A geo.A $['A']
Also, there is a convenient syntax for accessing or updating spreadsheet cells:
$['B', 2] = 12 # Set B2 to 12 $[3, 1] = 42 # Set C1 to 42 (A=1, B=2, ...) $['A', 1] = (2, 2) # Set A1 to the point (2, 2) $['A', 1].color = Color.RED # Change the color of the point
Points and Vectors
You can create points and vectors from coordinates
$A = Point(1, 2) $B = Point(-2, 3) $u = Vector(1, -1)
You can create a point from a vector
$C = Point($u)
You can create a vector from a point
$r_A = Vector($A)
You can create a vector joining two points
$v = Vector($A, $B)
If A is a point or a vector:
- $A.x gives you its x-coordinate
- $A.y gives you its y-coordinate
- $A.coords gives you its coordinates as a tuple (ordered pair)
However, you don't get the result as a number but as an expression whose value changes dynamically as the point or vector moves. To get the current value, you need to use A.x.value and A.y.value. The above also allows you to set the coordinates of a point or vector:
$A.x = 3 $B.coords = (-1, 2)
sets the x-coordinate of A to 3 and the coordinates of B to (-1, 2). You can also use these to link points together:
$C = Point(2*$A.x, 1+$B.y)
creates a point C whose x-coordinate is always twice that of A, an y-coordinate is always one more than that of B.
Points have the following additional attributes:
- point_size: an integer which represents the size of the point.
Attributes common to all elements
The following attributes don't just apply to points and vectors, but to all GeoGebra elements
- caption (a caption string)
- color (to set, use e.g. Color.RED or Color(0.5, 0.9, 0.8), i.e. like java.awt.Color)
- defined (boolean, read only): true if the element is defined
- infinite (boolean, read only): true if the element is infinite
- label (a string)
- label_color
- label_mode can be any of "name", "name+value", "value", "caption"
- label_visible (boolean)
- layer (integer): the layer, between 0 and 9 where the element is displayed
- trace (boolean): if true, the element is being traced
- visible (boolean)
For example, the following creates a red point with a black caption saying "Click Me":
$P = Point(3, 1) $P.color = Color.RED $P.label_color = Color.BLACK $P.label_mode = "caption" $P.caption = "Click Me"
Attributes can be set at object creation in a simpler way. The following has the same effect as above:
$P = Point(3, 1, color=Color.RED, label_color=Color.BLACK, label_mode='caption', caption="Click Me")
Paths
Lines and segments
This creates a line l through points A and B
$l = Line($A, $B)
This creates a line l1 through A with direction the vector u
$l_1 = Line($A, $u)
Rays and segments can also be created:
$r = Ray((1, 1), (2, 0)) $s = Segment((-3, 0), (2, 1))
Segments have two attributes called startpoint and endpoint. Lines, segments and rays have an attribute called direction which gives their direction vector.
Axes
There are two special objects, $xAxis and $yAxis which represent the two coordinate axes. What can be done with them is limited at the moment. They have the following attributes:
- visible: this allows to check and change the visibility of an axis
The following hides both axes from view.
$xAxis.visible = False $yAxis.visible = False
Circles, Ellipses, Hyperbolae, Parabolae
the code below creates four circles:
- C1 with centre (1, 1) and through (3, 2)
- C2 through the points (0, 0), (4, 0), (4, 3)
- C3 with centre A and radius BC
- C4 with centre (-2, 0) and radius 3
$C_1 = Circle((1, 1), (3, 2)) $C_2 = Circle((0, 0), (4, 0), (4, 3)) $C_3 = Circle($A, Segment($B, $C)) $C_4 = Circle((-2, 0), 3)
The code below creates two ellipses, two hyperbolae and a parabola:
- E1 with foci at (-2, 0), (2, 0) and semi major axis 3
- E2 with foci at (1, 1), (3, 1) and passing through (2, 2)
- H1 with foci at (-2, 0), (2, 0) and semi major axis 1
- H2 with foci at (1, 1), (3, 1) and passing through (4, 2)
- P with focus (0, 0) and directrix the line joining A and B
$E_1 = Ellipse((-2, 0), (2, 0), 3) $E_2 = Ellipse((1, 1), (3, 1), (2, 2)) $H_1 = Hyperbola((-2, 0), (2, 0), 1) $H_2 = Hyperbola((1, 1), (3, 1), (4, 2)) $P = Parabola((0, 0), Line($A, $B))
Path attributes
All paths (lines and curves) have the following attributes:
- thickness (a numerical value)
- linetype (this is a string; can be 'full', 'short-dash','long-dash', 'dot', 'dash-dot')
Polygons and PolyLines
To create a polygon through *A*, *B* and *C* you can do either:
$ABC = Polygon($A, $B, $C)
or
$ABC = Polygon([$A, $B, $C])
The latter is useful if you want want to create a polygon from an arbitrary sequence of points.
Polygons have the following attributes:
- boundary: the boundary of the Polygon as a PolyLine
- points: a Python list of all the vertices of the polygon (can also be obtained as list(poly))
- edges: a Python list of all the edges of the polygon
- area or value: the area of the polygon
- directed_area: the area with a sign (+ anticlockwise, - clockwise)
The length of a polygon, len(poly) is the number of points on the polygon. The point with index i can be obtained using poly[i].
PolyLines are similar but they do not have edges, area or directed_area attributes, and their value attribute returns their total length.
Text
One can create text object as follows:
t = Text("Hello there!")
Text objects have the following attributes:
- origin (a point). It can be read or set.
- text: the string for the text obect. It can be read or set.
- latex (a boolean): true if the text object should be displayed as LaTeX.
This moves the origin of the text to (2, 2) and sets the text displayed to "Abracadabra".
t.origin.coords = (2, 2) t.text = "Abracadabra"
You can also do the following change the origin. However, this will create a new origin point, whereas the above keeps the same point but updates its coordinates.
t.origin = (3, 1)
This sets the origin of the text to the point A, so if A moves, so does the text:
t.origin = $A
Lists
GeoGebra lists are not to be confused with Python lists. List object can be created as follows:
my_list = List(1, 2, 3) # A geogebra list python_list = [1, 2, 3] # A Python list
Subscript notation can be used to get or delete an item at a given position (but not to set it as I didn't find such a method in GeoList.java):
print my_list[1] # show the second item (the first has index 0) del my_list[0] # remove the first item
A new item can be added at the end of a list with the append method:
my_list.append(42)
It is possible to loop over a list:
for item in my_list: print item + 10
You can convert a GeoGebra list to a Python list:
python_list = list(my_list)
You can remove all elements from a GeoGebra list with the clear method:
my_list.clear()
Functions
Functions can easily be defined in Python:
def f(x): return sin(x)/x $f = Function(f)
Bivariate functions also work. Functions have an implicitcurve attribute:
def f(x, y): return x**2+y**2 - 5 $f = Function(f) $c = f.implicitcurve
Functions can contain inequalities:
def f(x, y): return x**2 > x + y geo.f = Function(f)
Turtles
Turtles are objects that can be moved and draw shapes in the euclidian view (see the logo programming language) To create a new turtle, just do:
t = Turtle()
Turtles can be moved and the nice thing about them is that they are animated, i.e. you can watch them move. Their speed can be adjusted, see below. Here is a simple example of drawing a regular pentagon with the turtle defined above:
t.pen_color = Color.RED for i in range(5): t.forward(2) t.turn_left(72)
Note how you can see the turtle move and turn smoothly. If you would prefer the turtle to draw instantly, you can do
t.speed = 0
Turtle objects have the following attributes:
- pen_color: can be used to get or set the color of the turtle pen
- position: can be used to get or set the current position of the turtle
- angle: can be used to get or set the current orientation of the turtle
- pen_thickness: get or set the thickness of the turtle pen
- running: set to True to animate the turtle, false to stop it moving
- speed: the animation speed of the turtle - it is a floating point number between 0 and 1. 0 means instant, 0.01 very slow, 1 very fast (default 0.1)
Turtle objects have the following methods:
- forward(distance): to move forward by distance units. It will also draw a line if the pen is down.
- turn_left(angle): to turn left by angle degrees
- turn_right(angle): to turn right by angle degrees
- clear(): resets the position and angle of the turtle and clears the drawing.
Intersections
Intersect(x, y) works where x, y are lines or conics at the moment. An Intersect object can be cast to a list or a tuple in order to find the intersection points. E.g.
E.g.
l = Line((0, 1), (2, 2)) c = Circle((0, 0), 3) p, q = Intersect(l, c)
To check if an intersection point p exists, use not p.infinite (or p.infinite to check that the intersection does not exist). Note that p.defined won't work because as the underlying geometric model for GeoGebra is projective, two lines always intersect.
Accessing selected objects
The selection object allows access to the current selection:
- selection.all returns a list of all selected objects
- selection.filter(<type>) returns a list of all selected objects of type <type>
As a convenience, the following can also be used:
- selection.points
- selection.vectors
- selection.lines
- selection.segments
Event handling
You can use the Events pane in the Python Window to select an object and an event, then type in a script in the editor text area. The target of the object can be referred to as self. E.g. you could write this in the onupdate field of a point:
if self.x < 0: self.caption = "negative x" else: self.caption = "positive x"
As long as the point's label mode is set to 'caption', you will see the point's caption change if you move it across the y-axis.
All variables defined in the Python Script are accessible in event scripts. However, if you want to change the value of a variable, you need to declare it as global - otherwise a new variable local to the event script is created. E.g.
global score score += 1
You can also add event handlers directly by defining the following attributes on elements:
- onupdate
- onadd
- onremove
- onclick
- onrename
the attributes must be set to a function with one argument (which is the target of the event)
E.g.
def paint_blue(pt): pt.color = Color.BLUE geo.A.onclick = paint_blue
Special Methods
- answer = input(<question>) opens a free-text dialog and the (String) response is put in <answer>
- answer = input(<question>, <default answer>) as above, but the dialog is filled in with <default answer> initially
- alert(<text>) shows a message box containing the <text>
- debug(<text>) prints <text> to the Java Console
- command(<text>) evaluate a GeoGebra command and return a list of Elements
>>> command("3x+2y=12") [<a: 2x + 3y = 12>] >>> x, y = 3, 2 >>> r = 4 >>> command('Circle', (x, y), r) [<c: (x - 3)² + (y - 2)² = 16>]
Concurrency in Python
See this page: Jython/Concurrency
Accessing the GeoGebra API
To call GgbAPI, you just need to prepend the call with ggbApplet. (ie the same syntax as from JavaScript)
E.g.
ggbApplet.evalCommand("x^2 + y^2 = 4") ggbApplet.startAnimation()
