Logiciel libre de géométrie, d'analyse et de simulation multiplateforme par Yves Biton

Accueil Tutoriels API Javascript, Python

Programming a figure in Python, even offline

modification vendredi 13 mars 2026.

Toutes les versions de cet article : [English] [Español] [français]



Version 9.5 of MathGraph32 now allows you to program a figure in Python (or in JavaScript) even when you are offline. (You do need to be online the first time, though.)

This will allow fir example iPad users to program a igure in Python, even offline.

To do this, you use the web application version of MathGraph32.

Simply enter the following in your browser’s address bar :
https://app.mathgraph32.org/?loadPython=true&language=eng

It is recommended to save the content of the address bar as a browser bookmark so you can return to it more easily.

You can then write Python code to interact with a MathGraph32 figure (an orthonormal coordinate system by default), as shown below.

Once you have entered your Python code, click the Run button to execute the Python code on the figure.
If you made mistakes, refer to the Execution Output field (bottom left).

Two buttons above allow you to open a Python code file or save your current Python code to a file.

Note that if you leave the page and return later (or if you refresh the page), the Python editor will be filled with the latest version of your code.

You can clear the Python code by clicking the Clear button.

Below, at the bottom right, the Download figure button lets you save the figure as a MathGraph32 file (with the .mgj extension).

The Reset with example 1 button replaces the content of the Python editor with a very simple example of Python code.

The Import button allows you to choose any starting figure in the form of Base64 code.

The Copy figure code button copies the Base64 code of the figure to the clipboard.

The Show figure code button opens a dialog box containing the Base64 code of the figure.

Note that you can force the interface to use a language other than French.

To use English, for example, enter in the browser’s address bar :
https://app.mathgraph32.org/?loadPython=true&language=eng

For Spanish :
https://app.mathgraph32.org/?loadPython=true&language=esp

For German :
https://app.mathgraph32.org/?loadPython=true&language=deu

For Arabic :
https://app.mathgraph32.org/?loadPython=true&language=ara

To try it out, enter in the Python editor the juggler code found at the bottom of this page (after using the Clear button). Then click the Run button, followed by the Start–Stop button on the figure.

Articles about Python on the MathGraph32 website can be found here :
https://www.mathgraph32.org/spip.php?page=recherche&recherche=pythonfr

For JavaScript enthusiasts, you can also program a MathGraph32 figure in JavaScript in the same way : simply enter in the address bar :
https://app.mathgraph32.org/?loadJavascript=true

Below is the Python code for the juggler :

"""
Animation inspired from Vincent Pantaloni in this article (in french) : https://afdm.apmep.fr/rubriques/ouvertures/mathematiques-du-jonglage/
"""

ph = addCalc('ph', '0') # Adds to the MathGraph32 figure a calculation, calculation whose value will be changed in function draw, creating the animation.
n_balls = addCalc('nballs', '5') # Adds to the figure a real calculation xith name nballs. Modifiable but ust be odd and >= 3
nballs = getValue(n_balls) #Returns the current value of MathGraph32 calculation nballs
valph = 0
def draw(): # Function used for the animation, changing the formula of MathGraph32 calculation ph and recalculating and updating all the objects depending on ph
	global valph
	valph += 0.0075
	giveFormulaTo('ph', str(valph))
	updateDependantDisplay(ph) # We recalculate and redraw only the objects depending on calculation ph
	
dimf = getFigDim() # Returns a list containing the dimension of the working wiindow (SVG) in pixels
width = dimf[0]
height = dimf[1]
zoomFig(width/2, height/2, 2) # We apply a zoom of factor 2 on the figure
addTimerButton(draw, 1/60) # Adds a Start - Stop button that will call function draw every 1/60 second
O = getPointByName('O') # We memorize point O , frame origin as a point object (faster to use the object rather than its name in the following code)
setAngleUnity('radian') # We set radian unity on our figure
# Strating creating fixed objects of the figure (objects not depending on ph)
head_0 = addPointXY(0, 2)
setHidden(head_0)
head_radius = 0.7
head = addCircleOr(head_0, head_radius, 'black', '-', 2)
head_0_position = getPointPosition(head_0)
head_base = addPointXY(head_0_position.x, head_0_position.y - head_radius)
setHidden(head_base)

spine_base = addPointXY(0, head_0_position.y - 4)
setHidden(spine_base)
torso = addSegment(head_base, spine_base, 'black', '-', 2)

shoulder_y = head_0_position.y - 1.5
l_shoulder = addPointXY(1.25, shoulder_y, '', 'black', 'O')
r_shoulder = addPointXY(-1.25, shoulder_y, '', "black", 'O')

shoulders = addSegment(l_shoulder, r_shoulder, 'black', '-', 2)
up_arm_0 = addPointXY(0.0, -1.0)
setHidden(up_arm_0)
    
