File: python.html

package info (click to toggle)
jsxgraph 1.10.1%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 24,804 kB
  • sloc: javascript: 82,299; xml: 5,869; java: 1,072; php: 281; makefile: 184; python: 174; cpp: 76; sh: 12
file content (91 lines) | stat: -rw-r--r-- 3,570 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<html>
    <head>
        <link rel="stylesheet" href="../../distrib/jsxgraph.css" />
        <script src="../../distrib/jsxgraphcore.js"></script>
        <script src="https://pyodide-cdn2.iodide.io/v0.15.0/full/pyodide.js"></script>
    </head>
    <body>
        <div id="box" class="jxgbox" style="width: 700px; height: 700px"></div>

        <script id="init" type="script/python">
            # These scripts don't have to be put into <script> tags, they can
            # also be defined as strings inside JavaScript.
            #
            # Initialize the Python script with imports and constants
            # This initialization takes quite long because it has to download,
            # parse and initialize a few packages. It only needs to be run once
            # so we split the Python script into two parts: init and plot.

            import numpy
            import math
            import matplotlib
            matplotlib.use('Agg')
            from matplotlib.pyplot import *
            from matplotlib.contour import *
            import js

            xs = -5.0
            xe = 5.0
            ys = -5.0
            ye = 5.0
            x, y = numpy.meshgrid(numpy.linspace(xs, xe, 200), numpy.linspace(ys, ye, 200))
        </script>

        <script id="plot" type="script/python">
            # This is the Python script that will be run on every board update

            # Get the coordinates of a JSXGraph point defined in JavaScript
            # and calculate the square of the euclidean distance to the origin
            r = js.window.P.X() ** 2 + js.window.P.Y() ** 2

            # Plot a circle
            z = eval(f"x**2 + y**2 - {r}")
            C = contour(x, y, z, [0])

            # Extract the plot data
            data = ""
            for i in range(0, len(C.collections[0].get_paths())):
                pa = C.collections[0].get_paths()[i].to_polygons()[0]

                for j in range(0,len(pa)):
                    data += f"{pa[j][0]},{pa[j][1]};"

                data += ";"

            data
        </script>
        <script>
            const init = document.getElementById('init').innerText;
            const plot = document.getElementById('plot').innerText;

            const board = JXG.JSXGraph.initBoard('box', {boundingBox: [-5, 5, 5, -5], axis: true});

            // Here we create a point and store it in the window object
            // so we can read its coordinates within the Python plot script
            // (see above)
            window.P = board.create('point', [2, 2]);
            const graph = board.create('curve', [[0], [0]]);

            languagePluginLoader.then(() => {
                pyodide.loadPackage(['matplotlib', 'numpy']).then(() => {
                    pyodide.runPython(init);

                    graph.updateDataArray = function() {
                        // Run the python script and parse the plot data
                        // returned by the plot script.
                        const plotData = pyodide.runPython(plot);
                        const data = plotData
                            .replace(/\n/g, '')
                            .split(';')
                            .map(e => e.split(',').map(f => parseFloat(f)));

                        // Update the curve with th extracted data.
                        this.dataX = data.map(e => e[0]);
                        this.dataY = data.map(e => e[1]);
                    };
                    board.update();
                });
            });
        </script>
    </body>
</html>