├── CODEOWNERS ├── Images └── Map.png ├── LICENSE ├── .github └── workflows │ └── manual.yml ├── README.md ├── main.cpp ├── solution.cpp ├── Data ├── poses.txt └── measurement.txt └── src └── matplotlibcpp.h /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @udacity/active-public-content -------------------------------------------------------------------------------- /Images/Map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/RoboND-OccupancyGridMappingAlgorithm/HEAD/Images/Map.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Udacity 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/manual.yml: -------------------------------------------------------------------------------- 1 | # Workflow to ensure whenever a Github PR is submitted, 2 | # a JIRA ticket gets created automatically. 3 | name: Manual Workflow 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on pull request events but only for the master branch 8 | pull_request_target: 9 | types: [opened, reopened] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | jobs: 15 | test-transition-issue: 16 | name: Convert Github Issue to Jira Issue 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@master 21 | 22 | - name: Login 23 | uses: atlassian/gajira-login@master 24 | env: 25 | JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} 26 | JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} 27 | JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} 28 | 29 | - name: Create NEW JIRA ticket 30 | id: create 31 | uses: atlassian/gajira-create@master 32 | with: 33 | project: CONUPDATE 34 | issuetype: Task 35 | summary: | 36 | Github PR [Assign the ND component] | Repo: ${{ github.repository }} | PR# ${{github.event.number}} 37 | description: | 38 | Repo link: https://github.com/${{ github.repository }} 39 | PR no. ${{ github.event.pull_request.number }} 40 | PR title: ${{ github.event.pull_request.title }} 41 | PR description: ${{ github.event.pull_request.description }} 42 | In addition, please resolve other issues, if any. 43 | fields: '{"components": [{"name":"Github PR"}], "customfield_16449":"https://classroom.udacity.com/", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' 44 | 45 | - name: Log created issue 46 | run: echo "Issue ${{ steps.create.outputs.issue }} was created" 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Udacity - Robotics NanoDegree Program](https://s3-us-west-1.amazonaws.com/udacity-robotics/Extra+Images/RoboND_flag.png)](https://www.udacity.com/robotics) 2 | 3 | # RoboND-OccupancyGridMappingAlgorithm 4 | You will visualize the mapped environment through the generated image 5 | 6 | ### Instruction 7 | Code the visualization function which will plot the state of each grid cell using the matplotlib python library 8 | ``` C++ 9 | void visualization() 10 | { 11 | //TODO: Initialize a plot named Map of size 300x150 12 | 13 | //TODO: Loop over the log odds values of the cells and plot each cell state. 14 | //Unkown state: green color, occupied state: black color, and free state: red color 15 | 16 | //TODO: Save the image and close the plot 17 | } 18 | ``` 19 | Here are some helpful commands you can use to generate plots with the `matplotlib` library: 20 | * *Set Title*: `plt::title("Your Title");` 21 | * *Set Limits*: `plt::xlim(x-axis lower limit, x-axis upper limit );` 22 | * *Plot Data*:`plt::plot({ x-value }, { y-value }, "Color and Shape");` 23 | * *Save Plot*: `plt::save("File name and directory")`; 24 | * *Close Plot*: `plt::clf()`; 25 | 26 | Check out this [link](https://github.com/lava/matplotlib-cpp) for more information on the `matplotlib` C++ library. For information regarding the plot color and shape refer to the LineSpec and LineColor section of the [MATLAB](https://www.mathworks.com/help/matlab/ref/plot.html?requestedDomain=true) documentation. 27 | 28 | ### Compiling 29 | ```sh 30 | $ cd /home/workspace/ 31 | $ git clone https://github.com/udacity/RoboND-OccupancyGridMappingAlgorithm 32 | $ cd RoboND-OccupancyGridMappingAlgorithm/ 33 | $ rm -rf Images/* #Delete the folder content and not the folder itself! 34 | $ g++ main.cpp -o app -std=c++11 -I/usr/include/python2.7 -lpython2.7 35 | ``` 36 | 37 | ### Running 38 | ```sh 39 | $ ./app 40 | ``` 41 | 42 | Now, wait for the program to generate the map! 43 | 44 | ### Generated Map 45 | 46 | ![alt text](Images/Map.png) 47 | 48 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "src/matplotlibcpp.h" //Graph Library 5 | 6 | using namespace std; 7 | namespace plt = matplotlibcpp; 8 | 9 | // Defining Map Characteristics 10 | double Zmax = 5000, Zmin = 170; 11 | double l0 = 0, locc = 0.4, lfree = -0.4; 12 | double gridWidth = 100, gridHeight = 100; 13 | double mapWidth = 30000, mapHeight = 15000; 14 | double robotXOffset = mapWidth / 5, robotYOffset = mapHeight / 3; 15 | vector > l(mapWidth / gridWidth, vector(mapHeight / gridHeight)); 16 | 17 | double inverseSensorModel(double x, double y, double theta, double xi, double yi, double sensorData[]) 18 | { 19 | // Defining Sensor Characteristics 20 | double Zk, thetaK, sensorTheta; 21 | double minDelta = -1; 22 | double alpha = 200, beta = 20; 23 | 24 | //******************Compute r and phi**********************// 25 | double r = sqrt(pow(xi - x, 2) + pow(yi - y, 2)); 26 | double phi = atan2(yi - y, xi - x) - theta; 27 | 28 | //Scaling Measurement to [-90 -37.5 -22.5 -7.5 7.5 22.5 37.5 90] 29 | for (int i = 0; i < 8; i++) { 30 | if (i == 0) { 31 | sensorTheta = -90 * (M_PI / 180); 32 | } 33 | else if (i == 1) { 34 | sensorTheta = -37.5 * (M_PI / 180); 35 | } 36 | else if (i == 6) { 37 | sensorTheta = 37.5 * (M_PI / 180); 38 | } 39 | else if (i == 7) { 40 | sensorTheta = 90 * (M_PI / 180); 41 | } 42 | else { 43 | sensorTheta = (-37.5 + (i - 1) * 15) * (M_PI / 180); 44 | } 45 | 46 | if (fabs(phi - sensorTheta) < minDelta || minDelta == -1) { 47 | Zk = sensorData[i]; 48 | thetaK = sensorTheta; 49 | minDelta = fabs(phi - sensorTheta); 50 | } 51 | } 52 | 53 | //******************Evaluate the three cases**********************// 54 | if (r > min((double)Zmax, Zk + alpha / 2) || fabs(phi - thetaK) > beta / 2 || Zk > Zmax || Zk < Zmin) { 55 | return l0; 56 | } 57 | else if (Zk < Zmax && fabs(r - Zk) < alpha / 2) { 58 | return locc; 59 | } 60 | else if (r <= Zk) { 61 | return lfree; 62 | } 63 | } 64 | 65 | void occupancyGridMapping(double Robotx, double Roboty, double Robottheta, double sensorData[]) 66 | { 67 | //******************Code the Occupancy Grid Mapping Algorithm**********************// 68 | for (int x = 0; x < mapWidth / gridWidth; x++) { 69 | for (int y = 0; y < mapHeight / gridHeight; y++) { 70 | double xi = x * gridWidth + gridWidth / 2 - robotXOffset; 71 | double yi = -(y * gridHeight + gridHeight / 2) + robotYOffset; 72 | if (sqrt(pow(xi - Robotx, 2) + pow(yi - Roboty, 2)) <= Zmax) { 73 | l[x][y] = l[x][y] + inverseSensorModel(Robotx, Roboty, Robottheta, xi, yi, sensorData) - l0; 74 | } 75 | } 76 | } 77 | } 78 | 79 | void visualization() 80 | { 81 | //TODO: Initialize a plot named Map of size 300x150 82 | 83 | //TODO: Loop over the log odds values of the cells and plot each cell state. 84 | //Unkown state: green color, occupied state: black color, and free state: red color 85 | 86 | //TODO: Save the image and close the plot 87 | } 88 | 89 | int main() 90 | { 91 | double timeStamp; 92 | double measurementData[8]; 93 | double robotX, robotY, robotTheta; 94 | 95 | FILE* posesFile = fopen("Data/poses.txt", "r"); 96 | FILE* measurementFile = fopen("Data/measurement.txt", "r"); 97 | 98 | // Scanning the files and retrieving measurement and poses at each timestamp 99 | while (fscanf(posesFile, "%lf %lf %lf %lf", &timeStamp, &robotX, &robotY, &robotTheta) != EOF) { 100 | fscanf(measurementFile, "%lf", &timeStamp); 101 | for (int i = 0; i < 8; i++) { 102 | fscanf(measurementFile, "%lf", &measurementData[i]); 103 | } 104 | occupancyGridMapping(robotX, robotY, (robotTheta / 10) * (M_PI / 180), measurementData); 105 | } 106 | 107 | // Visualize the map at the final step 108 | cout << "Wait for the image to generate" << endl; 109 | visualization(); 110 | cout << "Done!" << endl; 111 | 112 | return 0; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "src/matplotlibcpp.h" //Graph Library 5 | 6 | using namespace std; 7 | namespace plt = matplotlibcpp; 8 | 9 | // Sensor characteristic: Min and Max ranges of the beams 10 | double Zmax = 5000, Zmin = 170; 11 | // Defining free cells(lfree), occupied cells(locc), unknown cells(l0) log odds values 12 | double l0 = 0, locc = 0.4, lfree = -0.4; 13 | // Grid dimensions 14 | double gridWidth = 100, gridHeight = 100; 15 | // Map dimensions 16 | double mapWidth = 30000, mapHeight = 15000; 17 | // Robot size with respect to the map 18 | double robotXOffset = mapWidth / 5, robotYOffset = mapHeight / 3; 19 | // Defining an l vector to store the log odds values of each cell 20 | vector< vector > l(mapWidth/gridWidth, vector(mapHeight/gridHeight)); 21 | 22 | double inverseSensorModel(double x, double y, double theta, double xi, double yi, double sensorData[]) 23 | { 24 | // Defining Sensor Characteristics 25 | double Zk, thetaK, sensorTheta; 26 | double minDelta = -1; 27 | double alpha = 200, beta = 20; 28 | 29 | //******************Compute r and phi**********************// 30 | double r = sqrt(pow(xi - x, 2) + pow(yi - y, 2)); 31 | double phi = atan2(yi - y, xi - x) - theta; 32 | 33 | //Scaling Measurement to [-90 -37.5 -22.5 -7.5 7.5 22.5 37.5 90] 34 | for (int i = 0; i < 8; i++) { 35 | if (i == 0) { 36 | sensorTheta = -90 * (M_PI / 180); 37 | } 38 | else if (i == 1) { 39 | sensorTheta = -37.5 * (M_PI / 180); 40 | } 41 | else if (i == 6) { 42 | sensorTheta = 37.5 * (M_PI / 180); 43 | } 44 | else if (i == 7) { 45 | sensorTheta = 90 * (M_PI / 180); 46 | } 47 | else { 48 | sensorTheta = (-37.5 + (i - 1) * 15) * (M_PI / 180); 49 | } 50 | 51 | if (fabs(phi - sensorTheta) < minDelta || minDelta == -1) { 52 | Zk = sensorData[i]; 53 | thetaK = sensorTheta; 54 | minDelta = fabs(phi - sensorTheta); 55 | } 56 | } 57 | 58 | //******************Evaluate the three cases**********************// 59 | if (r > min((double)Zmax, Zk + alpha / 2) || fabs(phi - thetaK) > beta / 2 || Zk > Zmax || Zk < Zmin) { 60 | return l0; 61 | } 62 | else if (Zk < Zmax && fabs(r - Zk) < alpha / 2) { 63 | return locc; 64 | } 65 | else if (r <= Zk) { 66 | return lfree; 67 | } 68 | } 69 | 70 | void occupancyGridMapping(double Robotx, double Roboty, double Robottheta, double sensorData[]) 71 | { 72 | //******************Code the Occupancy Grid Mapping Algorithm**********************// 73 | for (int x = 0; x < mapWidth / gridWidth; x++) { 74 | for (int y = 0; y < mapHeight / gridHeight; y++) { 75 | double xi = x * gridWidth + gridWidth / 2 - robotXOffset; 76 | double yi = -(y * gridHeight + gridHeight / 2) + robotYOffset; 77 | if (sqrt(pow(xi - Robotx, 2) + pow(yi - Roboty, 2)) <= Zmax) { 78 | l[x][y] = l[x][y] + inverseSensorModel(Robotx, Roboty, Robottheta, xi, yi, sensorData) - l0; 79 | } 80 | } 81 | } 82 | } 83 | 84 | void visualization() 85 | { 86 | //Graph Format 87 | plt::title("Map"); 88 | plt::xlim(0, (int)(mapWidth / gridWidth)); 89 | plt::ylim(0, (int)(mapHeight / gridHeight)); 90 | 91 | // Draw every grid of the map: 92 | for (double x = 0; x < mapWidth / gridWidth; x++) { 93 | cout << "Remaining Rows= " << mapWidth / gridWidth - x << endl; 94 | for (double y = 0; y < mapHeight / gridHeight; y++) { 95 | if (l[x][y] == 0) { //Green unkown state 96 | plt::plot({ x }, { y }, "g."); 97 | } 98 | else if (l[x][y] > 0) { //Black occupied state 99 | plt::plot({ x }, { y }, "k."); 100 | } 101 | else { //Red free state 102 | plt::plot({ x }, { y }, "r."); 103 | } 104 | } 105 | } 106 | 107 | //Save the image and close the plot 108 | plt::save("./Images/Map.png"); 109 | plt::clf(); 110 | } 111 | 112 | int main() 113 | { 114 | double timeStamp; 115 | double measurementData[8]; 116 | double robotX, robotY, robotTheta; 117 | 118 | FILE* posesFile = fopen("Data/poses.txt", "r"); 119 | FILE* measurementFile = fopen("Data/measurement.txt", "r"); 120 | 121 | // Scanning the files and retrieving measurement and poses at each timestamp 122 | while (fscanf(posesFile, "%lf %lf %lf %lf", &timeStamp, &robotX, &robotY, &robotTheta) != EOF) { 123 | fscanf(measurementFile, "%lf", &timeStamp); 124 | for (int i = 0; i < 8; i++) { 125 | fscanf(measurementFile, "%lf", &measurementData[i]); 126 | } 127 | occupancyGridMapping(robotX, robotY, (robotTheta / 10) * (M_PI / 180), measurementData); 128 | } 129 | 130 | // Visualize the map at the final step 131 | cout << "Wait for the image to generate" << endl; 132 | visualization(); 133 | cout << "Done!" << endl; 134 | 135 | return 0; 136 | } 137 | 138 | -------------------------------------------------------------------------------- /Data/poses.txt: -------------------------------------------------------------------------------- 1 | 1686487 0 0 0 2 | 1686915 0 0 0 3 | 1687132 0 0 0 4 | 1687555 0 0 0 5 | 1687770 0 0 0 6 | 1688194 0 0 0 7 | 1688411 0 0 0 8 | 1688627 0 0 0 9 | 1688843 0 0 0 10 | 1689054 0 0 0 11 | 1689273 0 0 0 12 | 1689479 0 0 0 13 | 1689698 0 0 0 14 | 1689906 0 0 0 15 | 1690116 0 0 0 16 | 1690338 0 0 0 17 | 1690549 0 0 0 18 | 1690759 0 0 0 19 | 1690970 0 0 0 20 | 1691192 0 0 0 21 | 1691400 0 0 0 22 | 1691822 0 0 0 23 | 1692039 0 0 0 24 | 1692258 0 0 0 25 | 1692470 0 0 0 26 | 1692681 0 0 0 27 | 1692900 0 0 0 28 | 1693105 0 0 0 29 | 1693319 0 0 0 30 | 1693530 0 0 0 31 | 1693751 0 0 0 32 | 1693959 0 0 0 33 | 1694178 0 0 0 34 | 1694387 0 0 0 35 | 1694811 0 0 0 36 | 1695028 0 0 0 37 | 1695243 0 0 0 38 | 1695451 0 0 0 39 | 1695665 0 0 0 40 | 1695888 0 0 0 41 | 1696098 0 0 0 42 | 1696314 0 0 0 43 | 1696524 0 0 0 44 | 1696740 0 0 0 45 | 1696952 0 0 0 46 | 1697168 0 0 0 47 | 1697377 0 0 0 48 | 1697590 10 0 3600 49 | 1697802 33 0 0 50 | 1698013 71 0 0 51 | 1698233 122 0 1 52 | 1698442 184 0 0 53 | 1698652 249 0 0 54 | 1698868 379 0 0 55 | 1699087 445 0 0 56 | 1699293 511 0 3600 57 | 1699515 574 0 3599 58 | 1699721 636 0 3599 59 | 1699939 701 0 3597 60 | 1700150 767 0 3596 61 | 1700362 829 0 3595 62 | 1700578 888 -1 3595 63 | 1700788 951 -1 3594 64 | 1701000 1015 -2 3594 65 | 1701218 1077 -2 3594 66 | 1701435 1142 -3 3593 67 | 1701645 1208 -4 3592 68 | 1701857 1274 -5 3592 69 | 1702070 1340 -6 3592 70 | 1702289 1470 -7 3591 71 | 1702500 1530 -8 3591 72 | 1702713 1581 -10 3570 73 | 1702928 1624 -13 3549 74 | 1703144 1675 -18 3547 75 | 1703349 1733 -23 3549 76 | 1703566 1792 -28 3550 77 | 1703775 1855 -34 3551 78 | 1703990 1918 -39 3553 79 | 1704210 1981 -44 3555 80 | 1704423 2039 -49 3556 81 | 1704637 2103 -54 3557 82 | 1704845 2167 -58 3558 83 | 1705065 2223 -62 3562 84 | 1705272 2283 -66 3563 85 | 1705488 2411 -74 3567 86 | 1705695 2477 -78 3569 87 | 1705912 2540 -81 3570 88 | 1706122 2601 -84 3572 89 | 1706339 2668 -87 3574 90 | 1706549 2731 -90 3577 91 | 1706767 2792 -92 3578 92 | 1706977 2857 -95 3580 93 | 1707189 2919 -97 3582 94 | 1707409 2982 -99 3584 95 | 1707616 3039 -100 3586 96 | 1707834 3097 -102 3585 97 | 1708047 3161 -103 3585 98 | 1708261 3216 -105 3582 99 | 1708478 3338 -109 3581 100 | 1708688 3401 -111 3581 101 | 1708902 3468 -113 3580 102 | 1709118 3531 -115 3581 103 | 1709329 3595 -117 3583 104 | 1709540 3657 -119 3584 105 | 1709759 3718 -121 3585 106 | 1709968 3781 -122 3586 107 | 1710181 3845 -124 3588 108 | 1710391 3906 -125 3590 109 | 1710611 3970 -126 3592 110 | 1710820 4029 -127 3592 111 | 1711032 4080 -127 3592 112 | 1711247 4136 -128 3592 113 | 1711464 4202 -129 3591 114 | 1711882 4388 -132 3590 115 | 1712100 4451 -134 3589 116 | 1712317 4514 -135 3588 117 | 1712525 4579 -136 3587 118 | 1712739 4646 -138 3588 119 | 1712952 4711 -139 3589 120 | 1713170 4772 -140 3591 121 | 1713385 4836 -141 3592 122 | 1713599 4900 -142 3592 123 | 1713813 4957 -143 3593 124 | 1714021 5010 -143 3592 125 | 1714235 5068 -144 3591 126 | 1714452 5133 -145 3590 127 | 1714657 5199 -147 3589 128 | 1714872 5329 -150 3586 129 | 1715087 5395 -151 3585 130 | 1715303 5460 -153 3584 131 | 1715516 5518 -155 3583 132 | 1715731 5576 -156 3582 133 | 1715939 5639 -159 3581 134 | 1716156 5704 -161 3580 135 | 1716366 5768 -163 3579 136 | 1716584 5831 -165 3579 137 | 1716800 5894 -167 3581 138 | 1717008 5957 -170 3582 139 | 1717218 6022 -172 3583 140 | 1717436 6081 -173 3583 141 | 1717655 6143 -175 3585 142 | 1718071 6322 -180 3587 143 | 1718293 6383 -181 3589 144 | 1718503 6444 -182 3589 145 | 1718716 6507 -183 3590 146 | 1718928 6571 -184 3592 147 | 1719139 6637 -185 3592 148 | 1719359 6699 -186 3593 149 | 1719567 6760 -187 3594 150 | 1719787 6825 -187 3594 151 | 1719994 6890 -188 3593 152 | 1720215 6953 -189 3592 153 | 1720429 7013 -190 3591 154 | 1720641 7077 -191 3591 155 | 1720852 7143 -192 3590 156 | 1721063 7206 -193 3589 157 | 1721275 7336 -196 3587 158 | 1721699 7462 -199 3586 159 | 1721921 7528 -200 3585 160 | 1722339 7658 -204 3584 161 | 1722561 7721 -206 3585 162 | 1722769 7785 -207 3586 163 | 1722982 7849 -209 3586 164 | 1723203 7914 -210 3586 165 | 1723416 7978 -212 3585 166 | 1723627 8042 -214 3585 167 | 1723839 8104 -215 3584 168 | 1724051 8168 -217 3583 169 | 1724271 8297 -221 3581 170 | 1724480 8362 -224 3580 171 | 1724696 8425 -226 3580 172 | 1724905 8485 -228 3584 173 | 1725117 8540 -229 3591 174 | 1725337 8595 -230 0 175 | 1725544 8648 -229 12 176 | 1725755 8697 -227 28 177 | 1725975 8740 -224 42 178 | 1726185 8783 -221 56 179 | 1726403 8832 -215 70 180 | 1726612 8875 -209 87 181 | 1726824 8920 -202 103 182 | 1727247 9026 -180 118 183 | 1727467 9148 -155 112 184 | 1727680 9208 -143 106 185 | 1727890 9268 -132 101 186 | 1728104 9328 -122 94 187 | 1728322 9391 -111 89 188 | 1728531 9455 -102 82 189 | 1728748 9517 -93 77 190 | 1728962 9578 -85 75 191 | 1729173 9637 -77 72 192 | 1729390 9700 -69 72 193 | 1729808 9821 -54 71 194 | 1730032 9887 -45 69 195 | 1730238 9952 -37 68 196 | 1730456 10018 -29 68 197 | 1730664 10083 -22 66 198 | 1730878 10215 -7 61 199 | 1731094 10278 0 58 200 | 1731307 10341 6 57 201 | 1731521 10407 12 56 202 | 1731731 10473 19 55 203 | 1731943 10539 25 54 204 | 1732160 10605 31 53 205 | 1732378 10671 38 51 206 | 1732589 10738 44 51 207 | 1732800 10804 50 50 208 | 1733019 10870 55 50 209 | 1733232 10936 61 49 210 | 1733443 11002 67 48 211 | 1733651 11068 73 47 212 | 1734076 11264 88 43 213 | 1734300 11329 94 43 214 | 1734717 11461 103 41 215 | 1734932 11527 108 41 216 | 1735146 11593 113 39 217 | 1735364 11658 118 38 218 | 1735577 11724 122 36 219 | 1735788 11790 126 36 220 | 1736006 11854 130 34 221 | 1736214 11920 134 33 222 | 1736425 11986 138 32 223 | 1736647 12052 142 31 224 | 1736854 12118 145 30 225 | 1737069 12184 149 29 226 | 1737280 12315 156 28 227 | 1737495 12381 159 27 228 | 1737708 12447 162 26 229 | 1737924 12514 165 25 230 | 1738140 12580 168 25 231 | 1738350 12646 171 24 232 | 1738567 12712 174 24 233 | 1738775 12777 177 23 234 | 1738986 12843 180 22 235 | 1739208 12909 182 21 236 | 1739419 12974 185 21 237 | 1739631 13040 187 21 238 | 1739843 13105 190 20 239 | 1740058 13170 192 19 240 | 1740271 13299 196 17 241 | 1740483 13364 198 16 242 | 1740693 13429 200 17 243 | 1740912 13493 202 16 244 | 1741123 13559 204 15 245 | 1741338 13624 206 14 246 | 1741554 13689 208 14 247 | 1741763 13756 209 14 248 | 1741976 13822 211 13 249 | 1742188 13887 213 12 250 | 1742405 13953 214 11 251 | 1742615 14019 215 11 252 | 1742834 14084 217 10 253 | 1743043 14150 218 9 254 | 1743254 14216 219 8 255 | 1743467 14281 220 9 256 | 1743688 14408 223 12 257 | 1743896 14468 224 0 258 | 1744112 14516 223 3572 259 | 1744329 14556 220 3542 260 | 1744535 14593 215 3512 261 | 1744757 14631 208 3481 262 | 1744967 14668 199 3450 263 | 1745180 14707 187 3422 264 | 1745392 14750 173 3396 265 | 1745605 14789 157 3368 266 | 1745822 14827 139 3344 267 | 1746031 14867 119 3321 268 | 1746251 14906 97 3298 269 | 1746459 14946 73 3275 270 | 1746677 15023 20 3235 271 | 1746887 15062 -9 3217 272 | 1747096 15099 -40 3198 273 | 1747313 15139 -75 3181 274 | 1747522 15180 -112 3165 275 | 1747736 15220 -152 3150 276 | 1747952 15259 -191 3136 277 | 1748171 15298 -233 3123 278 | 1748379 15334 -274 3109 279 | 1748598 15366 -312 3097 280 | 1748805 15401 -354 3083 281 | 1749024 15436 -401 3072 282 | 1749234 15472 -448 3060 283 | 1749442 15503 -493 3048 284 | 1749655 15536 -542 3038 285 | 1749872 15599 -639 3018 286 | 1750093 15632 -694 3008 287 | 1750300 15662 -746 2998 288 | 1750517 15693 -800 2990 289 | 1750727 15723 -855 2981 290 | 1750945 15751 -909 2974 291 | 1751156 15779 -963 2967 292 | 1751369 15805 -1016 2960 293 | 1751579 15831 -1071 2954 294 | 1751799 15857 -1127 2948 295 | 1752004 15883 -1183 2942 296 | 1752218 15908 -1240 2938 297 | 1752430 15935 -1301 2938 298 | 1752653 15961 -1361 2932 299 | 1752863 15987 -1422 2927 300 | 1753078 16036 -1542 2918 301 | 1753291 16058 -1599 2913 302 | 1753497 16080 -1656 2908 303 | 1753712 16102 -1715 2902 304 | 1753931 16123 -1773 2897 305 | 1754147 16143 -1830 2893 306 | 1754359 16163 -1888 2887 307 | 1754564 16182 -1945 2883 308 | 1754779 16201 -2004 2878 309 | 1754997 16219 -2062 2872 310 | 1755208 16237 -2119 2868 311 | 1755418 16254 -2178 2863 312 | 1755633 16271 -2238 2858 313 | 1755846 16288 -2298 2853 314 | 1756067 16304 -2358 2850 315 | 1756278 16336 -2478 2843 316 | 1756488 16351 -2539 2840 317 | 1756702 16366 -2600 2835 318 | 1756913 16380 -2660 2830 319 | 1757128 16393 -2719 2826 320 | 1757348 16406 -2779 2821 321 | 1757559 16419 -2841 2814 322 | 1757771 16431 -2902 2810 323 | 1757985 16443 -2965 2805 324 | 1758404 16463 -3087 2792 325 | 1758623 16472 -3148 2785 326 | 1759045 16490 -3272 2776 327 | 1759260 16497 -3332 2775 328 | 1759475 16514 -3460 2777 329 | 1759692 16523 -3526 2778 330 | 1759904 16532 -3591 2778 331 | 1760117 16540 -3654 2779 332 | 1760331 16549 -3716 2780 333 | 1760544 16558 -3780 2783 334 | 1760754 16567 -3844 2785 335 | 1761179 16586 -3969 2788 336 | 1761606 16606 -4098 2792 337 | 1761821 16616 -4162 2793 338 | 1762041 16626 -4224 2789 339 | 1762253 16634 -4281 2783 340 | 1762463 16652 -4408 2785 341 | 1762886 16669 -4527 2771 342 | 1763108 16675 -4586 2764 343 | 1763315 16682 -4647 2755 344 | 1763530 16687 -4708 2749 345 | 1763742 16692 -4769 2742 346 | 1763960 16696 -4830 2736 347 | 1764170 16699 -4889 2727 348 | 1764388 16701 -4948 2720 349 | 1764603 16703 -5011 2718 350 | 1764811 16705 -5076 2716 351 | 1765025 16706 -5139 2713 352 | 1765242 16707 -5202 2714 353 | 1765450 16709 -5267 2716 354 | 1765669 16712 -5391 2719 355 | 1765881 16714 -5455 2720 356 | 1766097 16717 -5516 2721 357 | 1766308 16719 -5581 2723 358 | 1766518 16722 -5645 2725 359 | 1766735 16724 -5707 2727 360 | 1766948 16727 -5772 2727 361 | 1767161 16730 -5839 2726 362 | 1767372 16733 -5903 2726 363 | 1767582 16735 -5964 2727 364 | 1767796 16738 -6029 2726 365 | 1768222 16744 -6159 2728 366 | 1768443 16747 -6223 2730 367 | 1768861 16756 -6419 2730 368 | 1769085 16759 -6483 2730 369 | 1769298 16763 -6549 2729 370 | 1769504 16766 -6613 2730 371 | 1769724 16769 -6679 2730 372 | 1769933 16772 -6745 2730 373 | 1770148 16775 -6809 2730 374 | 1770361 16779 -6876 2729 375 | 1770569 16782 -6941 2729 376 | 1770787 16785 -7005 2731 377 | 1771003 16788 -7065 2734 378 | 1771213 16791 -7123 2738 379 | 1771427 16795 -7185 2739 380 | 1771643 16800 -7248 2740 381 | 1771852 16804 -7310 2741 382 | 1772067 16813 -7442 2741 383 | 1772282 16817 -7504 2740 384 | 1772500 16821 -7567 2741 385 | 1772710 16826 -7632 2739 386 | 1772921 16830 -7696 2737 387 | 1773131 16834 -7760 2735 388 | 1773344 16838 -7827 2734 389 | 1773567 16842 -7893 2734 390 | 1773777 16845 -7959 2734 391 | 1773986 16849 -8025 2733 392 | 1774197 16853 -8091 2732 393 | 1774410 16856 -8157 2732 394 | 1774632 16860 -8222 2731 395 | 1774838 16863 -8288 2730 396 | 1775264 16873 -8482 2728 397 | 1775486 16876 -8547 2727 398 | 1775696 16879 -8613 2727 399 | 1775904 16882 -8678 2727 400 | 1776119 16884 -8742 2725 401 | 1776339 16886 -8802 2720 402 | 1776545 16888 -8859 2713 403 | 1776760 16889 -8916 2705 404 | 1776979 16889 -8968 2695 405 | 1777188 16888 -9018 2683 406 | 1777405 16885 -9068 2667 407 | 1777618 16881 -9117 2649 408 | 1777829 16876 -9167 2632 409 | 1778252 16854 -9340 2630 410 | 1778473 16849 -9384 2630 411 | 1778892 16842 -9433 2630 412 | 1779109 16842 -9437 2631 413 | 1779324 16842 -9437 2631 414 | -------------------------------------------------------------------------------- /Data/measurement.txt: -------------------------------------------------------------------------------- 1 | 1686487 5110 5110 2320 2360 5110 5110 2160 1190 2 | 1686915 5110 5110 2320 2360 5110 5110 2160 1190 3 | 1687132 5110 5110 2320 2360 5110 5110 2160 1190 4 | 1687555 5110 5110 2320 2360 5110 5110 2160 1190 5 | 1687770 5110 5110 2320 2360 5110 5110 2160 1190 6 | 1688194 5110 5110 2320 2360 5110 5110 2170 1190 7 | 1688411 5110 5110 2320 2360 5110 5110 2160 1180 8 | 1688627 5110 5110 1040 2360 5110 5110 2160 1180 9 | 1688843 5110 5110 1040 2360 5110 5110 2170 1190 10 | 1689054 5110 5110 2320 2370 5110 5110 2170 1190 11 | 1689273 5110 5110 2320 2360 5110 5110 2160 1180 12 | 1689479 5110 5110 2320 2360 5110 5110 2170 1190 13 | 1689698 5110 5110 2320 2370 5110 5110 2170 1190 14 | 1689906 5110 5110 2320 2370 5110 5110 2160 1180 15 | 1690116 5110 5110 2320 2360 5110 5110 2160 1180 16 | 1690338 5110 5110 2320 2360 5110 5110 2160 1190 17 | 1690549 5110 5110 2320 2360 5110 5110 2160 1190 18 | 1690759 5110 5110 2320 2360 5110 5110 2160 1190 19 | 1690970 5110 5110 2320 2350 5110 5110 2160 1190 20 | 1691192 5110 5110 2320 2350 5110 5110 2160 1190 21 | 1691400 5110 5110 2320 2360 5110 5110 2160 1190 22 | 1691822 5110 5110 2320 2350 5110 5110 2160 1190 23 | 1692039 5110 5110 2320 2350 5110 5110 2160 1190 24 | 1692258 5110 5110 2320 400 5110 5110 2160 1190 25 | 1692470 5110 5110 2320 2360 5110 5110 2170 1190 26 | 1692681 5110 5110 2320 2360 5110 5110 2160 1180 27 | 1692900 5110 5110 2320 2350 5110 5110 2160 1180 28 | 1693105 5110 5110 2320 2350 5110 5110 2170 1190 29 | 1693319 5110 5110 2320 2360 5110 5110 2160 1190 30 | 1693530 5110 5110 2320 2360 5110 5110 2160 1180 31 | 1693751 5110 5110 2320 2360 5110 5110 2170 1180 32 | 1693959 5110 5110 2320 2360 5110 5110 2170 1190 33 | 1694178 5110 5110 2320 2360 5110 5110 2160 1190 34 | 1694387 5110 5110 2320 2360 5110 5110 2160 1190 35 | 1694811 5110 5110 2320 2350 5110 5110 2160 1190 36 | 1695028 5110 5110 2320 2360 5110 5110 2160 1190 37 | 1695243 5110 5110 2320 2360 5110 5110 2160 1190 38 | 1695451 5110 5110 2320 2360 5110 5110 2160 1190 39 | 1695665 5110 5110 2320 2360 5110 5110 2170 1190 40 | 1695888 5110 5110 2320 2350 5110 5110 2170 1190 41 | 1696098 5110 5110 2320 2350 5110 5110 2160 1180 42 | 1696314 5110 5110 2320 2360 5110 5110 2160 1180 43 | 1696524 5110 5110 2320 2360 5110 5110 2160 1190 44 | 1696740 5110 5110 2320 2360 5110 5110 2160 1190 45 | 1696952 5110 5110 2320 2360 5110 5110 2160 1180 46 | 1697168 5110 5110 2320 2360 5110 5110 2160 1180 47 | 1697377 5110 5110 2320 2360 5110 5110 2170 1190 48 | 1697590 5110 5110 2310 2360 5110 5110 2170 1190 49 | 1697802 5110 5110 2310 2360 5110 5110 2150 1180 50 | 1698013 5110 5110 2290 2310 5060 5110 2150 1180 51 | 1698233 5110 5110 2290 2310 5060 5110 2100 1190 52 | 1698442 5110 2240 2210 2240 4970 5110 2100 1190 53 | 1698652 5110 2240 2210 2240 4970 4950 2000 1260 54 | 1698868 860 2120 2100 4260 4860 4830 1910 1260 55 | 1699087 860 2010 2000 4140 5110 4830 1910 1260 56 | 1699293 870 2010 2000 4140 5110 4700 1830 1260 57 | 1699515 870 1900 1890 4020 5110 4700 1830 1260 58 | 1699721 860 1900 1890 4020 5110 4590 1740 1260 59 | 1699939 860 1800 1810 3910 5110 4480 1740 1260 60 | 1700150 870 1700 1810 3910 5110 4480 5110 1220 61 | 1700362 870 1700 2700 3800 5110 4370 5110 1220 62 | 1700578 870 1600 2700 3800 5110 4370 5080 1180 63 | 1700788 870 1600 2600 3680 5110 4250 5080 1180 64 | 1701000 860 1500 2600 3680 5110 4250 5110 1180 65 | 1701218 860 1500 2480 3570 5110 4140 5110 1180 66 | 1701435 830 1410 2480 3570 5110 4140 5110 1180 67 | 1701645 830 1410 2380 3450 5110 4030 5110 1180 68 | 1701857 920 1320 2380 3450 5110 4030 5110 1260 69 | 1702070 920 1320 2270 2290 5110 3900 5110 1260 70 | 1702289 920 5010 2150 2170 5110 3790 5110 1270 71 | 1702500 920 2070 2050 2170 5110 3790 5110 1270 72 | 1702713 920 2070 2050 2170 5110 2270 2390 1270 73 | 1702928 920 4800 1960 2170 5110 2270 2390 1270 74 | 1703144 920 4800 1960 1990 5110 3620 1670 1270 75 | 1703349 910 4720 1880 1990 5110 3620 1670 1220 76 | 1703566 910 4720 1880 1910 5110 3470 5110 1220 77 | 1703775 900 1810 1880 1910 5110 3470 5110 1210 78 | 1703990 900 1810 1880 2800 5110 3410 5110 1210 79 | 1704210 890 1700 1680 2800 5110 3410 5110 1210 80 | 1704423 890 1700 1680 2800 5110 3340 5110 1220 81 | 1704637 880 1590 1580 2600 5110 3340 5110 1220 82 | 1704845 880 1590 1580 2600 5110 3210 3220 1220 83 | 1705065 860 1480 2480 3550 5110 3210 3220 1220 84 | 1705272 860 1480 2480 3550 5110 3130 3110 1230 85 | 1705488 820 1380 2370 3450 5110 3020 3000 1230 86 | 1705695 840 1300 2260 3320 5110 3020 3000 1230 87 | 1705912 840 1300 2260 3320 5110 2900 2890 1240 88 | 1706122 860 1200 2150 3220 5110 2900 2890 1240 89 | 1706339 860 1200 2150 3220 5110 2820 2780 1260 90 | 1706549 860 1140 2030 2070 5110 2820 2780 1260 91 | 1706767 850 1140 2030 2070 5110 2820 2680 1250 92 | 1706977 850 5110 1930 1960 5110 2820 2680 1250 93 | 1707189 850 5110 1930 1960 5110 5110 2570 1260 94 | 1707409 850 1850 1820 2870 5110 5110 2570 1260 95 | 1707616 840 1850 1820 2870 5110 5110 2470 1260 96 | 1707834 840 1740 1730 2780 5110 5110 2470 1260 97 | 1708047 840 1740 1730 2780 5110 5110 2390 1260 98 | 1708261 840 1640 1630 2680 5110 5110 2390 1260 99 | 1708478 840 1550 1630 2580 5110 5110 2290 1260 100 | 1708688 790 1440 1630 2580 5110 5110 2200 1270 101 | 1708902 790 1440 2440 3120 5110 5010 2200 1270 102 | 1709118 780 1340 2440 3120 5110 5010 2090 1270 103 | 1709329 780 1340 2330 3000 5110 4900 2090 1270 104 | 1709540 820 1250 2330 3000 5110 4900 2020 1270 105 | 1709759 820 1250 2230 3610 5110 4780 2020 1270 106 | 1709968 830 1170 2230 3610 5110 4780 1950 1280 107 | 1710181 830 1170 2120 3490 5110 4670 1950 1280 108 | 1710391 820 5110 2120 3490 5110 4670 1900 1280 109 | 1710611 820 5110 2010 2030 5110 4550 1900 1280 110 | 1710820 820 5110 2010 2030 5110 4550 5110 1280 111 | 1711032 820 5110 1900 1920 5110 4450 5110 1280 112 | 1711247 820 1850 1820 1920 5110 4450 5110 1280 113 | 1711464 820 1850 1820 3190 5110 4340 5110 1280 114 | 1711882 810 1630 1620 3110 5110 4230 5110 1280 115 | 1712100 810 1630 1620 3000 5110 4120 5110 1280 116 | 1712317 810 1520 1620 3000 5110 4120 5110 1330 117 | 1712525 810 1520 1620 2910 5110 4020 5110 1330 118 | 1712739 770 1410 2010 2910 5110 4020 5110 1370 119 | 1712952 770 1410 2010 2790 5110 3910 5110 1370 120 | 1713170 760 1310 1360 2690 5110 3910 5110 1380 121 | 1713385 760 1310 1360 2690 5110 3800 5110 1380 122 | 1713599 810 1230 1800 5110 5110 3800 5110 1380 123 | 1713813 810 1230 1800 5110 5110 3690 5110 1360 124 | 1714021 800 1140 1710 5110 5110 3690 5110 1360 125 | 1714235 800 1140 1710 5110 5110 3590 5110 1320 126 | 1714452 800 1080 1610 5110 5110 3590 5110 1320 127 | 1714657 800 1080 1610 5110 5110 3480 5110 1310 128 | 1714872 800 1520 1610 5110 5110 3370 3390 1310 129 | 1715087 800 1520 2040 4990 5110 3370 3390 1310 130 | 1715303 790 1520 2040 4990 5110 3270 3390 1310 131 | 1715516 790 1310 1940 4880 5110 3270 3390 1310 132 | 1715731 790 1310 1940 4880 5110 3160 3170 1320 133 | 1715939 790 1220 1840 4780 5110 3160 3170 1320 134 | 1716156 790 1220 1840 4780 5110 3080 3060 1320 135 | 1716366 790 1130 1730 1830 5110 3080 3060 1320 136 | 1716584 730 1130 1730 1830 5110 2970 2950 1330 137 | 1716800 730 1050 1620 4540 5110 2970 2950 1330 138 | 1717008 730 1050 1620 4540 5110 2890 2840 1330 139 | 1717218 730 1550 1530 4540 5110 2890 2840 1330 140 | 1717436 760 1550 1530 4540 5110 2890 2740 1340 141 | 1717655 760 1430 1440 4310 5110 5110 2740 1340 142 | 1718071 750 1240 1390 4190 5110 5110 2540 1350 143 | 1718293 750 1240 5110 4090 5110 5110 2540 1350 144 | 1718503 750 1150 5110 4090 5110 5110 2440 1350 145 | 1718716 750 1150 5110 3970 5110 5110 2440 1350 146 | 1718928 730 1070 5110 3970 5110 5110 2350 1350 147 | 1719139 730 1070 5110 3850 5110 5110 2350 1350 148 | 1719359 720 1020 5110 3850 5110 5110 2260 1360 149 | 1719567 720 1020 5110 3730 5110 5110 2260 1360 150 | 1719787 720 980 5110 3730 5110 5110 2190 1360 151 | 1719994 720 980 5110 3620 5110 5110 2090 1360 152 | 1720215 730 5110 5110 3620 5110 5110 2090 1370 153 | 1720429 730 5110 5110 3510 5110 4850 2030 1370 154 | 1720641 740 5110 3440 3510 5110 4850 2030 1360 155 | 1720852 740 5110 3440 3390 5110 4730 5110 1360 156 | 1721063 730 5110 3300 3390 5110 4730 5110 1370 157 | 1721275 730 5110 3180 3270 5110 4610 5110 1370 158 | 1721699 670 5110 3070 3150 5110 4500 5110 1380 159 | 1721921 670 5110 3070 3030 5110 4400 5110 1390 160 | 1722339 660 5110 2940 2910 5110 4400 5110 1400 161 | 1722561 660 5010 2820 2800 5110 4400 5110 1400 162 | 1722769 660 5010 2820 2800 5110 4180 5110 1430 163 | 1722982 660 4890 2700 2680 5110 4180 5110 1430 164 | 1723203 660 4890 2700 2680 5110 4070 5110 1470 165 | 1723416 650 4780 2590 2570 5110 4070 5110 1470 166 | 1723627 650 4780 2590 2570 5110 3960 5110 1490 167 | 1723839 650 4690 2470 2570 5110 3960 5110 1490 168 | 1724051 650 4690 2470 2570 5110 3860 5110 1490 169 | 1724271 630 4600 2350 2360 5110 3730 5110 1440 170 | 1724480 630 4500 2230 2240 5110 3730 5110 1440 171 | 1724696 630 4500 2230 2240 5110 3730 5110 1420 172 | 1724905 630 4400 2110 2140 5110 3730 5110 1420 173 | 1725117 620 4400 2110 2140 5110 3550 5110 1420 174 | 1725337 620 2080 2020 5110 5110 3550 5110 1420 175 | 1725544 620 2080 2020 5110 5110 3430 5110 1430 176 | 1725755 620 4260 1910 1950 5110 3430 5110 1430 177 | 1725975 620 4260 1910 1950 5110 3340 5110 1420 178 | 1726185 620 1880 1840 1900 5110 3340 5110 1420 179 | 1726403 640 1780 1840 1900 5110 3260 5110 1420 180 | 1726612 640 1780 1840 5110 5110 3190 5110 1420 181 | 1726824 650 1700 1840 5110 5110 3190 5110 1400 182 | 1727247 690 1620 5110 5110 5110 3120 5110 1390 183 | 1727467 700 1520 1640 5110 5110 3000 5110 1370 184 | 1727680 700 1520 1560 5110 5110 2880 5110 1370 185 | 1727890 710 1440 1560 5110 5110 2880 5110 1350 186 | 1728104 710 1440 5110 5110 5110 2790 5110 1350 187 | 1728322 730 1350 5110 5110 5110 2790 5110 1330 188 | 1728531 730 1350 5110 5110 5110 2680 5110 1330 189 | 1728748 740 1290 5110 5110 5110 2680 5110 900 190 | 1728962 740 1290 5110 5110 5110 2570 3140 900 191 | 1729173 750 5110 5110 5110 5110 2570 3140 740 192 | 1729390 750 5110 5110 5110 5110 890 3030 740 193 | 1729808 780 5110 5110 5110 5110 840 2920 1290 194 | 1730032 860 5110 5110 5110 5110 840 2920 1290 195 | 1730238 860 5110 5110 5110 5110 2270 2240 1290 196 | 1730456 870 5110 5110 5110 5110 2270 2240 1270 197 | 1730664 870 5110 5110 1770 1290 5110 2120 1270 198 | 1730878 890 5110 5110 1640 4930 5110 2040 1250 199 | 1731094 890 5020 5110 2220 4930 5110 2040 1250 200 | 1731307 890 5020 5110 2220 4820 5110 1920 1240 201 | 1731521 880 3610 2800 5110 4820 5110 1920 1240 202 | 1731731 880 3610 2800 5110 4710 5110 1830 1230 203 | 1731943 850 4860 2880 5110 4710 5110 1830 1230 204 | 1732160 850 4860 2880 5110 4710 4580 1750 1220 205 | 1732378 850 4760 5110 5110 4710 4580 1750 1220 206 | 1732589 850 4760 5110 5110 5110 4460 1650 1210 207 | 1732800 870 4680 5110 5110 5110 4460 1650 1210 208 | 1733019 2850 4680 5110 5110 5110 4350 5110 1200 209 | 1733232 2850 4560 5110 5110 5110 4350 5110 1200 210 | 1733443 2860 4560 5110 5110 5110 4220 5110 1200 211 | 1733651 2860 4520 5110 5110 5110 4220 5110 1200 212 | 1734076 2880 4430 5110 5110 5110 3940 5110 1350 213 | 1734300 2880 5110 5110 5110 5110 3940 5110 1350 214 | 1734717 2880 5110 5110 5110 5110 3830 5110 2320 215 | 1734932 2890 5110 5110 5110 5110 3700 5110 2280 216 | 1735146 2890 5110 5110 5110 5110 3580 5110 2280 217 | 1735364 2890 5110 5110 5110 5110 3580 5110 2030 218 | 1735577 2890 5110 5110 5110 5110 3460 5110 2030 219 | 1735788 2890 5110 5110 5110 5110 3460 5110 1170 220 | 1736006 2890 5110 5110 5110 5110 3340 5110 1170 221 | 1736214 2900 5110 5110 5110 5110 3340 5110 1150 222 | 1736425 2900 5110 5110 5110 5110 3240 5110 1150 223 | 1736647 2900 5110 5110 5110 5110 3240 5110 1120 224 | 1736854 2900 5110 5110 5110 5110 3130 5110 1120 225 | 1737069 2910 5110 5110 5110 5110 3130 5110 1150 226 | 1737280 2900 5110 5110 5110 5110 3010 5110 1160 227 | 1737495 2900 5110 5110 5110 5110 2900 5110 1160 228 | 1737708 2910 5110 5110 5110 5110 2900 5110 1160 229 | 1737924 2910 5110 5110 5110 5110 2800 5110 1160 230 | 1738140 2900 5110 5110 5110 5110 2800 5110 1160 231 | 1738350 2900 5110 5110 5110 5110 2690 5110 1160 232 | 1738567 2910 5110 5110 5110 5110 2690 5110 1160 233 | 1738775 2910 5110 5110 5110 5110 2580 2570 1160 234 | 1738986 2900 5110 5110 5110 5110 2580 2570 1150 235 | 1739208 2900 5110 5110 5110 5110 1200 2460 1150 236 | 1739419 2910 5040 5110 5110 5110 1200 2460 1160 237 | 1739631 2910 5040 5110 5110 5110 2370 2340 1160 238 | 1739843 2910 4920 5110 5110 5110 2370 2340 1160 239 | 1740058 2910 4920 5110 5110 5110 2370 2230 1160 240 | 1740271 2900 4810 5110 5110 5110 5110 2130 1160 241 | 1740483 2900 4710 5110 5110 5110 5110 2130 1160 242 | 1740693 2900 4710 5110 5110 5110 5110 2030 1160 243 | 1740912 2890 4600 5110 5110 5110 5110 2030 1160 244 | 1741123 2890 4600 5110 5110 5110 5110 1920 1170 245 | 1741338 2900 4520 5110 5110 5110 5110 1920 1170 246 | 1741554 2900 4520 5110 5110 5110 5110 1840 1160 247 | 1741763 2900 4450 5110 5110 5110 5110 1840 1160 248 | 1741976 2920 4450 5110 5110 5110 5110 1770 1170 249 | 1742188 2920 4330 5110 5110 5110 5110 1770 1170 250 | 1742405 2970 4330 5110 5110 5110 4560 5110 1170 251 | 1742615 2970 4240 5110 5110 5110 4560 5110 1170 252 | 1742834 2970 4240 5110 5110 5110 4560 5110 1170 253 | 1743043 2970 4140 5110 5110 5110 4560 5110 1170 254 | 1743254 2950 4140 5110 5110 5110 5110 5110 1170 255 | 1743467 2950 4080 5110 5110 5110 5110 5110 1170 256 | 1743688 2910 4000 5110 5110 5110 5110 5110 1190 257 | 1743896 2890 3920 5110 5110 5110 5110 5110 1240 258 | 1744112 2890 3920 5110 5110 5110 4000 5110 1240 259 | 1744329 2880 3810 5110 5110 5110 4000 5110 1280 260 | 1744535 2880 3810 5110 5110 5110 4000 5110 1280 261 | 1744757 2940 3760 5110 5110 5110 4000 5110 1320 262 | 1744967 2940 3760 5110 5110 5110 5110 5110 1320 263 | 1745180 3040 3720 5110 5110 5110 5110 3820 1330 264 | 1745392 3040 3720 5110 5110 5110 5110 3820 1330 265 | 1745605 3020 5110 5110 5110 5110 5110 3790 5110 266 | 1745822 3020 5110 3650 5110 2420 5110 3790 5110 267 | 1746031 3010 5110 3650 5110 2420 5110 3790 5110 268 | 1746251 3010 5110 3580 5110 2340 5110 5110 5110 269 | 1746459 3000 5110 3510 5110 2340 5110 5110 5110 270 | 1746677 3000 5110 4900 3500 5110 5110 5110 5110 271 | 1746887 3000 5110 4900 3400 5110 5110 5110 5110 272 | 1747096 5110 5110 4830 3400 5110 5110 5110 1720 273 | 1747313 5110 5110 4830 3300 5110 5110 5110 1720 274 | 1747522 5110 4320 5110 3300 5110 5110 5110 1720 275 | 1747736 5110 4320 5110 3220 5110 5110 5110 1720 276 | 1747952 5110 4250 5110 3220 5110 5110 5110 5110 277 | 1748171 5110 4250 5110 3110 5110 5110 1860 5110 278 | 1748379 4940 4160 5110 4540 5110 5110 1860 3500 279 | 1748598 4940 4160 5110 4540 3010 5110 1780 3460 280 | 1748805 4950 4090 5110 4430 3010 5110 1780 3460 281 | 1749024 4950 4090 5110 4430 2870 4710 1700 3460 282 | 1749234 4950 4000 5110 4330 2870 4710 1700 3460 283 | 1749442 4950 4000 5110 4330 2760 5110 1700 3470 284 | 1749655 4960 3930 5110 4330 2760 5110 1700 3470 285 | 1749872 4960 3830 5110 5070 2660 5110 5110 3530 286 | 1750093 4960 3830 5110 5070 2550 5110 5110 3530 287 | 1750300 4960 3750 3760 4930 2550 5110 5110 3530 288 | 1750517 4980 3750 3760 4930 2450 2460 4300 5110 289 | 1750727 4980 3670 3660 4830 2330 2460 4300 5110 290 | 1750945 4990 3670 3660 4830 2330 2460 5110 5110 291 | 1751156 4990 3610 3550 4740 3730 2460 5110 5110 292 | 1751369 4990 3610 3550 4740 3730 2220 5100 5110 293 | 1751579 4990 3540 3460 5110 3610 2220 5100 5110 294 | 1751799 5000 3540 3460 5110 3610 2080 5110 5110 295 | 1752004 5000 3440 5110 5110 3500 2080 5110 5110 296 | 1752218 5010 3440 5110 5110 3500 1970 1430 5110 297 | 1752430 5010 3360 4380 5110 3370 1970 1430 5110 298 | 1752653 5020 3360 4380 5110 3370 1860 4970 2900 299 | 1752863 5020 3250 4270 5110 3250 1740 4970 2900 300 | 1753078 2470 3160 4160 5110 3120 1630 4840 1160 301 | 1753291 2430 3070 4160 5110 3120 1630 1670 1120 302 | 1753497 2430 3070 3110 5110 3010 1560 1670 1120 303 | 1753712 2410 2980 3110 5110 3010 1560 1530 2540 304 | 1753931 2410 2980 2990 5110 2900 5110 1530 2540 305 | 1754147 2390 2890 2990 5110 2900 5110 1410 1040 306 | 1754359 2390 2890 2740 5110 2800 2790 1410 1040 307 | 1754564 2380 2810 2740 5110 2800 2790 1320 2060 308 | 1754779 2380 2810 3740 5110 2700 2680 1320 2060 309 | 1754997 2350 2720 3640 5110 2700 2680 1220 980 310 | 1755208 2350 2720 3640 5110 3540 2570 1150 980 311 | 1755418 2350 2630 3540 5110 3540 2570 1150 980 312 | 1755633 2350 2630 3540 5110 3440 2450 4020 980 313 | 1755846 1340 2550 3450 5110 3440 2450 4020 1000 314 | 1756067 1340 2550 3450 5110 3250 2330 3950 1000 315 | 1756278 1320 2460 3320 5110 3130 2210 3860 1000 316 | 1756488 1050 2370 3210 5110 3130 2210 3860 960 317 | 1756702 1050 2370 3210 5110 3000 2110 3790 960 318 | 1756913 1330 2050 3110 5110 3000 2110 3790 950 319 | 1757128 1330 2050 3110 5110 2890 2010 2330 880 320 | 1757348 1000 2230 3010 5110 2890 2010 2330 880 321 | 1757559 1000 2230 3010 5110 2780 640 5110 800 322 | 1757771 1350 1860 2900 5110 2780 640 5110 800 323 | 1757985 1350 1860 2900 5110 2670 1820 1810 790 324 | 1758404 1360 1070 2810 5110 2670 2580 1680 770 325 | 1758623 1370 5110 1250 5110 2670 2580 1680 770 326 | 1759045 1380 5110 1250 5110 5110 2470 1580 760 327 | 1759260 1380 5110 1250 5110 5110 2350 1490 750 328 | 1759475 1400 1470 1600 5110 5110 2230 1430 750 329 | 1759692 1400 2200 2040 5110 5110 2230 1430 750 330 | 1759904 1420 2200 2040 5110 5110 2090 1350 990 331 | 1760117 1420 2410 2180 2310 3040 2090 1350 990 332 | 1760331 1420 2410 2180 2310 3040 1960 2050 990 333 | 1760544 1420 2180 2160 3060 2920 1960 2050 990 334 | 1760754 1430 2180 2160 3060 2920 1850 1920 980 335 | 1761179 1450 1560 5110 2970 2800 1740 1820 960 336 | 1761606 1460 1970 5110 2970 2680 1620 1710 960 337 | 1761821 1460 1860 5080 5110 2560 1500 1710 960 338 | 1762041 1470 1770 5080 5110 2560 1500 1710 950 339 | 1762253 1470 1770 4950 5110 2460 1400 1710 950 340 | 1762463 1480 1680 4840 5110 3570 1300 1510 940 341 | 1762886 910 1590 4730 5110 3440 5110 1420 930 342 | 1763108 900 1520 4730 5110 3440 5110 1310 920 343 | 1763315 900 1520 4640 5110 3470 4300 1310 920 344 | 1763530 910 1430 4640 5110 3470 4300 1080 930 345 | 1763742 910 1430 4530 5110 3470 1990 1080 930 346 | 1763960 910 4650 4440 5110 3470 1990 980 920 347 | 1764170 910 4650 4440 5110 5110 1880 980 920 348 | 1764388 910 4650 4320 5110 5110 1880 980 920 349 | 1764603 910 4650 4320 5110 5110 1770 3140 920 350 | 1764811 910 5110 4210 5110 5110 1770 3140 920 351 | 1765025 910 5110 4210 4870 5110 1680 3030 920 352 | 1765242 900 5110 4100 4870 5110 1680 3030 920 353 | 1765450 900 5110 4100 4750 5110 3280 2930 920 354 | 1765669 900 5110 3980 4630 5110 3150 2860 940 355 | 1765881 890 5110 3880 4630 5110 3150 2860 940 356 | 1766097 890 5110 3880 4520 5110 3050 1350 650 357 | 1766308 900 5110 3770 4390 5110 3050 1350 650 358 | 1766518 900 5110 3770 4390 5110 2930 1240 640 359 | 1766735 890 5110 3660 4280 5110 2930 1240 640 360 | 1766948 890 5110 3660 4280 5110 2810 1140 650 361 | 1767161 890 5110 3540 4170 5110 2810 1140 650 362 | 1767372 890 5110 3540 4170 5110 2700 1040 4160 363 | 1767582 890 5110 3440 4050 5110 2700 1040 4160 364 | 1767796 890 5110 3440 4050 5110 2670 970 3120 365 | 1768222 930 3370 3330 3930 5110 2500 2520 4230 366 | 1768443 940 3260 3230 3820 5110 2500 2520 4230 367 | 1768861 1490 3140 3130 3710 5110 2260 2210 4240 368 | 1769085 1490 2990 3020 3590 5110 2260 2210 4240 369 | 1769298 1490 2990 3020 3590 5110 2160 2020 4220 370 | 1769504 1490 2920 2940 3500 5110 2160 2020 4220 371 | 1769724 1490 2920 2940 3500 5110 2050 1880 660 372 | 1769933 1490 2820 3350 3500 5110 2050 1880 660 373 | 1770148 1490 2820 3350 3500 5110 1940 1930 640 374 | 1770361 1490 2720 3240 4220 5110 1940 1930 640 375 | 1770569 1490 2620 3240 4220 5110 1830 1930 650 376 | 1770787 1490 2620 3110 4110 5110 1730 1930 650 377 | 1771003 1490 2530 3110 4110 5110 1730 1720 640 378 | 1771213 1490 2530 3000 5110 5110 1630 1720 640 379 | 1771427 1490 2470 3000 5110 5110 1630 1720 650 380 | 1771643 1490 2470 2880 5110 5110 1530 1720 650 381 | 1771852 1500 2350 2880 5110 5110 1530 1520 1980 382 | 1772067 1500 2270 2730 5110 5110 1430 1520 1210 383 | 1772282 1500 2270 2600 5110 5110 1320 1520 1210 384 | 1772500 1510 2210 2600 5110 5110 1320 1300 1190 385 | 1772710 1510 2210 2570 5110 5110 1320 1220 1190 386 | 1772921 1510 2740 2380 5110 5110 1320 1220 1210 387 | 1773131 1510 2740 2380 5110 5110 5110 1100 1210 388 | 1773344 1510 2640 2340 5110 5110 5110 1100 1240 389 | 1773567 1510 2640 2340 5110 5110 5110 1000 1240 390 | 1773777 1510 2540 2240 5110 5110 5110 1000 1240 391 | 1773986 1510 2540 2240 5110 5110 4370 910 1240 392 | 1774197 1520 2440 2130 5110 5110 4370 910 1250 393 | 1774410 1520 2440 2130 5110 5110 4240 3590 1250 394 | 1774632 1510 2060 2030 5110 5110 4240 3590 1240 395 | 1774838 1510 2060 2030 5110 5110 4120 3500 1240 396 | 1775264 1510 1830 1820 5110 5110 3990 3410 1190 397 | 1775486 1510 1830 1820 5110 5110 3870 3390 1200 398 | 1775696 1510 1730 2410 5110 5110 3870 3390 1200 399 | 1775904 1510 1730 2410 5110 5110 3750 3250 630 400 | 1776119 1520 1620 2290 5110 5110 3750 3250 630 401 | 1776339 1520 1620 2290 5110 5110 3630 4780 620 402 | 1776545 1520 1530 2190 5110 5110 3630 4780 620 403 | 1776760 1520 1530 2190 5110 5110 3530 4700 620 404 | 1776979 1510 1430 2100 5110 5110 3530 4700 620 405 | 1777188 1510 1430 2100 5110 5110 3440 4620 620 406 | 1777405 1510 1360 2010 5110 5110 3440 4620 620 407 | 1777618 1500 1360 2010 5110 5110 3370 4570 640 408 | 1777829 1500 1280 1930 3820 5110 3370 4570 640 409 | 1778252 1400 1210 1830 3710 5110 3380 3170 680 410 | 1778473 1400 1120 420 3610 5110 3380 3170 680 411 | 1778892 1390 1060 1670 2570 5110 3290 3090 1280 412 | 1779109 1380 1060 1670 2570 5110 3250 3050 5110 413 | 1779324 1380 1040 1650 2550 5110 3240 3050 5110 414 | -------------------------------------------------------------------------------- /src/matplotlibcpp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include // requires c++11 support 10 | 11 | #if __cplusplus > 199711L || _MSC_VER > 1800 12 | #include 13 | #endif 14 | 15 | #include 16 | 17 | #ifndef WITHOUT_NUMPY 18 | #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 19 | #include 20 | #endif // WITHOUT_NUMPY 21 | 22 | #if PY_MAJOR_VERSION >= 3 23 | #define PyString_FromString PyUnicode_FromString 24 | #endif 25 | 26 | 27 | namespace matplotlibcpp { 28 | 29 | namespace detail { 30 | static std::string s_backend; 31 | 32 | struct _interpreter { 33 | PyObject *s_python_function_show; 34 | PyObject *s_python_function_draw; 35 | PyObject *s_python_function_pause; 36 | PyObject *s_python_function_save; 37 | PyObject *s_python_function_figure; 38 | PyObject *s_python_function_plot; 39 | PyObject *s_python_function_semilogx; 40 | PyObject *s_python_function_semilogy; 41 | PyObject *s_python_function_loglog; 42 | PyObject *s_python_function_fill_between; 43 | PyObject *s_python_function_hist; 44 | PyObject *s_python_function_subplot; 45 | PyObject *s_python_function_legend; 46 | PyObject *s_python_function_xlim; 47 | PyObject *s_python_function_ylim; 48 | PyObject *s_python_function_title; 49 | PyObject *s_python_function_axis; 50 | PyObject *s_python_function_xlabel; 51 | PyObject *s_python_function_ylabel; 52 | PyObject *s_python_function_grid; 53 | PyObject *s_python_function_clf; 54 | PyObject *s_python_function_errorbar; 55 | PyObject *s_python_function_annotate; 56 | PyObject *s_python_function_tight_layout; 57 | PyObject *s_python_empty_tuple; 58 | 59 | /* For now, _interpreter is implemented as a singleton since its currently not possible to have 60 | multiple independent embedded python interpreters without patching the python source code 61 | or starting a separate process for each. 62 | http://bytes.com/topic/python/answers/793370-multiple-independent-python-interpreters-c-c-program 63 | */ 64 | 65 | static _interpreter& get() { 66 | static _interpreter ctx; 67 | return ctx; 68 | } 69 | 70 | private: 71 | _interpreter() { 72 | 73 | // optional but recommended 74 | #if PY_MAJOR_VERSION >= 3 75 | wchar_t name[] = L"plotting"; 76 | #else 77 | char name[] = "plotting"; 78 | #endif 79 | Py_SetProgramName(name); 80 | Py_Initialize(); 81 | 82 | #ifndef WITHOUT_NUMPY 83 | import_array(); // initialize numpy C-API 84 | #endif 85 | 86 | PyObject* matplotlibname = PyString_FromString("matplotlib"); 87 | PyObject* pyplotname = PyString_FromString("matplotlib.pyplot"); 88 | PyObject* pylabname = PyString_FromString("pylab"); 89 | if (!pyplotname || !pylabname || !matplotlibname) { 90 | throw std::runtime_error("couldnt create string"); 91 | } 92 | 93 | PyObject* matplotlib = PyImport_Import(matplotlibname); 94 | Py_DECREF(matplotlibname); 95 | if(!matplotlib) { throw std::runtime_error("Error loading module matplotlib!"); } 96 | 97 | // matplotlib.use() must be called *before* pylab, matplotlib.pyplot, 98 | // or matplotlib.backends is imported for the first time 99 | if (!s_backend.empty()) { 100 | PyObject_CallMethod(matplotlib, const_cast("use"), const_cast("s"), s_backend.c_str()); 101 | } 102 | 103 | PyObject* pymod = PyImport_Import(pyplotname); 104 | Py_DECREF(pyplotname); 105 | if(!pymod) { throw std::runtime_error("Error loading module matplotlib.pyplot!"); } 106 | 107 | 108 | PyObject* pylabmod = PyImport_Import(pylabname); 109 | Py_DECREF(pylabname); 110 | if(!pylabmod) { throw std::runtime_error("Error loading module pylab!"); } 111 | 112 | s_python_function_show = PyObject_GetAttrString(pymod, "show"); 113 | s_python_function_draw = PyObject_GetAttrString(pymod, "draw"); 114 | s_python_function_pause = PyObject_GetAttrString(pymod, "pause"); 115 | s_python_function_figure = PyObject_GetAttrString(pymod, "figure"); 116 | s_python_function_plot = PyObject_GetAttrString(pymod, "plot"); 117 | s_python_function_semilogx = PyObject_GetAttrString(pymod, "semilogx"); 118 | s_python_function_semilogy = PyObject_GetAttrString(pymod, "semilogy"); 119 | s_python_function_loglog = PyObject_GetAttrString(pymod, "loglog"); 120 | s_python_function_fill_between = PyObject_GetAttrString(pymod, "fill_between"); 121 | s_python_function_hist = PyObject_GetAttrString(pymod,"hist"); 122 | s_python_function_subplot = PyObject_GetAttrString(pymod, "subplot"); 123 | s_python_function_legend = PyObject_GetAttrString(pymod, "legend"); 124 | s_python_function_ylim = PyObject_GetAttrString(pymod, "ylim"); 125 | s_python_function_title = PyObject_GetAttrString(pymod, "title"); 126 | s_python_function_axis = PyObject_GetAttrString(pymod, "axis"); 127 | s_python_function_xlabel = PyObject_GetAttrString(pymod, "xlabel"); 128 | s_python_function_ylabel = PyObject_GetAttrString(pymod, "ylabel"); 129 | s_python_function_grid = PyObject_GetAttrString(pymod, "grid"); 130 | s_python_function_xlim = PyObject_GetAttrString(pymod, "xlim"); 131 | s_python_function_save = PyObject_GetAttrString(pylabmod, "savefig"); 132 | s_python_function_annotate = PyObject_GetAttrString(pymod,"annotate"); 133 | s_python_function_clf = PyObject_GetAttrString(pymod, "clf"); 134 | s_python_function_errorbar = PyObject_GetAttrString(pymod, "errorbar"); 135 | s_python_function_tight_layout = PyObject_GetAttrString(pymod, "tight_layout"); 136 | 137 | if( !s_python_function_show 138 | || !s_python_function_draw 139 | || !s_python_function_pause 140 | || !s_python_function_figure 141 | || !s_python_function_plot 142 | || !s_python_function_semilogx 143 | || !s_python_function_semilogy 144 | || !s_python_function_loglog 145 | || !s_python_function_fill_between 146 | || !s_python_function_subplot 147 | || !s_python_function_legend 148 | || !s_python_function_ylim 149 | || !s_python_function_title 150 | || !s_python_function_axis 151 | || !s_python_function_xlabel 152 | || !s_python_function_ylabel 153 | || !s_python_function_grid 154 | || !s_python_function_xlim 155 | || !s_python_function_save 156 | || !s_python_function_clf 157 | || !s_python_function_annotate 158 | || !s_python_function_errorbar 159 | || !s_python_function_errorbar 160 | || !s_python_function_tight_layout 161 | ) { throw std::runtime_error("Couldn't find required function!"); } 162 | 163 | if ( !PyFunction_Check(s_python_function_show) 164 | || !PyFunction_Check(s_python_function_draw) 165 | || !PyFunction_Check(s_python_function_pause) 166 | || !PyFunction_Check(s_python_function_figure) 167 | || !PyFunction_Check(s_python_function_plot) 168 | || !PyFunction_Check(s_python_function_semilogx) 169 | || !PyFunction_Check(s_python_function_semilogy) 170 | || !PyFunction_Check(s_python_function_loglog) 171 | || !PyFunction_Check(s_python_function_fill_between) 172 | || !PyFunction_Check(s_python_function_subplot) 173 | || !PyFunction_Check(s_python_function_legend) 174 | || !PyFunction_Check(s_python_function_annotate) 175 | || !PyFunction_Check(s_python_function_ylim) 176 | || !PyFunction_Check(s_python_function_title) 177 | || !PyFunction_Check(s_python_function_axis) 178 | || !PyFunction_Check(s_python_function_xlabel) 179 | || !PyFunction_Check(s_python_function_ylabel) 180 | || !PyFunction_Check(s_python_function_grid) 181 | || !PyFunction_Check(s_python_function_xlim) 182 | || !PyFunction_Check(s_python_function_save) 183 | || !PyFunction_Check(s_python_function_clf) 184 | || !PyFunction_Check(s_python_function_tight_layout) 185 | || !PyFunction_Check(s_python_function_errorbar) 186 | ) { throw std::runtime_error("Python object is unexpectedly not a PyFunction."); } 187 | 188 | s_python_empty_tuple = PyTuple_New(0); 189 | } 190 | 191 | ~_interpreter() { 192 | Py_Finalize(); 193 | } 194 | }; 195 | } 196 | 197 | // must be called before the first regular call to matplotlib to have any effect 198 | void backend(const std::string& name) 199 | { 200 | detail::s_backend = name; 201 | } 202 | 203 | bool annotate(std::string annotation, double x, double y) 204 | { 205 | PyObject * xy = PyTuple_New(2); 206 | PyObject * str = PyString_FromString(annotation.c_str()); 207 | 208 | PyTuple_SetItem(xy,0,PyFloat_FromDouble(x)); 209 | PyTuple_SetItem(xy,1,PyFloat_FromDouble(y)); 210 | 211 | PyObject* kwargs = PyDict_New(); 212 | PyDict_SetItemString(kwargs, "xy", xy); 213 | 214 | PyObject* args = PyTuple_New(1); 215 | PyTuple_SetItem(args, 0, str); 216 | 217 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_annotate, args, kwargs); 218 | 219 | Py_DECREF(args); 220 | Py_DECREF(kwargs); 221 | 222 | if(res) Py_DECREF(res); 223 | 224 | return res; 225 | } 226 | 227 | #ifndef WITHOUT_NUMPY 228 | // Type selector for numpy array conversion 229 | template struct select_npy_type { const static NPY_TYPES type = NPY_NOTYPE; }; //Default 230 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_DOUBLE; }; 231 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_FLOAT; }; 232 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_BOOL; }; 233 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_INT8; }; 234 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_SHORT; }; 235 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_INT; }; 236 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_INT64; }; 237 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_UINT8; }; 238 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_USHORT; }; 239 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_ULONG; }; 240 | template <> struct select_npy_type { const static NPY_TYPES type = NPY_UINT64; }; 241 | 242 | template 243 | PyObject* get_array(const std::vector& v) 244 | { 245 | detail::_interpreter::get(); //interpreter needs to be initialized for the numpy commands to work 246 | NPY_TYPES type = select_npy_type::type; 247 | if (type == NPY_NOTYPE) 248 | { 249 | std::vector vd(v.size()); 250 | npy_intp vsize = v.size(); 251 | std::copy(v.begin(),v.end(),vd.begin()); 252 | PyObject* varray = PyArray_SimpleNewFromData(1, &vsize, NPY_DOUBLE, (void*)(vd.data())); 253 | return varray; 254 | } 255 | 256 | npy_intp vsize = v.size(); 257 | PyObject* varray = PyArray_SimpleNewFromData(1, &vsize, type, (void*)(v.data())); 258 | return varray; 259 | } 260 | 261 | #else // fallback if we don't have numpy: copy every element of the given vector 262 | 263 | template 264 | PyObject* get_array(const std::vector& v) 265 | { 266 | PyObject* list = PyList_New(v.size()); 267 | for(size_t i = 0; i < v.size(); ++i) { 268 | PyList_SetItem(list, i, PyFloat_FromDouble(v.at(i))); 269 | } 270 | return list; 271 | } 272 | 273 | #endif // WITHOUT_NUMPY 274 | 275 | template 276 | bool plot(const std::vector &x, const std::vector &y, const std::map& keywords) 277 | { 278 | assert(x.size() == y.size()); 279 | 280 | // using numpy arrays 281 | PyObject* xarray = get_array(x); 282 | PyObject* yarray = get_array(y); 283 | 284 | // construct positional args 285 | PyObject* args = PyTuple_New(2); 286 | PyTuple_SetItem(args, 0, xarray); 287 | PyTuple_SetItem(args, 1, yarray); 288 | 289 | // construct keyword args 290 | PyObject* kwargs = PyDict_New(); 291 | for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) 292 | { 293 | PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); 294 | } 295 | 296 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, args, kwargs); 297 | 298 | Py_DECREF(args); 299 | Py_DECREF(kwargs); 300 | if(res) Py_DECREF(res); 301 | 302 | return res; 303 | } 304 | 305 | template< typename Numeric > 306 | bool fill_between(const std::vector& x, const std::vector& y1, const std::vector& y2, const std::map& keywords) 307 | { 308 | assert(x.size() == y1.size()); 309 | assert(x.size() == y2.size()); 310 | 311 | // using numpy arrays 312 | PyObject* xarray = get_array(x); 313 | PyObject* y1array = get_array(y1); 314 | PyObject* y2array = get_array(y2); 315 | 316 | // construct positional args 317 | PyObject* args = PyTuple_New(3); 318 | PyTuple_SetItem(args, 0, xarray); 319 | PyTuple_SetItem(args, 1, y1array); 320 | PyTuple_SetItem(args, 2, y2array); 321 | 322 | // construct keyword args 323 | PyObject* kwargs = PyDict_New(); 324 | for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) 325 | { 326 | PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); 327 | } 328 | 329 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_fill_between, args, kwargs); 330 | 331 | Py_DECREF(args); 332 | Py_DECREF(kwargs); 333 | if(res) Py_DECREF(res); 334 | 335 | return res; 336 | } 337 | 338 | template< typename Numeric> 339 | bool hist(const std::vector& y, long bins=10,std::string color="b", double alpha=1.0) 340 | { 341 | 342 | PyObject* yarray = get_array(y); 343 | 344 | PyObject* kwargs = PyDict_New(); 345 | PyDict_SetItemString(kwargs, "bins", PyLong_FromLong(bins)); 346 | PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); 347 | PyDict_SetItemString(kwargs, "alpha", PyFloat_FromDouble(alpha)); 348 | 349 | 350 | PyObject* plot_args = PyTuple_New(1); 351 | 352 | PyTuple_SetItem(plot_args, 0, yarray); 353 | 354 | 355 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_hist, plot_args, kwargs); 356 | 357 | 358 | Py_DECREF(plot_args); 359 | Py_DECREF(kwargs); 360 | if(res) Py_DECREF(res); 361 | 362 | return res; 363 | } 364 | 365 | template< typename Numeric> 366 | bool named_hist(std::string label,const std::vector& y, long bins=10, std::string color="b", double alpha=1.0) 367 | { 368 | PyObject* yarray = get_array(y); 369 | 370 | PyObject* kwargs = PyDict_New(); 371 | PyDict_SetItemString(kwargs, "label", PyString_FromString(label.c_str())); 372 | PyDict_SetItemString(kwargs, "bins", PyLong_FromLong(bins)); 373 | PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); 374 | PyDict_SetItemString(kwargs, "alpha", PyFloat_FromDouble(alpha)); 375 | 376 | 377 | PyObject* plot_args = PyTuple_New(1); 378 | PyTuple_SetItem(plot_args, 0, yarray); 379 | 380 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_hist, plot_args, kwargs); 381 | 382 | Py_DECREF(plot_args); 383 | Py_DECREF(kwargs); 384 | if(res) Py_DECREF(res); 385 | 386 | return res; 387 | } 388 | 389 | template 390 | bool plot(const std::vector& x, const std::vector& y, const std::string& s = "") 391 | { 392 | assert(x.size() == y.size()); 393 | 394 | PyObject* xarray = get_array(x); 395 | PyObject* yarray = get_array(y); 396 | 397 | PyObject* pystring = PyString_FromString(s.c_str()); 398 | 399 | PyObject* plot_args = PyTuple_New(3); 400 | PyTuple_SetItem(plot_args, 0, xarray); 401 | PyTuple_SetItem(plot_args, 1, yarray); 402 | PyTuple_SetItem(plot_args, 2, pystring); 403 | 404 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_plot, plot_args); 405 | 406 | Py_DECREF(plot_args); 407 | if(res) Py_DECREF(res); 408 | 409 | return res; 410 | } 411 | 412 | template 413 | bool semilogx(const std::vector& x, const std::vector& y, const std::string& s = "") 414 | { 415 | assert(x.size() == y.size()); 416 | 417 | PyObject* xarray = get_array(x); 418 | PyObject* yarray = get_array(y); 419 | 420 | PyObject* pystring = PyString_FromString(s.c_str()); 421 | 422 | PyObject* plot_args = PyTuple_New(3); 423 | PyTuple_SetItem(plot_args, 0, xarray); 424 | PyTuple_SetItem(plot_args, 1, yarray); 425 | PyTuple_SetItem(plot_args, 2, pystring); 426 | 427 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_semilogx, plot_args); 428 | 429 | Py_DECREF(plot_args); 430 | if(res) Py_DECREF(res); 431 | 432 | return res; 433 | } 434 | 435 | template 436 | bool semilogy(const std::vector& x, const std::vector& y, const std::string& s = "") 437 | { 438 | assert(x.size() == y.size()); 439 | 440 | PyObject* xarray = get_array(x); 441 | PyObject* yarray = get_array(y); 442 | 443 | PyObject* pystring = PyString_FromString(s.c_str()); 444 | 445 | PyObject* plot_args = PyTuple_New(3); 446 | PyTuple_SetItem(plot_args, 0, xarray); 447 | PyTuple_SetItem(plot_args, 1, yarray); 448 | PyTuple_SetItem(plot_args, 2, pystring); 449 | 450 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_semilogy, plot_args); 451 | 452 | Py_DECREF(plot_args); 453 | if(res) Py_DECREF(res); 454 | 455 | return res; 456 | } 457 | 458 | template 459 | bool loglog(const std::vector& x, const std::vector& y, const std::string& s = "") 460 | { 461 | assert(x.size() == y.size()); 462 | 463 | PyObject* xarray = get_array(x); 464 | PyObject* yarray = get_array(y); 465 | 466 | PyObject* pystring = PyString_FromString(s.c_str()); 467 | 468 | PyObject* plot_args = PyTuple_New(3); 469 | PyTuple_SetItem(plot_args, 0, xarray); 470 | PyTuple_SetItem(plot_args, 1, yarray); 471 | PyTuple_SetItem(plot_args, 2, pystring); 472 | 473 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_loglog, plot_args); 474 | 475 | Py_DECREF(plot_args); 476 | if(res) Py_DECREF(res); 477 | 478 | return res; 479 | } 480 | 481 | template 482 | bool errorbar(const std::vector &x, const std::vector &y, const std::vector &yerr, const std::string &s = "") 483 | { 484 | assert(x.size() == y.size()); 485 | 486 | PyObject* xarray = get_array(x); 487 | PyObject* yarray = get_array(y); 488 | PyObject* yerrarray = get_array(yerr); 489 | 490 | PyObject *kwargs = PyDict_New(); 491 | 492 | PyDict_SetItemString(kwargs, "yerr", yerrarray); 493 | 494 | PyObject *pystring = PyString_FromString(s.c_str()); 495 | 496 | PyObject *plot_args = PyTuple_New(2); 497 | PyTuple_SetItem(plot_args, 0, xarray); 498 | PyTuple_SetItem(plot_args, 1, yarray); 499 | 500 | PyObject *res = PyObject_Call(detail::_interpreter::get().s_python_function_errorbar, plot_args, kwargs); 501 | 502 | Py_DECREF(kwargs); 503 | Py_DECREF(plot_args); 504 | 505 | if (res) 506 | Py_DECREF(res); 507 | else 508 | throw std::runtime_error("Call to errorbar() failed."); 509 | 510 | return res; 511 | } 512 | 513 | template 514 | bool named_plot(const std::string& name, const std::vector& y, const std::string& format = "") 515 | { 516 | PyObject* kwargs = PyDict_New(); 517 | PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); 518 | 519 | PyObject* yarray = get_array(y); 520 | 521 | PyObject* pystring = PyString_FromString(format.c_str()); 522 | 523 | PyObject* plot_args = PyTuple_New(2); 524 | 525 | PyTuple_SetItem(plot_args, 0, yarray); 526 | PyTuple_SetItem(plot_args, 1, pystring); 527 | 528 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); 529 | 530 | Py_DECREF(kwargs); 531 | Py_DECREF(plot_args); 532 | if(res) Py_DECREF(res); 533 | 534 | return res; 535 | } 536 | 537 | template 538 | bool named_plot(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") 539 | { 540 | PyObject* kwargs = PyDict_New(); 541 | PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); 542 | 543 | PyObject* xarray = get_array(x); 544 | PyObject* yarray = get_array(y); 545 | 546 | PyObject* pystring = PyString_FromString(format.c_str()); 547 | 548 | PyObject* plot_args = PyTuple_New(3); 549 | PyTuple_SetItem(plot_args, 0, xarray); 550 | PyTuple_SetItem(plot_args, 1, yarray); 551 | PyTuple_SetItem(plot_args, 2, pystring); 552 | 553 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); 554 | 555 | Py_DECREF(kwargs); 556 | Py_DECREF(plot_args); 557 | if(res) Py_DECREF(res); 558 | 559 | return res; 560 | } 561 | 562 | template 563 | bool named_semilogx(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") 564 | { 565 | PyObject* kwargs = PyDict_New(); 566 | PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); 567 | 568 | PyObject* xarray = get_array(x); 569 | PyObject* yarray = get_array(y); 570 | 571 | PyObject* pystring = PyString_FromString(format.c_str()); 572 | 573 | PyObject* plot_args = PyTuple_New(3); 574 | PyTuple_SetItem(plot_args, 0, xarray); 575 | PyTuple_SetItem(plot_args, 1, yarray); 576 | PyTuple_SetItem(plot_args, 2, pystring); 577 | 578 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_semilogx, plot_args, kwargs); 579 | 580 | Py_DECREF(kwargs); 581 | Py_DECREF(plot_args); 582 | if(res) Py_DECREF(res); 583 | 584 | return res; 585 | } 586 | 587 | template 588 | bool named_semilogy(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") 589 | { 590 | PyObject* kwargs = PyDict_New(); 591 | PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); 592 | 593 | PyObject* xarray = get_array(x); 594 | PyObject* yarray = get_array(y); 595 | 596 | PyObject* pystring = PyString_FromString(format.c_str()); 597 | 598 | PyObject* plot_args = PyTuple_New(3); 599 | PyTuple_SetItem(plot_args, 0, xarray); 600 | PyTuple_SetItem(plot_args, 1, yarray); 601 | PyTuple_SetItem(plot_args, 2, pystring); 602 | 603 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_semilogy, plot_args, kwargs); 604 | 605 | Py_DECREF(kwargs); 606 | Py_DECREF(plot_args); 607 | if(res) Py_DECREF(res); 608 | 609 | return res; 610 | } 611 | 612 | template 613 | bool named_loglog(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") 614 | { 615 | PyObject* kwargs = PyDict_New(); 616 | PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); 617 | 618 | PyObject* xarray = get_array(x); 619 | PyObject* yarray = get_array(y); 620 | 621 | PyObject* pystring = PyString_FromString(format.c_str()); 622 | 623 | PyObject* plot_args = PyTuple_New(3); 624 | PyTuple_SetItem(plot_args, 0, xarray); 625 | PyTuple_SetItem(plot_args, 1, yarray); 626 | PyTuple_SetItem(plot_args, 2, pystring); 627 | 628 | PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_loglog, plot_args, kwargs); 629 | 630 | Py_DECREF(kwargs); 631 | Py_DECREF(plot_args); 632 | if(res) Py_DECREF(res); 633 | 634 | return res; 635 | } 636 | 637 | template 638 | bool plot(const std::vector& y, const std::string& format = "") 639 | { 640 | std::vector x(y.size()); 641 | for(size_t i=0; i 662 | void ylim(Numeric left, Numeric right) 663 | { 664 | PyObject* list = PyList_New(2); 665 | PyList_SetItem(list, 0, PyFloat_FromDouble(left)); 666 | PyList_SetItem(list, 1, PyFloat_FromDouble(right)); 667 | 668 | PyObject* args = PyTuple_New(1); 669 | PyTuple_SetItem(args, 0, list); 670 | 671 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_ylim, args); 672 | if(!res) throw std::runtime_error("Call to ylim() failed."); 673 | 674 | Py_DECREF(args); 675 | Py_DECREF(res); 676 | } 677 | 678 | template 679 | void xlim(Numeric left, Numeric right) 680 | { 681 | PyObject* list = PyList_New(2); 682 | PyList_SetItem(list, 0, PyFloat_FromDouble(left)); 683 | PyList_SetItem(list, 1, PyFloat_FromDouble(right)); 684 | 685 | PyObject* args = PyTuple_New(1); 686 | PyTuple_SetItem(args, 0, list); 687 | 688 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_xlim, args); 689 | if(!res) throw std::runtime_error("Call to xlim() failed."); 690 | 691 | Py_DECREF(args); 692 | Py_DECREF(res); 693 | } 694 | 695 | 696 | inline double* xlim() 697 | { 698 | PyObject* args = PyTuple_New(0); 699 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_xlim, args); 700 | PyObject* left = PyTuple_GetItem(res,0); 701 | PyObject* right = PyTuple_GetItem(res,1); 702 | 703 | double* arr = new double[2]; 704 | arr[0] = PyFloat_AsDouble(left); 705 | arr[1] = PyFloat_AsDouble(right); 706 | 707 | if(!res) throw std::runtime_error("Call to xlim() failed."); 708 | 709 | Py_DECREF(res); 710 | return arr; 711 | } 712 | 713 | 714 | inline double* ylim() 715 | { 716 | PyObject* args = PyTuple_New(0); 717 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_ylim, args); 718 | PyObject* left = PyTuple_GetItem(res,0); 719 | PyObject* right = PyTuple_GetItem(res,1); 720 | 721 | double* arr = new double[2]; 722 | arr[0] = PyFloat_AsDouble(left); 723 | arr[1] = PyFloat_AsDouble(right); 724 | 725 | if(!res) throw std::runtime_error("Call to ylim() failed."); 726 | 727 | Py_DECREF(res); 728 | return arr; 729 | } 730 | 731 | inline void subplot(long nrows, long ncols, long plot_number) 732 | { 733 | // construct positional args 734 | PyObject* args = PyTuple_New(3); 735 | PyTuple_SetItem(args, 0, PyFloat_FromDouble(nrows)); 736 | PyTuple_SetItem(args, 1, PyFloat_FromDouble(ncols)); 737 | PyTuple_SetItem(args, 2, PyFloat_FromDouble(plot_number)); 738 | 739 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_subplot, args); 740 | if(!res) throw std::runtime_error("Call to subplot() failed."); 741 | 742 | Py_DECREF(args); 743 | Py_DECREF(res); 744 | } 745 | 746 | inline void title(const std::string &titlestr) 747 | { 748 | PyObject* pytitlestr = PyString_FromString(titlestr.c_str()); 749 | PyObject* args = PyTuple_New(1); 750 | PyTuple_SetItem(args, 0, pytitlestr); 751 | 752 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_title, args); 753 | if(!res) throw std::runtime_error("Call to title() failed."); 754 | 755 | // if PyDeCRFF, the function doesn't work on Mac OS 756 | } 757 | 758 | inline void axis(const std::string &axisstr) 759 | { 760 | PyObject* str = PyString_FromString(axisstr.c_str()); 761 | PyObject* args = PyTuple_New(1); 762 | PyTuple_SetItem(args, 0, str); 763 | 764 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_axis, args); 765 | if(!res) throw std::runtime_error("Call to title() failed."); 766 | 767 | // if PyDeCRFF, the function doesn't work on Mac OS 768 | } 769 | 770 | inline void xlabel(const std::string &str) 771 | { 772 | PyObject* pystr = PyString_FromString(str.c_str()); 773 | PyObject* args = PyTuple_New(1); 774 | PyTuple_SetItem(args, 0, pystr); 775 | 776 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_xlabel, args); 777 | if(!res) throw std::runtime_error("Call to xlabel() failed."); 778 | 779 | // if PyDeCRFF, the function doesn't work on Mac OS 780 | } 781 | 782 | inline void ylabel(const std::string &str) 783 | { 784 | PyObject* pystr = PyString_FromString(str.c_str()); 785 | PyObject* args = PyTuple_New(1); 786 | PyTuple_SetItem(args, 0, pystr); 787 | 788 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_ylabel, args); 789 | if(!res) throw std::runtime_error("Call to ylabel() failed."); 790 | 791 | // if PyDeCRFF, the function doesn't work on Mac OS 792 | } 793 | 794 | inline void grid(bool flag) 795 | { 796 | PyObject* pyflag = flag ? Py_True : Py_False; 797 | 798 | PyObject* args = PyTuple_New(1); 799 | PyTuple_SetItem(args, 0, pyflag); 800 | 801 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_grid, args); 802 | if(!res) throw std::runtime_error("Call to grid() failed."); 803 | 804 | // if PyDeCRFF, the function doesn't work on Mac OS 805 | } 806 | 807 | inline void show(const bool block = true) 808 | { 809 | PyObject* res; 810 | if(block) 811 | { 812 | res = PyObject_CallObject( 813 | detail::_interpreter::get().s_python_function_show, 814 | detail::_interpreter::get().s_python_empty_tuple); 815 | } 816 | else 817 | { 818 | PyObject *kwargs = PyDict_New(); 819 | PyDict_SetItemString(kwargs, "block", Py_False); 820 | res = PyObject_Call( detail::_interpreter::get().s_python_function_show, detail::_interpreter::get().s_python_empty_tuple, kwargs); 821 | } 822 | 823 | 824 | if (!res) throw std::runtime_error("Call to show() failed."); 825 | 826 | Py_DECREF(res); 827 | } 828 | 829 | inline void draw() 830 | { 831 | PyObject* res = PyObject_CallObject( 832 | detail::_interpreter::get().s_python_function_draw, 833 | detail::_interpreter::get().s_python_empty_tuple); 834 | 835 | if (!res) throw std::runtime_error("Call to draw() failed."); 836 | 837 | Py_DECREF(res); 838 | } 839 | 840 | template 841 | void pause(Numeric interval) 842 | { 843 | PyObject* args = PyTuple_New(1); 844 | PyTuple_SetItem(args, 0, PyFloat_FromDouble(interval)); 845 | 846 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_pause, args); 847 | if(!res) throw std::runtime_error("Call to pause() failed."); 848 | 849 | Py_DECREF(args); 850 | Py_DECREF(res); 851 | } 852 | 853 | inline void save(const std::string& filename) 854 | { 855 | PyObject* pyfilename = PyString_FromString(filename.c_str()); 856 | 857 | PyObject* args = PyTuple_New(1); 858 | PyTuple_SetItem(args, 0, pyfilename); 859 | 860 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_save, args); 861 | if (!res) throw std::runtime_error("Call to save() failed."); 862 | 863 | Py_DECREF(args); 864 | Py_DECREF(res); 865 | } 866 | 867 | inline void clf() { 868 | PyObject *res = PyObject_CallObject( 869 | detail::_interpreter::get().s_python_function_clf, 870 | detail::_interpreter::get().s_python_empty_tuple); 871 | 872 | if (!res) throw std::runtime_error("Call to clf() failed."); 873 | 874 | Py_DECREF(res); 875 | } 876 | 877 | // Actually, is there any reason not to call this automatically for every plot? 878 | inline void tight_layout() { 879 | PyObject *res = PyObject_CallObject( 880 | detail::_interpreter::get().s_python_function_tight_layout, 881 | detail::_interpreter::get().s_python_empty_tuple); 882 | 883 | if (!res) throw std::runtime_error("Call to tight_layout() failed."); 884 | 885 | Py_DECREF(res); 886 | } 887 | 888 | #if __cplusplus > 199711L || _MSC_VER > 1800 889 | // C++11-exclusive content starts here (variadic plot() and initializer list support) 890 | 891 | namespace detail { 892 | template 893 | using is_function = typename std::is_function>>::type; 894 | 895 | template 896 | struct is_callable_impl; 897 | 898 | template 899 | struct is_callable_impl 900 | { 901 | typedef is_function type; 902 | }; // a non-object is callable iff it is a function 903 | 904 | template 905 | struct is_callable_impl 906 | { 907 | struct Fallback { void operator()(); }; 908 | struct Derived : T, Fallback { }; 909 | 910 | template struct Check; 911 | 912 | template 913 | static std::true_type test( ... ); // use a variadic function to make sure (1) it accepts everything and (2) its always the worst match 914 | 915 | template 916 | static std::false_type test( Check* ); 917 | 918 | public: 919 | typedef decltype(test(nullptr)) type; 920 | typedef decltype(&Fallback::operator()) dtype; 921 | static constexpr bool value = type::value; 922 | }; // an object is callable iff it defines operator() 923 | 924 | template 925 | struct is_callable 926 | { 927 | // dispatch to is_callable_impl or is_callable_impl depending on whether T is of class type or not 928 | typedef typename is_callable_impl::value, T>::type type; 929 | }; 930 | 931 | template 932 | struct plot_impl { }; 933 | 934 | template<> 935 | struct plot_impl 936 | { 937 | template 938 | bool operator()(const IterableX& x, const IterableY& y, const std::string& format) 939 | { 940 | // 2-phase lookup for distance, begin, end 941 | using std::distance; 942 | using std::begin; 943 | using std::end; 944 | 945 | auto xs = distance(begin(x), end(x)); 946 | auto ys = distance(begin(y), end(y)); 947 | assert(xs == ys && "x and y data must have the same number of elements!"); 948 | 949 | PyObject* xlist = PyList_New(xs); 950 | PyObject* ylist = PyList_New(ys); 951 | PyObject* pystring = PyString_FromString(format.c_str()); 952 | 953 | auto itx = begin(x), ity = begin(y); 954 | for(size_t i = 0; i < xs; ++i) { 955 | PyList_SetItem(xlist, i, PyFloat_FromDouble(*itx++)); 956 | PyList_SetItem(ylist, i, PyFloat_FromDouble(*ity++)); 957 | } 958 | 959 | PyObject* plot_args = PyTuple_New(3); 960 | PyTuple_SetItem(plot_args, 0, xlist); 961 | PyTuple_SetItem(plot_args, 1, ylist); 962 | PyTuple_SetItem(plot_args, 2, pystring); 963 | 964 | PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_plot, plot_args); 965 | 966 | Py_DECREF(plot_args); 967 | if(res) Py_DECREF(res); 968 | 969 | return res; 970 | } 971 | }; 972 | 973 | template<> 974 | struct plot_impl 975 | { 976 | template 977 | bool operator()(const Iterable& ticks, const Callable& f, const std::string& format) 978 | { 979 | //std::cout << "Callable impl called" << std::endl; 980 | 981 | if(begin(ticks) == end(ticks)) return true; 982 | 983 | // We could use additional meta-programming to deduce the correct element type of y, 984 | // but all values have to be convertible to double anyways 985 | std::vector y; 986 | for(auto x : ticks) y.push_back(f(x)); 987 | return plot_impl()(ticks,y,format); 988 | } 989 | }; 990 | } 991 | 992 | // recursion stop for the above 993 | template 994 | bool plot() { return true; } 995 | 996 | template 997 | bool plot(const A& a, const B& b, const std::string& format, Args... args) 998 | { 999 | return detail::plot_impl::type>()(a,b,format) && plot(args...); 1000 | } 1001 | 1002 | /* 1003 | * This group of plot() functions is needed to support initializer lists, i.e. calling 1004 | * plot( {1,2,3,4} ) 1005 | */ 1006 | bool plot(const std::vector& x, const std::vector& y, const std::string& format = "") { 1007 | return plot(x,y,format); 1008 | } 1009 | 1010 | bool plot(const std::vector& y, const std::string& format = "") { 1011 | return plot(y,format); 1012 | } 1013 | 1014 | bool plot(const std::vector& x, const std::vector& y, const std::map& keywords) { 1015 | return plot(x,y,keywords); 1016 | } 1017 | 1018 | bool named_plot(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") { 1019 | return named_plot(name,x,y,format); 1020 | } 1021 | 1022 | #endif 1023 | 1024 | } 1025 | --------------------------------------------------------------------------------