Estimating Region covered by all sides - python-3.x

I need some help in estimating somekind of of morphological operations(preferably using skimage or scipy image or python in general) that can help me isolate the regions that are enclosed by all sides(see images.) The problem is the outer shell can be of varied shape and size. The enclosed regions are also of varied shapes and sizes.
Examples of the image where the enclosed(by the white regions) black region needs to isolated.
By isolation I mean to get all the pixel coordinates in the enclosed black regions.
Example 1
Example 2
Also another caveat is that the images like this should not be filled up.

Use scipy.ndimage.binary_fill_holes
from scipy import ndimage as ndi
filled = ndi.binary_fill_holes(image)
holes = filled - image # or np.logical_xor(filled, image)

I prefer #Juan's solution, but just for fun, here's a slightly different approach. Floodfill with white starting from the top-left corner and your fully-enclosed pixels will be all that is left over.
#!/usr/bin/env python3
import numpy as np
from skimage.segmentation import flood_fill
import cv2
im = cv2.imread('scan.png', cv2.IMREAD_GRAYSCALE)
# Fill with white from top-left
filled = flood_fill(im, (0, 0), 255)
# Save result
cv2.imwrite('DEBUG-result.png', filled)
# Get list of black pixels
blk = np.where(filled==0)
print(f'Number of fully enclosed black pixels: {len(blk[0])}')
print(blk)
So that you can see the extent of the image, I have artificially added a red border:
Here is the output:
Number of fully enclosed black pixels: 957
(array([364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364,
364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364,
364, 364, 364, 364, 364, 364, 364, 365, 365, 365, 365, 365, 365,
365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365,
365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365,
365, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
366, 366, 366, 366, 366, 366, 366, 366, 367, 367, 367, 367, 367,
367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367,
367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367,
367, 367, 367, 367, 367, 368, 368, 368, 368, 368, 368, 368, 368,
368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368,
368, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369,
369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369,
369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370,
370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370,
370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370,
370, 370, 370, 370, 370, 370, 370, 370, 370, 371, 371, 371, 371,
371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371,
371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371,
371, 371, 371, 371, 371, 371, 372, 372, 372, 372, 372, 372, 372,
372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372,
372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372,
372, 372, 372, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373,
373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373,
373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 374, 374, 374,
374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374,
374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374,
374, 374, 374, 374, 375, 375, 375, 375, 375, 375, 375, 375, 375,
375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375,
375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 376, 376,
376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376,
376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376,
376, 376, 376, 376, 376, 377, 377, 377, 377, 377, 377, 377, 377,
377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377,
377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 378,
378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378,
378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378,
378, 378, 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 379,
379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379,
379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379,
380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380,
380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380,
380, 380, 380, 380, 380, 380, 380, 381, 381, 381, 381, 381, 381,
381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
381, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382,
382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382,
382, 382, 382, 382, 382, 382, 382, 382, 383, 383, 383, 383, 383,
383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383,
383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383,
383, 383, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,
384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 385, 385, 385,
385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385,
385, 385, 385, 385, 385, 385, 385, 386, 386, 386, 386, 386, 386,
386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386,
386, 386, 386, 386, 386, 387, 387, 387, 387, 387, 387, 387, 387,
387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, 387,
387, 387, 387, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388,
388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 389, 389,
389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389,
389, 389, 389, 389, 389, 389, 390, 390, 390, 390, 390, 390, 390,
390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390,
390, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391,
391, 391, 391, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392,
392, 392, 392, 392, 392, 393, 393, 393, 393, 393, 393, 393, 393,
393, 393, 393, 393, 393, 393, 393, 394, 394, 394, 394, 394, 394,
394, 394, 394, 394, 394, 394, 394, 394, 394, 395, 395, 395, 395,
395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, 396, 396,
396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397,
397, 397, 397, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399,
399, 399, 400, 400, 400, 401, 401, 401]), array([244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256,
257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
270, 271, 272, 273, 274, 275, 276, 244, 245, 246, 247, 248, 249,
250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
276, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
269, 270, 271, 272, 273, 274, 275, 276, 241, 242, 243, 244, 245,
246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258,
259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
272, 273, 274, 275, 276, 241, 242, 243, 244, 245, 246, 247, 248,
249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 241,
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
268, 269, 270, 271, 272, 273, 274, 275, 276, 241, 242, 243, 244,
245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
271, 272, 273, 274, 275, 276, 241, 242, 243, 244, 245, 246, 247,
248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
274, 275, 276, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263,
264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 241, 242, 243,
244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256,
257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
270, 271, 272, 273, 241, 242, 243, 244, 245, 246, 247, 248, 249,
250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 241, 242,
243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
269, 270, 271, 272, 273, 241, 242, 243, 244, 245, 246, 247, 248,
249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 241,
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
268, 269, 270, 271, 272, 273, 241, 242, 243, 244, 245, 246, 247,
248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
267, 268, 269, 270, 271, 272, 273, 241, 242, 243, 244, 245, 246,
247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272,
273, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
266, 267, 268, 269, 270, 271, 272, 273, 241, 242, 243, 244, 245,
246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258,
259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
272, 273, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 253, 254, 255, 256,
257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
270, 271, 272, 273, 274, 275, 276, 253, 254, 255, 256, 257, 258,
259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
272, 273, 274, 275, 276, 253, 254, 255, 256, 257, 258, 259, 260,
261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
274, 275, 276, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 256, 257,
258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
271, 272, 273, 274, 275, 276, 256, 257, 258, 259, 260, 261, 262,
263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
276, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
271, 272, 273, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
269, 270, 271, 272, 273, 259, 260, 261, 262, 263, 264, 265, 266,
267, 268, 269, 270, 271, 272, 273, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 259, 260, 261, 262,
263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 262, 263,
264, 265, 266, 267, 268, 269, 270, 262, 263, 264, 265, 266, 267,
268, 269, 270, 262, 263, 264, 265, 266, 267, 268, 269, 270, 265,
266, 267, 265, 266, 267, 265, 266, 267]))
Hopefully you can see from the first element of each array that the first black pixel is at 364,244
Note that, if there is the possibility that the scan would touch the edge of the image, the flood-fill will fail to "flow" all the way around the edges. In this case, you can simply add a 1-pixel wide black border all the way around the edge for the floodfill to flow around... and remove it afterwards.