l_arm_ph = addCalc('larmph', 'mod(nballs * ph,1)')
l_arm_th = addCalc('larmth', '2.0 * pi * larmph')

l_up_th = addCalc('lupth', '-0.25 * larmph * sin(larmth)')
v_l_up_arm = addImPointRotation(up_arm_0, O, l_up_th)
setHidden(v_l_up_arm)
l_elbow = addImPointTranslation(v_l_up_arm, O, l_shoulder)

l_forearm_x = addCalc('lforearmx', '-0.75 * cos(larmth)')
l_forearm_y = addCalc('lforearmy', '0.5 * (sin(larmth) - 0.8)')

v_l_forearm = addPointXY(l_forearm_x, l_forearm_y)
setHidden(v_l_forearm)
l_hand = addImPointTranslation(v_l_forearm, O, l_elbow)
mesabsleft = addXMeasure(l_hand, 'masabsleft')
mesordleft = addYMeasure(l_hand, 'masordleft')
l_hand_comp = addCalcComp('lhand', 'masabsleft + i*masordleft')

l_up_arm = addSegment(l_shoulder, l_elbow, 'green', '-', 2)
l_forearm = addSegment(l_elbow, l_hand, 'green', '-', 2)

r_arm_ph = addCalc('rarmph', 'mod(larmph + 0.5, 1)')
r_arm_th = addCalc('rarmth', '2.0 * pi * rarmph')

r_up_th = addCalc('rupth', '0.25 * rarmph * sin(rarmth)')

v_r_up_arm = addImPointRotation(up_arm_0, O, r_up_th)
setHidden(v_r_up_arm)
r_elbow = addImPointTranslation(v_r_up_arm, O, r_shoulder)

r_forearm_x = addCalc('rforearmx', '0.75 * cos(rarmth)')
r_forearm_y = addCalc('rforearmy', '0.5 * (sin(rarmth) - 0.8)')
v_r_forearm = addPointXY(r_forearm_x, r_forearm_y)
setHidden(v_r_forearm)
r_hand = addImPointTranslation(v_r_forearm, O, r_elbow)
mesabsright = addXMeasure(r_hand, 'mesabsright')
mesordright = addYMeasure(r_hand, 'mesordright')
r_hand_comp = addCalcComp('rhand', 'mesabsright+i*mesordright')
r_up_arm = addSegment(r_shoulder, r_elbow, 'red', '-', 2)
r_forearm = addSegment(r_elbow, r_hand, 'red', '-', 2)
# Fin de la création des objest fixes de la figure (qui ne dépendent pas de h)

ball_colors = ["blue", "green", "red", "#ffbf00", "cyan"]

# In this function, MathGraph3n calculation objects must be assigned names depending  on i, because otherwise we will have errors of same name assigned to several calculations
def make_ball(i):
	stri = str(i)
	j = 'j' + stri # Name of the calculation that represents the current i value in the following MathGraph32 calculations
	addCalc(j, stri)
	ballph = 'ballph' + stri # Nom de calcul dans mtg32
	ball_ph = addCalc(ballph, f"mod(2.0 * (ph * nballs + {j}),nballs * 2)") 
	airph = 'airph' + stri # Calculation name in mtg32
	# f followed by " is used to insert in  string between "" the content of variables with name inside of brackets. So {j} insert the content of j string variable in the string
	air_ph = addCalc(airph, f"mod({ballph}, nballs) / (nballs - 1)")
	airltorx = 'airltorx' + stri  # Nom de calcul dans mtg32
	air_l_to_r_x = addCalc(airltorx, f"0.5 - {airph} * 2.5")
	airrtolx = 'airrtolx' + stri # Nom de calcul dans mtg32
	air_r_to_l_x = addCalc(airrtolx, f"-0.5 + {airph} * 2.5")
	airy = 'airy' + stri # Nom de calcul dans mtg32
	air_y = addCalc(airy, f"2 + 1.0 - 15.0 * ({airph} - 0.5)^2")
	airltor = 'airltor' + stri # Nom de calcul complexe dans mtg32
	air_l_to_r = addCalcComp(airltor, f"{airltorx}+i*{airy}")
	airrtol = 'airrtol' + stri # Nom de calcul complexe dans mtg32
	air_r_to_l = addCalcComp(airrtol, f"{airrtolx}+i*{airy}")
	# Here under we define a complex formula vald for MathGraph32 (if we  want our figure to be dynamic we must not use Python if condition)
	forcalc = f"if({ballph} <= nballs - 1, {airltor}, if({ballph} <= nballs ,rhand, if({ballph} <= 2*nballs - 1,{airrtol}, lhand)))"

	color = ball_colors[i % 5]
	point = addPointZ(f"{forcalc}", '') # The point is defined by its complex affix given bu formula forcalc
	setHidden(point)
	circle = addCircleOr(point, 0.15, 'black', '-', 2)
	return addSurface(circle, color, 'fill')

for i in range(nballs):
    make_ball(i)