Related

How can I write an Access (or Excel) query For range of values in one column change value of fields in another column

How can I write an Access (or Excel) query for a range of values in one column to change value of the respective fields in another column.
Of a range or array of values in column 'nParentSectionID' change value of respective fields in 'bSuppressHtml' to 'TRUE'
This would be the array follows:
1, 10, 20, 22, 23, 37, 68, 97, 101, 103, 106, 115, 116, 118, 119, 120, 121, 122, 123, 124, 127, 129, 130, 131, 133, 136, 137, 141, 148, 157, 159, 160, 165, 166, 169, 170, 172, 174, 175, 176, 178, 180, 182, 184, 186, 187, 188, 190, 191, 193, 198, 200, 201, 202, 226, 229, 230, 231, 238, 241, 244, 247, 249, 252, 256, 259, 262, 263, 264, 266, 268, 270, 271, 277, 278, 280, 281, 282, 284, 286, 292, 296, 299, 307, 310, 319, 325, 329, 331, 335, 340, 341, 346, 348, 353, 362, 365, 366, 370, 374, 382, 383, 385, 386, 410, 412, 413, 416, 418, 419, 428, 429, 444, 446, 448, 451, 453, 456, 462, 463, 467, 469, 493, 500, 501, 502, 503, 505, 506, 511, 512, 515, 519, 525, 526, 527, 532, 535, 536, 537, 550, 551, 555, 563, 565, 566, 567, 573, 575, 576, 577, 578, 579, 581, 595, 598, 599, 603, 609, 611, 623, 626, 627, 640, 641, 642, 643, 644, 647, 651, 654, 655, 664, 669, 670, 672, 688, 689, 690, 695, 696, 697, 702, 705, 706, 716, 717, 725, 729, 731, 732, 738, 740, 741, 743, 744, 746, 749, 751, 752, 753, 757, 758, 759, 768, 772, 779, 782, 783, 802, 805, 810, 811, 814, 818, 819, 821, 836, 841, 846, 847, 849, 852, 854, 857, 862, 871, 872, 877, 882, 920, 922, 923, 930, 934, 935, 937, 938, 942, 944, 952, 958, 963, 981, 984, 987, 988, 991, 994, 1037, 1041, 1051, 1058, 1059, 1060, 1062, 1064, 1067, 1071, 1075, 1095, 1117, 1119, 1133, 1140, 1164, 1166, 1182, 1203, 1211, 1226, 1234, 1240, 1241, 1242, 1244, 1251, 1252, 1253, 1272, 1281, 1283, 1310, 1321, 1322, 1335, 1342, 1346, 1348, 1350, 1353, 1355, 1365, 1373, 1384, 1390, 1392, 1394, 1405, 1413, 1414, 1415, 1417, 1424, 1425, 1430, 1464, 1465, 1468, 1471, 1476, 1482, 1484, 1528, 1532, 1534, 1540, 1560, 1565, 1568, 1569, 1571, 1573, 1576, 1577, 1602, 1603, 1605, 1685, 1714, 1756, 1764, 1776, 1782, 1783, 1786, 1834, 1865, 1974, 1980, 1981, 1983, 1994, 1997, 2023, 2078, 2081, 2087, 2099, 2104, 2116, 2119, 2121, 2125, 2127, 2130, 2135, 2139, 2142, 2146, 2155, 2156, 2191, 2207, 2220, 2227, 2236, 2288, 2329, 2330, 2337, 2363, 2366, 2368, 2371, 2379, 2395, 2422, 2440, 2510, 2550, 2596, 2664, 2716, 2727, 2733, 2772, 2782, 2832, 2874, 2889, 2895, 2945, 2951, 3010, 3050, 3148, 3168, 3169, 3170, 3187, 3254, 3261, 3264, 3278, 3282, 3286, 3292, 3408, 3417, 3427, 3428, 3433, 3479, 3487, 3576, 3588, 3592, 3598, 3600, 3605, 3640, 3656, 3660, 3668, 3669, 3673, 3682, 3691
UPDATE product SET bSuppresshtml = true, bExcludeFromFroogle = true
WHERE nParentSectionID in (select nSectionID from [catalog section] where nSectionID in
(1, 9, 10, 11, 12, 20, 22, 23, 37, 54, 68, 97, 101, 103, 106, 115, 116, 118, 119, 120, 121, 122, 123, 124, 127, 129, 130, 131, 133, 135, 136, 137, 141, 148, 157, 159, 160, 165, 166, 168, 169, 170, 172, 173, 174, 175, 176, 178, 180, 181, 182, 184, 186, 187, 188, 190, 191, 193, 198, 199, 200, 201, 202, 226, 229, 230, 231, 238, 241, 244, 246, 247, 249, 252, 256, 259, 262, 263, 264, 266, 268, 270, 271, 272, 277, 278, 280, 281, 282, 284, 286, 289, 290, 291, 292, 296, 299, 307, 310, 319, 323, 325, 329, 331, 335, 338, 339, 340, 341, 344, 346, 347, 348, 353, 362, 365, 366, 368, 370, 374, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 410, 411, 412, 413, 416, 418, 419, 425, 427, 428, 429, 430, 431, 432, 433, 444, 446, 448, 451, 453, 454, 455, 456, 457, 458, 459, 460, 462, 463, 467, 469, 493, 496, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 524, 525, 526, 527, 528, 529, 531, 532, 533, 534, 535, 536, 537, 546, 547, 548, 549, 550, 551, 552, 553, 555, 560, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 586, 592, 594, 595, 597, 598, 599, 600, 602, 603, 604, 605, 606, 607, 609, 610, 611, 614, 617, 618, 623, 626, 627, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 654, 655, 656, 658, 660, 661, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 688, 689, 690, 695, 696, 697, 699, 702, 704, 705, 706, 716, 717, 725, 729, 731, 732, 737, 738, 740, 741, 742, 743, 744, 746, 748, 749, 751, 752, 753, 754, 755, 757, 758, 759, 768, 769, 770, 772, 776, 777, 778, 779, 781, 782, 783, 784, 787, 789, 802, 805, 810, 811, 812, 814, 818, 819, 820, 821, 836, 841, 843, 846, 847, 849, 850, 852, 853, 854, 856, 857, 861, 862, 865, 871, 872, 877, 882, 891, 892, 896, 897, 899, 903, 904, 908, 909, 910, 911, 916, 917, 918, 920, 922, 923, 924, 925, 927, 929, 930, 931, 934, 935, 937, 938, 942, 944, 948, 949, 950, 952, 958, 963, 980, 981, 984, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 1037, 1041, 1051, 1053, 1054, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1071, 1072, 1073, 1074, 1075, 1084, 1085, 1086, 1087, 1095, 1104, 1105, 1110, 1117, 1119, 1133, 1139, 1140, 1147, 1148, 1149, 1163, 1164, 1166, 1182, 1185, 1203, 1211, 1226, 1229, 1231, 1233, 1234, 1235, 1236, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1255, 1256, 1257, 1258, 1259, 1265, 1269, 1272, 1281, 1283, 1310, 1318, 1321, 1322, 1335, 1342, 1346, 1348, 1350, 1352, 1353, 1355, 1362, 1365, 1373, 1384, 1386, 1387, 1390, 1392, 1393, 1394, 1395, 1396, 1397, 1405, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1423, 1424, 1425, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1464, 1465, 1466, 1468, 1471, 1476, 1482, 1484, 1487, 1489, 1495, 1496, 1497, 1498, 1503, 1504, 1506, 1518, 1528, 1532, 1534, 1540, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1568, 1569, 1570, 1571, 1572, 1573, 1576, 1577, 1580, 1585, 1591, 1592, 1593, 1596, 1600, 1602, 1603, 1605, 1633, 1645, 1671, 1681, 1682, 1683, 1685, 1714, 1723, 1724, 1725, 1726, 1727, 1756, 1764, 1773, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1788, 1789, 1791, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1812, 1813, 1814, 1816, 1834, 1835, 1865, 1937, 1974, 1980, 1981, 1983, 1994, 1995, 1996, 1997, 2023, 2078, 2081, 2082, 2087, 2099, 2104, 2109, 2111, 2116, 2119, 2121, 2125, 2127, 2130, 2135, 2139, 2142, 2143, 2144, 2146, 2155, 2156, 2157, 2164, 2168, 2169, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2181, 2182, 2183, 2184, 2186, 2187, 2191, 2195, 2197, 2198, 2200, 2201, 2205, 2206, 2207, 2212, 2220, 2225, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2236, 2252, 2255, 2256, 2288, 2291, 2292, 2299, 2300, 2301, 2322, 2326, 2329, 2330, 2334, 2335, 2337, 2363, 2366, 2368, 2371, 2376, 2379, 2390, 2395, 2402, 2416, 2417, 2418, 2420, 2422, 2426, 2429, 2430, 2431, 2433, 2435, 2436, 2437, 2438, 2440, 2442, 2443, 2444, 2445, 2447, 2449, 2456, 2457, 2461, 2463, 2464, 2465, 2466, 2479, 2481, 2482, 2489, 2500, 2510, 2513, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2524, 2527, 2531, 2543, 2550, 2555, 2560, 2562, 2563, 2565, 2569, 2570, 2571, 2573, 2574, 2575, 2576, 2588, 2589, 2590, 2596, 2599, 2606, 2607, 2640, 2642, 2643, 2644, 2653, 2658, 2659, 2660, 2661, 2662, 2663, 2664, 2671, 2680, 2696, 2700, 2706, 2716, 2718, 2719, 2721, 2727, 2729, 2730, 2731, 2733, 2747, 2752, 2753, 2762, 2772, 2782, 2790, 2791, 2792, 2817, 2818, 2820, 2824, 2832, 2838, 2839, 2841, 2844, 2849, 2856, 2857, 2862, 2864, 2874, 2875, 2876, 2877, 2881, 2882, 2883, 2884, 2889, 2895, 2927, 2928, 2929, 2931, 2945, 2947, 2951, 2953, 2954, 2955, 2956, 2961, 2962, 2975, 2983, 2990, 3000, 3001, 3002, 3005, 3010, 3014, 3019, 3020, 3021, 3035, 3050, 3056, 3058, 3064, 3065, 3066, 3067, 3068, 3070, 3072, 3073, 3079, 3080, 3081, 3082, 3091, 3101, 3102, 3103, 3105, 3106, 3107, 3128, 3148, 3167, 3168, 3169, 3170, 3181, 3183, 3187, 3200, 3202, 3215, 3224, 3225, 3253, 3254, 3255, 3256, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3267, 3271, 3272, 3274, 3278, 3279, 3282, 3286, 3292, 3300, 3309, 3319, 3320, 3321, 3325, 3326, 3328, 3345, 3349, 3358, 3359, 3367, 3368, 3369, 3374, 3396, 3405, 3408, 3417, 3422, 3423, 3427, 3428, 3431, 3433, 3446, 3473, 3474, 3475, 3476, 3477, 3478, 3479, 3487, 3495, 3496, 3499, 3500, 3503, 3515, 3531, 3533, 3534, 3565, 3576, 3588, 3592, 3598, 3600, 3605, 3640, 3656, 3660, 3668, 3669, 3673, 3682, 3691, )
);
Grateful to you for looking, the above works perfectly.

ortools vrp does not give me any solution

I want solve a vehicle routing problem with ORTools, both distance and duration matrix will be used.
but the problem is when I change the matrix , it wouldn't give me any solutions anymore!
there are 2 groups of matrixes. with the commented matrixes there is solution, but with the other group, there is not. do you have any idea why this is happening:
from __future__ import print_function
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def create_data_model():
"""Stores the data for the problem."""
data = {}
#data['distance_matrix']=[[0, 329, 146, 157, 318, 528, 457, 242, 491, 335, 471, 456, 391, 128, 461, 555, 460], [329, 0, 399, 384, 544, 493, 339, 378, 108, 243, 125, 394, 136, 561, 505, 315, 447], [146, 399, 0, 262, 471, 316, 297, 227, 548, 377, 267, 430, 383, 154, 234, 188, 400], [157, 384, 262, 0, 440, 271, 383, 525, 223, 367, 511, 354, 112, 539, 159, 152, 373], [318, 544, 471, 440, 0, 423, 112, 381, 346, 512, 161, 239, 581, 291, 284, 145, 143], [528, 493, 316, 271, 423, 0, 380, 196, 409, 212, 199, 277, 387, 515, 391, 261, 318], [457, 339, 297, 383, 112, 380, 0, 379, 298, 267, 482, 247, 462, 256, 296, 533, 200], [242, 378, 227, 525, 381, 196, 379, 0, 156, 230, 551, 555, 338, 372, 403, 358, 506], [491, 108, 548, 223, 346, 409, 298, 156, 0, 140, 532, 405, 531, 129, 220, 482, 222], [335, 243, 377, 367, 512, 212, 267, 230, 140, 0, 418, 440, 526, 255, 455, 296, 430], [471, 125, 267, 511, 161, 199, 482, 551, 532, 418, 0, 439, 285, 181, 254, 208, 304], [456, 394, 430, 354, 239, 277, 247, 555, 405, 440, 439, 0, 397, 229, 121, 385, 147], [391, 136, 383, 112, 581, 387, 462, 338, 531, 526, 285, 397, 0, 544, 205, 197, 226], [128, 561, 154, 539, 291, 515, 256, 372, 129, 255, 181, 229, 544, 0, 150, 204, 516], [461, 505, 234, 159, 284, 391, 296, 403, 220, 455, 254, 121, 205, 150, 0, 192, 544], [555, 315, 188, 152, 145, 261, 533, 358, 482, 296, 208, 385, 197, 204, 192, 0, 138], [460, 447, 400, 373, 143, 318, 200, 506, 222, 430, 304, 147, 226, 516, 544, 138, 0]]
data['distance_matrix']=[[0, 228, 299, 301, 235, 208, 405, 447, 144, 579], [228, 0, 343, 288, 357, 426, 530, 510, 122, 490], [299, 343, 0, 236, 228, 523, 274, 377, 397, 530], [301, 288, 236, 0, 594, 523, 289, 397, 154, 380], [235, 357, 228, 594, 0, 558, 370, 444, 173, 558], [208, 426, 523, 523, 558, 0, 219, 278, 504, 507], [405, 530, 274, 289, 370, 219, 0, 195, 283, 257], [447, 510, 377, 397, 444, 278, 195, 0, 407, 417], [144, 122, 397, 154, 173, 504, 283, 407, 0, 273], [579, 490, 530, 380, 558, 507, 257, 417, 273, 0]]
data['time_matrix']=[[0, 205, 519, 308, 428, 574, 399, 138, 573, 541], [205, 0, 447, 578, 296, 536, 135, 345, 198, 315], [519, 447, 0, 209, 438, 174, 231, 382, 104, 522], [308, 578, 209, 0, 235, 264, 492, 305, 134, 538], [428, 296, 438, 235, 0, 600, 177, 435, 204, 556], [574, 536, 174, 264, 600, 0, 476, 119, 183, 476], [399, 135, 231, 492, 177, 476, 0, 497, 208, 167], [138, 345, 382, 305, 435, 119, 497, 0, 344, 454], [573, 198, 104, 134, 204, 183, 208, 344, 0, 422], [541, 315, 522, 538, 556, 476, 167, 454, 422, 0]]
data['cost_matrix']=[[0, 160, 135, 433, 581, 453, 336, 329, 343, 237], [160, 0, 313, 596, 576, 458, 264, 380, 348, 354], [135, 313, 0, 591, 391, 211, 561, 236, 304, 414], [433, 596, 591, 0, 539, 253, 427, 300, 214, 118], [581, 576, 391, 539, 0, 243, 521, 499, 560, 255], [453, 458, 211, 253, 243, 0, 571, 216, 121, 314], [336, 264, 561, 427, 521, 571, 0, 425, 271, 165], [329, 380, 236, 300, 499, 216, 425, 0, 425, 549], [343, 348, 304, 214, 560, 121, 271, 425, 0, 176], [237, 354, 414, 118, 255, 314, 165, 549, 176, 0]]
data['num_vehicles'] = 4
data['depot'] = 0
return data
def print_solution(data, manager, routing, assignment):
"""Prints assignment on console."""
total_cost ,total_distance,total_time= 0,0,0
print('Objective: {}'.format(assignment.ObjectiveValue()))
distance_dimension=routing.GetDimensionOrDie('Distance')
time_dimension=routing.GetDimensionOrDie('Time')
for vehicle_id in range(data['num_vehicles']):
index = routing.Start(vehicle_id)
plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
route_cost = 0
route_distance = 0
route_time = 0
while not routing.IsEnd(index):
plan_output += ' {} -> '.format(manager.IndexToNode(index))
distance_var=distance_dimension.CumulVar(index)
time_var=time_dimension.CumulVar(index)
previous_index = index
index = assignment.Value(routing.NextVar(index))
route_cost += routing.GetArcCostForVehicle(previous_index, index, vehicle_id)
route_distance+=assignment.Value(distance_var)
route_time+=assignment.Value(time_var)
plan_output += '{}\n'.format(manager.IndexToNode(index))
plan_output += 'Cost of the route: {0}\nDistance of the route: {1}m\nTime of route: {2}\n'.format(
route_cost,
route_distance,
route_time)
print(plan_output)
total_cost += route_cost
total_time+=route_time
total_distance+=route_distance
print('Total Cost of all routes: {}\nTotal Distance of all routes: {}\nTotal Time of all routes: {}\n'.format(total_cost,total_distance,total_time))
def get_routes(manager, routing, solution, num_routes):
"""Get vehicle routes from a solution and store them in an array."""
# Get vehicle routes and store them in a two dimensional array whose
# i,j entry is the jth location visited by vehicle i along its route.
routes = []
for route_nbr in range(num_routes):
index = routing.Start(route_nbr)
route = [manager.IndexToNode(index)]
while not routing.IsEnd(index):
index = solution.Value(routing.NextVar(index))
route.append(manager.IndexToNode(index))
routes.append(route)
return routes
def main():
# Instantiate the data problem.
data = create_data_model()
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['cost_matrix']), data['num_vehicles'], data['depot'])
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
# Create and register a transit callback.
def cost_callback(from_index, to_index):
"""Returns the distance between the two nodes."""
# Convert from routing variable Index to distance matrix NodeIndex.
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data['cost_matrix'][from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(cost_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Add Cost constraint.
routing.AddDimension(
transit_callback_index,
0, # no slack
3000, # vehicle maximum travel distance
False, # start cumul to zero
'Cost')
cost_dimension = routing.GetDimensionOrDie('Cost')
cost_dimension.SetGlobalSpanCostCoefficient(1000)
#Add Distance constraint.
def distance_callback(from_index,to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data['distance_matrix'][from_node][to_node]
distance_callback_index=routing.RegisterTransitCallback(distance_callback)
routing.AddDimension(
distance_callback_index,
0,
3000,
False,
'Distance')
distance_dimension=routing.GetDimensionOrDie('Distance')
#Add Time constraint.
def time_callback(from_index,to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data['time_matrix'][from_node][to_node]
time_callback_index=routing.RegisterTransitCallback(time_callback)
routing.AddDimension(
time_callback_index,
0,
300,
False,
'Time')
time_dimension=routing.GetDimensionOrDie('Time')
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
search_parameters.solution_limit = 100
search_parameters.time_limit.seconds = 3
# Solve the problem.
assignment = routing.SolveWithParameters(search_parameters)
# Print solution on console.
if assignment:
print_solution(data, manager, routing, assignment)
routes = get_routes(manager, routing, assignment, data['num_vehicles'])
# Display the routes.
for i, route in enumerate(routes):
print('Route', i, route)
if __name__ == '__main__':
main()
None could mean that it did not find a solution. Most likely your limits are too low
by increasing the limits, it works fine.
but for better understanding, it's better to check solver status. time limit errors mostly refer to the low limitations.
in this example we have many value more than 300 in time matrix but the maximum time for every vehicle is 300.so there is not a feasible solution for this problem.

Compute optimal route for picking ressources

Here are the rules (Halite 3):
At each turn, you have to take one decision for your ship. You can either move right, move left, move up, move down or stay still (and gather ressoureces).
Moving your ship cost your ship 10% of current's cell available ressources.
Staying still cost you nothing and you pick 25% of current cell available ressources. If a ship doesn't have enought ressources to pay the 10% to move, he is pinned on the cell for this turn (can't go negative).
My goal: The ship starts at the center (0) and should return at this point with atleast (X amount of ressources) in the less turn possible.
How can I compute the most efficient path (round wise) that my ship should take to achieve my goal ?
Here is some code to compute a random map (the map is random every game) :
import random
how_Big = 11
center_Pos = int(how_Big/2) #how_Big must be even
game_Map = [[random.randint(1,500) for i in range(how_Big)] for x in range(how_Big)]
game_Map[center_Pos][center_Pos] = 0
for y in range(how_Big):
print(game_Map[y])
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 479, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 172, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
I am not really sure how to start. Is there any known algorithm for this ?
Thanks
Additionnal informations :
The matrix is the available ressources at the beginning on each cell.
Ship begins with 0 ressources.
Ship gains ressources by staying still for a round on a cell
(collecting 25% of the cell's ressources).
Ship spends ressources (of his own cargo) by moving (the cost is 10%
of current cell's available ressources).
The path can be returned in anyway, for example (moves = ["up",
"still", "still", "up", "still", "still", "down", "down"]).
BruteForcing it would be acceptable.
X would be the minimum ammount I want my ship's cargo to have when
returning to center.
Map always has a center Cell
Ressources collected or used are always rounded to nearest Int
Ressources collected by a ship are removed from the cell
Here is an example of what can happen :
move_Dict = {
"up": [-1, 0],
"down": [1, 0],
"right": [0, 1],
"left": [0, -1],
"still": [0, 0],
}
moves = ["up", "still", "still", "up", "still", "still", "down", "down"]
position = [5, 5]
cargo = 0
print("initial map :")
for y in range(how_Big):
print(game_Map[y])
for move in moves:
if move == "still":
ressources_Collected = round(game_Map[position[0]][position[1]] * 0.25)
cargo += ressources_Collected
game_Map[position[0]][position[1]] -= ressources_Collected
else:
ressources_Used = round(game_Map[position[0]][position[1]] * 0.10)
cargo -= ressources_Used
position = [position[0]+move_Dict[move][0], position[1]+move_Dict[move][1]]
print(f"ship is at position {position}, cargo = {cargo}")
for y in range(how_Big):
print(game_Map[y])
Output:
initial map :
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 479, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 172, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
ship is at position [4, 5], cargo = 0
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 479, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 172, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
ship is at position [4, 5], cargo = 43
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 479, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 129, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
ship is at position [4, 5], cargo = 75
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 479, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 97, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
ship is at position [3, 5], cargo = 65
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 479, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 97, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
ship is at position [3, 5], cargo = 185
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 359, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 97, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
ship is at position [3, 5], cargo = 275
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 269, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 97, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
ship is at position [4, 5], cargo = 248
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 269, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 97, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
ship is at position [5, 5], cargo = 238
[110, 179, 97, 467, 347, 336, 368, 298, 107, 84, 123]
[415, 86, 12, 75, 354, 74, 250, 221, 51, 254, 252]
[368, 235, 389, 1, 155, 186, 149, 135, 458, 243, 344]
[391, 480, 485, 358, 416, 269, 270, 354, 203, 436, 146]
[62, 132, 490, 33, 445, 97, 127, 274, 130, 77, 356]
[239, 11, 459, 245, 214, 0, 324, 162, 58, 394, 202]
[241, 395, 46, 78, 191, 384, 203, 191, 56, 474, 237]
[85, 480, 181, 98, 122, 482, 90, 351, 257, 266, 182]
[398, 125, 195, 423, 219, 290, 140, 166, 413, 499, 428]
[213, 367, 142, 471, 141, 407, 382, 229, 332, 455, 53]
[207, 12, 319, 54, 246, 274, 474, 312, 170, 374, 188]
[Finished in 0.1s]

Python fbprophet - export values from plot_components() for yearly

Any ideas on how to export the yearly seasonal trend using fbprophet library?
The plot_components() function plots the trend, yearly, and weekly.
I want to obtain the values for yearly only.
Example data:
import pandas as pd
from fbprophet import Prophet
import matplotlib.pyplot as plt
df = pd.DataFrame.from_dict({'ds': ['1949-01', '1949-02', '1949-03', '1949-04', '1949-05', '1949-06',
'1949-07', '1949-08', '1949-09', '1949-10', '1949-11', '1949-12',
'1950-01', '1950-02', '1950-03', '1950-04', '1950-05', '1950-06',
'1950-07', '1950-08', '1950-09', '1950-10', '1950-11', '1950-12',
'1951-01', '1951-02', '1951-03', '1951-04', '1951-05', '1951-06',
'1951-07', '1951-08', '1951-09', '1951-10', '1951-11', '1951-12',
'1952-01', '1952-02', '1952-03', '1952-04', '1952-05', '1952-06',
'1952-07', '1952-08', '1952-09', '1952-10', '1952-11', '1952-12',
'1953-01', '1953-02', '1953-03', '1953-04', '1953-05', '1953-06',
'1953-07', '1953-08', '1953-09', '1953-10', '1953-11',
'1953-12',
'1954-01', '1954-02', '1954-03', '1954-04', '1954-05', '1954-06',
'1954-07', '1954-08', '1954-09', '1954-10', '1954-11', '1954-12',
'1955-01', '1955-02', '1955-03', '1955-04', '1955-05', '1955-06',
'1955-07', '1955-08', '1955-09', '1955-10', '1955-11', '1955-12',
'1956-01', '1956-02', '1956-03', '1956-04', '1956-05', '1956-06',
'1956-07', '1956-08', '1956-09', '1956-10', '1956-11', '1956-12',
'1957-01', '1957-02', '1957-03', '1957-04', '1957-05', '1957-06',
'1957-07', '1957-08', '1957-09', '1957-10', '1957-11', '1957-12',
'1958-01', '1958-02', '1958-03', '1958-04', '1958-05', '1958-06',
'1958-07', '1958-08', '1958-09', '1958-10', '1958-11', '1958-12',
'1959-01', '1959-02', '1959-03', '1959-04', '1959-05', '1959-06',
'1959-07', '1959-08', '1959-09', '1959-10', '1959-11', '1959-12',
'1960-01', '1960-02', '1960-03', '1960-04', '1960-05', '1960-06',
'1960-07', '1960-08', '1960-09', '1960-10', '1960-11', '1960-12'],
'y': [112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118, 115, 126,
141, 135, 125, 149, 170, 170, 158, 133, 114, 140, 145, 150, 178, 163,
172, 178, 199, 199, 184, 162, 146, 166, 171, 180, 193, 181, 183, 218,
230, 242, 209, 191, 172, 194, 196, 196, 236, 235, 229, 243, 264, 272,
237, 211, 180, 201, 204, 188, 235, 227, 234, 264, 302, 293, 259, 229,
203, 229, 242, 233, 267, 269, 270, 315, 364, 347, 312, 274, 237, 278,
284, 277, 317, 313, 318, 374, 413, 405, 355, 306, 271, 306, 315, 301,
356, 348, 355, 422, 465, 467, 404, 347, 305, 336, 340, 318, 362, 348,
363, 435, 491, 505, 404, 359, 310, 337, 360, 342, 406, 396, 420, 472,
548, 559, 463, 407, 362, 405, 417, 391, 419, 461, 472, 535, 622, 606,
508, 461, 390, 432]})
df['ds'] = pd.to_datetime(df['ds'])
fbprophet plot_components():
model = Prophet()
model.fit(df)
future = model.make_future_dataframe(12, 'm')
fc = model.predict(future)
model.plot_components(fc)
plt.show()
I understand your question to mean "How do we get the values used in the "yearly" plot above?
days = (pd.date_range(start='2017-01-01', periods=365) + pd.Timedelta(days=0))
df_y = model.seasonality_plot_df(days)
seas = model.predict_seasonal_components(df_y)
fig,ax = plt.subplots(2, 1, figsize=(8,6))
ax[0].plot(fc['ds'].dt.to_pydatetime(), fc['trend'])
ax[0].grid(alpha=0.5)
ax[0].set_xlabel('ds')
ax[1].set_ylabel('trend')
ax[1].plot(df_y['ds'].dt.to_pydatetime(), seas['yearly'], ls='-', c='#0072B2')
ax[1].set_xlabel('Day of year')
ax[1].set_ylabel('yearly')
ax[1].grid(alpha=0.5)
plt.show()
Plot results:
How to obtain the values for yearly only?
The X values are an arbitrary yearly time period (basically). The y values use functions seasonality_plot_df() and predict_seasonal_components() to predict daily seasonality for a year time-span. You retrieve these values by looking in seas['yearly'].
There is a simple solution in the current version of the library. You can use from the predicted model fc. What you want for the value of yearly can be found with fc['yearly'] without using the functions in the above solution.
Moreover, if you want all the other components like trend, you can use fc['trend'].

'list' object is not callable python

numbers = [
951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544,
615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941,
386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345,
399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217,
815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717,
958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470,
743, 527]
count=0
while numbers(count)==527:
print(numbers(count))
count+=1
may in know what is the error in above code?
what is meant by "'list' object is not callable"
please correct the code
thanks.
numbers(count) replace on numbers[count]
count=0
while numbers[count]!=527:
print(numbers(count))
count+=1
If you want print all numbers except last:
for item in numbers[0:-1]:
print(item)
while numbers(count)==527: means that numbers is interpreted as a function with one argument, count. numbers is actually a list object, so when the interpreter tries to call the 'function' it will return the error you're seeing.
You need to use [] for indexing and slicing.
Your revised code would look like this:
numbers = [
951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544,
615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941,
386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345,
399, 162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217,
815, 67, 104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717,
958, 609, 842, 451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470,
743, 527]
count=0
while numbers[count]!=527:
print(numbers[count])
count+=1
This will print every item in numbers up until you get to the first instance of 527.

Resources