Compare commits
694 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2022aebb07 | |||
| b73c38fe69 | |||
| 82479d48b9 | |||
| a07fd5d3db | |||
| 10ab3ae974 | |||
| b908202c47 | |||
| 61d4c84ef4 | |||
| 68a0baf299 | |||
| aef75cb073 | |||
| c5fe90d135 | |||
| 85e5f2e971 | |||
| 58bf14fc85 | |||
| 0d09975fba | |||
| 06afcedf56 | |||
| c7cc76b2b6 | |||
| 84b108f6d0 | |||
| cb6f0772b7 | |||
| 4263ced69b | |||
| f5c6b06eb6 | |||
| 05ef841d63 | |||
| 140afeb53d | |||
| 639a09bccb | |||
| f105d41e54 | |||
| 140a429e09 | |||
| 28d5e0bb7d | |||
| 3dec7fe394 | |||
| e54eb53665 | |||
| 9b3cf3a818 | |||
| 3d306578f1 | |||
| e615718f1b | |||
| fbbbd40353 | |||
| 0e694a9767 | |||
| 203e351cef | |||
| 74ec895aca | |||
| 3459bcd817 | |||
| d2c0840c43 | |||
| 9534bae4ef | |||
| 2a720a7491 | |||
| 7b31e5f9b8 | |||
| d0be1e7d1d | |||
| 8434741599 | |||
| cfe1ede25a | |||
| ecc891279e | |||
| 750f96cca7 | |||
| 5051e06be0 | |||
| cde041e977 | |||
| 0fdf46fd2e | |||
| c902c3ff35 | |||
| f0b006d3c9 | |||
| 044daf08d4 | |||
| 0b5b8b2cc2 | |||
| fae5c45cc4 | |||
| 3bc8ffda58 | |||
| 589713cb75 | |||
| ca9ce5427d | |||
| 374809d3cf | |||
| e1d45dec5d | |||
| bf60d6482f | |||
| e04858c975 | |||
| e0148ba1a8 | |||
| ee521107d3 | |||
| acbce64be9 | |||
| bb11426274 | |||
| 2249aaafdf | |||
| 172193e706 | |||
| 93d7e53f8b | |||
| 7e05bb0aca | |||
| a1130efa2f | |||
| e903514f70 | |||
| 87f2b0154e | |||
| 0ab42eb008 | |||
| 39e93f40c2 | |||
| 0458c18c13 | |||
| a3fc47a7de | |||
| 715181585a | |||
| ecadf4c8f6 | |||
| 899c8b3634 | |||
| 68b344e7c3 | |||
| 58cf8e471e | |||
| 68b29f63a6 | |||
| 985d43bf4c | |||
| e3239bf312 | |||
| 39cb3733db | |||
| f9ea9cd999 | |||
| 47900b1a80 | |||
| 9488176a2d | |||
| 091ca327ba | |||
| f2af121661 | |||
| fe07fe0a7b | |||
| c4354c86c0 | |||
| 7ea1eebc9e | |||
| 3d73591178 | |||
| 5335159203 | |||
| 7b2be59b7b | |||
| 3eafc67654 | |||
| acf4cb4e5b | |||
| f53b070d79 | |||
| aaaedcab1a | |||
| 02b54e72a6 | |||
| c034d7bf1b | |||
| 8636718c88 | |||
| f11d5b1e63 | |||
| 903fb84af0 | |||
| 92814e71c7 | |||
| 35e24fef2a | |||
| 95a29f9cbe | |||
| 6ba1607bb1 | |||
| 2bbaf9d504 | |||
| 607640ce73 | |||
| 195c6d601c | |||
| c39a6d8ec3 | |||
| 42e88225c5 | |||
| b9b6915855 | |||
| b2852802db | |||
| ced201700e | |||
| 6d737dea7b | |||
| 311ace523d | |||
| d6bd10a937 | |||
| a03ae0be10 | |||
| faa401f0e5 | |||
| 6378f88ba9 | |||
| f5cbb1e341 | |||
| c9c4de37e6 | |||
| 567d3688e8 | |||
| e3a166f04c | |||
| 74001a555b | |||
| 4c6b96e38a | |||
| 1f14a4d4c6 | |||
| 242d8b290d | |||
| 2cfd1838ca | |||
| 642bb9aead | |||
| fc0a12ac36 | |||
| a2bdc4c3ef | |||
| faf905a932 | |||
| 1ba5ad0e90 | |||
| 59ad0d830b | |||
| 1fcd06f903 | |||
| 66e8f6615e | |||
| 10e7cb8eba | |||
| 3c9a7193fd | |||
| 424b98e1a1 | |||
| 57db8095c4 | |||
| c0e68af63f | |||
| f2f647c642 | |||
| a117bbc04b | |||
| abc212b039 | |||
| cb1d32422a | |||
| 0dd970fc6b | |||
| ce1276bcbd | |||
| c2c1c9d738 | |||
| 6d3e8fcb81 | |||
| 7954adedf3 | |||
| fc6dfb8dcb | |||
| 7f1863f3b9 | |||
| 9fb6b8059f | |||
| e34570e307 | |||
| 32d712ce29 | |||
| bc42001b75 | |||
| 914d3cac44 | |||
| 10868ef565 | |||
| 046643f743 | |||
| 1ef4cfb86a | |||
| 9324123b4d | |||
| eddf523d08 | |||
| 37ff1a73ed | |||
| 91d4e9dbe2 | |||
| 0821ad3c03 | |||
| bf2e5d3fdc | |||
| 7e54cd4306 | |||
| 6ecf783fd5 | |||
| b45c336063 | |||
| 4d9dc31c5e | |||
| ec4420cb38 | |||
| 243ff2d59e | |||
| cc2e8ed513 | |||
| ca0c78fe5c | |||
| e5b678f4a8 | |||
| fe7989798c | |||
| 12efedf3e3 | |||
| 25fec470a7 | |||
| 6d148b05a3 | |||
| 4c3002e72d | |||
| cc4750688e | |||
| be5cd7de2e | |||
| 0d2ccfddfb | |||
| 0b71f55b29 | |||
| 9cdc72662f | |||
| a37d9768a0 | |||
| 7de8d302fa | |||
| e29edc9e97 | |||
| 1e216291ab | |||
| ce5c36ded5 | |||
| 568c4a0228 | |||
| 0c5e561eac | |||
| d796812161 | |||
| 26905b18ac | |||
| 7fc7471f81 | |||
| 3272f72df0 | |||
| ab8b57ed49 | |||
| eb7ac6ea3d | |||
| c056f8525d | |||
| 024a11f35b | |||
| 33390a2c2d | |||
| d409ad22a0 | |||
| c600cb0294 | |||
| 077f1ddb84 | |||
| a9cbe354c1 | |||
| 44341d1ff5 | |||
| e2a4b0eb30 | |||
| d2ca5e3bf3 | |||
| 8cb32b1f14 | |||
| 8553bef132 | |||
| 20f6d559c3 | |||
| d50c28ebe7 | |||
| 1c854519c8 | |||
| 229f74e370 | |||
| fa324561da | |||
| e176c6c315 | |||
| 3b56977c49 | |||
| 5482cfac3f | |||
| 04e5ff7eba | |||
| e230686851 | |||
| 5694ce53f6 | |||
| 4dd4d5eb5f | |||
| 0e94e57263 | |||
| 7bf89d8614 | |||
| d47e8c0f44 | |||
| 48c04a5a44 | |||
| 31bc74e2b1 | |||
| 1e23b8d475 | |||
| 48208998e2 | |||
| 92aafb1349 | |||
| e1e8a480f9 | |||
| b6e641c035 | |||
| fe77659058 | |||
| b645ca984f | |||
| 46a3f2e495 | |||
| e4e9cbf6cb | |||
| d43e53f896 | |||
| 2d947f4a97 | |||
| 71720de7b2 | |||
| 4964eb31fa | |||
| 0b8f7d67dc | |||
| faf6ea72e0 | |||
| b66415a338 | |||
| e14733d460 | |||
| b6f7c8bc4b | |||
| 91aef71891 | |||
| 408db8dc4f | |||
| 4902716a44 | |||
| e084c1410c | |||
| ea790cc7c5 | |||
| c0fc671a83 | |||
| fb418c87ac | |||
| b6da96fb78 | |||
| 1a751c7bae | |||
| 2d100d8261 | |||
| 3f70fdb3aa | |||
| 1819e3dd99 | |||
| 64791017f8 | |||
| 5e0d42898c | |||
| 4486620918 | |||
| b6bd69055b | |||
| 1e2ea1614c | |||
| ea74fcd4d6 | |||
| c39613ddd8 | |||
| 4a4f9dff6a | |||
| cd55218a2c | |||
| 881d415f21 | |||
| db02ffa436 | |||
| 2c78f1ff7b | |||
| 2bf3ddf45b | |||
| d8c48f1a85 | |||
| 1f566294ac | |||
| 86643058b6 | |||
| 6b6d589aa7 | |||
| cbc0419c6e | |||
| 5920f3b34d | |||
| c472ecf3b0 | |||
| 70c507b8f8 | |||
| 2245e572aa | |||
| c984722807 | |||
| 97c0161b9d | |||
| 05eed0fdda | |||
| 9e74976d6d | |||
| c8b75dfae1 | |||
| ca600e9d76 | |||
| 94812cde7a | |||
| 3db930cb93 | |||
| 37300a9345 | |||
| 54fc1ff69c | |||
| 6d1c723e4b | |||
| eab5091147 | |||
| b8f21ad878 | |||
| cb4702f7b8 | |||
| 25313f6b43 | |||
| a0e0c2c950 | |||
| 8b43f70ed4 | |||
| 867a2b8748 | |||
| 63cd86589c | |||
| 31c4414c32 | |||
| 36558389b6 | |||
| 686ab1b51f | |||
| a728ed9a60 | |||
| 00fd916595 | |||
| 7c5b7b09c2 | |||
| c3c63971ab | |||
| 5c1c80fd9a | |||
| c9a9541d0e | |||
| 224858dad5 | |||
| 8a9e963d92 | |||
| 464c0271f0 | |||
| 798d78813a | |||
| 6b0e45c450 | |||
| cf8bd786d0 | |||
| 9b4a51c5be | |||
| b58c52f12c | |||
| 17eef46da2 | |||
| cc14ab20bb | |||
| 978f00bbb9 | |||
| d0a73eb862 | |||
| 0ca5a30b8a | |||
| 76c7d9dc89 | |||
| 653e0b80b2 | |||
| 8b0fc1629a | |||
| a76e756f4f | |||
| f632cd48a4 | |||
| e12b0a585c | |||
| 151ce619dc | |||
| 28903d5db2 | |||
| d179b5d6bf | |||
| 12df8fa500 | |||
| 99293ba5e6 | |||
| 2dc3096ee9 | |||
| 926a023b1d | |||
| 4f705a6e58 | |||
| 74beb86530 | |||
| a55f8d0099 | |||
| caca1b2e3c | |||
| 62fe5d003e | |||
| 216dae97fc | |||
| 07ffa8c117 | |||
| 62dc012c66 | |||
| 831987c76f | |||
| 32b85d48c5 | |||
| f6d37afba0 | |||
| 3b962ffb08 | |||
| 2c3bffaf76 | |||
| ba8110dc20 | |||
| 55e17a4a65 | |||
| 767b8b245a | |||
| 2ea37776ed | |||
| 03d2f704c5 | |||
| f7e19bcf63 | |||
| 1e0fcbc65e | |||
| 5d5c4d76b9 | |||
| 871561afd7 | |||
| 1da4b2eda9 | |||
| 9775abecc2 | |||
| 1650049b88 | |||
| d7cc15d391 | |||
| 57286ea40d | |||
| 5ad4c517e1 | |||
| eba6e29092 | |||
| 7dc6ea355c | |||
| 3e31c4363f | |||
| 61e3abaf80 | |||
| bd8e9dc947 | |||
| 236aaed2a3 | |||
| 37044e5fc8 | |||
| b05d6e2ed3 | |||
| d28164c897 | |||
| 6c68b6f6fe | |||
| d0c6f0d6ee | |||
| 150b5a1f06 | |||
| 8ea6d70433 | |||
| f8ee4da180 | |||
| 4a57f462bc | |||
| 11ae5ea014 | |||
| 4cb3e6a23c | |||
| dd645bcd9f | |||
| bccf4ef563 | |||
| 85e2534e93 | |||
| 2c57e0c958 | |||
| cb161a25da | |||
| a4380586e9 | |||
| f2a583a599 | |||
| 3ea4c8d9ca | |||
| 30f321d88b | |||
| 1db3b69489 | |||
| 3a775315b9 | |||
| 1ed9bcae5c | |||
| 03d57e690c | |||
| 4247584df2 | |||
| 844c3f7002 | |||
| ff774dc409 | |||
| 9fd7a84b48 | |||
| e555f679c1 | |||
| 89613bfee5 | |||
| 3fdf87a955 | |||
| 0f07975857 | |||
| 48a245559c | |||
| 648f26f075 | |||
| 808e20588e | |||
| 82dd5bf3eb | |||
| 0950c738e3 | |||
| f12f6db310 | |||
| ae4031b993 | |||
| 2495d2a1e9 | |||
| 0a97b08c72 | |||
| e0a89c55ac | |||
| 75ac34b719 | |||
| 2072c54c53 | |||
| 6e1ed63005 | |||
| 17e59daeb4 | |||
| 69e83ef89f | |||
| b2707f5c8a | |||
| 0fd24e5210 | |||
| 3dcc7e5556 | |||
| 57ebeae1ad | |||
| 9e35cc3fe1 | |||
| 3e1258aa0c | |||
| 96e1b1d105 | |||
| fe80e486aa | |||
| ad051f21c1 | |||
| ac24a4ae19 | |||
| 7ae43ee9f6 | |||
| 0e79070ad8 | |||
| f11b976574 | |||
| 59da5d5deb | |||
| 0deb7038e6 | |||
| 2ef692c690 | |||
| 9228c0b9ec | |||
| 89d02b1d67 | |||
| a63a9248d6 | |||
| 79777adc07 | |||
| 5619feb6c0 | |||
| f15a721db6 | |||
| d6b3b68cd9 | |||
| 78785fa8fe | |||
| 74c69f575f | |||
| 12e34bb24f | |||
| 4ac5484b4f | |||
| 8306619faf | |||
| 5673477428 | |||
| 84c5b67574 | |||
| e71a15d46e | |||
| daf9556bed | |||
| b6a7c1036c | |||
| 8c2a66b00c | |||
| a1182e0ebe | |||
| 750492f9e3 | |||
| c6893f6cb5 | |||
| 64e035c53c | |||
| adbe515af7 | |||
| f0dac1630f | |||
| ddaa69bce2 | |||
| bb7c2fd660 | |||
| 8dfca61769 | |||
| bb3c54cb27 | |||
| 2816b1128f | |||
| cf0cf972e3 | |||
| bb0e783c02 | |||
| a7b7c5ba81 | |||
| 7214b8b1b1 | |||
| db1e25252a | |||
| 7a248331e7 | |||
| 161ffdee94 | |||
| b3e8fd9c66 | |||
| 538135bc5f | |||
| 0aac0398e8 | |||
| 552024ff31 | |||
| 2f14c37c59 | |||
| 7f8dc486bb | |||
| a89b42229a | |||
| e061d156bc | |||
| 8f4753a0bb | |||
| 068523fac1 | |||
| b3336229ab | |||
| 3614966241 | |||
| 80c1cb954d | |||
| 0f6336b3dd | |||
| cd1ee47ace | |||
| 46ed2f6263 | |||
| 63f6128c87 | |||
| 9f9ac4ec92 | |||
| 7cf223a5b8 | |||
| 9a6e0b3a54 | |||
| 589643d591 | |||
| f75ae01c16 | |||
| 3509648553 | |||
| 94841669bf | |||
| fadc0bf6c7 | |||
| fd2c01808a | |||
| 8342da1ea2 | |||
| e9abb6d021 | |||
| 505989eec7 | |||
| 08a30b255d | |||
| 1543c77a39 | |||
| 4c22a421a1 | |||
| 972c97d5ec | |||
| fd611b3647 | |||
| 71cbaa843c | |||
| bbf8b50ad6 | |||
| ddd083b8c1 | |||
| 03f6c76b53 | |||
| 6d6d4f14b5 | |||
| 0735a3475c | |||
| 9a445d529d | |||
| 1ea5a5ac0b | |||
| bc8370eadd | |||
| cdc5a2b361 | |||
| 4270ac80fb | |||
| 405df5da8b | |||
| f742ae4c88 | |||
| a99783dfa0 | |||
| 9af5edd04d | |||
| d0830b90be | |||
| 8cd48bc660 | |||
| 379a320d2d | |||
| d5f3a3ef69 | |||
| a3be970f29 | |||
| 63f8f52c9f | |||
| 169851564c | |||
| c32b9029d1 | |||
| 3fe60b9d18 | |||
| 34cff752f1 | |||
| 0dba83daf6 | |||
| c399092261 | |||
| dcabb2c579 | |||
| 3542785021 | |||
| 65173e6dd2 | |||
| bf0bb68e28 | |||
| 21774dc36b | |||
| 0e3a9f0b8f | |||
| 903cb404c3 | |||
| 03325533bf | |||
| 710123aab4 | |||
| 4742ec972b | |||
| e860ba220a | |||
| 39605bccc2 | |||
| 1a4f411b8f | |||
| a6588daa3e | |||
| b053366b06 | |||
| e838ac502d | |||
| 6131154dd0 | |||
| 0c67a61e7d | |||
| 72696a4326 | |||
| 3231f4d9b1 | |||
| 8a81b398cf | |||
| a37a1a0004 | |||
| b6b00c843a | |||
| 5506c0543c | |||
| 7a1b48311c | |||
| 0b3dafcd18 | |||
| 81f6b3c7bd | |||
| c2da4acb48 | |||
| 841b05631d | |||
| a6e60aea04 | |||
| 7f2a1db64a | |||
| 926ccdf618 | |||
| 9774eca8e2 | |||
| 2ad033f8e2 | |||
| 7c26ffee51 | |||
| aa37ba0463 | |||
| d61c86b54b | |||
| e72fa1dc74 | |||
| 16db531cce | |||
| 226023043b | |||
| 5d2538c4c2 | |||
| 0075103ddf | |||
| 8982a67902 | |||
| 65ab45ff1b | |||
| 577d434bc8 | |||
| b300e634f6 | |||
| 61d13b9b2d | |||
| 78059bf825 | |||
| dd02a69e8f | |||
| 5ec80ad1f1 | |||
| 4849772435 | |||
| 6546879d3a | |||
| cbc379daa9 | |||
| a7be08ef46 | |||
| 47e48e5d27 | |||
| 968b8109dd | |||
| 19fba27951 | |||
| b78da20d04 | |||
| 5e445b4a71 | |||
| 0e5df883d0 | |||
| b79ea119ea | |||
| b21d98affd | |||
| d83666bed3 | |||
| cab6ca3ef0 | |||
| 33a37f9494 | |||
| 79e978aac9 | |||
| 3af60a81f8 | |||
| 56525ced92 | |||
| 581f3797bc | |||
| 2c8d51988b | |||
| 19243b741a | |||
| afc1e08f21 | |||
| 80c01e74c6 | |||
| d728bfb90c | |||
| 203d73ee26 | |||
| 05fe220102 | |||
| c4f2de198e | |||
| 50f9846836 | |||
| a33b3cfbd8 | |||
| 248f7cce90 | |||
| 8f381e2611 | |||
| f4b14d0d8d | |||
| 93428815e4 | |||
| 6b70610770 | |||
| 84eead47e3 | |||
| 009d03f1f8 | |||
| 9482a247e7 | |||
| 022c79fa95 | |||
| a9ed4ac21d | |||
| 354e39e9bf | |||
| 757e08c6fe | |||
| 33e5775294 | |||
| 5b73a8ed1c | |||
| f864ebbf1a | |||
| 54b6051315 | |||
| ebea34920b | |||
| 44294306ce | |||
| c2af1a0666 | |||
| 8f30696a4d | |||
| b58082a37b | |||
| a594878860 | |||
| 3a2b6296ac | |||
| 87af609a6f | |||
| a0d5d0f3c8 | |||
| 53510f3268 | |||
| 9d5ce9753a | |||
| d7a2df41fa | |||
| f905cb9577 | |||
| b9b6439f47 | |||
| ffcdf986a3 | |||
| 43245b5eb5 | |||
| 420228c67b | |||
| f1719d6e91 | |||
| 9aa1fd5c00 | |||
| 141845aa40 | |||
| 7867df6079 | |||
| 182b937143 | |||
| 5a54fb7e9f | |||
| 399a9b16f6 | |||
| fef45dfc30 | |||
| 42aa7d8d55 | |||
| 8778119792 | |||
| 10e3f2c990 | |||
| 5e25989366 | |||
| f12d328cf7 | |||
| efc4917724 | |||
| c2bf145ff5 | |||
| c8c82811b3 | |||
| c21e133e69 | |||
| 789a7fbb88 | |||
| 888ed9f0ae | |||
| 57da253fa8 | |||
| 44a6707397 | |||
| f0a3ca4314 | |||
| 9bbd52dcc2 | |||
| f50862ac51 | |||
| 017bed1a07 | |||
| 3765d5f549 | |||
| dd28159564 | |||
| 63cdf9f8e7 | |||
| e30889aa12 | |||
| b7caec1bfe | |||
| 660786b99c | |||
| b060576209 | |||
| 7b3826c2d5 | |||
| 51d4416b00 | |||
| cfe6103f48 | |||
| bee8230079 | |||
| 3d77c59c92 | |||
| 667ed161c0 | |||
| 979f9495f1 | |||
| d29a44efa7 | |||
| 7750003033 | |||
| e673339dc4 | |||
| b20b47f8eb | |||
| 689e437bac | |||
| e6bb17dc86 | |||
| 80a97b0f26 | |||
| ffea050bc2 | |||
| 268c2861c9 | |||
| 15739bc0ee | |||
| c2e8b5a1fa | |||
| 1a67ca897c | |||
| d1980ef978 | |||
| b3db49b4ae |
@@ -0,0 +1,24 @@
|
||||
name: CompatHelper
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '00 * * * *'
|
||||
|
||||
jobs:
|
||||
CompatHelper:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
julia-version: [1.2.0]
|
||||
julia-arch: [x86]
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: julia-actions/setup-julia@latest
|
||||
with:
|
||||
version: ${{ matrix.julia-version }}
|
||||
- name: Pkg.add("CompatHelper")
|
||||
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
|
||||
- name: CompatHelper.main()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: julia -e 'using CompatHelper; CompatHelper.main()'
|
||||
@@ -7,3 +7,4 @@ examples/meetup/.ipynb_checkpoints/*
|
||||
deps/plotly-latest.min.js
|
||||
deps/build.log
|
||||
deps/deps.jl
|
||||
Manifest.toml
|
||||
|
||||
+17
-43
@@ -4,57 +4,31 @@ os:
|
||||
- linux
|
||||
# - osx
|
||||
julia:
|
||||
# - 1.0
|
||||
- 1
|
||||
- 1.2
|
||||
- nightly
|
||||
# matrix:
|
||||
# allow_failures:
|
||||
# - julia: nightly
|
||||
|
||||
# # before install:
|
||||
# # - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||
# # - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install wkhtmltopdf; fi
|
||||
matrix:
|
||||
allow_failures:
|
||||
- julia: nightly
|
||||
|
||||
# ref: http://askubuntu.com/a/556672 for the wkhtmltopdf apt repository info
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- at-spi2-core
|
||||
- libgtk-3-dev
|
||||
- xauth
|
||||
- xvfb
|
||||
|
||||
sudo: required
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pwd ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./test/install_wkhtmltoimage.sh ; fi
|
||||
# - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository -y ppa:pov/wkhtmltopdf ; fi
|
||||
# - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi
|
||||
# - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y wkhtmltopdf ; fi
|
||||
# - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wkhtmltopdf -V ; fi
|
||||
# - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wkhtmltoimage -V ; fi
|
||||
# echo 'exec xvfb-run -a -s "-screen 0 640x480x16" wkhtmltopdf "$@"' | sudo tee /usr/local/bin/wkhtmltopdf.sh >/dev/null
|
||||
# sudo chmod a+x /usr/local/bin/wkhtmltopdf.sh
|
||||
|
||||
# # borrowed from Blink.jl's travis file
|
||||
# matrix:
|
||||
# include:
|
||||
# - os: linux
|
||||
# julia: 0.4
|
||||
# env: TESTCMD="xvfb-run julia"
|
||||
# - os: osx
|
||||
# julia: 0.4
|
||||
# env: TESTCMD="julia"
|
||||
|
||||
|
||||
|
||||
notifications:
|
||||
email: true
|
||||
# uncomment the following lines to override the default test script
|
||||
# script:
|
||||
# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
|
||||
# - julia -e 'import Pkg; Pkg.add(Pkg.PackageSpec(path=pwd())); Pkg.build("Plots")'
|
||||
# - julia test/travis_commands.jl
|
||||
# - julia -e 'Pkg.clone("ImageMagick"); Pkg.build("ImageMagick")'
|
||||
# - julia -e 'Pkg.clone("GR"); Pkg.build("GR")'
|
||||
# # - julia -e 'Pkg.clone("https://github.com/tbreloff/ImageMagick.jl.git"); Pkg.checkout("ImageMagick","tb_write"); Pkg.build("ImageMagick")'
|
||||
# - julia -e 'Pkg.clone("https://github.com/tbreloff/ExamplePlots.jl.git");'
|
||||
# # - julia -e 'Pkg.clone("https://github.com/JunoLab/Blink.jl.git"); Pkg.build("Blink"); import Blink; Blink.AtomShell.install()'
|
||||
# # - julia -e 'Pkg.clone("https://github.com/spencerlyon2/PlotlyJS.jl.git")'
|
||||
# - julia -e 'ENV["PYTHON"] = ""; Pkg.add("PyPlot"); Pkg.build("PyPlot")'
|
||||
#
|
||||
# # - $TESTCMD -e 'Pkg.test("Plots"; coverage=false)'
|
||||
# - julia -e 'Pkg.test("Plots"; coverage=false)'
|
||||
# # - julia -e 'cd(Pkg.dir("Plots")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder()); Codecov.submit(process_folder())'
|
||||
|
||||
script:
|
||||
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
|
||||
- if [[ `uname` = "Linux" ]]; then TESTCMD="xvfb-run julia"; else TESTCMD="julia"; fi
|
||||
- $TESTCMD -e 'using Pkg; Pkg.build(); Pkg.test(coverage=true)'
|
||||
|
||||
@@ -3,14 +3,115 @@
|
||||
|
||||
#### notes on release changes, ongoing development, and future planned work
|
||||
|
||||
- Minor version 0.17 is the last one to support Julia 0.6!!
|
||||
- Minor version 0.11 is the last one to support Julia 0.5!!
|
||||
- Critical bugfixes only
|
||||
- `backports` branch is for Julia 0.5
|
||||
|
||||
---
|
||||
## (current master)
|
||||
|
||||
## 0.28.3
|
||||
- support generalized array interface
|
||||
- save to pdf, svg and eps in plotlyjs
|
||||
- fix for clims in line_z
|
||||
- optimize heatmap logic in gr
|
||||
|
||||
## 0.26.3
|
||||
- fix `vline` with dates
|
||||
- fix PyPlot logscale bug
|
||||
- avoid annotation clipping for PyPlot
|
||||
- allow plotting of Any vectors and 3D plotting again in convertToAnyVector
|
||||
- specify legend title font in GR and PyPlot
|
||||
- delete `pushtomaster.sh`
|
||||
- use `=== nothing`
|
||||
|
||||
## 0.26.2
|
||||
- improve empty animation build error
|
||||
- fix GR axis flip for heatmaps and images
|
||||
- fix ribbons specified as tuples
|
||||
- add Char recipe
|
||||
- fix Plotly plots with single-element series
|
||||
- rewrite PlotlyJS backend
|
||||
|
||||
## 0.26.1
|
||||
- handle `Char`s as input data
|
||||
- fix html saving for Plotly
|
||||
- expand ~ in paths on UNIX systems
|
||||
- convertToAnyVector clean-up
|
||||
- fix color_palette grouping issue
|
||||
|
||||
## 0.26.0
|
||||
- use FFMPEG.jl
|
||||
- add missing method for convertToAnyVector
|
||||
|
||||
## 0.25.3
|
||||
- add areaplot
|
||||
- allow missing in z_color arguments
|
||||
- more general tuple recipe
|
||||
- stephist logscale improvements
|
||||
|
||||
## 0.25.2
|
||||
- improvements to handle missings
|
||||
- pyplot: allow setting the color gradient for z values
|
||||
- document :colorbar_entry
|
||||
- limit number of automatic bins
|
||||
- fix ENV['PLOTS_DEFAULT_BACKEND']
|
||||
- don't let aspect_ratio impact subplot size
|
||||
- implement arrowstyle for GR
|
||||
- fix bug in plotly_convert_to_datetime
|
||||
- improve missing support
|
||||
- gr: polar heatmaps
|
||||
- make sure show returns nothing
|
||||
|
||||
## 0.25.1
|
||||
- fix gr_display
|
||||
|
||||
## 0.25.0
|
||||
- Replace StaticArrays with GeometryTypes
|
||||
- Contour fixes for GR
|
||||
|
||||
## 0.24.0
|
||||
- Update to the new PyCall and PyPlot API
|
||||
- fix drawing of ticks
|
||||
- fix y label position with GR
|
||||
|
||||
## 0.23.2
|
||||
- pyplot fixes
|
||||
- Add option :tex_output_standalone to set the 'include_preamble' argument in the PGFPlots backend.
|
||||
- fix ticks
|
||||
- support plotly json mime
|
||||
- fix image axis limits
|
||||
- default to radius 0 at center for polar plots
|
||||
|
||||
## 0.23.1
|
||||
- slightly faster load time
|
||||
- fixed errant MethodError
|
||||
- fix bar plots with unicodeplots
|
||||
- better colorbars for contour
|
||||
- add volume seriestype for GR
|
||||
- fix passing a tuple to custom ticks
|
||||
- add vline to pgfplots
|
||||
- add tex output for pyplot
|
||||
- better 3d axis labels for GR
|
||||
|
||||
## 0.23.0
|
||||
- compatible with StatPlots -> StatsPlots name shift
|
||||
- fix histograms for vectors with NaN and Inf
|
||||
- change gif behaviour (remove cache-busting)
|
||||
- improved docstrings for shorthands functions
|
||||
- fix font rotation for pyplot
|
||||
- fix greyscale images for pyplot
|
||||
- clamp greyscale images with values outside 0,1
|
||||
- support keyword argument for font options
|
||||
- allow vector of markers for pyplot scatter
|
||||
|
||||
## 0.22.5
|
||||
- improve behaviour of plotlyjs backend
|
||||
|
||||
## 0.22.4
|
||||
- Add support for discrete contourf plots with GR
|
||||
|
||||
## 0.22.3
|
||||
- Fix the `showtheme` function
|
||||
|
||||
## 0.22.2
|
||||
- Allow annotations to accept a Tuple instead of the result of a text call (making it possible to specify font characteristics in recipes). E.g. `annotations = (2, 4, ("test", :right, 8, :red))` is the same as `annotations = (2, 4, text("test", :right, 8, :red))`
|
||||
|
||||
## 0.22.1
|
||||
- push PlotsDisplay just after REPLDisplay
|
||||
|
||||
@@ -182,7 +283,7 @@ Many updates, min julia 1.0
|
||||
- add `reset_defaults()` function to reset plot defaults
|
||||
- update syntax to 0.6
|
||||
- make `fill = true` fill to 0 rather than to 1
|
||||
- use new `@df` syntax in StatPlots examples
|
||||
- use new `@df` syntax in StatsPlots examples
|
||||
- allow changing the color of legend box
|
||||
- implement `title_location` for gr
|
||||
- add `hline` marker to pgfplots - fixes errorbars
|
||||
@@ -334,7 +435,7 @@ Many updates, min julia 1.0
|
||||
- added dependency on PlotThemes
|
||||
- set_theme --> theme
|
||||
- remove Compat from REQUIRE
|
||||
- warning for DataFrames without StatPlots
|
||||
- warning for DataFrames without StatsPlots
|
||||
- closeall exported and implemented for gr/pyplot
|
||||
- fix DateTime recipe
|
||||
- reset theme with theme(:none)
|
||||
@@ -456,8 +557,8 @@ Many updates, min julia 1.0
|
||||
#### 0.8.0
|
||||
|
||||
- added dependency on PlotUtils
|
||||
- BREAKING: removed DataFrames support (now in StatPlots.jl)
|
||||
- BREAKING: removed boxplot/violin/density recipes (now in StatPlots.jl)
|
||||
- BREAKING: removed DataFrames support (now in StatsPlots.jl)
|
||||
- BREAKING: removed boxplot/violin/density recipes (now in StatsPlots.jl)
|
||||
- GR:
|
||||
- inline iterm2 support
|
||||
- trisurface support
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
name = "Plots"
|
||||
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
author = ["Tom Breloff (@tbreloff)"]
|
||||
version = "0.28.4"
|
||||
|
||||
[deps]
|
||||
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||
Contour = "d38c429a-6771-53c6-b99e-75d170b6e991"
|
||||
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||
FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
|
||||
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
|
||||
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
|
||||
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
|
||||
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
||||
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||
Measures = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
|
||||
NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
|
||||
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
||||
PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
|
||||
PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043"
|
||||
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||||
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
|
||||
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
|
||||
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
|
||||
Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
|
||||
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
||||
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
||||
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
|
||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
|
||||
[compat]
|
||||
Contour = "0.5"
|
||||
FFMPEG = "0.2"
|
||||
FixedPointNumbers = "0.6"
|
||||
GR = "0.44"
|
||||
GeometryTypes = "0.7"
|
||||
JSON = "0.21"
|
||||
Measures = "0.3"
|
||||
NaNMath = "0.3"
|
||||
PlotThemes = "1"
|
||||
PlotUtils = "0.6.1"
|
||||
RecipesBase = "0.6, 0.7"
|
||||
Reexport = "0.2"
|
||||
Requires = "0.5, 1.0"
|
||||
Showoff = "0.3.1"
|
||||
StatsBase = "0.32"
|
||||
julia = "1"
|
||||
|
||||
[extras]
|
||||
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
|
||||
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
|
||||
Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44"
|
||||
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
|
||||
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
|
||||
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
|
||||
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
||||
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
|
||||
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
|
||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
|
||||
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"
|
||||
|
||||
[targets]
|
||||
test = ["FileIO", "GeometryTypes", "Gtk", "ImageMagick", "Images", "LaTeXStrings", "LibGit2", "PGFPlotsX", "Random", "RDatasets", "StatsPlots", "Test", "UnicodePlots", "VisualRegressionTests"]
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#### Created by Tom Breloff (@tbreloff)
|
||||
|
||||
#### Maintained by the [JuliaPlot members](https://github.com/orgs/JuliaPlots/people)
|
||||
#### Maintained by the [JuliaPlots members](https://github.com/orgs/JuliaPlots/people)
|
||||
|
||||
Plots is a plotting API and toolset. My goals with the package are:
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
julia 1.0
|
||||
|
||||
RecipesBase 0.6.0
|
||||
PlotUtils 0.4.1
|
||||
PlotThemes 0.1.3
|
||||
Reexport
|
||||
StaticArrays 0.5
|
||||
FixedPointNumbers 0.3
|
||||
Measures
|
||||
Showoff
|
||||
StatsBase 0.14.0
|
||||
JSON
|
||||
NaNMath
|
||||
Requires
|
||||
Contour
|
||||
GR 0.37.0
|
||||
@@ -2,6 +2,7 @@ environment:
|
||||
matrix:
|
||||
# - julia_version: 0.7
|
||||
- julia_version: 1
|
||||
- julia_version: 1.2
|
||||
- julia_version: nightly
|
||||
|
||||
platform:
|
||||
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
# To figure out what should be precompiled, run this script, then move
|
||||
# precompile_Plots.jl in precompiles_path (see below) to src/precompile.jl
|
||||
|
||||
# This script works by using SnoopCompile to log compilations that take place
|
||||
# while running the examples on the GR backend. So SnoopCompile must be
|
||||
# installed, and StatsPlots, RDatasets, and FileIO are also required for
|
||||
# certain examples.
|
||||
|
||||
# If precompilation fails with an UndefVarError for a module, probably what is
|
||||
# happening is that the module appears in the precompile statements, but is
|
||||
# only visible to one of Plots' dependencies, and not Plots itself. Adding the
|
||||
# module to the blacklist below will remove these precompile statements.
|
||||
|
||||
# Anonymous functions may appear in precompile statements as functions with
|
||||
# hashes in their name. Those of the form "#something##kw" have to do with
|
||||
# compiling functions with keyword arguments, and are named reproducibly, so
|
||||
# can be kept. Others generally will not work. Currently, SnoopCompile includes
|
||||
# some anonymous functions that not reproducible, but SnoopCompile PR #30
|
||||
# (which looks about to be merged) will ensure that anonymous functions are
|
||||
# actually defined before attempting to precompile them. Alternatively, we can
|
||||
# keep only the keyword argument related anonymous functions by changing the
|
||||
# regex that SnoopCompile uses to detect anonymous functions to
|
||||
# r"#{1,2}[^\"#]+#{1,2}\d+" (see anonrex in SnoopCompile.jl). To exclude all
|
||||
# precompile statements involving anonymous functions, "#" can also be added to
|
||||
# the blacklist below.
|
||||
|
||||
using SnoopCompile
|
||||
|
||||
log_path = joinpath(tempdir(), "compiles.log")
|
||||
precompiles_path = joinpath(tempdir(), "precompile")
|
||||
|
||||
# run examples with GR backend, logging what needs to be compiled
|
||||
SnoopCompile.@snoopc log_path begin
|
||||
using Plots
|
||||
Plots.test_examples(:gr, disp=true)
|
||||
end
|
||||
|
||||
# precompile calls containing the following strings are dropped
|
||||
blacklist = [
|
||||
# functions defined in examples
|
||||
"PlotExampleModule",
|
||||
# the following are not visible to Plots, only its dependencies
|
||||
"CategoricalArrays",
|
||||
"FixedPointNumbers",
|
||||
"SparseArrays",
|
||||
r"#{1,2}[^\"#]+#{1,2}\d+",
|
||||
]
|
||||
|
||||
data = SnoopCompile.read(log_path)
|
||||
pc = SnoopCompile.parcel(reverse!(data[2]), blacklist=blacklist)
|
||||
SnoopCompile.write(precompiles_path, pc)
|
||||
@@ -1,4 +0,0 @@
|
||||
git checkout master
|
||||
git merge --ff-only dev
|
||||
git push origin master
|
||||
git checkout dev
|
||||
+10
-94
@@ -1,13 +1,15 @@
|
||||
module Plots
|
||||
|
||||
_current_plots_version = v"0.20.6"
|
||||
const _current_plots_version = VersionNumber(split(first(filter(line -> occursin("version", line), readlines(normpath(@__DIR__, "..", "Project.toml")))), "\"")[2])
|
||||
|
||||
using Reexport
|
||||
|
||||
import StaticArrays
|
||||
import GeometryTypes
|
||||
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random
|
||||
import SparseArrays: findnz
|
||||
|
||||
using FFMPEG
|
||||
|
||||
@reexport using RecipesBase
|
||||
import RecipesBase: plot, plot!, animate
|
||||
using Base.Meta
|
||||
@@ -84,7 +86,6 @@ export
|
||||
backends,
|
||||
backend_name,
|
||||
backend_object,
|
||||
add_backend,
|
||||
aliases,
|
||||
|
||||
Shape,
|
||||
@@ -180,103 +181,15 @@ include("arg_desc.jl")
|
||||
include("plotattr.jl")
|
||||
include("backends.jl")
|
||||
include("output.jl")
|
||||
include("ijulia.jl")
|
||||
include("fileio.jl")
|
||||
include("init.jl")
|
||||
|
||||
include("backends/plotly.jl")
|
||||
include("backends/gr.jl")
|
||||
include("backends/web.jl")
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@shorthands scatter
|
||||
@shorthands bar
|
||||
@shorthands barh
|
||||
@shorthands histogram
|
||||
@shorthands barhist
|
||||
@shorthands stephist
|
||||
@shorthands scatterhist
|
||||
@shorthands histogram2d
|
||||
@shorthands density
|
||||
@shorthands heatmap
|
||||
@shorthands plots_heatmap
|
||||
@shorthands hexbin
|
||||
@shorthands sticks
|
||||
@shorthands hline
|
||||
@shorthands vline
|
||||
@shorthands hspan
|
||||
@shorthands vspan
|
||||
@shorthands ohlc
|
||||
@shorthands contour
|
||||
@shorthands contourf
|
||||
@shorthands contour3d
|
||||
@shorthands surface
|
||||
@shorthands wireframe
|
||||
@shorthands path3d
|
||||
@shorthands scatter3d
|
||||
@shorthands boxplot
|
||||
@shorthands violin
|
||||
@shorthands quiver
|
||||
@shorthands curves
|
||||
|
||||
"Plot a pie diagram"
|
||||
pie(args...; kw...) = plot(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
|
||||
pie!(args...; kw...) = plot!(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
|
||||
|
||||
"Plot with seriestype :path3d"
|
||||
plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d)
|
||||
plot3d!(args...; kw...) = plot!(args...; kw..., seriestype = :path3d)
|
||||
|
||||
"Add title to an existing plot"
|
||||
title!(s::AbstractString; kw...) = plot!(; title = s, kw...)
|
||||
|
||||
"Add xlabel to an existing plot"
|
||||
xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...)
|
||||
|
||||
"Add ylabel to an existing plot"
|
||||
ylabel!(s::AbstractString; kw...) = plot!(; ylabel = s, kw...)
|
||||
|
||||
"Set xlims for an existing plot"
|
||||
xlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; xlims = lims, kw...)
|
||||
|
||||
"Set ylims for an existing plot"
|
||||
ylims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; ylims = lims, kw...)
|
||||
|
||||
"Set zlims for an existing plot"
|
||||
zlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; zlims = lims, kw...)
|
||||
|
||||
xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin,xmax), kw...)
|
||||
ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...)
|
||||
zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmin,zmax), kw...)
|
||||
|
||||
|
||||
"Set xticks for an existing plot"
|
||||
xticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; xticks = v, kw...)
|
||||
|
||||
"Set yticks for an existing plot"
|
||||
yticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; yticks = v, kw...)
|
||||
|
||||
xticks!(
|
||||
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...)
|
||||
yticks!(
|
||||
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; yticks = (ticks,labels), kw...)
|
||||
|
||||
"Add annotations to an existing plot"
|
||||
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
|
||||
annotate!(anns::AVec{T}; kw...) where {T<:Tuple} = plot!(; annotation = anns, kw...)
|
||||
|
||||
"Flip the current plots' x axis"
|
||||
xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...)
|
||||
|
||||
"Flip the current plots' y axis"
|
||||
yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...)
|
||||
|
||||
"Specify x axis attributes for an existing plot"
|
||||
xaxis!(args...; kw...) = plot!(; xaxis = args, kw...)
|
||||
|
||||
"Specify x axis attributes for an existing plot"
|
||||
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
|
||||
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
|
||||
ygrid!(args...; kw...) = plot!(; ygrid = args, kw...)
|
||||
include("shorthands.jl")
|
||||
|
||||
let PlotOrSubplot = Union{Plot, Subplot}
|
||||
global title!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; title = s, kw...)
|
||||
@@ -309,4 +222,7 @@ end
|
||||
|
||||
const CURRENT_BACKEND = CurrentBackend(:none)
|
||||
|
||||
include("precompile.jl")
|
||||
_precompile_()
|
||||
|
||||
end # module
|
||||
|
||||
+37
-15
@@ -60,31 +60,39 @@ end
|
||||
|
||||
file_extension(fn) = Base.Filesystem.splitext(fn)[2][2:end]
|
||||
|
||||
gif(anim::Animation, fn = giffn(); kw...) = buildanimation(anim.dir, fn; kw...)
|
||||
mov(anim::Animation, fn = movfn(); kw...) = buildanimation(anim.dir, fn, false; kw...)
|
||||
mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim.dir, fn, false; kw...)
|
||||
gif(anim::Animation, fn = giffn(); kw...) = buildanimation(anim, fn; kw...)
|
||||
mov(anim::Animation, fn = movfn(); kw...) = buildanimation(anim, fn, false; kw...)
|
||||
mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim, fn, false; kw...)
|
||||
|
||||
ffmpeg_framerate(fps) = "$fps"
|
||||
ffmpeg_framerate(fps::Rational) = "$(fps.num)/$(fps.den)"
|
||||
|
||||
function buildanimation(animdir::AbstractString, fn::AbstractString,
|
||||
function buildanimation(anim::Animation, fn::AbstractString,
|
||||
is_animated_gif::Bool=true;
|
||||
fps::Integer = 20, loop::Integer = 0,
|
||||
fps::Real = 20, loop::Integer = 0,
|
||||
variable_palette::Bool=false,
|
||||
show_msg::Bool=true)
|
||||
fn = abspath(fn)
|
||||
if length(anim.frames) == 0
|
||||
throw(ArgumentError("Cannot build empty animations"))
|
||||
end
|
||||
|
||||
fn = abspath(expanduser(fn))
|
||||
animdir = anim.dir
|
||||
framerate = ffmpeg_framerate(fps)
|
||||
|
||||
if is_animated_gif
|
||||
if variable_palette
|
||||
# generate a colorpalette for each frame for highest quality, but larger filesize
|
||||
palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1"
|
||||
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`)
|
||||
ffmpeg_exe(`-v 0 -framerate $framerate -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`)
|
||||
else
|
||||
# generate a colorpalette first so ffmpeg does not have to guess it
|
||||
run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
|
||||
ffmpeg_exe(`-v 0 -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
|
||||
# then apply the palette to get better results
|
||||
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`)
|
||||
ffmpeg_exe(` -v 0 -framerate $framerate -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`)
|
||||
end
|
||||
else
|
||||
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
|
||||
ffmpeg_exe(`-v 0 -framerate $framerate -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
|
||||
end
|
||||
|
||||
show_msg && @info("Saved animation to ", fn)
|
||||
@@ -93,16 +101,30 @@ end
|
||||
|
||||
|
||||
|
||||
# write out html to view the gif... note the rand call which is a hack so the image doesn't get cached
|
||||
# write out html to view the gif
|
||||
function Base.show(io::IO, ::MIME"text/html", agif::AnimatedGif)
|
||||
ext = file_extension(agif.filename)
|
||||
write(io, if ext == "gif"
|
||||
"<img src=\"$(relpath(agif.filename))?$(rand())>\" />"
|
||||
if ext == "gif"
|
||||
html = "<img src=\"data:image/gif;base64," * base64encode(read(agif.filename)) * "\" />"
|
||||
elseif ext in ("mov", "mp4")
|
||||
"<video controls><source src=\"$(relpath(agif.filename))?$(rand())>\" type=\"video/$ext\"></video>"
|
||||
mimetype = ext == "mov" ? "video/quicktime" : "video/mp4"
|
||||
html = "<video controls><source src=\"data:$mimetype;base64," *
|
||||
base64encode(read(agif.filename)) *
|
||||
"\" type = \"$mimetype\"></video>"
|
||||
else
|
||||
error("Cannot show animation with extension $ext: $agif")
|
||||
end)
|
||||
end
|
||||
|
||||
write(io, html)
|
||||
return nothing
|
||||
end
|
||||
|
||||
|
||||
# Only gifs can be shown via image/gif
|
||||
Base.showable(::MIME"image/gif", agif::AnimatedGif) = file_extension(agif.filename) == "gif"
|
||||
|
||||
function Base.show(io::IO, ::MIME"image/gif", agif::AnimatedGif)
|
||||
open(fio-> write(io, fio), agif.filename)
|
||||
end
|
||||
|
||||
|
||||
|
||||
+35
-24
@@ -2,7 +2,7 @@
|
||||
const _arg_desc = KW(
|
||||
|
||||
# series args
|
||||
:label => "String type. The label for a series, which appears in a legend. If empty, no legend entry is added.",
|
||||
:label => "String type. The label for a series, which appears in a legend. If empty, no legend entry is added.",
|
||||
:seriescolor => "Color Type. The base color for this series. `:auto` (the default) will select a color from the subplot's `color_palette`, based on the order it was added to the subplot",
|
||||
:seriesalpha => "Number in [0,1]. The alpha/opacity override for the series. `nothing` (the default) means it will take the alpha value of the color.",
|
||||
:seriestype => "Symbol. This is the identifier of the type of visualization for this series. Choose from $(_allTypes) or any series recipes which are defined.",
|
||||
@@ -10,7 +10,7 @@ const _arg_desc = KW(
|
||||
:linewidth => "Number. Width of the line (in pixels)",
|
||||
:linecolor => "Color Type. Color of the line (for path and bar stroke). `:match` will take the value from `:seriescolor`, (though histogram/bar types use `:black` as a default).",
|
||||
:linealpha => "Number in [0,1]. The alpha/opacity override for the line. `nothing` (the default) means it will take the alpha value of linecolor.",
|
||||
:fillrange => "Number or AbstractVector. Fills area from this to y for line-types, sets the base for bar/stick types, and similar for other types.",
|
||||
:fillrange => "Number or AbstractVector. Fills area between fillrange and y for line-types, sets the base for bar/stick types, and similar for other types.",
|
||||
:fillcolor => "Color Type. Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`.",
|
||||
:fillalpha => "Number in [0,1]. The alpha/opacity override for the fill area. `nothing` (the default) means it will take the alpha value of fillcolor.",
|
||||
:markershape => "Symbol, Shape, or AbstractVector. Choose from $(_allMarkers).",
|
||||
@@ -21,7 +21,7 @@ const _arg_desc = KW(
|
||||
:markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)",
|
||||
:markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.",
|
||||
:markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.",
|
||||
:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `range(min(x), stop = extrema(x), length = 25)`",
|
||||
:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `range(minimum(x), stop = maximum(x), length = 25)`",
|
||||
:smooth => "Bool. Add a regression line?",
|
||||
:group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.",
|
||||
:x => "Various. Input data. First Dimension",
|
||||
@@ -29,26 +29,28 @@ const _arg_desc = KW(
|
||||
:z => "Various. Input data. Third Dimension. May be wrapped by a `Surface` for surface and heatmap types.",
|
||||
:marker_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. z-values for each series data point, which correspond to the color to be used from a markercolor gradient.",
|
||||
:line_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment).",
|
||||
:fill_z => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.",
|
||||
:levels => "Integer, NTuple{2,Integer}. Number of levels (or x-levels/y-levels) for a contour type.",
|
||||
:fill_z => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.",
|
||||
:levels => "Integer, NTuple{2,Integer}, or AbstractVector. Levels or number of levels (or x-levels/y-levels) for a contour type.",
|
||||
:orientation => "Symbol. Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default).",
|
||||
:bar_position => "Symbol. Choose from `:overlay` (default), `:stack`. (warning: May not be implemented fully)",
|
||||
:bar_width => "nothing or Number. Width of bars in data coordinates. When nothing, chooses based on x (or y when `orientation = :h`).",
|
||||
:bar_edges => "Bool. Align bars to edges (true), or centers (the default)?",
|
||||
:xerror => "AbstractVector or 2-Tuple of Vectors. x (horizontal) error relative to x-value. If 2-tuple of vectors, the first vector corresponds to the left error (and the second to the right)",
|
||||
:bar_width => "nothing or Number. Width of bars in data coordinates. When nothing, chooses based on x (or y when `orientation = :h`).",
|
||||
:bar_edges => "Bool. Align bars to edges (true), or centers (the default)?",
|
||||
:xerror => "AbstractVector or 2-Tuple of Vectors. x (horizontal) error relative to x-value. If 2-tuple of vectors, the first vector corresponds to the left error (and the second to the right)",
|
||||
:yerror => "AbstractVector or 2-Tuple of Vectors. y (vertical) error relative to y-value. If 2-tuple of vectors, the first vector corresponds to the bottom error (and the second to the top)",
|
||||
:ribbon => "Number or AbstractVector. Creates a fillrange around the data points.",
|
||||
:quiver => "AbstractVector or 2-Tuple of vectors. The directional vectors U,V which specify velocity/gradient vectors for a quiver plot.",
|
||||
:arrow => "nothing (no arrows), Bool (if true, default arrows), Arrow object, or arg(s) that could be style or head length/widths. Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar.",
|
||||
:normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete Probability Density Function, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes).",
|
||||
:weights => "AbstractVector. Used in histogram types for weighted counts.",
|
||||
:show_empty_bins => "Bool. Whether empty bins in a 2D histogram are colored as 0 (true), or transparent (the default).",
|
||||
:contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.",
|
||||
:contour_labels => "Bool. Show labels at the contour lines?",
|
||||
:contour_labels => "Bool. Show labels at the contour lines?",
|
||||
:match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.",
|
||||
:subplot => "Integer (subplot index) or Subplot object. The subplot that this series belongs to.",
|
||||
:series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.",
|
||||
:primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.",
|
||||
:hover => "nothing or vector of strings. Text to display when hovering over each data point.",
|
||||
:series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.",
|
||||
:primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.",
|
||||
:hover => "nothing or vector of strings. Text to display when hovering over each data point.",
|
||||
:colorbar_entry => "Bool. Include this series in the color bar? Set to `false` to exclude.",
|
||||
|
||||
# plot args
|
||||
:plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)",
|
||||
@@ -63,11 +65,12 @@ const _arg_desc = KW(
|
||||
:link => "Symbol. How/whether to link axis limits between subplots. Values: `:none`, `:x` (x axes are linked by columns), `:y` (y axes are linked by rows), `:both` (x and y are linked), `:all` (every subplot is linked together regardless of layout position).",
|
||||
:overwrite_figure => "Bool. Should we reuse the same GUI window/figure when plotting (true) or open a new one (false).",
|
||||
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
|
||||
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
|
||||
:dpi => "Number. Dots Per Inch of output figures",
|
||||
:tex_output_standalone => "Bool. When writing tex output, should the source include a preamble for a standalone document class.",
|
||||
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
|
||||
:dpi => "Number. Dots Per Inch of output figures",
|
||||
:thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.",
|
||||
:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.",
|
||||
:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.",
|
||||
:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.",
|
||||
:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.",
|
||||
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",
|
||||
|
||||
# subplot args
|
||||
@@ -93,12 +96,19 @@ const _arg_desc = KW(
|
||||
:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center",
|
||||
:legendfontrotation => "Real. Font rotation of legend entries",
|
||||
:legendfontcolor => "Color Type. Font color of legend entries",
|
||||
:legendtitlefontfamily => "String or Symbol. Font family of the legend title.",
|
||||
:legendtitlefontsize => "Integer. Font pointsize the legend title.",
|
||||
:legendtitlefonthalign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center",
|
||||
:legendtitlefontvalign => "Symbol. Font vertical alignment of the legend title: :vcenter, :top, :bottom or :center",
|
||||
:legendtitlefontrotation => "Real. Font rotation of the legend title",
|
||||
:legendtitlefontcolor => "Color Type. Font color of the legend title",
|
||||
:colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)",
|
||||
:clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.",
|
||||
:legendfont => "Font. Font of legend items.",
|
||||
:legendtitlefont => "Font. Font of the legend title.",
|
||||
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
|
||||
:projection => "Symbol or String. '3d' or 'polar'",
|
||||
:aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `apect_ratio` x-units.",
|
||||
:aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `aspect_ratio` x-units.",
|
||||
:margin => "Measure (multiply by `mm`, `px`, etc). Base for individual margins... not directly used. Specifies the extra padding around subplots.",
|
||||
:left_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the left of the subplot.",
|
||||
:top_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the top of the subplot.",
|
||||
@@ -110,14 +120,14 @@ const _arg_desc = KW(
|
||||
:camera => "NTuple{2, Real}. Sets the view angle (azimuthal, elevation) for 3D plots",
|
||||
|
||||
# axis args
|
||||
:guide => "String. Axis guide (label).",
|
||||
:guide => "String. Axis guide (label).",
|
||||
:guide_position => "Symbol. Position of axis guides: :top, :bottom, :left or :right",
|
||||
:lims => "NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example). `:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]",
|
||||
:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
|
||||
:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`",
|
||||
:rotation => "Number. Degrees rotation of tick labels.",
|
||||
:flip => "Bool. Should we flip (reverse) the axis?",
|
||||
:formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.",
|
||||
:lims => "NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example). `:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]",
|
||||
:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
|
||||
:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`",
|
||||
:rotation => "Number. Degrees rotation of tick labels.",
|
||||
:flip => "Bool. Should we flip (reverse) the axis?",
|
||||
:formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.",
|
||||
:tickfontfamily => "String or Symbol. Font family of tick labels.",
|
||||
:tickfontsize => "Integer. Font pointsize of tick labels.",
|
||||
:tickfonthalign => "Symbol. Font horizontal alignment of tick labels: :hcenter, :left, :right or :center",
|
||||
@@ -149,4 +159,5 @@ const _arg_desc = KW(
|
||||
:tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`",
|
||||
:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`",
|
||||
:widen => "Bool. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders. Defaults to `true`.",
|
||||
:draw_arrow => "Bool. Draw arrow at the end of the axis.",
|
||||
)
|
||||
|
||||
+85
-55
@@ -232,6 +232,7 @@ const _bar_width = 0.8
|
||||
|
||||
const _series_defaults = KW(
|
||||
:label => "AUTO",
|
||||
:colorbar_entry => true,
|
||||
:seriescolor => :auto,
|
||||
:seriesalpha => nothing,
|
||||
:seriestype => :path,
|
||||
@@ -271,6 +272,7 @@ const _series_defaults = KW(
|
||||
:arrow => nothing, # allows for adding arrows to line/path... call `arrow(args...)`
|
||||
:normalize => false, # do we want a normalized histogram?
|
||||
:weights => nothing, # optional weights for histograms (1D and 2D)
|
||||
:show_empty_bins => false, # should empty bins in 2D histogram be colored as zero (otherwise they are transparent)
|
||||
:contours => false, # add contours to 3d surface and wireframe plots
|
||||
:contour_labels => false,
|
||||
:match_dimensions => false, # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196
|
||||
@@ -298,6 +300,7 @@ const _plot_defaults = KW(
|
||||
:link => :none,
|
||||
:overwrite_figure => true,
|
||||
:html_output_format => :auto,
|
||||
:tex_output_standalone => false,
|
||||
:inset_subplots => nothing, # optionally pass a vector of (parent,bbox) tuples which are
|
||||
# the parent layout and the relative bounding box of inset subplots
|
||||
:dpi => DPI, # dots per inch for images, etc
|
||||
@@ -334,6 +337,12 @@ const _subplot_defaults = KW(
|
||||
:legendfontvalign => :vcenter,
|
||||
:legendfontrotation => 0.0,
|
||||
:legendfontcolor => :match,
|
||||
:legendtitlefontfamily => :match,
|
||||
:legendtitlefontsize => 11,
|
||||
:legendtitlefonthalign => :hcenter,
|
||||
:legendtitlefontvalign => :vcenter,
|
||||
:legendtitlefontrotation => 0.0,
|
||||
:legendtitlefontcolor => :match,
|
||||
:annotations => [], # annotation tuples... list of (x,y,annotation)
|
||||
:projection => :none, # can also be :polar or :3d
|
||||
:aspect_ratio => :none, # choose from :none or :equal
|
||||
@@ -390,6 +399,7 @@ const _axis_defaults = KW(
|
||||
:minorgrid => false,
|
||||
:showaxis => true,
|
||||
:widen => true,
|
||||
:draw_arrow => false,
|
||||
)
|
||||
|
||||
const _suppress_warnings = Set{Symbol}([
|
||||
@@ -447,6 +457,7 @@ const _initial_axis_defaults = deepcopy(_axis_defaults)
|
||||
# to be able to reset font sizes to initial values
|
||||
const _initial_fontsizes = Dict(:titlefontsize => _subplot_defaults[:titlefontsize],
|
||||
:legendfontsize => _subplot_defaults[:legendfontsize],
|
||||
:legendtitlefontsize => _subplot_defaults[:legendtitlefontsize],
|
||||
:tickfontsize => _axis_defaults[:tickfontsize],
|
||||
:guidefontsize => _axis_defaults[:guidefontsize])
|
||||
|
||||
@@ -571,6 +582,7 @@ add_aliases(:xerror, :xerr, :xerrorbar)
|
||||
add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar)
|
||||
add_aliases(:quiver, :velocity, :quiver2d, :gradient, :vectorfield)
|
||||
add_aliases(:normalize, :norm, :normed, :normalized)
|
||||
add_aliases(:show_empty_bins, :showemptybins, :showempty, :show_empty)
|
||||
add_aliases(:aspect_ratio, :aspectratio, :axis_ratio, :axisratio, :ratio)
|
||||
add_aliases(:match_dimensions, :transpose, :transpose_z)
|
||||
add_aliases(:subplot, :sp, :subplt, :splt)
|
||||
@@ -682,15 +694,15 @@ function processLineArg(plotattributes::KW, arg)
|
||||
plotattributes[:linestyle] = arg
|
||||
|
||||
elseif typeof(arg) <: Stroke
|
||||
arg.width == nothing || (plotattributes[:linewidth] = arg.width)
|
||||
arg.color == nothing || (plotattributes[:linecolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha == nothing || (plotattributes[:linealpha] = arg.alpha)
|
||||
arg.style == nothing || (plotattributes[:linestyle] = arg.style)
|
||||
arg.width === nothing || (plotattributes[:linewidth] = arg.width)
|
||||
arg.color === nothing || (plotattributes[:linecolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha === nothing || (plotattributes[:linealpha] = arg.alpha)
|
||||
arg.style === nothing || (plotattributes[:linestyle] = arg.style)
|
||||
|
||||
elseif typeof(arg) <: Brush
|
||||
arg.size == nothing || (plotattributes[:fillrange] = arg.size)
|
||||
arg.color == nothing || (plotattributes[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha == nothing || (plotattributes[:fillalpha] = arg.alpha)
|
||||
arg.size === nothing || (plotattributes[:fillrange] = arg.size)
|
||||
arg.color === nothing || (plotattributes[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha)
|
||||
|
||||
elseif typeof(arg) <: Arrow || arg in (:arrow, :arrows)
|
||||
plotattributes[:arrow] = arg
|
||||
@@ -721,20 +733,24 @@ function processMarkerArg(plotattributes::KW, arg)
|
||||
plotattributes[:markerstrokestyle] = arg
|
||||
|
||||
elseif typeof(arg) <: Stroke
|
||||
arg.width == nothing || (plotattributes[:markerstrokewidth] = arg.width)
|
||||
arg.color == nothing || (plotattributes[:markerstrokecolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha == nothing || (plotattributes[:markerstrokealpha] = arg.alpha)
|
||||
arg.style == nothing || (plotattributes[:markerstrokestyle] = arg.style)
|
||||
arg.width === nothing || (plotattributes[:markerstrokewidth] = arg.width)
|
||||
arg.color === nothing || (plotattributes[:markerstrokecolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha === nothing || (plotattributes[:markerstrokealpha] = arg.alpha)
|
||||
arg.style === nothing || (plotattributes[:markerstrokestyle] = arg.style)
|
||||
|
||||
elseif typeof(arg) <: Brush
|
||||
arg.size == nothing || (plotattributes[:markersize] = arg.size)
|
||||
arg.color == nothing || (plotattributes[:markercolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha == nothing || (plotattributes[:markeralpha] = arg.alpha)
|
||||
arg.size === nothing || (plotattributes[:markersize] = arg.size)
|
||||
arg.color === nothing || (plotattributes[:markercolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha === nothing || (plotattributes[:markeralpha] = arg.alpha)
|
||||
|
||||
# linealpha
|
||||
elseif allAlphas(arg)
|
||||
plotattributes[:markeralpha] = arg
|
||||
|
||||
# bool
|
||||
elseif typeof(arg) <: Bool
|
||||
plotattributes[:markershape] = arg ? :circle : :none
|
||||
|
||||
# markersize
|
||||
elseif allReals(arg)
|
||||
plotattributes[:markersize] = arg
|
||||
@@ -750,9 +766,9 @@ end
|
||||
function processFillArg(plotattributes::KW, arg)
|
||||
# fr = get(plotattributes, :fillrange, 0)
|
||||
if typeof(arg) <: Brush
|
||||
arg.size == nothing || (plotattributes[:fillrange] = arg.size)
|
||||
arg.color == nothing || (plotattributes[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha == nothing || (plotattributes[:fillalpha] = arg.alpha)
|
||||
arg.size === nothing || (plotattributes[:fillrange] = arg.size)
|
||||
arg.color === nothing || (plotattributes[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color))
|
||||
arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha)
|
||||
|
||||
elseif typeof(arg) <: Bool
|
||||
plotattributes[:fillrange] = arg ? 0 : nothing
|
||||
@@ -786,10 +802,10 @@ function processGridArg!(plotattributes::KW, arg, letter)
|
||||
plotattributes[Symbol(letter, :gridstyle)] = arg
|
||||
|
||||
elseif typeof(arg) <: Stroke
|
||||
arg.width == nothing || (plotattributes[Symbol(letter, :gridlinewidth)] = arg.width)
|
||||
arg.color == nothing || (plotattributes[Symbol(letter, :foreground_color_grid)] = arg.color in (:auto, :match) ? :match : plot_color(arg.color))
|
||||
arg.alpha == nothing || (plotattributes[Symbol(letter, :gridalpha)] = arg.alpha)
|
||||
arg.style == nothing || (plotattributes[Symbol(letter, :gridstyle)] = arg.style)
|
||||
arg.width === nothing || (plotattributes[Symbol(letter, :gridlinewidth)] = arg.width)
|
||||
arg.color === nothing || (plotattributes[Symbol(letter, :foreground_color_grid)] = arg.color in (:auto, :match) ? :match : plot_color(arg.color))
|
||||
arg.alpha === nothing || (plotattributes[Symbol(letter, :gridalpha)] = arg.alpha)
|
||||
arg.style === nothing || (plotattributes[Symbol(letter, :gridstyle)] = arg.style)
|
||||
|
||||
# linealpha
|
||||
elseif allAlphas(arg)
|
||||
@@ -815,10 +831,10 @@ function processMinorGridArg!(plotattributes::KW, arg, letter)
|
||||
plotattributes[Symbol(letter, :minorgrid)] = true
|
||||
|
||||
elseif typeof(arg) <: Stroke
|
||||
arg.width == nothing || (plotattributes[Symbol(letter, :minorgridlinewidth)] = arg.width)
|
||||
arg.color == nothing || (plotattributes[Symbol(letter, :foreground_color_minor_grid)] = arg.color in (:auto, :match) ? :match : plot_color(arg.color))
|
||||
arg.alpha == nothing || (plotattributes[Symbol(letter, :minorgridalpha)] = arg.alpha)
|
||||
arg.style == nothing || (plotattributes[Symbol(letter, :minorgridstyle)] = arg.style)
|
||||
arg.width === nothing || (plotattributes[Symbol(letter, :minorgridlinewidth)] = arg.width)
|
||||
arg.color === nothing || (plotattributes[Symbol(letter, :foreground_color_minor_grid)] = arg.color in (:auto, :match) ? :match : plot_color(arg.color))
|
||||
arg.alpha === nothing || (plotattributes[Symbol(letter, :minorgridalpha)] = arg.alpha)
|
||||
arg.style === nothing || (plotattributes[Symbol(letter, :minorgridstyle)] = arg.style)
|
||||
plotattributes[Symbol(letter, :minorgrid)] = true
|
||||
|
||||
# linealpha
|
||||
@@ -923,6 +939,15 @@ function preprocessArgs!(plotattributes::KW)
|
||||
end
|
||||
end
|
||||
|
||||
# vline accesses the y argument but actually maps it to the x axis.
|
||||
# Hence, we have to swap formatters
|
||||
if get(plotattributes, :seriestype, :path) == :vline
|
||||
xformatter = get(plotattributes, :xformatter, :auto)
|
||||
yformatter = get(plotattributes, :yformatter, :auto)
|
||||
plotattributes[:xformatter] = yformatter
|
||||
plotattributes[:yformatter] = xformatter
|
||||
end
|
||||
|
||||
# handle grid args common to all axes
|
||||
args = pop!(plotattributes, :grid, ())
|
||||
for arg in wraptuple(args)
|
||||
@@ -954,7 +979,7 @@ function preprocessArgs!(plotattributes::KW)
|
||||
end
|
||||
end
|
||||
# fonts
|
||||
for fontname in (:titlefont, :legendfont)
|
||||
for fontname in (:titlefont, :legendfont, :legendtitlefont)
|
||||
args = pop!(plotattributes, fontname, ())
|
||||
for arg in wraptuple(args)
|
||||
processFontArg!(plotattributes, fontname, arg)
|
||||
@@ -1023,7 +1048,7 @@ function preprocessArgs!(plotattributes::KW)
|
||||
arrow()
|
||||
elseif a in (false, nothing, :none)
|
||||
nothing
|
||||
elseif !(typeof(a) <: Arrow)
|
||||
elseif !(typeof(a) <: Arrow || typeof(a) <: AbstractArray{Arrow})
|
||||
arrow(wraptuple(a)...)
|
||||
else
|
||||
a
|
||||
@@ -1050,8 +1075,8 @@ function preprocessArgs!(plotattributes::KW)
|
||||
|
||||
# warnings for moved recipes
|
||||
st = get(plotattributes, :seriestype, :path)
|
||||
if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatPlots)
|
||||
@warn("seriestype $st has been moved to StatPlots. To use: \`Pkg.add(\"StatPlots\"); using StatPlots\`")
|
||||
if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatsPlots)
|
||||
@warn("seriestype $st has been moved to StatsPlots. To use: \`Pkg.add(\"StatsPlots\"); using StatsPlots\`")
|
||||
end
|
||||
|
||||
return
|
||||
@@ -1073,7 +1098,7 @@ function extractGroupArgs(v::AVec, args...; legendEntry = string)
|
||||
if n > 100
|
||||
@warn("You created n=$n groups... Is that intended?")
|
||||
end
|
||||
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels]
|
||||
groupIds = Vector{Int}[filter(i -> v[i] == glab, eachindex(v)) for glab in groupLabels]
|
||||
GroupBy(map(legendEntry, groupLabels), groupIds)
|
||||
end
|
||||
|
||||
@@ -1081,7 +1106,7 @@ legendEntryFromTuple(ns::Tuple) = join(ns, ' ')
|
||||
|
||||
# this is when given a tuple of vectors of values to group by
|
||||
function extractGroupArgs(vs::Tuple, args...)
|
||||
isempty(vs) && return GroupBy([""], [1:size(args[1],1)])
|
||||
isempty(vs) && return GroupBy([""], [axes(args[1],1)])
|
||||
v = map(tuple, vs...)
|
||||
extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple)
|
||||
end
|
||||
@@ -1091,7 +1116,7 @@ legendEntryFromTuple(ns::NamedTuple) =
|
||||
join(["$k = $v" for (k, v) in pairs(ns)], ", ")
|
||||
|
||||
function extractGroupArgs(vs::NamedTuple, args...)
|
||||
isempty(vs) && return GroupBy([""], [1:size(args[1],1)])
|
||||
isempty(vs) && return GroupBy([""], [axes(args[1],1)])
|
||||
v = map(NamedTuple{keys(vs)}∘tuple, values(vs)...)
|
||||
extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple)
|
||||
end
|
||||
@@ -1114,7 +1139,7 @@ end
|
||||
|
||||
function _filter_input_data!(plotattributes::KW)
|
||||
idxfilter = pop!(plotattributes, :idxfilter, nothing)
|
||||
if idxfilter != nothing
|
||||
if idxfilter !== nothing
|
||||
filter_data!(plotattributes, idxfilter)
|
||||
end
|
||||
end
|
||||
@@ -1180,7 +1205,7 @@ function convertLegendValue(val::Symbol)
|
||||
:best
|
||||
elseif val in (:no, :none)
|
||||
:none
|
||||
elseif val in (:right, :left, :top, :bottom, :inside, :best, :legend, :topright, :topleft, :bottomleft, :bottomright, :outertopright)
|
||||
elseif val in (:right, :left, :top, :bottom, :inside, :best, :legend, :topright, :topleft, :bottomleft, :bottomright, :outertopright, :outertopleft, :outertop, :outerright, :outerleft, :outerbottomright, :outerbottomleft, :outerbottom)
|
||||
val
|
||||
else
|
||||
error("Invalid symbol for legend: $val")
|
||||
@@ -1200,7 +1225,8 @@ convertLegendValue(v::AbstractArray) = map(convertLegendValue, v)
|
||||
# anything else is returned as-is
|
||||
function slice_arg(v::AMat, idx::Int)
|
||||
c = mod1(idx, size(v,2))
|
||||
size(v,1) == 1 ? v[1,c] : v[:,c]
|
||||
m,n = axes(v)
|
||||
size(v,1) == 1 ? v[first(m),n[c]] : v[:,n[c]]
|
||||
end
|
||||
slice_arg(wrapper::InputWrapper, idx) = wrapper.obj
|
||||
slice_arg(v, idx) = v
|
||||
@@ -1230,7 +1256,7 @@ end
|
||||
# v = plotattributes[k]
|
||||
# plotattributes[k] = if v == :match
|
||||
# match_color
|
||||
# elseif v == nothing
|
||||
# elseif v === nothing
|
||||
# plot_color(RGBA(0,0,0,0))
|
||||
# else
|
||||
# v
|
||||
@@ -1239,7 +1265,7 @@ end
|
||||
|
||||
function color_or_nothing!(plotattributes::KW, k::Symbol)
|
||||
v = plotattributes[k]
|
||||
plotattributes[k] = if v == nothing || v == false
|
||||
plotattributes[k] = if v === nothing || v == false
|
||||
RGBA{Float64}(0,0,0,0)
|
||||
elseif v != :match
|
||||
plot_color(v)
|
||||
@@ -1264,8 +1290,10 @@ const _match_map = KW(
|
||||
:bottom_margin => :margin,
|
||||
:titlefontfamily => :fontfamily_subplot,
|
||||
:legendfontfamily => :fontfamily_subplot,
|
||||
:legendtitlefontfamily => :fontfamily_subplot,
|
||||
:titlefontcolor => :foreground_color_subplot,
|
||||
:legendfontcolor => :foreground_color_subplot,
|
||||
:legendtitlefontcolor => :foreground_color_subplot,
|
||||
:tickfontcolor => :foreground_color_text,
|
||||
:guidefontcolor => :foreground_color_guide,
|
||||
)
|
||||
@@ -1508,19 +1536,19 @@ function has_black_border_for_default(st::Symbol)
|
||||
like_histogram(st) || st in (:hexbin, :bar, :shape)
|
||||
end
|
||||
|
||||
|
||||
# converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically
|
||||
function getSeriesRGBColor(c, sp::Subplot, n::Int)
|
||||
# converts a symbol or string into a Colorant or ColorGradient
|
||||
# and assigns a color automatically
|
||||
function get_series_color(c, sp::Subplot, n::Int, seriestype)
|
||||
if c == :auto
|
||||
c = autopick(sp[:color_palette], n)
|
||||
c = like_surface(seriestype) ? cgrad() : autopick(sp[:color_palette], n)
|
||||
elseif isa(c, Int)
|
||||
c = autopick(sp[:color_palette], c)
|
||||
end
|
||||
plot_color(c)
|
||||
end
|
||||
|
||||
function getSeriesRGBColor(c::AbstractArray, sp::Subplot, n::Int)
|
||||
map(x->getSeriesRGBColor(x, sp, n), c)
|
||||
function get_series_color(c::AbstractArray, sp::Subplot, n::Int, seriestype)
|
||||
map(x->get_series_color(x, sp, n, seriestype), c)
|
||||
end
|
||||
|
||||
function ensure_gradient!(plotattributes::KW, csym::Symbol, asym::Symbol)
|
||||
@@ -1556,30 +1584,32 @@ function _update_series_attributes!(plotattributes::KW, plt::Plot, sp::Subplot)
|
||||
|
||||
# update alphas
|
||||
for asym in (:linealpha, :markeralpha, :fillalpha)
|
||||
if plotattributes[asym] == nothing
|
||||
if plotattributes[asym] === nothing
|
||||
plotattributes[asym] = plotattributes[:seriesalpha]
|
||||
end
|
||||
end
|
||||
if plotattributes[:markerstrokealpha] == nothing
|
||||
if plotattributes[:markerstrokealpha] === nothing
|
||||
plotattributes[:markerstrokealpha] = plotattributes[:markeralpha]
|
||||
end
|
||||
|
||||
# update series color
|
||||
plotattributes[:seriescolor] = getSeriesRGBColor(plotattributes[:seriescolor], sp, plotIndex)
|
||||
scolor = plotattributes[:seriescolor]
|
||||
stype = plotattributes[:seriestype]
|
||||
plotattributes[:seriescolor] = scolor = get_series_color(scolor, sp, plotIndex, stype)
|
||||
|
||||
# update other colors
|
||||
for s in (:line, :marker, :fill)
|
||||
csym, asym = Symbol(s,:color), Symbol(s,:alpha)
|
||||
plotattributes[csym] = if plotattributes[csym] == :auto
|
||||
plot_color(if has_black_border_for_default(plotattributes[:seriestype]) && s == :line
|
||||
plot_color(if has_black_border_for_default(stype) && s == :line
|
||||
sp[:foreground_color_subplot]
|
||||
else
|
||||
plotattributes[:seriescolor]
|
||||
scolor
|
||||
end)
|
||||
elseif plotattributes[csym] == :match
|
||||
plot_color(plotattributes[:seriescolor])
|
||||
plot_color(scolor)
|
||||
else
|
||||
getSeriesRGBColor(plotattributes[csym], sp, plotIndex)
|
||||
get_series_color(plotattributes[csym], sp, plotIndex, stype)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1587,19 +1617,19 @@ function _update_series_attributes!(plotattributes::KW, plt::Plot, sp::Subplot)
|
||||
plotattributes[:markerstrokecolor] = if plotattributes[:markerstrokecolor] == :match
|
||||
plot_color(sp[:foreground_color_subplot])
|
||||
elseif plotattributes[:markerstrokecolor] == :auto
|
||||
getSeriesRGBColor(plotattributes[:markercolor], sp, plotIndex)
|
||||
get_series_color(plotattributes[:markercolor], sp, plotIndex, stype)
|
||||
else
|
||||
getSeriesRGBColor(plotattributes[:markerstrokecolor], sp, plotIndex)
|
||||
get_series_color(plotattributes[:markerstrokecolor], sp, plotIndex, stype)
|
||||
end
|
||||
|
||||
# if marker_z, fill_z or line_z are set, ensure we have a gradient
|
||||
if plotattributes[:marker_z] != nothing
|
||||
if plotattributes[:marker_z] !== nothing
|
||||
ensure_gradient!(plotattributes, :markercolor, :markeralpha)
|
||||
end
|
||||
if plotattributes[:line_z] != nothing
|
||||
if plotattributes[:line_z] !== nothing
|
||||
ensure_gradient!(plotattributes, :linecolor, :linealpha)
|
||||
end
|
||||
if plotattributes[:fill_z] != nothing
|
||||
if plotattributes[:fill_z] !== nothing
|
||||
ensure_gradient!(plotattributes, :fillcolor, :fillalpha)
|
||||
end
|
||||
|
||||
|
||||
+384
-108
@@ -67,7 +67,7 @@ function process_axis_arg!(plotattributes::KW, arg, letter = "")
|
||||
elseif T <: AVec
|
||||
plotattributes[Symbol(letter,:ticks)] = arg
|
||||
|
||||
elseif arg == nothing
|
||||
elseif arg === nothing
|
||||
plotattributes[Symbol(letter,:ticks)] = []
|
||||
|
||||
elseif T <: Bool || arg in _allShowaxisArgs
|
||||
@@ -117,7 +117,7 @@ end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
Base.show(io::IO, axis::Axis) = dumpdict(axis.plotattributes, "Axis", true)
|
||||
Base.show(io::IO, axis::Axis) = dumpdict(io, axis.plotattributes, "Axis", true)
|
||||
# Base.getindex(axis::Axis, k::Symbol) = getindex(axis.plotattributes, k)
|
||||
Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.plotattributes, v, ks...)
|
||||
Base.haskey(axis::Axis, k::Symbol) = haskey(axis.plotattributes, k)
|
||||
@@ -152,8 +152,8 @@ scalefunc(scale::Symbol) = x -> get(_scale_funcs, scale, identity)(Float64(x))
|
||||
invscalefunc(scale::Symbol) = x -> get(_inv_scale_funcs, scale, identity)(Float64(x))
|
||||
labelfunc(scale::Symbol, backend::AbstractBackend) = get(_label_func, scale, string)
|
||||
|
||||
function optimal_ticks_and_labels(axis::Axis, ticks = nothing)
|
||||
amin,amax = axis_limits(axis)
|
||||
function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
|
||||
amin, amax = axis_limits(sp, axis[:letter])
|
||||
|
||||
# scale the limits
|
||||
scale = axis[:scale]
|
||||
@@ -166,7 +166,7 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing)
|
||||
# or DateTime) is chosen based on the time span between amin and amax
|
||||
# rather than on the input format
|
||||
# TODO: maybe: non-trivial scale (:ln, :log2, :log10) for date/datetime
|
||||
if ticks == nothing && scale == :identity
|
||||
if ticks === nothing && scale == :identity
|
||||
if axis[:formatter] == dateformatter
|
||||
# optimize_datetime_ticks returns ticks and labels(!) based on
|
||||
# integers/floats corresponding to the DateTime type. Thus, the axes
|
||||
@@ -184,7 +184,7 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing)
|
||||
end
|
||||
|
||||
# get a list of well-laid-out ticks
|
||||
if ticks == nothing
|
||||
if ticks === nothing
|
||||
scaled_ticks = optimize_ticks(
|
||||
sf(amin),
|
||||
sf(amax);
|
||||
@@ -218,6 +218,8 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing)
|
||||
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :plain))
|
||||
elseif formatter == :scientific
|
||||
Showoff.showoff(unscaled_ticks, :scientific)
|
||||
elseif formatter == :latex
|
||||
map(x -> string("\$", replace(convert_sci_unicode(x), '×' => "\\times"), "\$"), Showoff.showoff(unscaled_ticks, :auto))
|
||||
else
|
||||
# there was an override for the formatter... use that on the unscaled ticks
|
||||
map(formatter, unscaled_ticks)
|
||||
@@ -238,9 +240,9 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing)
|
||||
end
|
||||
|
||||
# return (continuous_values, discrete_values) for the ticks on this axis
|
||||
function get_ticks(axis::Axis)
|
||||
function get_ticks(sp::Subplot, axis::Axis)
|
||||
ticks = _transform_ticks(axis[:ticks])
|
||||
ticks in (nothing, false) && return nothing
|
||||
ticks in (:none, nothing, false) && return nothing
|
||||
|
||||
# treat :native ticks as :auto
|
||||
ticks = ticks == :native ? :auto : ticks
|
||||
@@ -251,7 +253,7 @@ function get_ticks(axis::Axis)
|
||||
# discrete ticks...
|
||||
n = length(dvals)
|
||||
rng = if ticks == :auto
|
||||
Int[round(Int,i) for i in range(1, stop=n, length=15)]
|
||||
Int[round(Int,i) for i in range(1, stop=n, length=min(n,15))]
|
||||
else # if ticks == :all
|
||||
1:n
|
||||
end
|
||||
@@ -261,7 +263,7 @@ function get_ticks(axis::Axis)
|
||||
(collect(0:pi/4:7pi/4), string.(0:45:315))
|
||||
else
|
||||
# compute optimal ticks and labels
|
||||
optimal_ticks_and_labels(axis)
|
||||
optimal_ticks_and_labels(sp, axis)
|
||||
end
|
||||
elseif typeof(ticks) <: Union{AVec, Int}
|
||||
if !isempty(dvals) && typeof(ticks) <: Int
|
||||
@@ -269,7 +271,7 @@ function get_ticks(axis::Axis)
|
||||
axis[:continuous_values][rng], dvals[rng]
|
||||
else
|
||||
# override ticks, but get the labels
|
||||
optimal_ticks_and_labels(axis, ticks)
|
||||
optimal_ticks_and_labels(sp, axis, ticks)
|
||||
end
|
||||
elseif typeof(ticks) <: NTuple{2, Any}
|
||||
# assuming we're passed (ticks, labels)
|
||||
@@ -286,16 +288,16 @@ _transform_ticks(ticks) = ticks
|
||||
_transform_ticks(ticks::AbstractArray{T}) where T <: Dates.TimeType = Dates.value.(ticks)
|
||||
_transform_ticks(ticks::NTuple{2, Any}) = (_transform_ticks(ticks[1]), ticks[2])
|
||||
|
||||
function get_minor_ticks(axis,ticks)
|
||||
axis[:minorticks] in (nothing, false) && !axis[:minorgrid] && return nothing
|
||||
function get_minor_ticks(sp, axis, ticks)
|
||||
axis[:minorticks] in (:none, nothing, false) && !axis[:minorgrid] && return nothing
|
||||
ticks = ticks[1]
|
||||
length(ticks) < 2 && return nothing
|
||||
|
||||
amin, amax = axis_limits(axis)
|
||||
amin, amax = axis_limits(sp, axis[:letter])
|
||||
#Add one phantom tick either side of the ticks to ensure minor ticks extend to the axis limits
|
||||
if length(ticks) > 2
|
||||
ratio = (ticks[3] - ticks[2])/(ticks[2] - ticks[1])
|
||||
elseif axis[:scale] == :none
|
||||
elseif axis[:scale] in (:none, :identity)
|
||||
ratio = 1
|
||||
else
|
||||
return nothing
|
||||
@@ -309,7 +311,9 @@ function get_minor_ticks(axis,ticks)
|
||||
minorticks = typeof(ticks[1])[]
|
||||
for (i,hi) in enumerate(ticks[2:end])
|
||||
lo = ticks[i]
|
||||
append!(minorticks,collect(lo + (hi-lo)/n :(hi-lo)/n: hi - (hi-lo)/2n))
|
||||
if isfinite(lo) && hi > lo
|
||||
append!(minorticks,collect(lo + (hi-lo)/n :(hi-lo)/n: hi - (hi-lo)/2n))
|
||||
end
|
||||
end
|
||||
minorticks[amin .<= minorticks .<= amax]
|
||||
end
|
||||
@@ -382,7 +386,7 @@ function expand_extrema!(sp::Subplot, plotattributes::KW)
|
||||
data = plotattributes[letter] = Surface(Matrix{Float64}(data.surf))
|
||||
end
|
||||
expand_extrema!(axis, data)
|
||||
elseif data != nothing
|
||||
elseif data !== nothing
|
||||
# TODO: need more here... gotta track the discrete reference value
|
||||
# as well as any coord offset (think of boxplot shape coords... they all
|
||||
# correspond to the same x-value)
|
||||
@@ -399,10 +403,10 @@ function expand_extrema!(sp::Subplot, plotattributes::KW)
|
||||
|
||||
# expand for fillrange
|
||||
fr = plotattributes[:fillrange]
|
||||
if fr == nothing && plotattributes[:seriestype] == :bar
|
||||
if fr === nothing && plotattributes[:seriestype] == :bar
|
||||
fr = 0.0
|
||||
end
|
||||
if fr != nothing && !all3D(plotattributes)
|
||||
if fr !== nothing && !all3D(plotattributes)
|
||||
axis = sp.attr[vert ? :yaxis : :xaxis]
|
||||
if typeof(fr) <: Tuple
|
||||
for fri in fr
|
||||
@@ -419,7 +423,7 @@ function expand_extrema!(sp::Subplot, plotattributes::KW)
|
||||
data = plotattributes[dsym]
|
||||
|
||||
bw = plotattributes[:bar_width]
|
||||
if bw == nothing
|
||||
if bw === nothing
|
||||
bw = plotattributes[:bar_width] = _bar_width * ignorenan_minimum(filter(x->x>0,diff(sort(data))))
|
||||
end
|
||||
axis = sp.attr[Symbol(dsym, :axis)]
|
||||
@@ -479,11 +483,13 @@ function round_limits(amin,amax)
|
||||
end
|
||||
|
||||
# using the axis extrema and limit overrides, return the min/max value for this axis
|
||||
function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis))
|
||||
function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(letter, :axis)]), consider_aspect = true)
|
||||
axis = sp[Symbol(letter, :axis)]
|
||||
ex = axis[:extrema]
|
||||
amin, amax = ex.emin, ex.emax
|
||||
lims = axis[:lims]
|
||||
if (isa(lims, Tuple) || isa(lims, AVec)) && length(lims) == 2
|
||||
has_user_lims = (isa(lims, Tuple) || isa(lims, AVec)) && length(lims) == 2
|
||||
if has_user_lims
|
||||
if isfinite(lims[1])
|
||||
amin = lims[1]
|
||||
end
|
||||
@@ -497,12 +503,12 @@ function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis)
|
||||
if !isfinite(amin) && !isfinite(amax)
|
||||
amin, amax = 0.0, 1.0
|
||||
end
|
||||
if ispolar(axis.sps[1])
|
||||
amin, amax = if ispolar(axis.sps[1])
|
||||
if axis[:letter] == :x
|
||||
amin, amax = 0, 2pi
|
||||
elseif lims == :auto
|
||||
#widen max radius so ticks dont overlap with theta axis
|
||||
amin, amax + 0.1 * abs(amax - amin)
|
||||
0, amax + 0.1 * abs(amax - amin)
|
||||
else
|
||||
amin, amax
|
||||
end
|
||||
@@ -513,6 +519,32 @@ function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis)
|
||||
else
|
||||
amin, amax
|
||||
end
|
||||
|
||||
if !has_user_lims && consider_aspect && letter in (:x, :y) && !(sp[:aspect_ratio] in (:none, :auto) || is3d(:sp))
|
||||
aspect_ratio = isa(sp[:aspect_ratio], Number) ? sp[:aspect_ratio] : 1
|
||||
plot_ratio = height(plotarea(sp)) / width(plotarea(sp))
|
||||
dist = amax - amin
|
||||
|
||||
if letter == :x
|
||||
yamin, yamax = axis_limits(sp, :y, default_should_widen(sp[:yaxis]), false)
|
||||
ydist = yamax - yamin
|
||||
axis_ratio = aspect_ratio * ydist / dist
|
||||
factor = axis_ratio / plot_ratio
|
||||
else
|
||||
xamin, xamax = axis_limits(sp, :x, default_should_widen(sp[:xaxis]), false)
|
||||
xdist = xamax - xamin
|
||||
axis_ratio = aspect_ratio * dist / xdist
|
||||
factor = plot_ratio / axis_ratio
|
||||
end
|
||||
|
||||
if factor > 1
|
||||
center = (amin + amax) / 2
|
||||
amin = center + factor * (amin - center)
|
||||
amax = center + factor * (amax - center)
|
||||
end
|
||||
end
|
||||
|
||||
return amin, amax
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@@ -545,10 +577,10 @@ end
|
||||
|
||||
# add the discrete value for each item. return the continuous values and the indices
|
||||
function discrete_value!(axis::Axis, v::AVec)
|
||||
n = length(v)
|
||||
cvec = zeros(n)
|
||||
discrete_indices = zeros(Int, n)
|
||||
for i=1:n
|
||||
n = eachindex(v)
|
||||
cvec = zeros(axes(v))
|
||||
discrete_indices = similar(Array{Int}, axes(v))
|
||||
for i in n
|
||||
cvec[i], discrete_indices[i] = discrete_value!(axis, v[i])
|
||||
end
|
||||
cvec, discrete_indices
|
||||
@@ -556,10 +588,10 @@ end
|
||||
|
||||
# add the discrete value for each item. return the continuous values and the indices
|
||||
function discrete_value!(axis::Axis, v::AMat)
|
||||
n,m = size(v)
|
||||
cmat = zeros(n,m)
|
||||
discrete_indices = zeros(Int, n, m)
|
||||
for i=1:n, j=1:m
|
||||
n,m = axes(v)
|
||||
cmat = zeros(axes(v))
|
||||
discrete_indices = similar(Array{Int}, axes(v))
|
||||
for i in n, j in m
|
||||
cmat[i,j], discrete_indices[i,j] = discrete_value!(axis, v[i,j])
|
||||
end
|
||||
cmat, discrete_indices
|
||||
@@ -586,12 +618,12 @@ end
|
||||
# compute the line segments which should be drawn for this axis
|
||||
function axis_drawing_info(sp::Subplot)
|
||||
xaxis, yaxis = sp[:xaxis], sp[:yaxis]
|
||||
xmin, xmax = axis_limits(xaxis)
|
||||
ymin, ymax = axis_limits(yaxis)
|
||||
xticks = get_ticks(xaxis)
|
||||
yticks = get_ticks(yaxis)
|
||||
xminorticks = get_minor_ticks(xaxis,xticks)
|
||||
yminorticks = get_minor_ticks(yaxis,yticks)
|
||||
xmin, xmax = axis_limits(sp, :x)
|
||||
ymin, ymax = axis_limits(sp, :y)
|
||||
xticks = get_ticks(sp, xaxis)
|
||||
yticks = get_ticks(sp, yaxis)
|
||||
xminorticks = get_minor_ticks(sp, xaxis, xticks)
|
||||
yminorticks = get_minor_ticks(sp, yaxis, yticks)
|
||||
xaxis_segs = Segments(2)
|
||||
yaxis_segs = Segments(2)
|
||||
xtick_segs = Segments(2)
|
||||
@@ -605,126 +637,370 @@ function axis_drawing_info(sp::Subplot)
|
||||
|
||||
if sp[:framestyle] != :none
|
||||
# xaxis
|
||||
y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
|
||||
end
|
||||
if xaxis[:showaxis]
|
||||
if sp[:framestyle] != :grid
|
||||
y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
|
||||
end
|
||||
push!(xaxis_segs, (xmin, y1), (xmax, y1))
|
||||
# don't show the 0 tick label for the origin framestyle
|
||||
if sp[:framestyle] == :origin && !(xticks in (nothing,false)) && length(xticks) > 1
|
||||
if sp[:framestyle] == :origin && !(xticks in (:none, nothing, false)) && length(xticks) > 1
|
||||
showticks = xticks[1] .!= 0
|
||||
xticks = (xticks[1][showticks], xticks[2][showticks])
|
||||
end
|
||||
end
|
||||
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2), (xmax, y2)) # top spine
|
||||
end
|
||||
if !(xaxis[:ticks] in (nothing, false))
|
||||
if !(xaxis[:ticks] in (:none, nothing, false))
|
||||
f = scalefunc(yaxis[:scale])
|
||||
invf = invscalefunc(yaxis[:scale])
|
||||
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
|
||||
t1 = invf(f(ymin) + 0.015 * (f(ymax) - f(ymin)) * ticks_in)
|
||||
t2 = invf(f(ymax) - 0.015 * (f(ymax) - f(ymin)) * ticks_in)
|
||||
t3 = invf(f(0) + 0.015 * (f(ymax) - f(ymin)) * ticks_in)
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
|
||||
(-t, t)
|
||||
else
|
||||
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(y1) + 0.012 * (f(y2) - f(y1)) * ticks_in)
|
||||
(y1, t)
|
||||
end
|
||||
|
||||
for xtick in xticks[1]
|
||||
if xaxis[:showaxis]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
(0, t3)
|
||||
else
|
||||
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, t2) : (ymin, t1)
|
||||
end
|
||||
push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick
|
||||
end
|
||||
# sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick
|
||||
xaxis[:grid] && push!(xgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid
|
||||
end
|
||||
end
|
||||
if !(xaxis[:minorticks] in (nothing, false)) || xaxis[:minorgrid]
|
||||
f = scalefunc(yaxis[:scale])
|
||||
invf = invscalefunc(yaxis[:scale])
|
||||
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
|
||||
t1 = invf(f(ymin) + 0.01 * (f(ymax) - f(ymin)) * ticks_in)
|
||||
t2 = invf(f(ymax) - 0.01 * (f(ymax) - f(ymin)) * ticks_in)
|
||||
t3 = invf(f(0) + 0.01 * (f(ymax) - f(ymin)) * ticks_in)
|
||||
|
||||
for xminortick in xminorticks
|
||||
if xaxis[:showaxis]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
(0, t3)
|
||||
else
|
||||
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, t2) : (ymin, t1)
|
||||
end
|
||||
push!(xtick_segs, (xminortick, tick_start), (xminortick, tick_stop)) # bottom tick
|
||||
if !(xaxis[:minorticks] in (:none, nothing, false)) || xaxis[:minorgrid]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.006 * (f(ymax) - f(ymin)))
|
||||
(-t, t)
|
||||
else
|
||||
t = invf(f(y1) + 0.006 * (f(y2) - f(y1)) * ticks_in)
|
||||
(y1, t)
|
||||
end
|
||||
for xtick in xminorticks
|
||||
if xaxis[:showaxis]
|
||||
push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick
|
||||
end
|
||||
xaxis[:minorgrid] && push!(xminorgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid
|
||||
end
|
||||
# sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick
|
||||
xaxis[:minorgrid] && push!(xminorgrid_segs, (xminortick, ymin), (xminortick, ymax)) # vertical grid
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# yaxis
|
||||
x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax)
|
||||
end
|
||||
if yaxis[:showaxis]
|
||||
if sp[:framestyle] != :grid
|
||||
x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax)
|
||||
end
|
||||
push!(yaxis_segs, (x1, ymin), (x1, ymax))
|
||||
# don't show the 0 tick label for the origin framestyle
|
||||
if sp[:framestyle] == :origin && !(yticks in (nothing,false)) && length(yticks) > 1
|
||||
if sp[:framestyle] == :origin && !(yticks in (:none, nothing,false)) && length(yticks) > 1
|
||||
showticks = yticks[1] .!= 0
|
||||
yticks = (yticks[1][showticks], yticks[2][showticks])
|
||||
end
|
||||
end
|
||||
sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (x2, ymin), (x2, ymax)) # right spine
|
||||
end
|
||||
if !(yaxis[:ticks] in (nothing, false))
|
||||
if !(yaxis[:ticks] in (:none, nothing, false))
|
||||
f = scalefunc(xaxis[:scale])
|
||||
invf = invscalefunc(xaxis[:scale])
|
||||
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
|
||||
t1 = invf(f(xmin) + 0.015 * (f(xmax) - f(xmin)) * ticks_in)
|
||||
t2 = invf(f(xmax) - 0.015 * (f(xmax) - f(xmin)) * ticks_in)
|
||||
t3 = invf(f(0) + 0.015 * (f(xmax) - f(xmin)) * ticks_in)
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.012 * (f(xmax) - f(xmin)))
|
||||
(-t, t)
|
||||
else
|
||||
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(x1) + 0.012 * (f(x2) - f(x1)) * ticks_in)
|
||||
(x1, t)
|
||||
end
|
||||
|
||||
for ytick in yticks[1]
|
||||
if yaxis[:showaxis]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
(0, t3)
|
||||
else
|
||||
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, t2) : (xmin, t1)
|
||||
end
|
||||
push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick
|
||||
end
|
||||
# sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick
|
||||
yaxis[:grid] && push!(ygrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
|
||||
end
|
||||
end
|
||||
if !(yaxis[:minorticks] in (nothing, false)) || yaxis[:minorgrid]
|
||||
f = scalefunc(xaxis[:scale])
|
||||
invf = invscalefunc(xaxis[:scale])
|
||||
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
|
||||
t1 = invf(f(xmin) + 0.01 * (f(xmax) - f(xmin)) * ticks_in)
|
||||
t2 = invf(f(xmax) - 0.01 * (f(xmax) - f(xmin)) * ticks_in)
|
||||
t3 = invf(f(0) + 0.01 * (f(xmax) - f(xmin)) * ticks_in)
|
||||
|
||||
for ytick in yminorticks
|
||||
if yaxis[:showaxis]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
(0, t3)
|
||||
else
|
||||
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, t2) : (xmin, t1)
|
||||
end
|
||||
push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick
|
||||
if !(yaxis[:minorticks] in (:none, nothing, false)) || yaxis[:minorgrid]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.006 * (f(xmax) - f(xmin)))
|
||||
(-t, t)
|
||||
else
|
||||
t = invf(f(x1) + 0.006 * (f(x2) - f(x1)) * ticks_in)
|
||||
(x1, t)
|
||||
end
|
||||
for ytick in yminorticks
|
||||
if yaxis[:showaxis]
|
||||
push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick
|
||||
end
|
||||
yaxis[:minorgrid] && push!(yminorgrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
|
||||
end
|
||||
# sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick
|
||||
yaxis[:minorgrid] && push!(yminorgrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
xticks, yticks, xaxis_segs, yaxis_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xminorgrid_segs, yminorgrid_segs, xborder_segs, yborder_segs
|
||||
end
|
||||
|
||||
|
||||
function axis_drawing_info_3d(sp::Subplot)
|
||||
xaxis, yaxis, zaxis = sp[:xaxis], sp[:yaxis], sp[:zaxis]
|
||||
xmin, xmax = axis_limits(sp, :x)
|
||||
ymin, ymax = axis_limits(sp, :y)
|
||||
zmin, zmax = axis_limits(sp, :z)
|
||||
xticks = get_ticks(sp, xaxis)
|
||||
yticks = get_ticks(sp, yaxis)
|
||||
zticks = get_ticks(sp, zaxis)
|
||||
xminorticks = get_minor_ticks(sp, xaxis, xticks)
|
||||
yminorticks = get_minor_ticks(sp, yaxis, yticks)
|
||||
zminorticks = get_minor_ticks(sp, zaxis, zticks)
|
||||
xaxis_segs = Segments(3)
|
||||
yaxis_segs = Segments(3)
|
||||
zaxis_segs = Segments(3)
|
||||
xtick_segs = Segments(3)
|
||||
ytick_segs = Segments(3)
|
||||
ztick_segs = Segments(3)
|
||||
xgrid_segs = Segments(3)
|
||||
ygrid_segs = Segments(3)
|
||||
zgrid_segs = Segments(3)
|
||||
xminorgrid_segs = Segments(3)
|
||||
yminorgrid_segs = Segments(3)
|
||||
zminorgrid_segs = Segments(3)
|
||||
xborder_segs = Segments(3)
|
||||
yborder_segs = Segments(3)
|
||||
zborder_segs = Segments(3)
|
||||
|
||||
if sp[:framestyle] != :none
|
||||
|
||||
# xaxis
|
||||
y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
|
||||
end
|
||||
z1, z2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(xaxis[:mirror], zaxis[:flip]) ? (zmax, zmin) : (zmin, zmax)
|
||||
end
|
||||
if xaxis[:showaxis]
|
||||
if sp[:framestyle] != :grid
|
||||
push!(xaxis_segs, (xmin, y1, z1), (xmax, y1, z1))
|
||||
# don't show the 0 tick label for the origin framestyle
|
||||
if sp[:framestyle] == :origin && !(xticks in (:none, nothing, false)) && length(xticks) > 1
|
||||
showticks = xticks[1] .!= 0
|
||||
xticks = (xticks[1][showticks], xticks[2][showticks])
|
||||
end
|
||||
end
|
||||
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2, z2), (xmax, y2, z2)) # top spine
|
||||
end
|
||||
if !(xaxis[:ticks] in (:none, nothing, false))
|
||||
f = scalefunc(yaxis[:scale])
|
||||
invf = invscalefunc(yaxis[:scale])
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
|
||||
(-t, t)
|
||||
else
|
||||
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(y1) + 0.012 * (f(y2) - f(y1)) * ticks_in)
|
||||
(y1, t)
|
||||
end
|
||||
|
||||
for xtick in xticks[1]
|
||||
if xaxis[:showaxis]
|
||||
push!(xtick_segs, (xtick, tick_start, z1), (xtick, tick_stop, z1)) # bottom tick
|
||||
end
|
||||
if xaxis[:grid]
|
||||
if sp[:framestyle] in (:origin, :zerolines)
|
||||
push!(xgrid_segs, (xtick, ymin, 0.0), (xtick, ymax, 0.0))
|
||||
push!(xgrid_segs, (xtick, 0.0, zmin), (xtick, 0.0, zmax))
|
||||
else
|
||||
push!(xgrid_segs, (xtick, y1, z1), (xtick, y2, z1))
|
||||
push!(xgrid_segs, (xtick, y2, z1), (xtick, y2, z2))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !(xaxis[:minorticks] in (:none, nothing, false)) || xaxis[:minorgrid]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.006 * (f(ymax) - f(ymin)))
|
||||
(-t, t)
|
||||
else
|
||||
t = invf(f(y1) + 0.006 * (f(y2) - f(y1)) * ticks_in)
|
||||
(y1, t)
|
||||
end
|
||||
for xtick in xminorticks
|
||||
if xaxis[:showaxis]
|
||||
push!(xtick_segs, (xtick, tick_start, z1), (xtick, tick_stop, z1)) # bottom tick
|
||||
end
|
||||
if xaxis[:minorgrid]
|
||||
if sp[:framestyle] in (:origin, :zerolines)
|
||||
push!(xminorgrid_segs, (xtick, ymin, 0.0), (xtick, ymax, 0.0))
|
||||
push!(xminorgrid_segs, (xtick, 0.0, zmin), (xtick, 0.0, zmax))
|
||||
else
|
||||
push!(xminorgrid_segs, (xtick, y1, z1), (xtick, y2, z1))
|
||||
push!(xminorgrid_segs, (xtick, y2, z1), (xtick, y2, z2))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# yaxis
|
||||
x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(yaxis[:mirror], xaxis[:flip]) ? (xmin, xmax) : (xmax, xmin)
|
||||
end
|
||||
z1, z2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(yaxis[:mirror], zaxis[:flip]) ? (zmax, zmin) : (zmin, zmax)
|
||||
end
|
||||
if yaxis[:showaxis]
|
||||
if sp[:framestyle] != :grid
|
||||
push!(yaxis_segs, (x1, ymin, z1), (x1, ymax, z1))
|
||||
# don't show the 0 tick label for the origin framestyle
|
||||
if sp[:framestyle] == :origin && !(yticks in (:none, nothing,false)) && length(yticks) > 1
|
||||
showticks = yticks[1] .!= 0
|
||||
yticks = (yticks[1][showticks], yticks[2][showticks])
|
||||
end
|
||||
end
|
||||
sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (x2, ymin, z2), (x2, ymax, z2)) # right spine
|
||||
end
|
||||
if !(yaxis[:ticks] in (:none, nothing, false))
|
||||
f = scalefunc(xaxis[:scale])
|
||||
invf = invscalefunc(xaxis[:scale])
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.012 * (f(xmax) - f(xmin)))
|
||||
(-t, t)
|
||||
else
|
||||
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(x1) + 0.012 * (f(x2) - f(x1)) * ticks_in)
|
||||
(x1, t)
|
||||
end
|
||||
|
||||
for ytick in yticks[1]
|
||||
if yaxis[:showaxis]
|
||||
push!(ytick_segs, (tick_start, ytick, z1), (tick_stop, ytick, z1)) # left tick
|
||||
end
|
||||
if yaxis[:grid]
|
||||
if sp[:framestyle] in (:origin, :zerolines)
|
||||
push!(ygrid_segs, (xmin, ytick, 0.0), (xmax, ytick, 0.0))
|
||||
push!(ygrid_segs, (0.0, ytick, zmin), (0.0, ytick, zmax))
|
||||
else
|
||||
push!(ygrid_segs, (x1, ytick, z1), (x2, ytick, z1))
|
||||
push!(ygrid_segs, (x2, ytick, z1), (x2, ytick, z2))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !(yaxis[:minorticks] in (:none, nothing, false)) || yaxis[:minorgrid]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.006 * (f(xmax) - f(xmin)))
|
||||
(-t, t)
|
||||
else
|
||||
t = invf(f(x1) + 0.006 * (f(x2) - f(x1)) * ticks_in)
|
||||
(x1, t)
|
||||
end
|
||||
for ytick in yminorticks
|
||||
if yaxis[:showaxis]
|
||||
push!(ytick_segs, (tick_start, ytick, z1), (tick_stop, ytick, z1)) # left tick
|
||||
end
|
||||
if yaxis[:minorgrid]
|
||||
if sp[:framestyle] in (:origin, :zerolines)
|
||||
push!(yminorgrid_segs, (xmin, ytick, 0.0), (xmax, ytick, 0.0))
|
||||
push!(yminorgrid_segs, (0.0, ytick, zmin), (0.0, ytick, zmax))
|
||||
else
|
||||
push!(yminorgrid_segs, (x1, ytick, z1), (x2, ytick, z1))
|
||||
push!(yminorgrid_segs, (x2, ytick, z1), (x2, ytick, z2))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# zaxis
|
||||
x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(zaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax)
|
||||
end
|
||||
y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0.0, 0.0
|
||||
else
|
||||
xor(zaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
|
||||
end
|
||||
if zaxis[:showaxis]
|
||||
if sp[:framestyle] != :grid
|
||||
push!(zaxis_segs, (x1, y1, zmin), (x1, y1, zmax))
|
||||
# don't show the 0 tick label for the origin framestyle
|
||||
if sp[:framestyle] == :origin && !(zticks in (:none, nothing,false)) && length(zticks) > 1
|
||||
showticks = zticks[1] .!= 0
|
||||
zticks = (zticks[1][showticks], zticks[2][showticks])
|
||||
end
|
||||
end
|
||||
sp[:framestyle] in (:semi, :box) && push!(zborder_segs, (x2, y2, zmin), (x2, y2, zmax))
|
||||
end
|
||||
if !(zaxis[:ticks] in (:none, nothing, false))
|
||||
f = scalefunc(xaxis[:scale])
|
||||
invf = invscalefunc(xaxis[:scale])
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
|
||||
(-t, t)
|
||||
else
|
||||
ticks_in = zaxis[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(y1) + 0.012 * (f(y2) - f(y1)) * ticks_in)
|
||||
(y1, t)
|
||||
end
|
||||
|
||||
for ztick in zticks[1]
|
||||
if zaxis[:showaxis]
|
||||
push!(ztick_segs, (x1, tick_start, ztick), (x1, tick_stop, ztick)) # left tick
|
||||
end
|
||||
if zaxis[:grid]
|
||||
if sp[:framestyle] in (:origin, :zerolines)
|
||||
push!(zgrid_segs, (xmin, 0.0, ztick), (xmax, 0.0, ztick))
|
||||
push!(ygrid_segs, (0.0, ymin, ztick), (0.0, ymax, ztick))
|
||||
else
|
||||
push!(ygrid_segs, (x1, y1, ztick), (x1, y2, ztick))
|
||||
push!(ygrid_segs, (x1, y2, ztick), (x2, y2, ztick))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if !(zaxis[:minorticks] in (:none, nothing, false)) || zaxis[:minorgrid]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.006 * (f(ymax) - f(ymin)))
|
||||
(-t, t)
|
||||
else
|
||||
t = invf(f(y1) + 0.006 * (f(y2) - f(y1)) * ticks_in)
|
||||
(y1, t)
|
||||
end
|
||||
for ztick in zminorticks
|
||||
if zaxis[:showaxis]
|
||||
push!(ztick_segs, (x1, tick_start, ztick), (x1, tick_stop, ztick)) # left tick
|
||||
end
|
||||
if zaxis[:minorgrid]
|
||||
if sp[:framestyle] in (:origin, :zerolines)
|
||||
push!(zminorgrid_segs, (xmin, 0.0, ztick), (xmax, 0.0, ztick))
|
||||
push!(zminorgrid_segs, (0.0, ymin, ztick), (0.0, ymax, ztick))
|
||||
else
|
||||
push!(zminorgrid_segs, (x1, y1, ztick), (x1, y2, ztick))
|
||||
push!(zminorgrid_segs, (x1, y2, ztick), (x2, y2, ztick))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
xticks, yticks, zticks, xaxis_segs, yaxis_segs, zaxis_segs, xtick_segs, ytick_segs, ztick_segs, xgrid_segs, ygrid_segs, zgrid_segs, xminorgrid_segs, yminorgrid_segs, zminorgrid_segs, xborder_segs, yborder_segs, zborder_segs
|
||||
end
|
||||
|
||||
+107
-113
@@ -7,16 +7,20 @@ const _backendSymbol = Dict{DataType, Symbol}(NoBackend => :none)
|
||||
const _backends = Symbol[]
|
||||
const _initialized_backends = Set{Symbol}()
|
||||
const _default_backends = (:none, :gr, :plotly)
|
||||
const _backendPackage = Dict{Symbol, Symbol}()
|
||||
|
||||
const _backend_packages = Dict{Symbol, Symbol}()
|
||||
|
||||
"Returns a list of supported backends"
|
||||
backends() = _backends
|
||||
|
||||
"Returns the name of the current backend"
|
||||
backend_name() = CURRENT_BACKEND.sym
|
||||
_backend_instance(sym::Symbol) = haskey(_backendType, sym) ? _backendType[sym]() : error("Unsupported backend $sym")
|
||||
backend_package(pkg::Symbol) = pkg in _default_backends ? :Plots : Symbol("Plots", _backendPackage[pkg])
|
||||
backend_package_name(sym::Symbol) = sym in _default_backends ? :Plots : _backendPackage[sym]
|
||||
|
||||
function _backend_instance(sym::Symbol)::AbstractBackend
|
||||
haskey(_backendType, sym) ? _backendType[sym]() : error("Unsupported backend $sym")
|
||||
end
|
||||
|
||||
backend_package_name(sym::Symbol) = _backend_packages[sym]
|
||||
|
||||
macro init_backend(s)
|
||||
package_str = string(s)
|
||||
@@ -26,14 +30,13 @@ macro init_backend(s)
|
||||
esc(quote
|
||||
struct $T <: AbstractBackend end
|
||||
export $sym
|
||||
$sym(; kw...) = (default(; kw...); backend(Symbol($str)))
|
||||
$sym(; kw...) = (default(; kw...); backend($T()))
|
||||
backend_name(::$T) = Symbol($str)
|
||||
backend_package_name(pkg::$T) = backend_package_name(Symbol($str))
|
||||
push!(_backends, Symbol($str))
|
||||
_backendType[Symbol($str)] = $T
|
||||
_backendSymbol[$T] = Symbol($str)
|
||||
_backendPackage[Symbol($str)] = Symbol($package_str)
|
||||
# include("backends/" * $str * ".jl")
|
||||
_backend_packages[Symbol($str)] = Symbol($package_str)
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -42,12 +45,6 @@ end
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
function add_backend(pkg::Symbol)
|
||||
@info("To do a standard install of $pkg, copy and run this:\n\n")
|
||||
println(add_backend_string(_backend_instance(pkg)))
|
||||
println()
|
||||
end
|
||||
|
||||
# don't do anything as a default
|
||||
_create_backend_figure(plt::Plot) = nothing
|
||||
_prepare_plot_object(plt::Plot) = nothing
|
||||
@@ -77,9 +74,9 @@ end
|
||||
text_size(lab::AbstractString, sz::Number, rot::Number = 0) = text_size(length(lab), sz, rot)
|
||||
|
||||
# account for the size/length/rotation of tick labels
|
||||
function tick_padding(axis::Axis)
|
||||
ticks = get_ticks(axis)
|
||||
if ticks == nothing
|
||||
function tick_padding(sp::Subplot, axis::Axis)
|
||||
ticks = get_ticks(sp, axis)
|
||||
if ticks === nothing
|
||||
0mm
|
||||
else
|
||||
vals, labs = ticks
|
||||
@@ -108,10 +105,10 @@ end
|
||||
# to fit ticks, tick labels, guides, colorbars, etc.
|
||||
function _update_min_padding!(sp::Subplot)
|
||||
# TODO: something different when `is3d(sp) == true`
|
||||
leftpad = tick_padding(sp[:yaxis]) + sp[:left_margin] + guide_padding(sp[:yaxis])
|
||||
leftpad = tick_padding(sp, sp[:yaxis]) + sp[:left_margin] + guide_padding(sp[:yaxis])
|
||||
toppad = sp[:top_margin] + title_padding(sp)
|
||||
rightpad = sp[:right_margin]
|
||||
bottompad = tick_padding(sp[:xaxis]) + sp[:bottom_margin] + guide_padding(sp[:xaxis])
|
||||
bottompad = tick_padding(sp, sp[:xaxis]) + sp[:bottom_margin] + guide_padding(sp[:xaxis])
|
||||
|
||||
# switch them?
|
||||
if sp[:xaxis][:mirror]
|
||||
@@ -138,33 +135,22 @@ CurrentBackend(sym::Symbol) = CurrentBackend(sym, _backend_instance(sym))
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
function pickDefaultBackend()
|
||||
_fallback_default_backend() = backend(GRBackend())
|
||||
|
||||
function _pick_default_backend()
|
||||
env_default = get(ENV, "PLOTS_DEFAULT_BACKEND", "")
|
||||
if env_default != ""
|
||||
sym = Symbol(lowercase(env_default))
|
||||
if sym in _backends
|
||||
if sym in _initialized_backends
|
||||
return backend(sym)
|
||||
else
|
||||
@warn("You have set `PLOTS_DEFAULT_BACKEND=$env_default` but `$(backend_package_name(sym))` is not loaded.")
|
||||
end
|
||||
backend(sym)
|
||||
else
|
||||
@warn("You have set PLOTS_DEFAULT_BACKEND=$env_default but it is not a valid backend package. Choose from:\n\t" *
|
||||
join(sort(_backends), "\n\t"))
|
||||
_fallback_default_backend()
|
||||
end
|
||||
else
|
||||
_fallback_default_backend()
|
||||
end
|
||||
|
||||
# the ordering/inclusion of this package list is my semi-arbitrary guess at
|
||||
# which one someone will want to use if they have the package installed...accounting for
|
||||
# features, speed, and robustness
|
||||
# for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR")
|
||||
# if pkgstr in keys(Pkg.installed())
|
||||
# return backend(Symbol(lowercase(pkgstr)))
|
||||
# end
|
||||
# end
|
||||
|
||||
# the default if nothing else is installed
|
||||
backend(:gr)
|
||||
end
|
||||
|
||||
|
||||
@@ -174,13 +160,11 @@ end
|
||||
Returns the current plotting package name. Initializes package on first call.
|
||||
"""
|
||||
function backend()
|
||||
if CURRENT_BACKEND.sym == :none
|
||||
_pick_default_backend()
|
||||
end
|
||||
|
||||
global CURRENT_BACKEND
|
||||
if CURRENT_BACKEND.sym == :none
|
||||
pickDefaultBackend()
|
||||
end
|
||||
|
||||
CURRENT_BACKEND.pkg
|
||||
CURRENT_BACKEND.pkg
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -188,20 +172,13 @@ Set the plot backend.
|
||||
"""
|
||||
function backend(pkg::AbstractBackend)
|
||||
sym = backend_name(pkg)
|
||||
if sym in _initialized_backends
|
||||
CURRENT_BACKEND.sym = backend_name(pkg)
|
||||
CURRENT_BACKEND.pkg = pkg
|
||||
else
|
||||
# try
|
||||
_initialize_backend(pkg)
|
||||
push!(_initialized_backends, sym)
|
||||
CURRENT_BACKEND.sym = backend_name(pkg)
|
||||
CURRENT_BACKEND.pkg = pkg
|
||||
# catch
|
||||
# add_backend(sym)
|
||||
# end
|
||||
if !(sym in _initialized_backends)
|
||||
_initialize_backend(pkg)
|
||||
push!(_initialized_backends, sym)
|
||||
end
|
||||
backend()
|
||||
CURRENT_BACKEND.sym = sym
|
||||
CURRENT_BACKEND.pkg = pkg
|
||||
pkg
|
||||
end
|
||||
|
||||
function backend(sym::Symbol)
|
||||
@@ -209,8 +186,8 @@ function backend(sym::Symbol)
|
||||
backend(_backend_instance(sym))
|
||||
else
|
||||
@warn("`:$sym` is not a supported backend.")
|
||||
backend()
|
||||
end
|
||||
backend()
|
||||
end
|
||||
|
||||
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize]
|
||||
@@ -251,7 +228,7 @@ const _base_supported_args = [
|
||||
:subplot_index,
|
||||
:discrete_values,
|
||||
:projection,
|
||||
|
||||
:show_empty_bins
|
||||
]
|
||||
|
||||
function merge_with_base_supported(v::AVec)
|
||||
@@ -274,6 +251,7 @@ end
|
||||
@init_backend PlotlyJS
|
||||
@init_backend GR
|
||||
@init_backend PGFPlots
|
||||
@init_backend PGFPlotsX
|
||||
@init_backend InspectDR
|
||||
@init_backend HDF5
|
||||
|
||||
@@ -316,13 +294,7 @@ function _initialize_backend(pkg::AbstractBackend)
|
||||
end
|
||||
end
|
||||
|
||||
function add_backend_string(pkg::AbstractBackend)
|
||||
sym = backend_package_name(pkg)
|
||||
"""
|
||||
using Pkg
|
||||
Pkg.add("$sym")
|
||||
"""
|
||||
end
|
||||
_initialize_backend(pkg::GRBackend) = nothing
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# gr
|
||||
@@ -352,7 +324,7 @@ const _gr_attr = merge_with_base_supported([
|
||||
:guidefontfamily, :guidefontsize, :guidefonthalign, :guidefontvalign,
|
||||
:guidefontrotation, :guidefontcolor,
|
||||
:grid, :gridalpha, :gridstyle, :gridlinewidth,
|
||||
:legend, :legendtitle, :colorbar, :colorbar_title,
|
||||
:legend, :legendtitle, :colorbar, :colorbar_title, :colorbar_entry,
|
||||
:fill_z, :line_z, :marker_z, :levels,
|
||||
:ribbon, :quiver,
|
||||
:orientation,
|
||||
@@ -371,7 +343,7 @@ const _gr_attr = merge_with_base_supported([
|
||||
const _gr_seriestype = [
|
||||
:path, :scatter, :straightline,
|
||||
:heatmap, :pie, :image,
|
||||
:contour, :path3d, :scatter3d, :surface, :wireframe,
|
||||
:contour, :path3d, :scatter3d, :surface, :wireframe, :volume,
|
||||
:shape
|
||||
]
|
||||
const _gr_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||
@@ -379,16 +351,19 @@ const _gr_marker = _allMarkers
|
||||
const _gr_scale = [:identity, :log10]
|
||||
is_marker_supported(::GRBackend, shape::Shape) = true
|
||||
|
||||
function add_backend_string(::GRBackend)
|
||||
"""
|
||||
Pkg.add("GR")
|
||||
Pkg.build("GR")
|
||||
"""
|
||||
end
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# plotly
|
||||
|
||||
function _initialize_backend(pkg::PlotlyBackend)
|
||||
try
|
||||
@eval Main begin
|
||||
import ORCA
|
||||
end
|
||||
catch
|
||||
@info "For saving to png with the Plotly backend ORCA has to be installed."
|
||||
end
|
||||
end
|
||||
|
||||
const _plotly_attr = merge_with_base_supported([
|
||||
:annotations,
|
||||
:background_color_legend, :background_color_inside, :background_color_outside,
|
||||
@@ -413,7 +388,7 @@ const _plotly_attr = merge_with_base_supported([
|
||||
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
||||
:tickfont, :guidefont, :legendfont,
|
||||
:grid, :gridalpha, :gridlinewidth,
|
||||
:legend, :colorbar, :colorbar_title,
|
||||
:legend, :colorbar, :colorbar_title, :colorbar_entry,
|
||||
:marker_z, :fill_z, :line_z, :levels,
|
||||
:ribbon, :quiver,
|
||||
:orientation,
|
||||
@@ -444,17 +419,11 @@ const _plotly_marker = [
|
||||
]
|
||||
const _plotly_scale = [:identity, :log10]
|
||||
|
||||
defaultOutputFormat(plt::Plot{Plots.PlotlyBackend}) = "html"
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# pgfplots
|
||||
|
||||
function add_backend_string(::PGFPlotsBackend)
|
||||
"""
|
||||
using Pkg
|
||||
Pkg.add("PGFPlots")
|
||||
Pkg.build("PGFPlots")
|
||||
"""
|
||||
end
|
||||
|
||||
const _pgfplots_attr = merge_with_base_supported([
|
||||
:annotations,
|
||||
:background_color_legend,
|
||||
@@ -492,29 +461,19 @@ const _pgfplots_attr = merge_with_base_supported([
|
||||
])
|
||||
const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape, :straightline,]
|
||||
const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||
const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon, :hline] #vcat(_allMarkers, Shape)
|
||||
const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon, :hline, :vline] #vcat(_allMarkers, Shape)
|
||||
const _pgfplots_scale = [:identity, :ln, :log2, :log10]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# plotlyjs
|
||||
|
||||
function _initialize_backend(pkg::PlotlyJSBackend)
|
||||
sym = backend_package_name(pkg)
|
||||
@eval Main begin
|
||||
import PlotlyJS, ORCA
|
||||
export PlotlyJS
|
||||
end
|
||||
end
|
||||
|
||||
function add_backend_string(::PlotlyJSBackend)
|
||||
"""
|
||||
using Pkg
|
||||
Pkg.add(["PlotlyJS", "Blink", "ORCA"])
|
||||
import Blink
|
||||
Blink.AtomShell.install()
|
||||
"""
|
||||
end
|
||||
|
||||
const _plotlyjs_attr = _plotly_attr
|
||||
const _plotlyjs_seriestype = _plotly_seriestype
|
||||
const _plotlyjs_style = _plotly_style
|
||||
@@ -535,16 +494,6 @@ function _initialize_backend(::PyPlotBackend)
|
||||
end
|
||||
end
|
||||
|
||||
function add_backend_string(::PyPlotBackend)
|
||||
"""
|
||||
using Pkg
|
||||
withenv("PYTHON" => "") do
|
||||
Pkg.add("PyPlot")
|
||||
Pkg.build("PyPlot")
|
||||
end
|
||||
"""
|
||||
end
|
||||
|
||||
const _pyplot_attr = merge_with_base_supported([
|
||||
:annotations,
|
||||
:background_color_legend, :background_color_inside, :background_color_outside,
|
||||
@@ -564,7 +513,7 @@ const _pyplot_attr = merge_with_base_supported([
|
||||
:tickfontfamily, :tickfontsize, :tickfontcolor,
|
||||
:guidefontfamily, :guidefontsize, :guidefontcolor,
|
||||
:grid, :gridalpha, :gridstyle, :gridlinewidth,
|
||||
:legend, :legendtitle, :colorbar,
|
||||
:legend, :legendtitle, :colorbar, :colorbar_title, :colorbar_entry,
|
||||
:marker_z, :line_z, :fill_z,
|
||||
:levels,
|
||||
:ribbon, :quiver, :arrow,
|
||||
@@ -577,7 +526,6 @@ const _pyplot_attr = merge_with_base_supported([
|
||||
:clims,
|
||||
:inset_subplots,
|
||||
:dpi,
|
||||
:colorbar_title,
|
||||
:stride,
|
||||
:framestyle,
|
||||
:tick_direction,
|
||||
@@ -598,14 +546,6 @@ const _pyplot_scale = [:identity, :ln, :log2, :log10]
|
||||
# ------------------------------------------------------------------------------
|
||||
# unicodeplots
|
||||
|
||||
function add_backend_string(::UnicodePlotsBackend)
|
||||
"""
|
||||
using Pkg
|
||||
Pkg.add("UnicodePlots")
|
||||
Pkg.build("UnicodePlots")
|
||||
"""
|
||||
end
|
||||
|
||||
const _unicodeplots_attr = merge_with_base_supported([
|
||||
:label,
|
||||
:legend,
|
||||
@@ -728,3 +668,57 @@ const _inspectdr_marker = Symbol[
|
||||
]
|
||||
|
||||
const _inspectdr_scale = [:identity, :ln, :log2, :log10]
|
||||
# ------------------------------------------------------------------------------
|
||||
# pgfplotsx
|
||||
|
||||
const _pgfplotsx_attr = merge_with_base_supported([
|
||||
:annotations,
|
||||
:background_color_legend, :background_color_inside, :background_color_outside,
|
||||
:foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
|
||||
:foreground_color_text, :foreground_color_border,
|
||||
:label,
|
||||
:seriescolor, :seriesalpha,
|
||||
:linecolor, :linestyle, :linewidth, :linealpha,
|
||||
:markershape, :markercolor, :markersize, :markeralpha,
|
||||
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
|
||||
:fillrange, :fillcolor, :fillalpha,
|
||||
:bins,
|
||||
:layout,
|
||||
:title, :window_title,
|
||||
:guide, :lims, :ticks, :scale, :flip,
|
||||
:match_dimensions,
|
||||
:titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign,
|
||||
:titlefontrotation, :titlefontcolor,
|
||||
:legendfontfamily, :legendfontsize, :legendfonthalign, :legendfontvalign,
|
||||
:legendfontrotation, :legendfontcolor,
|
||||
:tickfontfamily, :tickfontsize, :tickfonthalign, :tickfontvalign,
|
||||
:tickfontrotation, :tickfontcolor,
|
||||
:guidefontfamily, :guidefontsize, :guidefonthalign, :guidefontvalign,
|
||||
:guidefontrotation, :guidefontcolor,
|
||||
:grid, :gridalpha, :gridstyle, :gridlinewidth,
|
||||
:legend, :legendtitle, :colorbar, :colorbar_title, :colorbar_entry,
|
||||
:fill_z, :line_z, :marker_z, :levels,
|
||||
:ribbon, :quiver,
|
||||
:orientation,
|
||||
:overwrite_figure,
|
||||
:polar,
|
||||
:aspect_ratio,
|
||||
:normalize, :weights,
|
||||
:inset_subplots,
|
||||
:bar_width,
|
||||
:arrow,
|
||||
:framestyle,
|
||||
:tick_direction,
|
||||
:camera,
|
||||
:contour_labels,
|
||||
])
|
||||
const _pgfplotsx_seriestype =
|
||||
[:path, :scatter, :straightline,
|
||||
:path3d, :scatter3d, :surface, :wireframe,
|
||||
:heatmap, :contour, :contour3d,
|
||||
:shape,
|
||||
:steppre, :stepmid, :steppost, :ysticks, :xsticks]
|
||||
const _pgfplotsx_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||
const _pgfplotsx_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :ltriangle, :rtriangle, :cross, :xcross, :star5, :pentagon, :hline, :vline, Shape]
|
||||
const _pgfplotsx_scale = [:identity, :ln, :log2, :log10]
|
||||
is_marker_supported(::PGFPlotsXBackend, shape::Shape) = true
|
||||
|
||||
+893
-303
File diff suppressed because it is too large
Load Diff
@@ -121,9 +121,9 @@ function _create_backend_figure(plt::Plot{InspectDRBackend})
|
||||
gplot = _inspectdr_getgui(plt.o)
|
||||
|
||||
#:overwrite_figure: want to reuse current figure
|
||||
if plt[:overwrite_figure] && mplot != nothing
|
||||
if plt[:overwrite_figure] && mplot !== nothing
|
||||
mplot.subplots = [] #Reset
|
||||
if gplot != nothing #Ensure still references current plot
|
||||
if gplot !== nothing #Ensure still references current plot
|
||||
gplot.src = mplot
|
||||
end
|
||||
else #want new one:
|
||||
@@ -294,8 +294,8 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
||||
|
||||
plot.xscale = _inspectdr_getscale(xaxis[:scale], false)
|
||||
strip.yscale = _inspectdr_getscale(yaxis[:scale], true)
|
||||
xmin, xmax = axis_limits(xaxis)
|
||||
ymin, ymax = axis_limits(yaxis)
|
||||
xmin, xmax = axis_limits(sp, :x)
|
||||
ymin, ymax = axis_limits(sp, :y)
|
||||
if ispolar(sp)
|
||||
#Plots.jl appears to give (xmin,xmax) ≜ (Θmin,Θmax) & (ymin,ymax) ≜ (rmin,rmax)
|
||||
rmax = NaNMath.max(abs(ymin), abs(ymax))
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
function plotlybase_syncplot(plt::Plot)
|
||||
plt.o = ORCA.PlotlyBase.Plot()
|
||||
traces = ORCA.PlotlyBase.GenericTrace[]
|
||||
for series_dict in plotly_series(plt)
|
||||
plotly_type = pop!(series_dict, :type)
|
||||
push!(traces, ORCA.PlotlyBase.GenericTrace(plotly_type; series_dict...))
|
||||
end
|
||||
ORCA.PlotlyBase.addtraces!(plt.o, traces...)
|
||||
layout = plotly_layout(plt)
|
||||
w, h = plt[:size]
|
||||
ORCA.PlotlyBase.relayout!(plt.o, layout, width = w, height = h)
|
||||
return plt.o
|
||||
end
|
||||
|
||||
const _orca_mimeformats = Dict(
|
||||
"application/pdf" => "pdf",
|
||||
"image/png" => "png",
|
||||
"image/svg+xml" => "svg",
|
||||
"image/eps" => "eps",
|
||||
)
|
||||
|
||||
for (mime, fmt) in _orca_mimeformats
|
||||
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyBackend}) = ORCA.PlotlyBase.savefig(io, plotlybase_syncplot(plt), format = $fmt)
|
||||
end
|
||||
+45
-28
@@ -26,7 +26,8 @@ const _pgfplots_markers = KW(
|
||||
:star6 => "asterisk",
|
||||
:diamond => "diamond*",
|
||||
:pentagon => "pentagon*",
|
||||
:hline => "-"
|
||||
:hline => "-",
|
||||
:vline => "|"
|
||||
)
|
||||
|
||||
const _pgfplots_legend_pos = KW(
|
||||
@@ -95,7 +96,7 @@ pgf_thickness_scaling(series) = pgf_thickness_scaling(series[:subplot])
|
||||
function pgf_fillstyle(plotattributes, i = 1)
|
||||
cstr,a = pgf_color(get_fillcolor(plotattributes, i))
|
||||
fa = get_fillalpha(plotattributes, i)
|
||||
if fa != nothing
|
||||
if fa !== nothing
|
||||
a = fa
|
||||
end
|
||||
"fill = $cstr, fill opacity=$a"
|
||||
@@ -127,16 +128,18 @@ function pgf_marker(plotattributes, i = 1)
|
||||
shape = _cycle(plotattributes[:markershape], i)
|
||||
cstr, a = pgf_color(plot_color(get_markercolor(plotattributes, i), get_markeralpha(plotattributes, i)))
|
||||
cstr_stroke, a_stroke = pgf_color(plot_color(get_markerstrokecolor(plotattributes, i), get_markerstrokealpha(plotattributes, i)))
|
||||
"""
|
||||
mark = $(get(_pgfplots_markers, shape, "*")),
|
||||
mark size = $(pgf_thickness_scaling(plotattributes) * 0.5 * _cycle(plotattributes[:markersize], i)),
|
||||
mark options = {
|
||||
color = $cstr_stroke, draw opacity = $a_stroke,
|
||||
fill = $cstr, fill opacity = $a,
|
||||
line width = $(pgf_thickness_scaling(plotattributes) * _cycle(plotattributes[:markerstrokewidth], i)),
|
||||
rotate = $(shape == :dtriangle ? 180 : 0),
|
||||
$(get(_pgfplots_linestyles, _cycle(plotattributes[:markerstrokestyle], i), "solid"))
|
||||
}"""
|
||||
return string(
|
||||
"mark = $(get(_pgfplots_markers, shape, "*")),\n",
|
||||
"mark size = $(pgf_thickness_scaling(plotattributes) * 0.5 * _cycle(plotattributes[:markersize], i)),\n",
|
||||
plotattributes[:seriestype] == :scatter ? "only marks,\n" : "",
|
||||
"mark options = {
|
||||
color = $cstr_stroke, draw opacity = $a_stroke,
|
||||
fill = $cstr, fill opacity = $a,
|
||||
line width = $(pgf_thickness_scaling(plotattributes) * _cycle(plotattributes[:markerstrokewidth], i)),
|
||||
rotate = $(shape == :dtriangle ? 180 : 0),
|
||||
$(get(_pgfplots_linestyles, _cycle(plotattributes[:markerstrokestyle], i), "solid"))
|
||||
}"
|
||||
)
|
||||
end
|
||||
|
||||
function pgf_add_annotation!(o, x, y, val, thickness_scaling = 1)
|
||||
@@ -170,18 +173,18 @@ function pgf_series(sp::Subplot, series::Series)
|
||||
elseif st == :shape
|
||||
shape_data(series)
|
||||
elseif ispolar(sp)
|
||||
theta, r = filter_radial_data(plotattributes[:x], plotattributes[:y], axis_limits(sp[:yaxis]))
|
||||
theta, r = plotattributes[:x], plotattributes[:y]
|
||||
rad2deg.(theta), r
|
||||
else
|
||||
plotattributes[:x], plotattributes[:y]
|
||||
end
|
||||
|
||||
# PGFPlots can't handle non-Vector?
|
||||
args = map(a -> if typeof(a) <: AbstractVector && typeof(a) != Vector
|
||||
collect(a)
|
||||
else
|
||||
a
|
||||
end, args)
|
||||
# args = map(a -> if typeof(a) <: AbstractVector && typeof(a) != Vector
|
||||
# collect(a)
|
||||
# else
|
||||
# a
|
||||
# end, args)
|
||||
|
||||
if st in (:contour, :histogram2d)
|
||||
style = []
|
||||
@@ -215,12 +218,12 @@ function pgf_series(sp::Subplot, series::Series)
|
||||
|
||||
# add to legend?
|
||||
if i == 1 && sp[:legend] != :none && should_add_to_legend(series)
|
||||
if plotattributes[:fillrange] != nothing
|
||||
if plotattributes[:fillrange] !== nothing
|
||||
push!(style, "forget plot")
|
||||
push!(series_collection, pgf_fill_legend_hack(plotattributes, args))
|
||||
else
|
||||
kw[:legendentry] = plotattributes[:label]
|
||||
if st == :shape # || plotattributes[:fillrange] != nothing
|
||||
if st == :shape # || plotattributes[:fillrange] !== nothing
|
||||
push!(style, "area legend")
|
||||
end
|
||||
end
|
||||
@@ -237,7 +240,7 @@ function pgf_series(sp::Subplot, series::Series)
|
||||
kw[:style] = join(style, ',')
|
||||
|
||||
# add fillrange
|
||||
if series[:fillrange] != nothing && st != :shape
|
||||
if series[:fillrange] !== nothing && st != :shape
|
||||
push!(series_collection, pgf_fillrange_series(series, i, _cycle(series[:fillrange], rng), seg_args...))
|
||||
end
|
||||
|
||||
@@ -360,13 +363,13 @@ function pgf_axis(sp::Subplot, letter)
|
||||
# limits
|
||||
# TODO: support zlims
|
||||
if letter != :z
|
||||
lims = ispolar(sp) && letter == :x ? rad2deg.(axis_limits(axis)) : axis_limits(axis)
|
||||
lims = ispolar(sp) && letter == :x ? rad2deg.(axis_limits(sp, :x)) : axis_limits(sp, letter)
|
||||
kw[Symbol(letter,:min)] = lims[1]
|
||||
kw[Symbol(letter,:max)] = lims[2]
|
||||
end
|
||||
|
||||
if !(axis[:ticks] in (nothing, false, :none, :native)) && framestyle != :none
|
||||
ticks = get_ticks(axis)
|
||||
ticks = get_ticks(sp, axis)
|
||||
#pgf plot ignores ticks with angle below 90 when xmin = 90 so shift values
|
||||
tick_values = ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] : ticks[1]
|
||||
push!(style, string(letter, "tick = {", join(tick_values,","), "}"))
|
||||
@@ -398,8 +401,12 @@ function pgf_axis(sp::Subplot, letter)
|
||||
# framestyle
|
||||
if framestyle in (:axes, :origin)
|
||||
axispos = framestyle == :axes ? "left" : "middle"
|
||||
# the * after lines disables the arrows at the axes
|
||||
push!(style, string("axis lines* = ", axispos))
|
||||
if axis[:draw_arrow]
|
||||
push!(style, string("axis ", letter, " line = ", axispos))
|
||||
else
|
||||
# the * after line disables the arrow at the axis
|
||||
push!(style, string("axis ", letter, " line* = ", axispos))
|
||||
end
|
||||
end
|
||||
|
||||
if framestyle == :zerolines
|
||||
@@ -471,8 +478,18 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
||||
if haskey(_pgfplots_legend_pos, legpos)
|
||||
kw[:legendPos] = _pgfplots_legend_pos[legpos]
|
||||
end
|
||||
cstr, a = pgf_color(plot_color(sp[:background_color_legend]))
|
||||
push!(style, string("legend style = {", pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], 1.0, "solid"), ",", "fill = $cstr,", "font = ", pgf_font(sp[:legendfontsize], pgf_thickness_scaling(sp)), "}"))
|
||||
cstr, bg_alpha = pgf_color(plot_color(sp[:background_color_legend]))
|
||||
fg_alpha = alpha(plot_color(sp[:foreground_color_legend]))
|
||||
|
||||
push!(style, string(
|
||||
"legend style = {",
|
||||
pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], fg_alpha, "solid", ), ",",
|
||||
"fill = $cstr,",
|
||||
"fill opacity = $bg_alpha,",
|
||||
"text opacity = $(alpha(plot_color(sp[:legendfontcolor]))),",
|
||||
"font = ", pgf_font(sp[:legendfontsize], pgf_thickness_scaling(sp)),
|
||||
"}",
|
||||
))
|
||||
|
||||
if any(s[:seriestype] == :contour for s in series_list(sp))
|
||||
kw[:view] = "{0}{90}"
|
||||
@@ -563,7 +580,7 @@ end
|
||||
|
||||
function _show(io::IO, mime::MIME"application/x-tex", plt::Plot{PGFPlotsBackend})
|
||||
fn = tempname()*".tex"
|
||||
PGFPlots.save(fn, backend_object(plt), include_preamble=false)
|
||||
PGFPlots.save(fn, backend_object(plt), include_preamble=plt.attr[:tex_output_standalone])
|
||||
write(io, read(open(fn), String))
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,862 @@
|
||||
using Contour: Contour
|
||||
using UUIDs
|
||||
Base.@kwdef mutable struct PGFPlotsXPlot
|
||||
is_created::Bool = false
|
||||
was_shown::Bool = false
|
||||
the_plot::PGFPlotsX.TikzDocument = PGFPlotsX.TikzDocument()
|
||||
function PGFPlotsXPlot(is_created, was_shown, the_plot)
|
||||
pgfx_plot = new(is_created, was_shown, the_plot)
|
||||
# tikz libraries
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, "\\usetikzlibrary{arrows.meta}")
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, "\\usetikzlibrary{backgrounds}")
|
||||
# pgfplots libraries
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, "\\usepgfplotslibrary{patchplots}")
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, "\\usepgfplotslibrary{fillbetween}")
|
||||
# compatibility fixes
|
||||
# add background layer to standard layers
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot,
|
||||
raw"""
|
||||
\pgfplotsset{
|
||||
/pgfplots/layers/axis on top/.define layer set={
|
||||
background, axis background,pre main,main,axis grid,axis ticks,axis lines,axis tick labels,
|
||||
axis descriptions,axis foreground
|
||||
}{/pgfplots/layers/standard},
|
||||
}
|
||||
"""
|
||||
)
|
||||
pgfx_plot
|
||||
end
|
||||
end
|
||||
|
||||
## end user utility functions
|
||||
function pgfx_axes(pgfx_plot::PGFPlotsXPlot)
|
||||
gp = pgfx_plot.the_plot.elements[1].elements[1]
|
||||
return gp isa PGFPlotsX.GroupPlot ? gp.contents : gp
|
||||
end
|
||||
|
||||
function pgfx_preamble(pgfx_plot::Plot{PGFPlotsXBackend})
|
||||
old_flag = pgfx_plot.attr[:tex_output_standalone]
|
||||
pgfx_plot.attr[:tex_output_standalone] = true
|
||||
fulltext = String(repr("application/x-tex", pgfx_plot))
|
||||
preamble = fulltext[1:first(findfirst("\\begin{document}", fulltext)) - 1]
|
||||
pgfx_plot.attr[:tex_output_standalone] = old_flag
|
||||
preamble
|
||||
end
|
||||
##
|
||||
|
||||
function surface_to_vecs(x::AVec, y::AVec, s::Union{AMat, Surface})
|
||||
a = Array(s)
|
||||
xn = Vector{eltype(x)}(undef, length(a))
|
||||
yn = Vector{eltype(y)}(undef, length(a))
|
||||
zn = Vector{eltype(s)}(undef, length(a))
|
||||
for (n, (i, j)) in enumerate(Tuple.(CartesianIndices(a)))
|
||||
xn[n] = x[j]
|
||||
yn[n] = y[i]
|
||||
zn[n] = a[i,j]
|
||||
end
|
||||
return xn, yn, zn
|
||||
end
|
||||
|
||||
function Base.push!(pgfx_plot::PGFPlotsXPlot, item)
|
||||
push!(pgfx_plot.the_plot, item)
|
||||
end
|
||||
|
||||
function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
if !pgfx_plot.is_created
|
||||
the_plot = PGFPlotsX.TikzPicture(PGFPlotsX.Options())
|
||||
rows, cols = size(plt.layout.grid)
|
||||
bgc = plt.attr[:background_color_outside] == :match ? plt.attr[:background_color] : plt.attr[:background_color_outside]
|
||||
if bgc isa Colors.Colorant
|
||||
cstr = plot_color(bgc)
|
||||
a = alpha(cstr)
|
||||
push!(the_plot.options,
|
||||
"/tikz/background rectangle/.style" => PGFPlotsX.Options(
|
||||
"fill" => cstr,
|
||||
"draw opacity" => a,
|
||||
),
|
||||
"show background rectangle" => nothing,
|
||||
)
|
||||
end
|
||||
|
||||
# the combination of groupplot and polaraxis is broken in pgfplots
|
||||
if !any( sp -> ispolar(sp), plt.subplots )
|
||||
pl_height, pl_width = plt.attr[:size]
|
||||
push!( the_plot, PGFPlotsX.GroupPlot(
|
||||
PGFPlotsX.Options(
|
||||
"group style" => PGFPlotsX.Options(
|
||||
"group size" => string(cols)*" by "*string(rows),
|
||||
"horizontal sep" => string(maximum(sp -> sp.minpad[1], plt.subplots)),
|
||||
"vertical sep" => string(maximum(sp -> sp.minpad[2], plt.subplots)),
|
||||
),
|
||||
"height" => pl_height > 0 ? string(pl_height * px) : "{}",
|
||||
"width" => pl_width > 0 ? string(pl_width * px) : "{}",
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
for sp in plt.subplots
|
||||
bb = bbox(sp)
|
||||
sp_width = width(bb)
|
||||
sp_height = height(bb)
|
||||
cstr = plot_color(sp[:background_color_legend])
|
||||
a = alpha(cstr)
|
||||
fg_alpha = alpha(plot_color(sp[:foreground_color_legend]))
|
||||
title_cstr = plot_color(sp[:titlefontcolor])
|
||||
title_a = alpha(title_cstr)
|
||||
axis_opt = PGFPlotsX.Options(
|
||||
"title" => sp[:title],
|
||||
"title style" => PGFPlotsX.Options(
|
||||
"font" => pgfx_font(sp[:titlefontsize], pgfx_thickness_scaling(sp)),
|
||||
"color" => title_cstr,
|
||||
"draw opacity" => title_a,
|
||||
"rotate" => sp[:titlefontrotation]
|
||||
),
|
||||
"legend style" => PGFPlotsX.Options(
|
||||
pgfx_linestyle(pgfx_thickness_scaling(sp), sp[:foreground_color_legend], fg_alpha, "solid") => nothing,
|
||||
"fill" => cstr,
|
||||
"fill opacity" => a,
|
||||
"text opacity" => alpha(plot_color(sp[:legendfontcolor])),
|
||||
"font" => pgfx_font(sp[:legendfontsize], pgfx_thickness_scaling(sp))
|
||||
),
|
||||
"axis background/.style" => PGFPlotsX.Options(
|
||||
"fill" => sp[:background_color_inside]
|
||||
),
|
||||
"axis on top" => nothing,
|
||||
)
|
||||
sp_width > 0*mm ? push!(axis_opt, "width" => string(sp_width)) : nothing
|
||||
sp_height > 0*mm ? push!(axis_opt, "height" => string(sp_height)) : nothing
|
||||
# legend position
|
||||
if sp[:legend] isa Tuple
|
||||
x, y = sp[:legend]
|
||||
push!(axis_opt["legend style"], "at={($x, $y)}" )
|
||||
else
|
||||
push!(axis_opt, "legend pos" => get(_pgfplotsx_legend_pos, sp[:legend], "outer north east"),
|
||||
)
|
||||
end
|
||||
for letter in (:x, :y, :z)
|
||||
if letter != :z || is3d(sp)
|
||||
pgfx_axis!(axis_opt, sp, letter)
|
||||
end
|
||||
end
|
||||
# Search series for any gradient. In case one series uses a gradient set
|
||||
# the colorbar and colomap.
|
||||
# The reasoning behind doing this on the axis level is that pgfplots
|
||||
# colorbar seems to only works on axis level and needs the proper colormap for
|
||||
# correctly displaying it.
|
||||
# It's also possible to assign the colormap to the series itself but
|
||||
# then the colormap needs to be added twice, once for the axis and once for the
|
||||
# series.
|
||||
# As it is likely that all series within the same axis use the same
|
||||
# colormap this should not cause any problem.
|
||||
for series in series_list(sp)
|
||||
for col in (:markercolor, :fillcolor, :linecolor)
|
||||
if typeof(series.plotattributes[col]) == ColorGradient
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, """\\pgfplotsset{
|
||||
colormap={plots$(sp.attr[:subplot_index])}{$(pgfx_colormap(series.plotattributes[col]))},
|
||||
}""")
|
||||
push!(axis_opt,
|
||||
"colorbar" => nothing,
|
||||
"colormap name" => "plots$(sp.attr[:subplot_index])",
|
||||
)
|
||||
# goto is needed to break out of col and series for
|
||||
@goto colorbar_end
|
||||
end
|
||||
end
|
||||
end
|
||||
@label colorbar_end
|
||||
|
||||
push!(axis_opt, "colorbar style" => PGFPlotsX.Options(
|
||||
"title" => sp[:colorbar_title],
|
||||
"point meta max" => get_clims(sp)[2],
|
||||
"point meta min" => get_clims(sp)[1]
|
||||
)
|
||||
)
|
||||
if is3d(sp)
|
||||
azim, elev = sp[:camera]
|
||||
push!( axis_opt, "view" => (azim, elev) )
|
||||
end
|
||||
axisf = if sp[:projection] == :polar
|
||||
# push!(axis_opt, "xmin" => 90)
|
||||
# push!(axis_opt, "xmax" => 450)
|
||||
PGFPlotsX.PolarAxis
|
||||
else
|
||||
PGFPlotsX.Axis
|
||||
end
|
||||
axis = axisf(
|
||||
axis_opt
|
||||
)
|
||||
for (series_index, series) in enumerate(series_list(sp))
|
||||
opt = series.plotattributes
|
||||
st = series[:seriestype]
|
||||
series_opt = PGFPlotsX.Options(
|
||||
"color" => single_color(opt[:linecolor]),
|
||||
)
|
||||
if is3d(series) || st == :heatmap
|
||||
series_func = PGFPlotsX.Plot3
|
||||
else
|
||||
series_func = PGFPlotsX.Plot
|
||||
end
|
||||
if series[:fillrange] !== nothing && !isfilledcontour(series) && series[:ribbon] === nothing
|
||||
push!(series_opt, "area legend" => nothing)
|
||||
end
|
||||
if st == :heatmap
|
||||
push!(axis.options,
|
||||
"view" => "{0}{90}",
|
||||
)
|
||||
end
|
||||
# treat segments
|
||||
segments = if st in (:wireframe, :heatmap, :contour, :surface, :contour3d)
|
||||
iter_segments(surface_to_vecs(series[:x], series[:y], series[:z])...)
|
||||
else
|
||||
iter_segments(series)
|
||||
end
|
||||
for (i, rng) in enumerate(segments)
|
||||
segment_opt = PGFPlotsX.Options()
|
||||
segment_opt = merge( segment_opt, pgfx_linestyle(opt, i) )
|
||||
if opt[:markershape] != :none
|
||||
marker = opt[:markershape]
|
||||
if marker isa Shape
|
||||
x = marker.x
|
||||
y = marker.y
|
||||
scale_factor = 0.025
|
||||
mark_size = opt[:markersize] * scale_factor
|
||||
path = join(["($(x[i] * mark_size), $(y[i] * mark_size))" for i in eachindex(x)], " -- ")
|
||||
c = get_markercolor(series, i)
|
||||
a = get_markeralpha(series, i)
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot,
|
||||
"""
|
||||
\\pgfdeclareplotmark{PlotsShape$(series_index)}{
|
||||
\\filldraw
|
||||
$path;
|
||||
}
|
||||
"""
|
||||
)
|
||||
end
|
||||
segment_opt = merge( segment_opt, pgfx_marker(opt, i) )
|
||||
end
|
||||
if st == :shape ||
|
||||
isfilledcontour(series)
|
||||
segment_opt = merge( segment_opt, pgfx_fillstyle(opt, i) )
|
||||
end
|
||||
# add fillrange
|
||||
if series[:fillrange] !== nothing && !isfilledcontour(series) && series[:ribbon] === nothing
|
||||
pgfx_fillrange_series!( axis, series, series_func, i, _cycle(series[:fillrange], rng), rng)
|
||||
if i == 1 && opt[:label] != "" && sp[:legend] != :none && should_add_to_legend(series)
|
||||
pgfx_filllegend!(series_opt, opt)
|
||||
end
|
||||
end
|
||||
# series
|
||||
#
|
||||
coordinates = pgfx_series_coordinates!( sp, series, segment_opt, opt, rng )
|
||||
segment_plot = series_func(
|
||||
merge(series_opt, segment_opt),
|
||||
coordinates,
|
||||
)
|
||||
push!(axis, segment_plot)
|
||||
# add ribbons?
|
||||
ribbon = series[:ribbon]
|
||||
if ribbon !== nothing
|
||||
pgfx_add_ribbons!( axis, series, segment_plot, series_func, series_index )
|
||||
end
|
||||
# add to legend?
|
||||
if i == 1 && opt[:label] != "" && sp[:legend] != :none && should_add_to_legend(series)
|
||||
leg_opt = PGFPlotsX.Options()
|
||||
if ribbon !== nothing
|
||||
pgfx_filllegend!(axis.contents[end-3].options, opt)
|
||||
end
|
||||
legend = PGFPlotsX.LegendEntry(leg_opt, opt[:label], false)
|
||||
push!( axis, legend )
|
||||
end
|
||||
# add series annotations
|
||||
anns = series[:series_annotations]
|
||||
for (xi,yi,str,fnt) in EachAnn(anns, series[:x], series[:y])
|
||||
pgfx_add_annotation!(axis, xi, yi, PlotText(str, fnt), pgfx_thickness_scaling(series))
|
||||
end
|
||||
end
|
||||
# add subplot annotations
|
||||
anns = sp.attr[:annotations]
|
||||
for (xi,yi,txt) in anns
|
||||
pgfx_add_annotation!(axis, xi, yi, txt, pgfx_thickness_scaling(sp))
|
||||
end
|
||||
end
|
||||
if ispolar(sp)
|
||||
axes = the_plot
|
||||
else
|
||||
axes = the_plot.elements[1]
|
||||
end
|
||||
push!( axes, axis )
|
||||
if length(plt.o.the_plot.elements) > 0
|
||||
plt.o.the_plot.elements[1] = the_plot
|
||||
else
|
||||
push!(plt.o, the_plot)
|
||||
end
|
||||
end
|
||||
pgfx_plot.is_created = true
|
||||
end
|
||||
return pgfx_plot
|
||||
end
|
||||
## seriestype specifics
|
||||
@inline function pgfx_series_coordinates!(sp, series, segment_opt, opt, rng)
|
||||
st = series[:seriestype]
|
||||
# function args
|
||||
args = if st in (:contour, :contour3d)
|
||||
opt[:x], opt[:y], Array(opt[:z])'
|
||||
elseif st in (:heatmap, :surface, :wireframe)
|
||||
surface_to_vecs(opt[:x], opt[:y], opt[:z])
|
||||
elseif is3d(st)
|
||||
opt[:x], opt[:y], opt[:z]
|
||||
elseif st == :straightline
|
||||
straightline_data(series)
|
||||
elseif st == :shape
|
||||
shape_data(series)
|
||||
elseif ispolar(sp)
|
||||
theta, r = opt[:x], opt[:y]
|
||||
rad2deg.(theta), r
|
||||
else
|
||||
opt[:x], opt[:y]
|
||||
end
|
||||
seg_args = if st in (:contour, :contour3d)
|
||||
args
|
||||
else
|
||||
(arg[rng] for arg in args)
|
||||
end
|
||||
if opt[:quiver] !== nothing
|
||||
push!(segment_opt, "quiver" => PGFPlotsX.Options(
|
||||
"u" => "\\thisrow{u}",
|
||||
"v" => "\\thisrow{v}",
|
||||
pgfx_arrow(opt[:arrow]) => nothing
|
||||
),
|
||||
)
|
||||
x, y = collect(seg_args)
|
||||
return PGFPlotsX.Table([:x => x, :y => y, :u => opt[:quiver][1], :v => opt[:quiver][2]])
|
||||
else
|
||||
if isfilledcontour(series)
|
||||
st = :filledcontour
|
||||
end
|
||||
pgfx_series_coordinates!(Val(st), segment_opt, opt, seg_args)
|
||||
end
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Union{Val{:path}, Val{:path3d}, Val{:straightline}}, segment_opt, opt, args)
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Union{Val{:scatter}, Val{:scatter3d}}, segment_opt, opt, args)
|
||||
push!( segment_opt, "only marks" => nothing )
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:heatmap}, segment_opt, opt, args)
|
||||
push!(segment_opt,
|
||||
"matrix plot*" => nothing,
|
||||
"mesh/rows" => length(opt[:x]),
|
||||
"mesh/cols" => length(opt[:y]),
|
||||
)
|
||||
return PGFPlotsX.Table(args...)
|
||||
end
|
||||
|
||||
function pgfx_series_coordinates!(st_val::Val{:steppre}, segment_opt, opt, args)
|
||||
push!( segment_opt, "const plot mark right" => nothing )
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:stepmid}, segment_opt, opt, args)
|
||||
push!( segment_opt, "const plot mark mid" => nothing )
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:steppost}, segment_opt, opt, args)
|
||||
push!( segment_opt, "const plot" => nothing )
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Union{Val{:ysticks},Val{:sticks}}, segment_opt, opt, args)
|
||||
push!( segment_opt, "ycomb" => nothing )
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:xsticks}, segment_opt, opt, args)
|
||||
push!( segment_opt, "xcomb" => nothing )
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:surface}, segment_opt, opt, args)
|
||||
push!( segment_opt, "surf" => nothing,
|
||||
"mesh/rows" => length(opt[:x]),
|
||||
"mesh/cols" => length(opt[:y]),
|
||||
)
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:volume}, segment_opt, opt, args)
|
||||
push!( segment_opt, "patch" => nothing )
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:wireframe}, segment_opt, opt, args)
|
||||
push!( segment_opt, "mesh" => nothing,
|
||||
"mesh/rows" => length(opt[:x])
|
||||
)
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:shape}, segment_opt, opt, args)
|
||||
push!( segment_opt, "area legend" => nothing )
|
||||
return PGFPlotsX.Coordinates(args...)
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Union{Val{:contour}, Val{:contour3d}}, segment_opt, opt, args)
|
||||
push!(segment_opt,
|
||||
"contour prepared" => PGFPlotsX.Options(
|
||||
"labels" => opt[:contour_labels],
|
||||
),
|
||||
)
|
||||
return PGFPlotsX.Table(Contour.contours(args..., opt[:levels]))
|
||||
end
|
||||
function pgfx_series_coordinates!(st_val::Val{:filledcontour}, segment_opt, opt, args)
|
||||
xs, ys, zs = collect(args)
|
||||
push!(segment_opt,
|
||||
"contour filled" => PGFPlotsX.Options(
|
||||
"labels" => opt[:contour_labels],
|
||||
),
|
||||
"point meta" => "explicit",
|
||||
"shader" => "flat"
|
||||
)
|
||||
if opt[:levels] isa Number
|
||||
push!(segment_opt["contour filled"],
|
||||
"number" => opt[:levels],
|
||||
)
|
||||
elseif opt[:levels] isa AVec
|
||||
push!(segment_opt["contour filled"],
|
||||
"levels" => opt[:levels],
|
||||
)
|
||||
end
|
||||
|
||||
cs = join([
|
||||
join(["($x, $y) [$(zs[j, i])]" for (j, x) in enumerate(xs)], " ") for (i, y) in enumerate(ys)], "\n\n"
|
||||
)
|
||||
"""
|
||||
coordinates {
|
||||
$cs
|
||||
};
|
||||
"""
|
||||
end
|
||||
##
|
||||
const _pgfplotsx_linestyles = KW(
|
||||
:solid => "solid",
|
||||
:dash => "dashed",
|
||||
:dot => "dotted",
|
||||
:dashdot => "dashdotted",
|
||||
:dashdotdot => "dashdotdotted",
|
||||
)
|
||||
|
||||
const _pgfplotsx_markers = KW(
|
||||
:none => "none",
|
||||
:cross => "+",
|
||||
:xcross => "x",
|
||||
:+ => "+",
|
||||
:x => "x",
|
||||
:utriangle => "triangle*",
|
||||
:dtriangle => "triangle*",
|
||||
:rtriangle => "triangle*",
|
||||
:ltriangle => "triangle*",
|
||||
:circle => "*",
|
||||
:rect => "square*",
|
||||
:star5 => "star",
|
||||
:star6 => "asterisk",
|
||||
:diamond => "diamond*",
|
||||
:pentagon => "pentagon*",
|
||||
:hline => "-",
|
||||
:vline => "|"
|
||||
)
|
||||
|
||||
const _pgfplotsx_legend_pos = KW(
|
||||
:bottomleft => "south west",
|
||||
:bottomright => "south east",
|
||||
:topright => "north east",
|
||||
:topleft => "north west",
|
||||
:outertopright => "outer north east",
|
||||
)
|
||||
|
||||
const _pgfx_framestyles = [:box, :axes, :origin, :zerolines, :grid, :none]
|
||||
const _pgfx_framestyle_defaults = Dict(:semi => :box)
|
||||
|
||||
# we use the anchors to define orientations for example to align left
|
||||
# one needs to use the right edge as anchor
|
||||
const _pgfx_annotation_halign = KW(
|
||||
:center => "",
|
||||
:left => "right",
|
||||
:right => "left"
|
||||
)
|
||||
## --------------------------------------------------------------------------------------
|
||||
# Generates a colormap for pgfplots based on a ColorGradient
|
||||
pgfx_arrow(::Nothing) = "every arrow/.append style={-}"
|
||||
function pgfx_arrow( arr::Arrow )
|
||||
components = String[]
|
||||
head = String[]
|
||||
push!(head, "{stealth[length = $(arr.headlength)pt, width = $(arr.headwidth)pt")
|
||||
if arr.style == :open
|
||||
push!(head, ", open")
|
||||
end
|
||||
push!(head, "]}")
|
||||
head = join(head, "")
|
||||
if arr.side == :both || arr.side == :tail
|
||||
push!( components, head )
|
||||
end
|
||||
push!(components, "-")
|
||||
if arr.side == :both || arr.side == :head
|
||||
push!( components, head )
|
||||
end
|
||||
components = join( components, "" )
|
||||
return "every arrow/.append style={$(components)}"
|
||||
end
|
||||
|
||||
function pgfx_filllegend!( series_opt, opt )
|
||||
io = IOBuffer()
|
||||
PGFPlotsX.print_tex(io, pgfx_fillstyle(opt))
|
||||
style = strip(String(take!(io)),['[',']', ' '])
|
||||
push!( series_opt, "legend image code/.code" => """{
|
||||
\\draw[$style] (0cm,-0.1cm) rectangle (0.6cm,0.1cm);
|
||||
}""" )
|
||||
end
|
||||
|
||||
function pgfx_colormap(grad::ColorGradient)
|
||||
join(map(grad.colors) do c
|
||||
@sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c), blue(c))
|
||||
end,"\n")
|
||||
end
|
||||
function pgfx_colormap(grad::Vector{<:Colorant})
|
||||
join(map(grad) do c
|
||||
@sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c), blue(c))
|
||||
end,"\n")
|
||||
end
|
||||
|
||||
function pgfx_framestyle(style::Symbol)
|
||||
if style in _pgfx_framestyles
|
||||
return style
|
||||
else
|
||||
default_style = get(_pgfx_framestyle_defaults, style, :axes)
|
||||
@warn("Framestyle :$style is not (yet) supported by the PGFPlots backend. :$default_style was cosen instead.")
|
||||
default_style
|
||||
end
|
||||
end
|
||||
|
||||
pgfx_thickness_scaling(plt::Plot) = plt[:thickness_scaling]
|
||||
pgfx_thickness_scaling(sp::Subplot) = pgfx_thickness_scaling(sp.plt)
|
||||
pgfx_thickness_scaling(series) = pgfx_thickness_scaling(series[:subplot])
|
||||
|
||||
function pgfx_fillstyle(plotattributes, i = 1)
|
||||
cstr = get_fillcolor(plotattributes, i)
|
||||
a = get_fillalpha(plotattributes, i)
|
||||
if a === nothing
|
||||
a = alpha(single_color(cstr))
|
||||
end
|
||||
PGFPlotsX.Options("fill" => cstr, "fill opacity" => a)
|
||||
end
|
||||
|
||||
function pgfx_linestyle(linewidth::Real, color, α = 1, linestyle = "solid")
|
||||
cstr = plot_color(color, α)
|
||||
a = alpha(cstr)
|
||||
return PGFPlotsX.Options(
|
||||
"color" => cstr,
|
||||
"draw opacity" => a,
|
||||
"line width" => linewidth,
|
||||
get(_pgfplotsx_linestyles, linestyle, "solid") => nothing
|
||||
)
|
||||
end
|
||||
|
||||
function pgfx_linestyle(plotattributes, i = 1)
|
||||
lw = pgfx_thickness_scaling(plotattributes) * get_linewidth(plotattributes, i)
|
||||
lc = single_color(get_linecolor(plotattributes, i))
|
||||
la = get_linealpha(plotattributes, i)
|
||||
ls = get_linestyle(plotattributes, i)
|
||||
return pgfx_linestyle(lw, lc, la, ls)
|
||||
end
|
||||
|
||||
function pgfx_font(fontsize, thickness_scaling = 1, font = "\\selectfont")
|
||||
fs = fontsize * thickness_scaling
|
||||
return string("{\\fontsize{", fs, " pt}{", 1.3fs, " pt}", font, "}")
|
||||
end
|
||||
|
||||
function pgfx_marker(plotattributes, i = 1)
|
||||
shape = _cycle(plotattributes[:markershape], i)
|
||||
cstr = plot_color(get_markercolor(plotattributes, i), get_markeralpha(plotattributes, i))
|
||||
a = alpha(cstr)
|
||||
cstr_stroke = plot_color(get_markerstrokecolor(plotattributes, i), get_markerstrokealpha(plotattributes, i))
|
||||
a_stroke = alpha(cstr_stroke)
|
||||
mark_size = pgfx_thickness_scaling(plotattributes) * 0.5 * _cycle(plotattributes[:markersize], i)
|
||||
return PGFPlotsX.Options(
|
||||
"mark" => shape isa Shape ? "PlotsShape$i" : get(_pgfplotsx_markers, shape, "*"),
|
||||
"mark size" => "$mark_size pt",
|
||||
"mark options" => PGFPlotsX.Options(
|
||||
"color" => cstr_stroke,
|
||||
"draw opacity" => a_stroke,
|
||||
"fill" => cstr,
|
||||
"fill opacity" => a,
|
||||
"line width" => pgfx_thickness_scaling(plotattributes) * _cycle(plotattributes[:markerstrokewidth], i),
|
||||
"rotate" => if shape == :dtriangle
|
||||
180
|
||||
elseif shape == :rtriangle
|
||||
270
|
||||
elseif shape == :ltriangle
|
||||
90
|
||||
else
|
||||
0
|
||||
end,
|
||||
get(_pgfplotsx_linestyles, _cycle(plotattributes[:markerstrokestyle], i), "solid") => nothing
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
function pgfx_add_annotation!(o, x, y, val, thickness_scaling = 1)
|
||||
# Construct the style string.
|
||||
cstr = val.font.color
|
||||
a = alpha(cstr)
|
||||
push!(o, ["\\node",
|
||||
PGFPlotsX.Options(
|
||||
get(_pgfx_annotation_halign, val.font.halign, "") => nothing,
|
||||
"color" => cstr,
|
||||
"draw opacity" => convert(Float16, a),
|
||||
"rotate" => val.font.rotation,
|
||||
"font" => pgfx_font(val.font.pointsize, thickness_scaling)
|
||||
),
|
||||
" at (axis cs:$x, $y) {$(val.str)};"
|
||||
])
|
||||
end
|
||||
|
||||
function pgfx_add_ribbons!( axis, series, segment_plot, series_func, series_index )
|
||||
ribbon_y = series[:ribbon]
|
||||
opt = series.plotattributes
|
||||
if ribbon_y isa AVec
|
||||
ribbon_n = length(opt[:y]) ÷ length(ribbon_y)
|
||||
ribbon_yp = ribbon_ym = repeat(ribbon_y, outer = ribbon_n)
|
||||
elseif ribbon_y isa Tuple
|
||||
ribbon_ym, ribbon_yp = ribbon_y
|
||||
ribbon_nm = length(opt[:y]) ÷ length(ribbon_ym)
|
||||
ribbon_ym = repeat(ribbon_ym, outer = ribbon_nm)
|
||||
ribbon_np = length(opt[:y]) ÷ length(ribbon_yp)
|
||||
ribbon_yp = repeat(ribbon_yp, outer = ribbon_np)
|
||||
else
|
||||
ribbon_yp = ribbon_ym = ribbon_y
|
||||
end
|
||||
# upper ribbon
|
||||
rib_uuid = uuid4()
|
||||
ribbon_name_plus = "plots_rib_p$rib_uuid"
|
||||
ribbon_opt_plus = merge(segment_plot.options, PGFPlotsX.Options(
|
||||
"name path" => ribbon_name_plus,
|
||||
"color" => opt[:fillcolor],
|
||||
"draw opacity" => opt[:fillalpha],
|
||||
"forget plot" => nothing
|
||||
))
|
||||
coordinates_plus = PGFPlotsX.Coordinates(opt[:x], opt[:y] .+ ribbon_yp)
|
||||
ribbon_plot_plus = series_func(
|
||||
ribbon_opt_plus,
|
||||
coordinates_plus
|
||||
)
|
||||
push!(axis, ribbon_plot_plus)
|
||||
# lower ribbon
|
||||
ribbon_name_minus = "plots_rib_m$rib_uuid"
|
||||
ribbon_opt_minus = merge(segment_plot.options, PGFPlotsX.Options(
|
||||
"name path" => ribbon_name_minus,
|
||||
"color" => opt[:fillcolor],
|
||||
"draw opacity" => opt[:fillalpha],
|
||||
"forget plot" => nothing
|
||||
))
|
||||
coordinates_plus = PGFPlotsX.Coordinates(opt[:x], opt[:y] .- ribbon_ym)
|
||||
ribbon_plot_plus = series_func(
|
||||
ribbon_opt_minus,
|
||||
coordinates_plus
|
||||
)
|
||||
push!(axis, ribbon_plot_plus)
|
||||
# fill
|
||||
push!(axis, series_func(
|
||||
merge(pgfx_fillstyle(opt, series_index), PGFPlotsX.Options("forget plot" => nothing)),
|
||||
"fill between [of=$(ribbon_name_plus) and $(ribbon_name_minus)]"
|
||||
))
|
||||
return axis
|
||||
end
|
||||
|
||||
function pgfx_fillrange_series!(axis, series, series_func, i, fillrange, rng)
|
||||
fillrange_opt = PGFPlotsX.Options(
|
||||
"line width" => "0",
|
||||
"draw opacity" => "0",
|
||||
)
|
||||
fillrange_opt = merge( fillrange_opt, pgfx_fillstyle(series, i) )
|
||||
fillrange_opt = merge( fillrange_opt, pgfx_marker(series, i) )
|
||||
push!( fillrange_opt, "forget plot" => nothing )
|
||||
opt = series.plotattributes
|
||||
args = is3d(series) ? (opt[:x][rng], opt[:y][rng], opt[:z][rng]) : (opt[:x][rng], opt[:y][rng])
|
||||
push!(axis, PGFPlotsX.PlotInc(fillrange_opt, pgfx_fillrange_args(fillrange, args...)))
|
||||
return axis
|
||||
end
|
||||
|
||||
function pgfx_fillrange_args(fillrange, x, y)
|
||||
n = length(x)
|
||||
x_fill = [x; x[n:-1:1]; x[1]]
|
||||
y_fill = [y; _cycle(fillrange, n:-1:1); y[1]]
|
||||
return PGFPlotsX.Coordinates(x_fill, y_fill)
|
||||
end
|
||||
|
||||
function pgfx_fillrange_args(fillrange, x, y, z)
|
||||
n = length(x)
|
||||
x_fill = [x; x[n:-1:1]; x[1]]
|
||||
y_fill = [y; y[n:-1:1]; x[1]]
|
||||
z_fill = [z; _cycle(fillrange, n:-1:1); z[1]]
|
||||
return PGFPlotsX.Coordiantes(x_fill, y_fill, z_fill)
|
||||
end
|
||||
# --------------------------------------------------------------------------------------
|
||||
function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
axis = sp[Symbol(letter,:axis)]
|
||||
|
||||
# turn off scaled ticks
|
||||
push!(opt, "scaled $(letter) ticks" => "false",
|
||||
string(letter,:label) => axis[:guide],
|
||||
)
|
||||
|
||||
# set to supported framestyle
|
||||
framestyle = pgfx_framestyle(sp[:framestyle] == false ? :none : sp[:framestyle])
|
||||
|
||||
# axis label position
|
||||
labelpos = ""
|
||||
if letter == :x && axis[:guide_position] == :top
|
||||
labelpos = "at={(0.5,1)},above,"
|
||||
elseif letter == :y && axis[:guide_position] == :right
|
||||
labelpos = "at={(1,0.5)},below,"
|
||||
end
|
||||
|
||||
# Add label font
|
||||
cstr = plot_color(axis[:guidefontcolor])
|
||||
α = alpha(cstr)
|
||||
push!(opt, string(letter, "label style") => PGFPlotsX.Options(
|
||||
labelpos => nothing,
|
||||
"font" => pgfx_font(axis[:guidefontsize], pgfx_thickness_scaling(sp)),
|
||||
"color" => cstr,
|
||||
"draw opacity" => α,
|
||||
"rotate" => axis[:guidefontrotation],
|
||||
)
|
||||
)
|
||||
|
||||
# flip/reverse?
|
||||
axis[:flip] && push!(opt, "$letter dir" => "reverse")
|
||||
|
||||
# scale
|
||||
scale = axis[:scale]
|
||||
if scale in (:log2, :ln, :log10)
|
||||
push!(opt, string(letter,:mode) => "log")
|
||||
scale == :ln || push!(opt, "log basis $letter" => "$(scale == :log2 ? 2 : 10)")
|
||||
end
|
||||
|
||||
# ticks on or off
|
||||
if axis[:ticks] in (nothing, false, :none) || framestyle == :none
|
||||
push!(opt, "$(letter)majorticks" => "false")
|
||||
end
|
||||
|
||||
# grid on or off
|
||||
if axis[:grid] && framestyle != :none
|
||||
push!(opt, "$(letter)majorgrids" => "true")
|
||||
else
|
||||
push!(opt, "$(letter)majorgrids" => "false")
|
||||
end
|
||||
|
||||
# limits
|
||||
lims = ispolar(sp) && letter == :x ? rad2deg.(axis_limits(sp, :x)) : axis_limits(sp, letter)
|
||||
push!( opt,
|
||||
string(letter,:min) => lims[1],
|
||||
string(letter,:max) => lims[2]
|
||||
)
|
||||
|
||||
if !(axis[:ticks] in (nothing, false, :none, :native)) && framestyle != :none
|
||||
ticks = get_ticks(sp, axis)
|
||||
#pgf plot ignores ticks with angle below 90 when xmin = 90 so shift values
|
||||
tick_values = ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] : ticks[1]
|
||||
push!(opt, string(letter, "tick") => string("{", join(tick_values,","), "}"))
|
||||
if axis[:showaxis] && axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto
|
||||
# wrap the power part of label with }
|
||||
tick_labels = Vector{String}(undef, length(ticks[2]))
|
||||
for (i, label) in enumerate(ticks[2])
|
||||
base, power = split(label, "^")
|
||||
power = string("{", power, "}")
|
||||
tick_labels[i] = string(base, "^", power)
|
||||
end
|
||||
push!(opt, string(letter, "ticklabels") => string("{\$", join(tick_labels,"\$,\$"), "\$}"))
|
||||
elseif axis[:showaxis]
|
||||
tick_labels = ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2]
|
||||
if axis[:formatter] in (:scientific, :auto)
|
||||
tick_labels = string.("\$", convert_sci_unicode.(tick_labels), "\$")
|
||||
tick_labels = replace.(tick_labels, Ref("×" => "\\times"))
|
||||
end
|
||||
push!(opt, string(letter, "ticklabels") => string("{", join(tick_labels,","), "}"))
|
||||
else
|
||||
push!(opt, string(letter, "ticklabels") => "{}")
|
||||
end
|
||||
push!(opt, string(letter, "tick align") => (axis[:tick_direction] == :out ? "outside" : "inside"))
|
||||
cstr = plot_color(axis[:tickfontcolor])
|
||||
α = alpha(cstr)
|
||||
push!(opt, string(letter, "ticklabel style") => PGFPlotsX.Options(
|
||||
"font" => pgfx_font(axis[:tickfontsize], pgfx_thickness_scaling(sp)),
|
||||
"color" => cstr,
|
||||
"draw opacity" => α,
|
||||
"rotate" => axis[:tickfontrotation]
|
||||
)
|
||||
)
|
||||
push!(opt, string(letter, " grid style") => pgfx_linestyle(pgfx_thickness_scaling(sp) * axis[:gridlinewidth], axis[:foreground_color_grid], axis[:gridalpha], axis[:gridstyle])
|
||||
)
|
||||
end
|
||||
|
||||
# framestyle
|
||||
if framestyle in (:axes, :origin)
|
||||
axispos = framestyle == :axes ? "left" : "middle"
|
||||
if axis[:draw_arrow]
|
||||
push!(opt, string("axis ", letter, " line") => axispos)
|
||||
else
|
||||
# the * after line disables the arrow at the axis
|
||||
push!(opt, string("axis ", letter, " line*") => axispos)
|
||||
end
|
||||
end
|
||||
|
||||
if framestyle == :zerolines
|
||||
push!(opt, string("extra ", letter, " ticks") => "0")
|
||||
push!(opt, string("extra ", letter, " tick labels") => "")
|
||||
push!(opt, string("extra ", letter, " tick style") => PGFPlotsX.Options(
|
||||
"grid" => "major",
|
||||
"major grid style" => pgfx_linestyle(pgfx_thickness_scaling(sp), axis[:foreground_color_border], 1.0)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
if !axis[:showaxis]
|
||||
push!(opt, "separate axis lines")
|
||||
end
|
||||
if !axis[:showaxis] || framestyle in (:zerolines, :grid, :none)
|
||||
push!(opt, string(letter, " axis line style") => "{draw opacity = 0}")
|
||||
else
|
||||
push!(opt, string(letter, " axis line style") => pgfx_linestyle(pgfx_thickness_scaling(sp), axis[:foreground_color_border], 1.0)
|
||||
)
|
||||
end
|
||||
end
|
||||
# --------------------------------------------------------------------------------------
|
||||
# display calls this and then _display, its called 3 times for plot(1:5)
|
||||
# Set the (left, top, right, bottom) minimum padding around the plot area
|
||||
# to fit ticks, tick labels, guides, colorbars, etc.
|
||||
function _update_min_padding!(sp::Subplot{PGFPlotsXBackend})
|
||||
# TODO: make padding more intelligent
|
||||
# order: right, top, left, bottom
|
||||
sp.minpad = (22mm + sp[:right_margin],
|
||||
12mm + sp[:top_margin],
|
||||
2mm + sp[:left_margin],
|
||||
10mm + sp[:bottom_margin])
|
||||
end
|
||||
|
||||
function _create_backend_figure(plt::Plot{PGFPlotsXBackend})
|
||||
plt.o = PGFPlotsXPlot()
|
||||
end
|
||||
|
||||
function _series_added(plt::Plot{PGFPlotsXBackend}, series::Series)
|
||||
plt.o.is_created = false
|
||||
end
|
||||
|
||||
function _update_plot_object(plt::Plot{PGFPlotsXBackend})
|
||||
plt.o(plt)
|
||||
end
|
||||
|
||||
for mime in ("application/pdf", "image/png", "image/svg+xml")
|
||||
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{PGFPlotsXBackend})
|
||||
show(io, mime, plt.o.the_plot)
|
||||
end
|
||||
end
|
||||
|
||||
function _show(io::IO, mime::MIME{Symbol("application/x-tex")}, plt::Plot{PGFPlotsXBackend})
|
||||
PGFPlotsX.print_tex(io, plt.o.the_plot, include_preamble = plt.attr[:tex_output_standalone])
|
||||
end
|
||||
|
||||
function _display(plt::Plot{PGFPlotsXBackend})
|
||||
display(PGFPlotsX.PGFPlotsXDisplay(), plt.o.the_plot)
|
||||
end
|
||||
+60
-49
@@ -26,7 +26,6 @@ const plotly_remote_file_path = "https://cdn.plot.ly/plotly-latest.min.js"
|
||||
# end
|
||||
using UUIDs
|
||||
|
||||
push!(_initialized_backends, :plotly)
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
const _plotly_legend_pos = KW(
|
||||
@@ -114,8 +113,8 @@ function plotly_apply_aspect_ratio(sp::Subplot, plotarea, pcts)
|
||||
if aspect_ratio == :equal
|
||||
aspect_ratio = 1.0
|
||||
end
|
||||
xmin,xmax = axis_limits(sp[:xaxis])
|
||||
ymin,ymax = axis_limits(sp[:yaxis])
|
||||
xmin,xmax = axis_limits(sp, :x)
|
||||
ymin,ymax = axis_limits(sp, :y)
|
||||
want_ratio = ((xmax-xmin) / (ymax-ymin)) / aspect_ratio
|
||||
parea_ratio = width(plotarea) / height(plotarea)
|
||||
if want_ratio > parea_ratio
|
||||
@@ -174,7 +173,7 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
|
||||
|
||||
ax[:tickangle] = -axis[:rotation]
|
||||
ax[:type] = plotly_scale(axis[:scale])
|
||||
lims = axis_limits(axis)
|
||||
lims = axis_limits(sp, letter)
|
||||
|
||||
if axis[:ticks] != :native || axis[:lims] != :auto
|
||||
ax[:range] = map(scalefunc(axis[:scale]), lims)
|
||||
@@ -186,14 +185,9 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
|
||||
ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis])
|
||||
ax[:linecolor] = rgba_string(axis[:foreground_color_axis])
|
||||
|
||||
# flip
|
||||
if axis[:flip]
|
||||
ax[:range] = reverse(ax[:range])
|
||||
end
|
||||
|
||||
# ticks
|
||||
if axis[:ticks] != :native
|
||||
ticks = get_ticks(axis)
|
||||
ticks = get_ticks(sp, axis)
|
||||
ttype = ticksType(ticks)
|
||||
if ttype == :ticks
|
||||
ax[:tickmode] = "array"
|
||||
@@ -208,20 +202,24 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
|
||||
ax[:showgrid] = false
|
||||
end
|
||||
|
||||
# flip
|
||||
if axis[:flip]
|
||||
ax[:range] = reverse(ax[:range])
|
||||
end
|
||||
|
||||
ax
|
||||
end
|
||||
|
||||
function plotly_polaraxis(axis::Axis)
|
||||
function plotly_polaraxis(sp::Subplot, axis::Axis)
|
||||
ax = KW(
|
||||
:visible => axis[:showaxis],
|
||||
:showline => axis[:grid],
|
||||
)
|
||||
|
||||
if axis[:letter] == :x
|
||||
ax[:range] = rad2deg.(axis_limits(axis))
|
||||
ax[:range] = rad2deg.(axis_limits(sp, :x))
|
||||
else
|
||||
ax[:range] = axis_limits(axis)
|
||||
ax[:range] = axis_limits(sp, :y)
|
||||
ax[:orientation] = -90
|
||||
end
|
||||
|
||||
@@ -284,8 +282,8 @@ function plotly_layout(plt::Plot)
|
||||
),
|
||||
)
|
||||
elseif ispolar(sp)
|
||||
plotattributes_out[Symbol("angularaxis$(spidx)")] = plotly_polaraxis(sp[:xaxis])
|
||||
plotattributes_out[Symbol("radialaxis$(spidx)")] = plotly_polaraxis(sp[:yaxis])
|
||||
plotattributes_out[Symbol("angularaxis$(spidx)")] = plotly_polaraxis(sp, sp[:xaxis])
|
||||
plotattributes_out[Symbol("radialaxis$(spidx)")] = plotly_polaraxis(sp, sp[:yaxis])
|
||||
else
|
||||
plotattributes_out[Symbol("xaxis$(x_idx)")] = plotly_axis(plt, sp[:xaxis], sp)
|
||||
# don't allow yaxis to be reupdated/reanchored in a linked subplot
|
||||
@@ -348,14 +346,14 @@ function plotly_layout(plt::Plot)
|
||||
end
|
||||
|
||||
function plotly_layout_json(plt::Plot)
|
||||
JSON.json(plotly_layout(plt))
|
||||
JSON.json(plotly_layout(plt), 4)
|
||||
end
|
||||
|
||||
|
||||
function plotly_colorscale(grad::ColorGradient, α)
|
||||
[[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in 1:length(grad.colors)]
|
||||
[[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in eachindex(grad.colors)]
|
||||
end
|
||||
plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α)
|
||||
plotly_colorscale(c::Colorant,α) = plotly_colorscale(_as_gradient(c),α)
|
||||
function plotly_colorscale(c::AbstractVector{<:RGBA}, α)
|
||||
if length(c) == 1
|
||||
return [[0.0, rgba_string(plot_color(c[1], α))], [1.0, rgba_string(plot_color(c[1], α))]]
|
||||
@@ -394,7 +392,7 @@ end
|
||||
# we split by NaNs and then construct/destruct the shapes to get the closed coords
|
||||
function plotly_close_shapes(x, y)
|
||||
xs, ys = nansplit(x), nansplit(y)
|
||||
for i=1:length(xs)
|
||||
for i=eachindex(xs)
|
||||
shape = Shape(xs[i], ys[i])
|
||||
xs[i], ys[i] = coords(shape)
|
||||
end
|
||||
@@ -404,7 +402,7 @@ end
|
||||
function plotly_data(series::Series, letter::Symbol, data)
|
||||
axis = series[:subplot][Symbol(letter, :axis)]
|
||||
|
||||
data = if axis[:ticks] == :native && data != nothing
|
||||
data = if axis[:ticks] == :native && data !== nothing
|
||||
plotly_native_data(axis, data)
|
||||
else
|
||||
data
|
||||
@@ -416,7 +414,8 @@ function plotly_data(series::Series, letter::Symbol, data)
|
||||
plotly_data(data)
|
||||
end
|
||||
end
|
||||
plotly_data(v) = v != nothing ? collect(v) : v
|
||||
plotly_data(v) = v !== nothing ? collect(v) : v
|
||||
plotly_data(v::AbstractArray) = v
|
||||
plotly_data(surf::Surface) = surf.surf
|
||||
plotly_data(v::AbstractArray{R}) where {R<:Rational} = float(v)
|
||||
|
||||
@@ -437,7 +436,7 @@ plotly_native_data(axis::Axis, a::Surface) = Surface(plotly_native_data(axis, a.
|
||||
|
||||
function plotly_convert_to_datetime(x::AbstractArray, formatter::Function)
|
||||
if formatter == datetimeformatter
|
||||
map(xi -> replace(formatter(xi), "T", " "), x)
|
||||
map(xi -> replace(formatter(xi), "T" => " "), x)
|
||||
elseif formatter == dateformatter
|
||||
map(xi -> string(formatter(xi), " 00:00:00"), x)
|
||||
elseif formatter == timeformatter
|
||||
@@ -455,7 +454,7 @@ function plotly_series(plt::Plot, series::Series)
|
||||
st = series[:seriestype]
|
||||
|
||||
sp = series[:subplot]
|
||||
clims = get_clims(sp)
|
||||
clims = get_clims(sp, series)
|
||||
|
||||
if st == :shape
|
||||
return plotly_series_shapes(plt, series, clims)
|
||||
@@ -470,7 +469,7 @@ function plotly_series(plt::Plot, series::Series)
|
||||
plotattributes_out[:showlegend] = should_add_to_legend(series)
|
||||
|
||||
if st == :straightline
|
||||
x, y = straightline_data(series)
|
||||
x, y = straightline_data(series, 100)
|
||||
z = series[:z]
|
||||
else
|
||||
x, y, z = series[:x], series[:y], series[:z]
|
||||
@@ -507,13 +506,13 @@ function plotly_series(plt::Plot, series::Series)
|
||||
plotattributes_out[:showscale] = hascolorbar(sp)
|
||||
|
||||
elseif st == :contour
|
||||
filled = isfilledcontour(series)
|
||||
plotattributes_out[:type] = "contour"
|
||||
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
|
||||
# plotattributes_out[:showscale] = series[:colorbar] != :none
|
||||
plotattributes_out[:ncontours] = series[:levels]
|
||||
plotattributes_out[:contours] = KW(:coloring => series[:fillrange] != nothing ? "fill" : "lines", :showlabels => series[:contour_labels] == true)
|
||||
plotattributes_out[:ncontours] = series[:levels] + 2
|
||||
plotattributes_out[:contours] = KW(:coloring => filled ? "fill" : "lines", :showlabels => series[:contour_labels] == true)
|
||||
plotattributes_out[:colorscale] = plotly_colorscale(series[:linecolor], series[:linealpha])
|
||||
plotattributes_out[:showscale] = hascolorbar(sp)
|
||||
plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series)
|
||||
|
||||
elseif st in (:surface, :wireframe)
|
||||
plotattributes_out[:type] = "surface"
|
||||
@@ -530,7 +529,7 @@ function plotly_series(plt::Plot, series::Series)
|
||||
else
|
||||
plotattributes_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
||||
plotattributes_out[:opacity] = series[:fillalpha]
|
||||
if series[:fill_z] != nothing
|
||||
if series[:fill_z] !== nothing
|
||||
plotattributes_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z])
|
||||
end
|
||||
plotattributes_out[:showscale] = hascolorbar(sp)
|
||||
@@ -585,7 +584,7 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
|
||||
)
|
||||
|
||||
x, y = (plotly_data(series, letter, data)
|
||||
for (letter, data) in zip((:x, :y), shape_data(series))
|
||||
for (letter, data) in zip((:x, :y), shape_data(series, 100))
|
||||
)
|
||||
|
||||
for (i,rng) in enumerate(segments)
|
||||
@@ -612,11 +611,11 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
|
||||
plotly_hover!(plotattributes_out, _cycle(series[:hover], i))
|
||||
plotattributes_outs[i] = plotattributes_out
|
||||
end
|
||||
if series[:fill_z] != nothing
|
||||
if series[:fill_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill))
|
||||
elseif series[:line_z] != nothing
|
||||
elseif series[:line_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :line))
|
||||
elseif series[:marker_z] != nothing
|
||||
elseif series[:marker_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :marker))
|
||||
end
|
||||
plotattributes_outs
|
||||
@@ -632,11 +631,9 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
(isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple))
|
||||
|
||||
segments = iter_segments(series)
|
||||
plotattributes_outs = Vector{KW}(undef, (hasfillrange ? 2 : 1 ) * length(segments))
|
||||
plotattributes_outs = fill(KW(), (hasfillrange ? 2 : 1 ) * length(segments))
|
||||
|
||||
for (i,rng) in enumerate(segments)
|
||||
!isscatter && length(rng) < 2 && continue
|
||||
|
||||
plotattributes_out = deepcopy(plotattributes_base)
|
||||
plotattributes_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
|
||||
plotattributes_out[:legendgroup] = series[:label]
|
||||
@@ -736,11 +733,11 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
end
|
||||
end
|
||||
|
||||
if series[:line_z] != nothing
|
||||
if series[:line_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :line))
|
||||
elseif series[:fill_z] != nothing
|
||||
elseif series[:fill_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill))
|
||||
elseif series[:marker_z] != nothing
|
||||
elseif series[:marker_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :marker))
|
||||
end
|
||||
|
||||
@@ -775,7 +772,7 @@ end
|
||||
function plotly_polar!(plotattributes_out::KW, series::Series)
|
||||
# convert polar plots x/y to theta/radius
|
||||
if ispolar(series[:subplot])
|
||||
theta, r = filter_radial_data(pop!(plotattributes_out, :x), pop!(plotattributes_out, :y), axis_limits(series[:subplot][:yaxis]))
|
||||
theta, r = pop!(plotattributes_out, :x), pop!(plotattributes_out, :y)
|
||||
plotattributes_out[:t] = rad2deg.(theta)
|
||||
plotattributes_out[:r] = r
|
||||
end
|
||||
@@ -785,7 +782,7 @@ function plotly_hover!(plotattributes_out::KW, hover)
|
||||
# hover text
|
||||
if hover in (:none, false)
|
||||
plotattributes_out[:hoverinfo] = "none"
|
||||
elseif hover != nothing
|
||||
elseif hover !== nothing
|
||||
plotattributes_out[:hoverinfo] = "text"
|
||||
plotattributes_out[:text] = hover
|
||||
end
|
||||
@@ -801,13 +798,16 @@ function plotly_series(plt::Plot)
|
||||
end
|
||||
|
||||
# get json string for a list of dictionaries, each representing the series params
|
||||
plotly_series_json(plt::Plot) = JSON.json(plotly_series(plt))
|
||||
plotly_series_json(plt::Plot) = JSON.json(plotly_series(plt), 4)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
html_head(plt::Plot{PlotlyBackend}) = plotly_html_head(plt)
|
||||
html_body(plt::Plot{PlotlyBackend}) = plotly_html_body(plt)
|
||||
|
||||
const ijulia_initialized = Ref(false)
|
||||
|
||||
function html_head(plt::Plot{PlotlyBackend})
|
||||
function plotly_html_head(plt::Plot)
|
||||
local_file = ("file://" * plotly_local_file_path)
|
||||
plotly = use_local_dependencies[] ? local_file : plotly_remote_file_path
|
||||
if isijulia() && !ijulia_initialized[]
|
||||
@@ -823,13 +823,11 @@ function html_head(plt::Plot{PlotlyBackend})
|
||||
""")
|
||||
ijulia_initialized[] = true
|
||||
end
|
||||
# IJulia just needs one initialization
|
||||
isijulia() && return ""
|
||||
return "<script src=$(repr(plotly))></script>"
|
||||
end
|
||||
|
||||
function html_body(plt::Plot{PlotlyBackend}, style = nothing)
|
||||
if style == nothing
|
||||
function plotly_html_body(plt, style = nothing)
|
||||
if style === nothing
|
||||
w, h = plt[:size]
|
||||
style = "width:$(w)px;height:$(h)px;"
|
||||
end
|
||||
@@ -844,21 +842,34 @@ function html_body(plt::Plot{PlotlyBackend}, style = nothing)
|
||||
html
|
||||
end
|
||||
|
||||
function js_body(plt::Plot{PlotlyBackend}, uuid)
|
||||
function js_body(plt::Plot, uuid)
|
||||
js = """
|
||||
PLOT = document.getElementById('$(uuid)');
|
||||
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
|
||||
"""
|
||||
end
|
||||
|
||||
function plotly_show_js(io::IO, plot::Plot)
|
||||
data = []
|
||||
for series in plot.series_list
|
||||
append!(data, plotly_series(plot, series))
|
||||
end
|
||||
layout = plotly_layout(plot)
|
||||
JSON.print(io, Dict(:data => data, :layout => layout))
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function _show(io::IO, ::MIME"application/vnd.plotly.v1+json", plot::Plot{PlotlyBackend})
|
||||
plotly_show_js(io, plot)
|
||||
end
|
||||
|
||||
|
||||
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
|
||||
write(io, html_head(plt) * html_body(plt))
|
||||
write(io, standalone_html(plt))
|
||||
end
|
||||
|
||||
|
||||
function _display(plt::Plot{PlotlyBackend})
|
||||
standalone_html_window(plt)
|
||||
end
|
||||
|
||||
+30
-72
@@ -1,86 +1,44 @@
|
||||
# https://github.com/sglyon/PlotlyJS.jl
|
||||
|
||||
# https://github.com/spencerlyon2/PlotlyJS.jl
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
function _create_backend_figure(plt::Plot{PlotlyJSBackend})
|
||||
if !isplotnull() && plt[:overwrite_figure] && isa(current().o, PlotlyJS.SyncPlot)
|
||||
PlotlyJS.SyncPlot(PlotlyJS.Plot(), options = current().o.options)
|
||||
else
|
||||
PlotlyJS.plot()
|
||||
function plotlyjs_syncplot(plt::Plot{PlotlyJSBackend})
|
||||
plt[:overwrite_figure] && closeall()
|
||||
plt.o = PlotlyJS.plot()
|
||||
traces = PlotlyJS.GenericTrace[]
|
||||
for series_dict in plotly_series(plt)
|
||||
plotly_type = pop!(series_dict, :type)
|
||||
push!(traces, PlotlyJS.GenericTrace(plotly_type; series_dict...))
|
||||
end
|
||||
PlotlyJS.addtraces!(plt.o, traces...)
|
||||
layout = plotly_layout(plt)
|
||||
w, h = plt[:size]
|
||||
PlotlyJS.relayout!(plt.o, layout, width = w, height = h)
|
||||
return plt.o
|
||||
end
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
function _series_added(plt::Plot{PlotlyJSBackend}, series::Series)
|
||||
syncplot = plt.o
|
||||
pdicts = plotly_series(plt, series)
|
||||
for pdict in pdicts
|
||||
typ = pop!(pdict, :type)
|
||||
gt = PlotlyJS.GenericTrace(typ; pdict...)
|
||||
PlotlyJS.addtraces!(syncplot, gt)
|
||||
end
|
||||
const _plotlyjs_mimeformats = Dict(
|
||||
"application/pdf" => "pdf",
|
||||
"image/png" => "png",
|
||||
"image/svg+xml" => "svg",
|
||||
"image/eps" => "eps",
|
||||
)
|
||||
|
||||
for (mime, fmt) in _plotlyjs_mimeformats
|
||||
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plotlyjs_syncplot(plt), format = $fmt)
|
||||
end
|
||||
|
||||
function _series_updated(plt::Plot{PlotlyJSBackend}, series::Series)
|
||||
xsym, ysym = (ispolar(series) ? (:t,:r) : (:x,:y))
|
||||
kw = KW(xsym => (series.plotattributes[:x],), ysym => (series.plotattributes[:y],))
|
||||
z = series[:z]
|
||||
if z != nothing
|
||||
kw[:z] = (isa(z,Surface) ? transpose_z(series, series[:z].surf, false) : z,)
|
||||
end
|
||||
PlotlyJS.restyle!(
|
||||
plt.o,
|
||||
findfirst(isequal(series), plt.series_list),
|
||||
kw
|
||||
)
|
||||
end
|
||||
# Use the Plotly implementation for json and html:
|
||||
_show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) = plotly_show_js(io, plt)
|
||||
|
||||
html_head(plt::Plot{PlotlyJSBackend}) = plotly_html_head(plt)
|
||||
html_body(plt::Plot{PlotlyJSBackend}) = plotly_html_body(plt)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, standalone_html(plt))
|
||||
|
||||
function _update_plot_object(plt::Plot{PlotlyJSBackend})
|
||||
pdict = plotly_layout(plt)
|
||||
syncplot = plt.o
|
||||
w,h = plt[:size]
|
||||
PlotlyJS.relayout!(syncplot, pdict, width = w, height = h)
|
||||
end
|
||||
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend})
|
||||
if isijulia() && !_use_remote[]
|
||||
write(io, PlotlyJS.html_body(PlotlyJS.JupyterPlot(plt.o)))
|
||||
else
|
||||
show(io, MIME("text/html"), plt.o)
|
||||
end
|
||||
end
|
||||
|
||||
function plotlyjs_save_hack(io::IO, plt::Plot{PlotlyJSBackend}, ext::String)
|
||||
tmpfn = tempname() * "." * ext
|
||||
PlotlyJS.savefig(plt.o, tmpfn)
|
||||
write(io, read(open(tmpfn)))
|
||||
end
|
||||
_show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "svg")
|
||||
_show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "png")
|
||||
_show(io::IO, ::MIME"application/pdf", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "pdf")
|
||||
_show(io::IO, ::MIME"image/eps", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "eps")
|
||||
|
||||
function write_temp_html(plt::Plot{PlotlyJSBackend})
|
||||
filename = string(tempname(), ".html")
|
||||
savefig(plt, filename)
|
||||
filename
|
||||
end
|
||||
|
||||
function _display(plt::Plot{PlotlyJSBackend})
|
||||
if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes")
|
||||
display(plt.o)
|
||||
else
|
||||
standalone_html_window(plt)
|
||||
end
|
||||
end
|
||||
_display(plt::Plot{PlotlyJSBackend}) = display(plotlyjs_syncplot(plt))
|
||||
|
||||
@require WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" begin
|
||||
function WebIO.render(plt::Plot{PlotlyJSBackend})
|
||||
|
||||
+302
-182
File diff suppressed because it is too large
Load Diff
@@ -27,8 +27,8 @@ function rebuildUnicodePlot!(plt::Plot, width, height)
|
||||
for sp in plt.subplots
|
||||
xaxis = sp[:xaxis]
|
||||
yaxis = sp[:yaxis]
|
||||
xlim = axis_limits(xaxis)
|
||||
ylim = axis_limits(yaxis)
|
||||
xlim = axis_limits(sp, :x)
|
||||
ylim = axis_limits(sp, :y)
|
||||
|
||||
# make vectors
|
||||
xlim = [xlim[1], xlim[2]]
|
||||
@@ -116,7 +116,7 @@ function addUnicodeSeries!(o, plotattributes::KW, addlegend::Bool, xlim, ylim)
|
||||
x, y = if st == :straightline
|
||||
straightline_data(plotattributes)
|
||||
elseif st == :shape
|
||||
shape_data(series)
|
||||
shape_data(plotattributes)
|
||||
else
|
||||
[collect(float(plotattributes[s])) for s in (:x, :y)]
|
||||
end
|
||||
|
||||
+58
-18
@@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
const P2 = StaticArrays.SVector{2,Float64}
|
||||
const P3 = StaticArrays.SVector{3,Float64}
|
||||
const P2 = GeometryTypes.Point2{Float64}
|
||||
const P3 = GeometryTypes.Point3{Float64}
|
||||
|
||||
nanpush!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); push!(a, b))
|
||||
nanappend!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); append!(a, b))
|
||||
@@ -187,7 +187,7 @@ end
|
||||
function scale!(shape::Shape, x::Real, y::Real = x, c = center(shape))
|
||||
sx, sy = coords(shape)
|
||||
cx, cy = c
|
||||
for i=1:length(sx)
|
||||
for i=eachindex(sx)
|
||||
sx[i] = (sx[i] - cx) * x + cx
|
||||
sy[i] = (sy[i] - cy) * y + cy
|
||||
end
|
||||
@@ -202,7 +202,7 @@ end
|
||||
"translate a Shape in space"
|
||||
function translate!(shape::Shape, x::Real, y::Real = x)
|
||||
sx, sy = coords(shape)
|
||||
for i=1:length(sx)
|
||||
for i=eachindex(sx)
|
||||
sx[i] += x
|
||||
sy[i] += y
|
||||
end
|
||||
@@ -230,7 +230,7 @@ end
|
||||
function rotate!(shape::Shape, Θ::Real, c = center(shape))
|
||||
x, y = coords(shape)
|
||||
cx, cy = c
|
||||
for i=1:length(x)
|
||||
for i=eachindex(x)
|
||||
xi = rotate_x(x[i], y[i], Θ, cx, cy)
|
||||
yi = rotate_y(x[i], y[i], Θ, cx, cy)
|
||||
x[i], y[i] = xi, yi
|
||||
@@ -256,8 +256,24 @@ mutable struct Font
|
||||
color::Colorant
|
||||
end
|
||||
|
||||
"Create a Font from a list of unordered features"
|
||||
function font(args...)
|
||||
"""
|
||||
font(args...)
|
||||
Create a Font from a list of features. Values may be specified either as
|
||||
arguments (which are distinguished by type/value) or as keyword arguments.
|
||||
# Arguments
|
||||
- `family`: AbstractString. "serif" or "sans-serif" or "monospace"
|
||||
- `pointsize`: Integer. Size of font in points
|
||||
- `halign`: Symbol. Horizontal alignment (:hcenter, :left, or :right)
|
||||
- `valign`: Symbol. Vertical aligment (:vcenter, :top, or :bottom)
|
||||
- `rotation`: Real. Angle of rotation for text in degrees (use a non-integer type)
|
||||
- `color`: Colorant or Symbol
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> font(8)
|
||||
julia> font(family="serif",halign=:center,rotation=45.0)
|
||||
```
|
||||
"""
|
||||
function font(args...;kw...)
|
||||
|
||||
# defaults
|
||||
family = "sans-serif"
|
||||
@@ -301,6 +317,32 @@ function font(args...)
|
||||
end
|
||||
end
|
||||
|
||||
for symbol in keys(kw)
|
||||
if symbol == :family
|
||||
family = kw[:family]
|
||||
elseif symbol == :pointsize
|
||||
pointsize = kw[:pointsize]
|
||||
elseif symbol == :halign
|
||||
halign = kw[:halign]
|
||||
if halign == :center
|
||||
halign = :hcenter
|
||||
end
|
||||
@assert halign in (:hcenter, :left, :right)
|
||||
elseif symbol == :valign
|
||||
valign = kw[:valign]
|
||||
if valign == :center
|
||||
valign = :vcenter
|
||||
end
|
||||
@assert valign in (:vcenter, :top, :bottom)
|
||||
elseif symbol == :rotation
|
||||
rotation = kw[:rotation]
|
||||
elseif symbol == :color
|
||||
color = parse(Colorant, kw[:color])
|
||||
else
|
||||
@warn("Unused font kwarg: $symbol")
|
||||
end
|
||||
end
|
||||
|
||||
Font(family, pointsize, halign, valign, rotation, color)
|
||||
end
|
||||
|
||||
@@ -344,15 +386,16 @@ end
|
||||
PlotText(str) = PlotText(string(str), font())
|
||||
|
||||
"""
|
||||
text(string, args...)
|
||||
text(string, args...; kw...)
|
||||
|
||||
Create a PlotText object wrapping a string with font info, for plot annotations
|
||||
Create a PlotText object wrapping a string with font info, for plot annotations.
|
||||
`args` and `kw` are passed to `font`.
|
||||
"""
|
||||
text(t::PlotText) = t
|
||||
text(t::PlotText, font::Font) = PlotText(t.str, font)
|
||||
text(str::AbstractString, f::Font) = PlotText(str, f)
|
||||
function text(str, args...)
|
||||
PlotText(string(str), font(args...))
|
||||
function text(str, args...;kw...)
|
||||
PlotText(string(str), font(args...;kw...))
|
||||
end
|
||||
|
||||
Base.length(t::PlotText) = length(t.str)
|
||||
@@ -486,7 +529,7 @@ function series_annotations_shapes!(series::Series, scaletype::Symbol = :pixels)
|
||||
# end
|
||||
|
||||
# @show msw msh
|
||||
if anns != nothing && anns.baseshape != nothing
|
||||
if anns !== nothing && anns.baseshape !== nothing
|
||||
# we use baseshape to overwrite the markershape attribute
|
||||
# with a list of custom shapes for each
|
||||
msw,msh = anns.scalefactor
|
||||
@@ -525,7 +568,7 @@ mutable struct EachAnn
|
||||
end
|
||||
|
||||
function Base.iterate(ea::EachAnn, i = 1)
|
||||
if ea.anns == nothing || isempty(ea.anns.strs) || i > length(ea.y)
|
||||
if ea.anns === nothing || isempty(ea.anns.strs) || i > length(ea.y)
|
||||
return nothing
|
||||
end
|
||||
|
||||
@@ -736,7 +779,7 @@ end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
"create a BezierCurve for plotting"
|
||||
mutable struct BezierCurve{T <: StaticArrays.SVector}
|
||||
mutable struct BezierCurve{T <: GeometryTypes.Point}
|
||||
control_points::Vector{T}
|
||||
end
|
||||
|
||||
@@ -749,12 +792,9 @@ function (bc::BezierCurve)(t::Real)
|
||||
p
|
||||
end
|
||||
|
||||
# mean(x::Real, y::Real) = 0.5*(x+y) #commented out as I cannot see this used anywhere and it overwrites a Base method with different functionality
|
||||
# mean{N,T<:Real}(ps::StaticArrays.SVector{N,T}...) = sum(ps) / length(ps) # I also could not see this used anywhere, and it's type piracy - implementing a NaNMath version for this would just involve converting to a standard array
|
||||
|
||||
@deprecate curve_points coords
|
||||
|
||||
coords(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, range(range..., stop=n, length=50))
|
||||
coords(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, Base.range(range..., length=n))
|
||||
|
||||
# build a BezierCurve which leaves point p vertically upwards and arrives point q vertically upwards.
|
||||
# may create a loop if necessary. Assumes the view is [0,1]
|
||||
|
||||
+65
-14
@@ -86,8 +86,9 @@ yaxis!("YLABEL", :log10)
|
||||
PlotExample("Images",
|
||||
"Plot an image. y-axis is set to flipped",
|
||||
[:(begin
|
||||
import FileIO, PlotReferenceImages
|
||||
img = FileIO.load(joinpath(dirname(pathof(PlotReferenceImages)), "..", "Plots","pyplot","0.7.0","ref1.png"))
|
||||
import FileIO
|
||||
path = download("http://juliaplots.org/PlotReferenceImages.jl/Plots/pyplot/0.7.0/ref1.png")
|
||||
img = FileIO.load(path)
|
||||
plot(img)
|
||||
end)]
|
||||
),
|
||||
@@ -164,7 +165,7 @@ PlotExample("Marker types",
|
||||
),
|
||||
|
||||
PlotExample("Bar",
|
||||
"x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)",
|
||||
"`x` is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)",
|
||||
[:(begin
|
||||
bar(randn(99))
|
||||
end)]
|
||||
@@ -237,12 +238,12 @@ build with the method `text(string, attr...)`, which wraps font and color attrib
|
||||
""",
|
||||
[:(begin
|
||||
y = rand(10)
|
||||
plot(y, annotations = (3,y[3],text("this is #3",:left)), leg=false)
|
||||
annotate!([(5, y[5], text("this is #5",16,:red,:center)),
|
||||
(10, y[10], text("this is #10",:right,20,"courier"))])
|
||||
plot(y, annotations = (3,y[3], Plots.text("this is #3",:left)), leg=false)
|
||||
annotate!([(5, y[5], Plots.text("this is #5",16,:red,:center)),
|
||||
(10, y[10], Plots.text("this is #10",:right,20,"courier"))])
|
||||
scatter!(range(2, stop=8, length=6), rand(6), marker=(50,0.2,:orange),
|
||||
series_annotations = ["series","annotations","map","to","series",
|
||||
text("data",:green)])
|
||||
Plots.text("data",:green)])
|
||||
end)]
|
||||
),
|
||||
|
||||
@@ -304,7 +305,8 @@ PlotExample("3D",
|
||||
|
||||
PlotExample("DataFrames",
|
||||
"Plot using DataFrame column symbols.",
|
||||
[:(begin
|
||||
[:(using StatsPlots), # can't be inside begin block because @df gets expanded first
|
||||
:(begin
|
||||
import RDatasets
|
||||
iris = RDatasets.dataset("datasets", "iris")
|
||||
@df iris scatter(:SepalLength, :SepalWidth, group=:Species,
|
||||
@@ -353,7 +355,8 @@ PlotExample("Layouts, margins, label rotation, title location",
|
||||
|
||||
PlotExample("Boxplot and Violin series recipes",
|
||||
"",
|
||||
[:(begin
|
||||
[:(using StatsPlots), # can't be inside begin block because @df gets expanded first
|
||||
:(begin
|
||||
import RDatasets
|
||||
singers = RDatasets.dataset("lattice", "singer")
|
||||
@df singers violin(:VoicePart, :Height, line = 0, fill = (0.2, :blue))
|
||||
@@ -453,6 +456,49 @@ see: http://stackoverflow.com/a/37732384/5075246
|
||||
end)]
|
||||
),
|
||||
|
||||
PlotExample("Ribbons",
|
||||
"""
|
||||
Ribbons can be added to lines via the `ribbon` keyword;
|
||||
you can pass a tuple of arrays (upper and lower bounds),
|
||||
a single Array (for symmetric ribbons), a Function, or a number.
|
||||
""",
|
||||
[:(begin
|
||||
plot(
|
||||
plot(0:10; ribbon = (LinRange(0, 2, 10), LinRange(0, 1, 10))),
|
||||
plot(0:10; ribbon = 0:0.5:5),
|
||||
plot(0:10; ribbon = sqrt),
|
||||
plot(0:10; ribbon = 1),
|
||||
)
|
||||
end)]
|
||||
),
|
||||
|
||||
PlotExample("Histogram2D (complex values)",
|
||||
"",
|
||||
[:(begin
|
||||
n = 10_000
|
||||
x = exp.(0.1randn(n) .+ randn(n).*(im))
|
||||
histogram2d(x, nbins=(20,40), show_empty_bins=true,
|
||||
normed=true, aspect_ratio=1)
|
||||
end)]
|
||||
),
|
||||
|
||||
PlotExample("Unconnected lines using `missing` or `NaN`",
|
||||
"""
|
||||
Missing values and non-finite values, including `NaN`, are not plotted.
|
||||
Instead, lines are separated into segments at these values.
|
||||
""",
|
||||
[:(begin
|
||||
x,y = [1,2,2,1,1], [1,2,1,2,1]
|
||||
plot(
|
||||
plot([rand(5); NaN; rand(5); NaN; rand(5)]),
|
||||
plot([1,missing,2,3], marker=true),
|
||||
plot([x; NaN; x.+2], [y; NaN; y.+1], arrow=2),
|
||||
plot([1, 2+3im, Inf, 4im, 3, -Inf*im, 0, 3+3im], marker=true),
|
||||
legend=false
|
||||
)
|
||||
end)]
|
||||
),
|
||||
|
||||
]
|
||||
|
||||
# Some constants for PlotDocs and PlotReferenceImages
|
||||
@@ -460,7 +506,7 @@ _animation_examples = [2, 30]
|
||||
_backend_skips = Dict(
|
||||
:gr => [25, 30],
|
||||
:pyplot => [25, 30],
|
||||
:plotlyjs => [2, 21, 25, 30, 31],
|
||||
:plotlyjs => [2, 21, 24, 25, 30, 31],
|
||||
:pgfplots => [2, 5, 6, 10, 16, 20, 22, 23, 25, 28, 30],
|
||||
)
|
||||
|
||||
@@ -474,7 +520,12 @@ function test_examples(pkgname::Symbol, idx::Int; debug = false, disp = true)
|
||||
@info("Testing plot: $pkgname:$idx:$(_examples[idx].header)")
|
||||
backend(pkgname)
|
||||
backend()
|
||||
map(eval, _examples[idx].exprs)
|
||||
|
||||
# prevent leaking variables (esp. functions) directly into Plots namespace
|
||||
m = Module(:PlotExampleModule)
|
||||
Base.eval(m, :(using Plots))
|
||||
map(exprs -> Base.eval(m, exprs), _examples[idx].exprs)
|
||||
|
||||
plt = current()
|
||||
if disp
|
||||
gui(plt)
|
||||
@@ -494,8 +545,8 @@ function test_examples(pkgname::Symbol; debug = false, disp = true, sleep = noth
|
||||
skip = [], only = nothing)
|
||||
Plots._debugMode.on = debug
|
||||
plts = Dict()
|
||||
for i in 1:length(_examples)
|
||||
only != nothing && !(i in only) && continue
|
||||
for i in eachindex(_examples)
|
||||
only !== nothing && !(i in only) && continue
|
||||
i in skip && continue
|
||||
try
|
||||
plt = test_examples(pkgname, i, debug=debug, disp=disp)
|
||||
@@ -504,7 +555,7 @@ function test_examples(pkgname::Symbol; debug = false, disp = true, sleep = noth
|
||||
# TODO: put error info into markdown?
|
||||
@warn("Example $pkgname:$i:$(_examples[i].header) failed with: $ex")
|
||||
end
|
||||
if sleep != nothing
|
||||
if sleep !== nothing
|
||||
Base.sleep(sleep)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# ---------------------------------------------------------
|
||||
# A backup, if no PNG generation is defined, is to try to make a PDF and use FileIO to convert
|
||||
|
||||
_fileio_load(@nospecialize(filename::AbstractString)) = FileIO.load(filename::AbstractString)
|
||||
_fileio_save(@nospecialize(filename::AbstractString), @nospecialize(x)) = FileIO.save(filename::AbstractString, x)
|
||||
|
||||
function _show_pdfbackends(io::IO, ::MIME"image/png", plt::Plot)
|
||||
fn = tempname()
|
||||
|
||||
# first save a pdf file
|
||||
pdf(plt, fn)
|
||||
|
||||
# load that pdf into a FileIO Stream
|
||||
s = _fileio_load(fn * ".pdf")
|
||||
|
||||
# save a png
|
||||
pngfn = fn * ".png"
|
||||
_fileio_save(pngfn, s)
|
||||
|
||||
# now write from the file
|
||||
write(io, read(open(pngfn), String))
|
||||
end
|
||||
|
||||
const PDFBackends = Union{PGFPlotsBackend,PlotlyJSBackend,PyPlotBackend,InspectDRBackend,GRBackend}
|
||||
@@ -0,0 +1,62 @@
|
||||
const use_local_dependencies = Ref(false)
|
||||
const use_local_plotlyjs = Ref(false)
|
||||
|
||||
|
||||
function _init_ijulia_plotting()
|
||||
# IJulia is more stable with local file
|
||||
use_local_plotlyjs[] = isfile(plotly_local_file_path)
|
||||
|
||||
ENV["MPLBACKEND"] = "Agg"
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
Add extra jupyter mimetypes to display_dict based on the plot backed.
|
||||
|
||||
The default is nothing, except for plotly based backends, where it
|
||||
adds data for `application/vnd.plotly.v1+json` that is used in
|
||||
frontends like jupyterlab and nteract.
|
||||
"""
|
||||
_ijulia__extra_mime_info!(plt::Plot, out::Dict) = out
|
||||
|
||||
function _ijulia__extra_mime_info!(plt::Plot{PlotlyJSBackend}, out::Dict)
|
||||
out["application/vnd.plotly.v1+json"] = Dict(
|
||||
:data => plotly_series(plt),
|
||||
:layout => plotly_layout(plt)
|
||||
)
|
||||
out
|
||||
end
|
||||
|
||||
function _ijulia__extra_mime_info!(plt::Plot{PlotlyBackend}, out::Dict)
|
||||
out["application/vnd.plotly.v1+json"] = Dict(
|
||||
:data => plotly_series(plt),
|
||||
:layout => plotly_layout(plt)
|
||||
)
|
||||
out
|
||||
end
|
||||
|
||||
|
||||
function _ijulia_display_dict(plt::Plot)
|
||||
output_type = Symbol(plt.attr[:html_output_format])
|
||||
if output_type == :auto
|
||||
output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
|
||||
end
|
||||
out = Dict()
|
||||
if output_type == :txt
|
||||
mime = "text/plain"
|
||||
out[mime] = sprint(show, MIME(mime), plt)
|
||||
elseif output_type == :png
|
||||
mime = "image/png"
|
||||
out[mime] = base64encode(show, MIME(mime), plt)
|
||||
elseif output_type == :svg
|
||||
mime = "image/svg+xml"
|
||||
out[mime] = sprint(show, MIME(mime), plt)
|
||||
elseif output_type == :html
|
||||
mime = "text/html"
|
||||
out[mime] = sprint(show, MIME(mime), plt)
|
||||
else
|
||||
error("Unsupported output type $output_type")
|
||||
end
|
||||
_ijulia__extra_mime_info!(plt, out)
|
||||
out
|
||||
end
|
||||
+69
-91
@@ -1,16 +1,22 @@
|
||||
using REPL
|
||||
|
||||
const use_local_dependencies = Ref(false)
|
||||
|
||||
function _plots_defaults()
|
||||
if isdefined(Main, :PLOTS_DEFAULTS)
|
||||
Dict{Symbol,Any}(Main.PLOTS_DEFAULTS)
|
||||
else
|
||||
Dict{Symbol,Any}()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function __init__()
|
||||
|
||||
if isdefined(Main, :PLOTS_DEFAULTS)
|
||||
if haskey(Main.PLOTS_DEFAULTS, :theme)
|
||||
theme(Main.PLOTS_DEFAULTS[:theme])
|
||||
end
|
||||
for (k,v) in Main.PLOTS_DEFAULTS
|
||||
k == :theme || default(k, v)
|
||||
end
|
||||
user_defaults = _plots_defaults()
|
||||
if haskey(user_defaults, :theme)
|
||||
theme(user_defaults[:theme])
|
||||
end
|
||||
for (k,v) in user_defaults
|
||||
k == :theme || default(k, v)
|
||||
end
|
||||
|
||||
insert!(Base.Multimedia.displays, findlast(x -> x isa Base.TextDisplay || x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, PlotsDisplay())
|
||||
@@ -22,102 +28,74 @@ function __init__()
|
||||
insert!(Base.Multimedia.displays, findlast(x -> x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, PlotsDisplay())
|
||||
end)
|
||||
|
||||
@require HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" include(joinpath(@__DIR__, "backends", "hdf5.jl"))
|
||||
@require InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d" include(joinpath(@__DIR__, "backends", "inspectdr.jl"))
|
||||
@require PGFPlots = "3b7a836e-365b-5785-a47d-02c71176b4aa" include(joinpath(@__DIR__, "backends", "pgfplots.jl"))
|
||||
@require PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" include(joinpath(@__DIR__, "backends", "plotlyjs.jl"))
|
||||
@require PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" include(joinpath(@__DIR__, "backends", "pyplot.jl"))
|
||||
@require UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" include(joinpath(@__DIR__, "backends", "unicodeplots.jl"))
|
||||
@require HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" begin
|
||||
fn = joinpath(@__DIR__, "backends", "hdf5.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
@require InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d" begin
|
||||
fn = joinpath(@__DIR__, "backends", "inspectdr.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
@require PGFPlots = "3b7a836e-365b-5785-a47d-02c71176b4aa" begin
|
||||
fn = joinpath(@__DIR__, "backends", "pgfplots.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
@require ORCA = "47be7bcc-f1a6-5447-8b36-7eeeff7534fd" begin
|
||||
fn = joinpath(@__DIR__, "backends", "orca.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
@require PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925" begin
|
||||
fn = joinpath(@__DIR__, "backends", "pgfplotsx.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
@require PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" begin
|
||||
fn = joinpath(@__DIR__, "backends", "plotlyjs.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
@require PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" begin
|
||||
fn = joinpath(@__DIR__, "backends", "pyplot.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
@require UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" begin
|
||||
fn = joinpath(@__DIR__, "backends", "unicodeplots.jl")
|
||||
include(fn)
|
||||
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# IJulia
|
||||
# ---------------------------------------------------------
|
||||
use_local = false
|
||||
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
|
||||
if IJulia.inited
|
||||
# IJulia is more stable with local file
|
||||
use_local = isfile(plotly_local_file_path)
|
||||
"""
|
||||
Add extra jupyter mimetypes to display_dict based on the plot backed.
|
||||
_init_ijulia_plotting()
|
||||
|
||||
The default is nothing, except for plotly based backends, where it
|
||||
adds data for `application/vnd.plotly.v1+json` that is used in
|
||||
frontends like jupyterlab and nteract.
|
||||
"""
|
||||
_extra_mime_info!(plt::Plot, out::Dict) = out
|
||||
function _extra_mime_info!(plt::Plot{PlotlyJSBackend}, out::Dict)
|
||||
out["application/vnd.plotly.v1+json"] = JSON.lower(plt.o)
|
||||
out
|
||||
end
|
||||
|
||||
function _extra_mime_info!(plt::Plot{PlotlyBackend}, out::Dict)
|
||||
out["application/vnd.plotly.v1+json"] = Dict(
|
||||
:data => plotly_series(plt),
|
||||
:layout => plotly_layout(plt)
|
||||
)
|
||||
out
|
||||
end
|
||||
|
||||
function IJulia.display_dict(plt::Plot)
|
||||
output_type = Symbol(plt.attr[:html_output_format])
|
||||
if output_type == :auto
|
||||
output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
|
||||
end
|
||||
out = Dict()
|
||||
if output_type == :txt
|
||||
mime = "text/plain"
|
||||
out[mime] = sprint(show, MIME(mime), plt)
|
||||
elseif output_type == :png
|
||||
mime = "image/png"
|
||||
out[mime] = base64encode(show, MIME(mime), plt)
|
||||
elseif output_type == :svg
|
||||
mime = "image/svg+xml"
|
||||
out[mime] = sprint(show, MIME(mime), plt)
|
||||
elseif output_type == :html
|
||||
mime = "text/html"
|
||||
out[mime] = sprint(show, MIME(mime), plt)
|
||||
else
|
||||
error("Unsupported output type $output_type")
|
||||
end
|
||||
_extra_mime_info!(plt, out)
|
||||
out
|
||||
end
|
||||
|
||||
ENV["MPLBACKEND"] = "Agg"
|
||||
IJulia.display_dict(plt::Plot) = _ijulia_display_dict(plt)
|
||||
end
|
||||
end
|
||||
|
||||
if haskey(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL")
|
||||
use_local = ENV["PLOTS_HOST_DEPENDENCY_LOCAL"] == "true"
|
||||
use_local_dependencies[] = isfile(plotly_local_file_path) && use_local
|
||||
if use_local && !isfile(plotly_local_file_path)
|
||||
use_local_plotlyjs[] = ENV["PLOTS_HOST_DEPENDENCY_LOCAL"] == "true"
|
||||
use_local_dependencies[] = isfile(plotly_local_file_path) && use_local_plotlyjs[]
|
||||
if use_local_plotlyjs[] && !isfile(plotly_local_file_path)
|
||||
@warn("PLOTS_HOST_DEPENDENCY_LOCAL is set to true, but no local plotly file found. run Pkg.build(\"Plots\") and make sure PLOTS_HOST_DEPENDENCY_LOCAL is set to true")
|
||||
end
|
||||
else
|
||||
use_local_dependencies[] = use_local
|
||||
use_local_dependencies[] = use_local_plotlyjs[]
|
||||
end
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# A backup, if no PNG generation is defined, is to try to make a PDF and use FileIO to convert
|
||||
@require FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" begin
|
||||
PDFBackends = Union{PGFPlotsBackend,PlotlyJSBackend,PyPlotBackend,InspectDRBackend,GRBackend}
|
||||
function _show(io::IO, ::MIME"image/png", plt::Plot{<:PDFBackends})
|
||||
fn = tempname()
|
||||
|
||||
# first save a pdf file
|
||||
pdf(plt, fn)
|
||||
|
||||
# load that pdf into a FileIO Stream
|
||||
s = FileIO.load(fn * ".pdf")
|
||||
|
||||
# save a png
|
||||
pngfn = fn * ".png"
|
||||
FileIO.save(pngfn, s)
|
||||
|
||||
# now write from the file
|
||||
write(io, read(open(pngfn), String))
|
||||
end
|
||||
_show(io::IO, mime::MIME"image/png", plt::Plot{<:PDFBackends}) = _show_pdfbackends(io, mime, plt)
|
||||
end
|
||||
end
|
||||
|
||||
+22
-5
@@ -107,11 +107,10 @@ function resolve_mixed(mix::MixedMeasures, sp::Subplot, letter::Symbol)
|
||||
if mix.len != 0mm
|
||||
f = (letter == :x ? width : height)
|
||||
totlen = f(plotarea(sp))
|
||||
@show totlen
|
||||
pct += mix.len / totlen
|
||||
end
|
||||
if pct != 0
|
||||
amin, amax = axis_limits(sp[Symbol(letter,:axis)])
|
||||
amin, amax = axis_limits(sp, letter)
|
||||
xy += pct * (amax-amin)
|
||||
end
|
||||
xy
|
||||
@@ -218,6 +217,7 @@ bottompad(layout::AbstractLayout) = 0mm
|
||||
# this is the parent of the top-level layout
|
||||
struct RootLayout <: AbstractLayout end
|
||||
|
||||
Base.show(io::IO, layout::RootLayout) = Base.show_default(io, layout)
|
||||
Base.parent(::RootLayout) = nothing
|
||||
parent_bbox(::RootLayout) = defaultbox
|
||||
bbox(::RootLayout) = defaultbox
|
||||
@@ -469,7 +469,7 @@ function layout_args(plotattributes::KW)
|
||||
end
|
||||
|
||||
function layout_args(plotattributes::KW, n_override::Integer)
|
||||
layout, n = layout_args(get(plotattributes, :layout, n_override))
|
||||
layout, n = layout_args(n_override, get(plotattributes, :layout, n_override))
|
||||
if n != n_override
|
||||
error("When doing layout, n ($n) != n_override ($(n_override)). You're probably trying to force existing plots into a layout that doesn't fit them.")
|
||||
end
|
||||
@@ -481,12 +481,27 @@ function layout_args(n::Integer)
|
||||
GridLayout(nr, nc), n
|
||||
end
|
||||
|
||||
function layout_args(sztup::NTuple{2,I}) where I<:Integer
|
||||
function layout_args(sztup::NTuple{2, Integer})
|
||||
nr, nc = sztup
|
||||
GridLayout(nr, nc), nr*nc
|
||||
end
|
||||
|
||||
function layout_args(sztup::NTuple{3,I}) where I<:Integer
|
||||
layout_args(n_override::Integer, n::Integer) = layout_args(n)
|
||||
layout_args(n, sztup::NTuple{2, Integer}) = layout_args(sztup)
|
||||
|
||||
function layout_args(n, sztup::Tuple{Colon, Integer})
|
||||
nc = sztup[2]
|
||||
nr = ceil(Int, n / nc)
|
||||
GridLayout(nr, nc), n
|
||||
end
|
||||
|
||||
function layout_args(n, sztup::Tuple{Integer, Colon})
|
||||
nr = sztup[1]
|
||||
nc = ceil(Int, n / nr)
|
||||
GridLayout(nr, nc), n
|
||||
end
|
||||
|
||||
function layout_args(sztup::NTuple{3, Integer})
|
||||
n, nr, nc = sztup
|
||||
nr, nc = compute_gridsize(n, nr, nc)
|
||||
GridLayout(nr, nc), n
|
||||
@@ -499,6 +514,8 @@ function layout_args(layout::GridLayout)
|
||||
layout, n
|
||||
end
|
||||
|
||||
layout_args(n_override::Integer, layout::GridLayout) = layout_args(layout)
|
||||
|
||||
layout_args(huh) = error("unhandled layout type $(typeof(huh)): $huh")
|
||||
|
||||
|
||||
|
||||
+12
-7
@@ -55,9 +55,7 @@ tex(fn::AbstractString) = tex(current(), fn)
|
||||
function html(plt::Plot, fn::AbstractString)
|
||||
fn = addExtension(fn, "html")
|
||||
io = open(fn, "w")
|
||||
_use_remote[] = true
|
||||
show(io, MIME("text/html"), plt)
|
||||
_use_remote[] = false
|
||||
close(io)
|
||||
end
|
||||
html(fn::AbstractString) = html(current(), fn)
|
||||
@@ -74,6 +72,7 @@ const _savemap = Dict(
|
||||
"eps" => eps,
|
||||
"tex" => tex,
|
||||
"html" => html,
|
||||
"tikz" => tex,
|
||||
)
|
||||
|
||||
function getExtension(fn::AbstractString)
|
||||
@@ -105,7 +104,7 @@ type is inferred from the file extension. All backends support png and pdf
|
||||
file types, some also support svg, ps, eps, html and tex.
|
||||
"""
|
||||
function savefig(plt::Plot, fn::AbstractString)
|
||||
|
||||
fn = abspath(expanduser(fn))
|
||||
# get the extension
|
||||
local ext
|
||||
try
|
||||
@@ -191,7 +190,7 @@ end
|
||||
# for writing to io streams... first prepare, then callback
|
||||
for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml",
|
||||
"application/eps", "application/pdf", "application/postscript",
|
||||
"application/x-tex")
|
||||
"application/x-tex", "application/vnd.plotly.v1+json")
|
||||
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
|
||||
if haskey(io, :juno_plotsize)
|
||||
showjuno(io, m, plt)
|
||||
@@ -199,9 +198,12 @@ for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml
|
||||
prepare_output(plt)
|
||||
_show(io, m, plt)
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
end
|
||||
|
||||
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) = showjuno(io, MIME("text/html"), plt)
|
||||
|
||||
# default text/plain for all backends
|
||||
_show(io::IO, ::MIME{Symbol("text/plain")}, plt::Plot) = show(io, plt)
|
||||
|
||||
@@ -230,15 +232,16 @@ closeall() = closeall(backend())
|
||||
# Atom PlotPane
|
||||
# ---------------------------------------------------------
|
||||
function showjuno(io::IO, m, plt)
|
||||
sz = plt[:size]
|
||||
sz = collect(plt[:size])
|
||||
dpi = plt[:dpi]
|
||||
thickness_scaling = plt[:thickness_scaling]
|
||||
|
||||
jsize = get(io, :juno_plotsize, [400, 500])
|
||||
jratio = get(io, :juno_dpi_ratio, 1)
|
||||
|
||||
scale = minimum(jsize[i] / sz[i] for i in 1:2)
|
||||
plt[:size] = (s * scale for s in sz)
|
||||
plt[:dpi] = Plots.DPI
|
||||
plt[:size] = [s * scale for s in sz]
|
||||
plt[:dpi] = jratio*Plots.DPI
|
||||
plt[:thickness_scaling] *= scale
|
||||
|
||||
prepare_output(plt)
|
||||
@@ -259,4 +262,6 @@ function _showjuno(io::IO, m::MIME"image/svg+xml", plt)
|
||||
end
|
||||
end
|
||||
|
||||
Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot) = showable(MIME"text/html"(), plt)
|
||||
|
||||
_showjuno(io::IO, m, plt) = _show(io, m, plt)
|
||||
|
||||
+4
-4
@@ -12,7 +12,7 @@ function _expand_seriestype_array(plotattributes::KW, args)
|
||||
if typeof(sts) <: AbstractArray
|
||||
delete!(plotattributes, :seriestype)
|
||||
rd = Vector{RecipeData}(undef, size(sts, 1))
|
||||
for r in 1:size(sts, 1)
|
||||
for r in axes(sts, 1)
|
||||
dc = copy(plotattributes)
|
||||
dc[:seriestype] = sts[r:r,:]
|
||||
rd[r] = RecipeData(dc, args)
|
||||
@@ -126,7 +126,7 @@ function _preprocess_userrecipe(kw::KW)
|
||||
end
|
||||
|
||||
# convert a ribbon into a fillrange
|
||||
if get(kw, :ribbon, nothing) != nothing
|
||||
if get(kw, :ribbon, nothing) !== nothing
|
||||
make_fillrange_from_ribbon(kw)
|
||||
end
|
||||
return
|
||||
@@ -136,7 +136,7 @@ function _add_errorbar_kw(kw_list::Vector{KW}, kw::KW)
|
||||
# handle error bars by creating new recipedata data... these will have
|
||||
# the same recipedata index as the recipedata they are copied from
|
||||
for esym in (:xerror, :yerror)
|
||||
if get(kw, esym, nothing) != nothing
|
||||
if get(kw, esym, nothing) !== nothing
|
||||
# we make a copy of the KW and apply an errorbar recipe
|
||||
errkw = copy(kw)
|
||||
errkw[:seriestype] = esym
|
||||
@@ -227,7 +227,7 @@ function _plot_setup(plt::Plot, plotattributes::KW, kw_list::Vector{KW})
|
||||
|
||||
# handle inset subplots
|
||||
insets = plt[:inset_subplots]
|
||||
if insets != nothing
|
||||
if insets !== nothing
|
||||
if !(typeof(insets) <: AVec)
|
||||
insets = [insets]
|
||||
end
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@ mutable struct CurrentPlot
|
||||
end
|
||||
const CURRENT_PLOT = CurrentPlot(nothing)
|
||||
|
||||
isplotnull() = CURRENT_PLOT.nullableplot == nothing
|
||||
isplotnull() = CURRENT_PLOT.nullableplot === nothing
|
||||
|
||||
"""
|
||||
current()
|
||||
@@ -166,9 +166,9 @@ end
|
||||
function _plot!(plt::Plot, plotattributes::KW, args::Tuple)
|
||||
plotattributes[:plot_object] = plt
|
||||
|
||||
if !isempty(args) && !isdefined(Main, :StatPlots) &&
|
||||
if !isempty(args) && !isdefined(Main, :StatsPlots) &&
|
||||
first(split(string(typeof(args[1])), ".")) == "DataFrames"
|
||||
@warn("You're trying to plot a DataFrame, but this functionality is provided by StatPlots")
|
||||
@warn("You're trying to plot a DataFrame, but this functionality is provided by StatsPlots")
|
||||
end
|
||||
|
||||
# --------------------------------
|
||||
|
||||
+7
-2
@@ -50,8 +50,13 @@ function plotattr(attrtype::Symbol, attribute::AbstractString)
|
||||
|
||||
desc = get(_arg_desc, attribute, "")
|
||||
first_period_idx = findfirst(isequal('.'), desc)
|
||||
typedesc = desc[1:first_period_idx-1]
|
||||
desc = strip(desc[first_period_idx+1:end])
|
||||
if isnothing(first_period_idx)
|
||||
typedesc = ""
|
||||
desc = strip(desc)
|
||||
else
|
||||
typedesc = desc[1:first_period_idx-1]
|
||||
desc = strip(desc[first_period_idx+1:end])
|
||||
end
|
||||
als = keys(filter(x->x[2]==attribute, _keyAliases)) |> collect |> sort
|
||||
als = join(map(string,als), ", ")
|
||||
def = _attribute_defaults[attrtype][attribute]
|
||||
|
||||
@@ -1,3 +1,873 @@
|
||||
function _precompile_()
|
||||
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
|
||||
isdefined(Plots, Symbol("#@layout")) && precompile(Tuple{getfield(Plots, Symbol("#@layout")), LineNumberNode, Module, Expr})
|
||||
isdefined(Plots, Symbol("#kw##_make_hist")) && precompile(Tuple{getfield(Plots, Symbol("#kw##_make_hist")), NamedTuple{(:normed, :weights), Tuple{Bool, Array{Int64, 1}}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}}, Symbol})
|
||||
isdefined(Plots, Symbol("#kw##_make_hist")) && precompile(Tuple{getfield(Plots, Symbol("#kw##_make_hist")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
|
||||
isdefined(Plots, Symbol("#kw##_make_hist")) && precompile(Tuple{getfield(Plots, Symbol("#kw##_make_hist")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Tuple{Int64, Int64}})
|
||||
isdefined(Plots, Symbol("#kw##_make_hist")) && precompile(Tuple{getfield(Plots, Symbol("#kw##_make_hist")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}}, Symbol})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:flip,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:foreground_color_grid, :grid, :gridalpha, :gridstyle, :gridlinewidth), Tuple{ColorTypes.RGBA{Float64}, Bool, Float64, Symbol, Int64}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:formatter,), Tuple{Symbol}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Int64, Int64}, Bool}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid, :ticks), Tuple{Bool, Nothing}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:guide,), Tuple{String}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:lims, :flip, :ticks, :guide), Tuple{Tuple{Int64, Int64}, Bool, Base.StepRange{Int64, Int64}, String}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:rotation,), Tuple{Int64}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:scale, :guide), Tuple{Symbol, String}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:ticks,), Tuple{Base.UnitRange{Int64}}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:ticks,), Tuple{Nothing}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#kw##contour")) && precompile(Tuple{getfield(Plots, Symbol("#kw##contour")), NamedTuple{(:fill,), Tuple{Bool}}, typeof(Plots.contour), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
|
||||
isdefined(Plots, Symbol("#kw##gr_polyline")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_polyline")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}})
|
||||
isdefined(Plots, Symbol("#kw##gr_polyline")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_polyline")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Array{Int64, 1}, Array{Float64, 1}})
|
||||
isdefined(Plots, Symbol("#kw##gr_polyline")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_polyline")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Base.UnitRange{Int64}, Array{Float64, 1}})
|
||||
isdefined(Plots, Symbol("#kw##gr_set_font")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_set_font")), NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}}, typeof(Plots.gr_set_font), Plots.Font})
|
||||
isdefined(Plots, Symbol("#kw##gr_set_font")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_set_font")), NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}}, typeof(Plots.gr_set_font), Plots.Font})
|
||||
isdefined(Plots, Symbol("#kw##heatmap")) && precompile(Tuple{getfield(Plots, Symbol("#kw##heatmap")), NamedTuple{(:aspect_ratio,), Tuple{Int64}}, typeof(Plots.heatmap), Array{String, 1}, Int})
|
||||
isdefined(Plots, Symbol("#kw##histogram")) && precompile(Tuple{getfield(Plots, Symbol("#kw##histogram")), NamedTuple{(:bins, :weights), Tuple{Symbol, Array{Int64, 1}}}, typeof(Plots.histogram), Array{Float64, 1}})
|
||||
isdefined(Plots, Symbol("#kw##histogram2d")) && precompile(Tuple{getfield(Plots, Symbol("#kw##histogram2d")), NamedTuple{(:nbins, :show_empty_bins, :normed, :aspect_ratio), Tuple{Tuple{Int64, Int64}, Bool, Bool, Int64}}, typeof(Plots.histogram2d), Array{Base.Complex{Float64}, 1}})
|
||||
isdefined(Plots, Symbol("#kw##histogram2d")) && precompile(Tuple{getfield(Plots, Symbol("#kw##histogram2d")), NamedTuple{(:nbins,), Tuple{Int64}}, typeof(Plots.histogram2d), Array{Float64, 1}, Array{Float64, 1}})
|
||||
isdefined(Plots, Symbol("#kw##hline!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##hline!")), NamedTuple{(:line,), Tuple{Tuple{Int64, Symbol, Float64, Array{Symbol, 2}}}}, typeof(Plots.hline!), Array{Float64, 2}})
|
||||
isdefined(Plots, Symbol("#kw##pie")) && precompile(Tuple{getfield(Plots, Symbol("#kw##pie")), NamedTuple{(:title, :l), Tuple{String, Float64}}, typeof(Plots.pie), Array{String, 1}, Int})
|
||||
isdefined(Plots, Symbol("#kw##portfoliocomposition")) && precompile(Tuple{getfield(Plots, Symbol("#kw##portfoliocomposition")), NamedTuple{(:labels,), Tuple{Array{String, 2}}}, typeof(Plots.portfoliocomposition), Array{Float64, 2}, Int})
|
||||
isdefined(Plots, Symbol("#kw##scatter!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter!")), NamedTuple{(:marker, :series_annotations), Tuple{Tuple{Int64, Float64, Symbol}, Array{Any, 1}}}, typeof(Plots.scatter!), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
|
||||
isdefined(Plots, Symbol("#kw##scatter!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter!")), NamedTuple{(:markersize, :c), Tuple{Int64, Symbol}}, typeof(Plots.scatter!), Array{Float64, 1}})
|
||||
isdefined(Plots, Symbol("#kw##scatter!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter!")), NamedTuple{(:zcolor, :m, :ms, :lab), Tuple{Array{Float64, 1}, Tuple{Symbol, Float64, Plots.Stroke}, Array{Float64, 1}, String}}, typeof(Plots.scatter!), Array{Float64, 1}})
|
||||
isdefined(Plots, Symbol("#kw##scatter")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter")), NamedTuple{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks), Tuple{Array{Symbol, 2}, Array{String, 2}, Base.ReshapedArray{Int64, 2, Base.UnitRange{Int64}, Tuple{}}, Int64, String, Int64, Base.UnitRange{Int64}}}, typeof(Plots.scatter), Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
|
||||
isdefined(Plots, Symbol("#kw##scatter")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter")), NamedTuple{(:m, :lab, :bg, :xlim, :ylim), Tuple{Tuple{Int64, Symbol}, Array{String, 2}, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}}}, typeof(Plots.scatter), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
|
||||
isdefined(Plots, Symbol("#kw##test_examples")) && precompile(Tuple{getfield(Plots, Symbol("#kw##test_examples")), NamedTuple{(:disp,), Tuple{Bool}}, typeof(Plots.test_examples), Symbol})
|
||||
precompile(Tuple{typeof(Plots.__init__)})
|
||||
precompile(Tuple{typeof(Plots._add_defaults!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
|
||||
precompile(Tuple{typeof(Plots._add_defaults!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
|
||||
precompile(Tuple{typeof(Plots._add_errorbar_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._add_errorbar_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._add_markershape), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._add_markershape), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._add_smooth_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._add_smooth_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Array{Float64, 1}, 1}})
|
||||
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Array{T, 1} where T, 1}})
|
||||
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Function, 1}})
|
||||
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Function, 1}})
|
||||
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{String, 1}})
|
||||
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Union{Base.Missing, Int64}, 1}})
|
||||
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, typeof(identity)})
|
||||
precompile(Tuple{typeof(Plots._backend_instance), Symbol})
|
||||
precompile(Tuple{typeof(Plots._backend_instance), Symbol})
|
||||
precompile(Tuple{typeof(Plots._bin_centers), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots._binbarlike_baseline), Float64, Symbol})
|
||||
precompile(Tuple{typeof(Plots._cbar_unique), Array{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, 1}, String})
|
||||
precompile(Tuple{typeof(Plots._cbar_unique), Array{Int64, 1}, String})
|
||||
precompile(Tuple{typeof(Plots._cbar_unique), Array{Nothing, 1}, String})
|
||||
precompile(Tuple{typeof(Plots._cbar_unique), Array{PlotUtils.ColorGradient, 1}, String})
|
||||
precompile(Tuple{typeof(Plots._cbar_unique), Array{Symbol, 1}, String})
|
||||
precompile(Tuple{typeof(Plots._create_backend_figure), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._cycle), Array{Any, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Base.StepRange{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Base.UnitRange{Int64}})
|
||||
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Array{Plots.Subplot{T} where T<:RecipesBase.AbstractBackend, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Array{String, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Base.OneTo{Int64}, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots._cycle), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Base.StepRange{Int64, Int64}, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), ColorTypes.RGBA{Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Float64, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Int64, Base.StepRange{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots._cycle), Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Nothing, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Plots.Shape, Int64})
|
||||
precompile(Tuple{typeof(Plots._cycle), Symbol, Int64})
|
||||
precompile(Tuple{typeof(Plots._display), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._display), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Bool})
|
||||
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Bool})
|
||||
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Symbol})
|
||||
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Symbol})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Array{T, 1} where T, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Base.Complex{Float64}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Function, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Function, 1}, Int64}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Int64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Plots.OHLC{T} where T<:Real, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{String, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Union{Base.Missing, Int64}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.UnitRange{Int64}}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Plots.PortfolioComposition}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Plots.Spy}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, typeof(Base.log), Int64}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{}})
|
||||
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{}})
|
||||
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots._filter_input_data!), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._heatmap_edges), Array{Float64, 1}, Bool})
|
||||
precompile(Tuple{typeof(Plots._hist_edge), Tuple{Array{Float64, 1}}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
|
||||
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Tuple{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}}, Symbol})
|
||||
precompile(Tuple{typeof(Plots._override_seriestype_check), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots._pick_default_backend)})
|
||||
precompile(Tuple{typeof(Plots._pick_default_backend)})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
|
||||
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
|
||||
precompile(Tuple{typeof(Plots._plot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
|
||||
precompile(Tuple{typeof(Plots._plot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
|
||||
precompile(Tuple{typeof(Plots._plots_defaults)})
|
||||
precompile(Tuple{typeof(Plots._prepare_annotations), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._prepare_annotations), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Plots.Spy}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{}, Array{RecipesBase.RecipeData, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_barlike), Base.Dict{Symbol, Any}, Array{Float64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_barlike), Base.Dict{Symbol, Any}, Array{Int64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_barlike), Base.Dict{Symbol, Any}, Base.OneTo{Int64}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_binlike), Base.Dict{Symbol, Any}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_userrecipe), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._preprocess_userrecipe), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._process_plotrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}, Array{Base.Dict{Symbol, Any}, 1}})
|
||||
precompile(Tuple{typeof(Plots._process_plotrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}, Array{Base.Dict{Symbol, Any}, 1}})
|
||||
precompile(Tuple{typeof(Plots._process_seriesrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._process_seriesrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._process_seriesrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipe), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}, RecipesBase.RecipeData})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipe), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}, RecipesBase.RecipeData})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
|
||||
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
|
||||
precompile(Tuple{typeof(Plots._replace_linewidth), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._replace_linewidth), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._replace_markershape), Array{Symbol, 2}})
|
||||
precompile(Tuple{typeof(Plots._replace_markershape), Plots.Shape})
|
||||
precompile(Tuple{typeof(Plots._scale_adjusted_values), Type{Float64}, Array{Float64, 1}, Symbol})
|
||||
precompile(Tuple{typeof(Plots._series_index), Base.Dict{Symbol, Any}, Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._show), Base.IOStream, Base.Multimedia.MIME{Symbol("image/png")}, Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._show), Base.IOStream, Base.Multimedia.MIME{Symbol("image/png")}, Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._subplot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
|
||||
precompile(Tuple{typeof(Plots._subplot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
|
||||
precompile(Tuple{typeof(Plots._transform_ticks), Base.StepRange{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots._transform_ticks), Base.UnitRange{Int64}})
|
||||
precompile(Tuple{typeof(Plots._transform_ticks), Nothing})
|
||||
precompile(Tuple{typeof(Plots._transform_ticks), Symbol})
|
||||
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, Base.Dict{Symbol, Any}, Symbol, Int64})
|
||||
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, Base.Dict{Symbol, Any}, Symbol, Int64})
|
||||
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Int64})
|
||||
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Int64})
|
||||
precompile(Tuple{typeof(Plots._update_axis_colors), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots._update_axis_colors), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots._update_axis_links), Plots.Plot{Plots.GRBackend}, Plots.Axis, Symbol})
|
||||
precompile(Tuple{typeof(Plots._update_axis_links), Plots.Plot{Plots.GRBackend}, Plots.Axis, Symbol})
|
||||
precompile(Tuple{typeof(Plots._update_clims), Float64, Float64, Float64, Float64})
|
||||
precompile(Tuple{typeof(Plots._update_clims), Float64, Float64, Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.GridLayout})
|
||||
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.GridLayout})
|
||||
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots._update_series_attributes!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._update_series_attributes!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._update_series_attributes!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots._update_subplot_periphery), Plots.Subplot{Plots.GRBackend}, Array{Any, 1}})
|
||||
precompile(Tuple{typeof(Plots._update_subplot_periphery), Plots.Subplot{Plots.GRBackend}, Array{Any, 1}})
|
||||
precompile(Tuple{typeof(Plots.addExtension), String, String})
|
||||
precompile(Tuple{typeof(Plots.add_layout_pct!), Base.Dict{Symbol, Any}, Expr, Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.add_layout_pct!), Base.Dict{Symbol, Any}, Expr, Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.aliasesAndAutopick), Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Symbol}, Array{Symbol, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots.aliasesAndAutopick), Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Symbol}, Array{Symbol, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots.all3D), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.allAlphas), Int64})
|
||||
precompile(Tuple{typeof(Plots.allStyles), Int64})
|
||||
precompile(Tuple{typeof(Plots.allStyles), Symbol})
|
||||
precompile(Tuple{typeof(Plots.annotate!), Array{Tuple{Int64, Float64, Plots.PlotText}, 1}})
|
||||
precompile(Tuple{typeof(Plots.annotations), Array{Any, 1}})
|
||||
precompile(Tuple{typeof(Plots.arrow), Int64})
|
||||
precompile(Tuple{typeof(Plots.attr!), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.attr!), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.attr), Plots.EmptyLayout, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.attr), Plots.EmptyLayout, Symbol})
|
||||
precompile(Tuple{typeof(Plots.autopick), Array{ColorTypes.RGBA{Float64}, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots.autopick_ignore_none_auto), Array{Symbol, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots.axis_drawing_info), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.axis_drawing_info), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.axis_drawing_info_3d), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.axis_drawing_info_3d), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol, Bool, Bool})
|
||||
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol, Bool, Bool})
|
||||
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.backend), Plots.GRBackend})
|
||||
precompile(Tuple{typeof(Plots.backend), Symbol})
|
||||
precompile(Tuple{typeof(Plots.backend), Symbol})
|
||||
precompile(Tuple{typeof(Plots.backend)})
|
||||
precompile(Tuple{typeof(Plots.backend)})
|
||||
precompile(Tuple{typeof(Plots.bar), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.bbox!), Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
precompile(Tuple{typeof(Plots.bbox!), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
precompile(Tuple{typeof(Plots.bottom), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
precompile(Tuple{typeof(Plots.bottompad), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.build_layout), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.build_layout), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64, Array{Plots.Plot{T} where T<:RecipesBase.AbstractBackend, 1}})
|
||||
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64, Array{Plots.Plot{T} where T<:RecipesBase.AbstractBackend, 1}})
|
||||
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64})
|
||||
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64})
|
||||
precompile(Tuple{typeof(Plots.calc_num_subplots), Plots.EmptyLayout})
|
||||
precompile(Tuple{typeof(Plots.calc_num_subplots), Plots.GridLayout})
|
||||
precompile(Tuple{typeof(Plots.color_or_nothing!), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.color_or_nothing!), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.colorbar_style), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.colorbar_style), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.command_idx), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.compute_gridsize), Int64, Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, Array{Float64, 1}, Nothing})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, Array{Float64, 1}, Plots.Surface{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, typeof(identity), Nothing})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, typeof(identity), Nothing})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Array{String, 1}, Array{Float64, 1}, Nothing})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Array{String, 1}, Array{String, 1}, Plots.Surface{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Nothing, Array{Float64, 1}, Nothing})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Nothing, Array{Union{Base.Missing, Float64}, 1}, Nothing})
|
||||
precompile(Tuple{typeof(Plots.compute_xyz), Nothing, Nothing, Nothing})
|
||||
precompile(Tuple{typeof(Plots.contour), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
|
||||
precompile(Tuple{typeof(Plots.contour_levels), Plots.Series, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.convertLegendValue), Bool})
|
||||
precompile(Tuple{typeof(Plots.convertLegendValue), Symbol})
|
||||
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Array{Float64, 1}, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Array{T, 1} where T, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Float64, 2}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Function, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Function, 1}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.convertToAnyVector), Int64, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.convert_sci_unicode), String})
|
||||
precompile(Tuple{typeof(Plots.convert_sci_unicode), String})
|
||||
precompile(Tuple{typeof(Plots.convert_to_polar), Array{Float64, 1}, Array{Float64, 1}, Tuple{Int64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.create_grid), Expr})
|
||||
precompile(Tuple{typeof(Plots.create_grid), Expr})
|
||||
precompile(Tuple{typeof(Plots.create_grid), Symbol})
|
||||
precompile(Tuple{typeof(Plots.create_grid_curly), Expr})
|
||||
precompile(Tuple{typeof(Plots.create_grid_curly), Expr})
|
||||
precompile(Tuple{typeof(Plots.create_grid_vcat), Expr})
|
||||
precompile(Tuple{typeof(Plots.create_grid_vcat), Expr})
|
||||
precompile(Tuple{typeof(Plots.default), Symbol})
|
||||
precompile(Tuple{typeof(Plots.default_should_widen), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.default_should_widen), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Array{Any, 1}})
|
||||
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Array{String, 1}})
|
||||
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Array{Union{Base.Missing, Float64}, 1}})
|
||||
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Base.Missing})
|
||||
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Char})
|
||||
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, String})
|
||||
precompile(Tuple{typeof(Plots.ensure_gradient!), Base.Dict{Symbol, Any}, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.ensure_gradient!), Base.Dict{Symbol, Any}, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.ensure_gradient!), Base.Dict{Symbol, Any}, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.OneTo{Int64}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.OneTo{Int64}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.UnitRange{Int64}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Float64})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Float64})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Int64})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Int64})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Plots.Surface{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Plots.Surface{Array{Float64, 2}}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.extendSeriesData), Array{Float64, 1}, Float64})
|
||||
precompile(Tuple{typeof(Plots.extractGroupArgs), Array{String, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.fakedata), Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.fakedata), Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.fg_color), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.fg_color), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.filter_data!), Base.Dict{Symbol, Any}, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.filter_data), Array{Float64, 1}, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.filter_data), Base.OneTo{Int64}, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.filter_data), Nothing, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.font), Int64, Int})
|
||||
precompile(Tuple{typeof(Plots.font), String, Int})
|
||||
precompile(Tuple{typeof(Plots.font), String, Int})
|
||||
precompile(Tuple{typeof(Plots.font), Symbol, Int})
|
||||
precompile(Tuple{typeof(Plots.frame), Plots.Animation, Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.frame), Plots.Animation})
|
||||
precompile(Tuple{typeof(Plots.get_axis), Plots.Subplot{Plots.GRBackend}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_axis), Plots.Subplot{Plots.GRBackend}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_clims), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.get_clims), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}, Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}, Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.get_fillalpha), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_fillalpha), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Float64, Float64, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.get_linealpha), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_linealpha), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Float64, Float64, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Float64, Float64, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.get_linestyle), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_linestyle), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.get_linewidth), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_linewidth), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.get_markeralpha), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_markercolor), Plots.Series, Float64, Float64, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_markercolor), Plots.Series, Float64, Float64, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_markerstrokealpha), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_markerstrokecolor), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{Any, 1}}})
|
||||
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{String, 1}}})
|
||||
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{String, 1}}})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), Int64, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ColorGradient, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ColorGradient, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.get_subplot), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.get_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.get_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.get_xy), Array{Plots.OHLC{T} where T<:Real, 1}, Base.OneTo{Int64}})
|
||||
precompile(Tuple{typeof(Plots.get_xy), Plots.OHLC{Float64}, Int64, Float64})
|
||||
precompile(Tuple{typeof(Plots.getxy), Plots.Plot{Plots.GRBackend}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_axis_height), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.gr_axis_width), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.gr_color), ColorTypes.RGBA{Float64}, Type{ColorTypes.RGB{Float64}}})
|
||||
precompile(Tuple{typeof(Plots.gr_colorbar_colors), Plots.Series, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_contour_levels), Plots.Series, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_display), Plots.Plot{Plots.GRBackend}, String})
|
||||
precompile(Tuple{typeof(Plots.gr_display), Plots.Plot{Plots.GRBackend}, String})
|
||||
precompile(Tuple{typeof(Plots.gr_display), Plots.Subplot{Plots.GRBackend}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.gr_display), Plots.Subplot{Plots.GRBackend}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_colorbar), Plots.GRColorbar, Plots.Subplot{Plots.GRBackend}, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_marker), Float64, Float64, Int64, Plots.Shape})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_marker), Float64, Float64, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Float64, Float64, Plots.Shape})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Float64, Float64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Float64, Int64, Plots.Shape})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Float64, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Int64, Int64, Plots.Shape})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Int64, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_fill_viewport), Array{Float64, 1}, ColorTypes.RGBA{Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_get_color), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.gr_get_color), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{Any, 1}}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{String, 1}}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{String, 1}}, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_inqtext), Int64, Int64, String})
|
||||
precompile(Tuple{typeof(Plots.gr_inqtext), Int64, Int64, String})
|
||||
precompile(Tuple{typeof(Plots.gr_legend_pos), Plots.Subplot{Plots.GRBackend}, Float64, Float64})
|
||||
precompile(Tuple{typeof(Plots.gr_polaraxes), Int64, Float64, Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}, typeof(identity)})
|
||||
precompile(Tuple{typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_fill), ColorTypes.RGBA{Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_fillcolor), ColorTypes.RGBA{Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_font), Plots.Font})
|
||||
precompile(Tuple{typeof(Plots.gr_set_font), Plots.Font})
|
||||
precompile(Tuple{typeof(Plots.gr_set_gradient), PlotUtils.ColorGradient})
|
||||
precompile(Tuple{typeof(Plots.gr_set_gradient), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.gr_set_gradient), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.gr_set_line), Float64, Symbol, ColorTypes.RGBA{Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, ColorTypes.RGBA{Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, PlotUtils.ColorGradient})
|
||||
precompile(Tuple{typeof(Plots.gr_set_linecolor), PlotUtils.ColorGradient})
|
||||
precompile(Tuple{typeof(Plots.gr_set_markercolor), ColorTypes.RGBA{Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_textcolor), ColorTypes.RGBA{Float64}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Float64})
|
||||
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Nothing})
|
||||
precompile(Tuple{typeof(Plots.gr_set_viewport_cmap), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_viewport_polar)})
|
||||
precompile(Tuple{typeof(Plots.gr_set_xticks_font), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_xticks_font), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_yticks_font), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.gr_set_yticks_font), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.gr_text), Float64, Float64, String})
|
||||
precompile(Tuple{typeof(Plots.gr_text), Float64, Float64, String})
|
||||
precompile(Tuple{typeof(Plots.gr_text_size), String, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_text_size), String, Int64})
|
||||
precompile(Tuple{typeof(Plots.gr_text_size), String})
|
||||
precompile(Tuple{typeof(Plots.gr_update_colorbar!), Plots.GRColorbar, Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.gr_update_colorbar!), Plots.GRColorbar, Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.gr_viewport_from_bbox), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.gr_viewport_from_bbox), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.gr_w3tondc), Float64, Float64, Float64})
|
||||
precompile(Tuple{typeof(Plots.gui), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.guidefont), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.guidefont), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Array{Symbol, 2}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Array{Symbol, 2}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Array{Symbol, 2}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, ColorTypes.RGBA{Float64}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Plots.Shape, Symbol})
|
||||
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.has_attribute_segments), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.has_attribute_segments), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.hascolorbar), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.hascolorbar), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.hasgrid), Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Array{Float64, 1}, Symbol, Tuple{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Bool})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Bool})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Tuple{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Bool})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Bool})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Bool})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_extrema), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_extrema), Array{Float64, 2}})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_extrema), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_extrema), Base.StepRange{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_extrema), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_extrema), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_maximum), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_maximum), Base.OneTo{Int64}})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_minimum), Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.ignorenan_minimum), Base.OneTo{Int64}})
|
||||
precompile(Tuple{typeof(Plots.inline), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.is3d), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.is3d), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.is3d), Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_2tuple), Int64})
|
||||
precompile(Tuple{typeof(Plots.is_2tuple), Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots.is_attr_supported), Plots.GRBackend, Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_attr_supported), Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.GRBackend, Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.Shape})
|
||||
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.Stroke})
|
||||
precompile(Tuple{typeof(Plots.is_marker_supported), Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_marker_supported), Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_scale_supported), Plots.GRBackend, Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_seriestype_supported), Plots.GRBackend, Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_seriestype_supported), Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_seriestype_supported), Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_style_supported), Plots.GRBackend, Symbol})
|
||||
precompile(Tuple{typeof(Plots.is_uniformly_spaced), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.iscontour), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.iscontour), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.isijulia)})
|
||||
precompile(Tuple{typeof(Plots.ispolar), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.ispolar), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.isvertical), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.isvertical), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.iter_segments), Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.iter_segments), Array{Float64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.iter_segments), Array{Int64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.iter_segments), Base.OneTo{Int64}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.iter_segments), Base.UnitRange{Int64}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.iter_segments), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.iter_segments), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.labelfunc), Symbol, Plots.GRBackend})
|
||||
precompile(Tuple{typeof(Plots.layout_args), Base.Dict{Symbol, Any}, Int64})
|
||||
precompile(Tuple{typeof(Plots.layout_args), Base.Dict{Symbol, Any}, Int64})
|
||||
precompile(Tuple{typeof(Plots.layout_args), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.layout_args), Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.layout_args), Int64, Plots.GridLayout})
|
||||
precompile(Tuple{typeof(Plots.layout_args), Int64, Tuple{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots.layout_args), Int64})
|
||||
precompile(Tuple{typeof(Plots.layout_args), Plots.GridLayout})
|
||||
precompile(Tuple{typeof(Plots.leftpad), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.legendfont), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.legendfont), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.legendtitlefont), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.legendtitlefont), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.like_histogram), Symbol})
|
||||
precompile(Tuple{typeof(Plots.like_surface), Symbol})
|
||||
precompile(Tuple{typeof(Plots.link_axes!), Array{RecipesBase.AbstractLayout, 1}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.link_axes!), Array{RecipesBase.AbstractLayout, 1}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.link_axes!), Plots.Axis, Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.link_axes!), Plots.Axis, Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.link_axes!), Plots.GridLayout, Symbol})
|
||||
precompile(Tuple{typeof(Plots.link_axes!), Plots.GridLayout, Symbol})
|
||||
precompile(Tuple{typeof(Plots.link_axes!), Plots.Subplot{Plots.GRBackend}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.link_subplots), Array{RecipesBase.AbstractLayout, 1}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.locate_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText})
|
||||
precompile(Tuple{typeof(Plots.make_fillrange_from_ribbon), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.make_fillrange_side), Array{Float64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.make_fillrange_side), Array{Float64, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots.make_steps), Array{Float64, 1}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.make_steps), Array{Int64, 1}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.make_steps), Base.OneTo{Int64}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.make_steps), Nothing, Symbol})
|
||||
precompile(Tuple{typeof(Plots.nanappend!), Array{Float64, 1}, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.nobigs), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.ohlc), Array{Plots.OHLC{T} where T<:Real, 1}})
|
||||
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Base.StepRange{Int64, Int64}})
|
||||
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Base.UnitRange{Int64}})
|
||||
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Nothing})
|
||||
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Nothing})
|
||||
precompile(Tuple{typeof(Plots.pie_labels), Plots.Subplot{Plots.GRBackend}, Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.plotarea!), Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
precompile(Tuple{typeof(Plots.plotarea!), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
precompile(Tuple{typeof(Plots.png), Plots.Plot{Plots.GRBackend}, String})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Float64, 2}})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Int32, 1}})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Union{Base.Missing, Int64}, 1}})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Union{Base.Missing, Number}, 1}})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Union{Base.Missing, Number}, 1}})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Base.LinRange{Float64}})
|
||||
precompile(Tuple{typeof(Plots.prepareSeriesData), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
|
||||
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.preprocessArgs!), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.preprocessArgs!), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Bool})
|
||||
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Float64})
|
||||
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Int64})
|
||||
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Bool, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Float64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Int64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
|
||||
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
|
||||
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Float64})
|
||||
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Int64})
|
||||
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Bool})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, ColorTypes.RGBA{Float64}})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Float64})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Float64})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Int64})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Int64})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Plots.Shape})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Plots.Stroke})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.process_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText, Plots.Font})
|
||||
precompile(Tuple{typeof(Plots.process_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText})
|
||||
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Base.StepRange{Int64, Int64}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, String, Symbol})
|
||||
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Tuple{Int64, Int64}, Symbol})
|
||||
precompile(Tuple{typeof(Plots.process_fillrange), Int64, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.process_fillrange), Nothing, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.process_ribbon), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.process_ribbon), Int64, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.process_ribbon), Nothing, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.process_ribbon), Tuple{Base.LinRange{Float64}, Base.LinRange{Float64}}, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.process_ribbon), typeof(identity), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.recompute_lengths), Array{Measures.Measure, 1}})
|
||||
precompile(Tuple{typeof(Plots.recompute_lengths), Array{Measures.Measure, 1}})
|
||||
precompile(Tuple{typeof(Plots.replaceAlias!), Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Symbol}})
|
||||
precompile(Tuple{typeof(Plots.replaceAliases!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Symbol}})
|
||||
precompile(Tuple{typeof(Plots.reset_extrema!), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.reset_extrema!), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.right), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
precompile(Tuple{typeof(Plots.rightpad), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.rowsize), Expr})
|
||||
precompile(Tuple{typeof(Plots.rowsize), Symbol})
|
||||
precompile(Tuple{typeof(Plots.series_annotations), Array{Any, 1}})
|
||||
precompile(Tuple{typeof(Plots.series_annotations), Nothing})
|
||||
precompile(Tuple{typeof(Plots.series_annotations), Plots.SeriesAnnotations})
|
||||
precompile(Tuple{typeof(Plots.series_annotations_shapes!), Plots.Series, Symbol})
|
||||
precompile(Tuple{typeof(Plots.series_annotations_shapes!), Plots.Series, Symbol})
|
||||
precompile(Tuple{typeof(Plots.setxy!), Plots.Plot{Plots.GRBackend}, Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
|
||||
precompile(Tuple{typeof(Plots.shape_data), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.shape_data), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.should_add_to_legend), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.should_add_to_legend), Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.showaxis), Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Array{Any, 1}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Array{Any, 1}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Any}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Any}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Bool, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Bool, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Float64, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Float64, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Int64, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Int64, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Measures.Length{:mm, Float64}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Measures.Length{:mm, Float64}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Nothing, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Nothing, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, String, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, String, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Symbol, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Symbol, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Tuple{Int64, Int64}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Tuple{Int64, Int64}, Int64, Bool})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Array{ColorTypes.RGBA{Float64}, 2}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Array{Measures.Length{:mm, Float64}, 2}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Array{String, 2}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Array{Symbol, 2}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Base.ReshapedArray{Int64, 2, Base.UnitRange{Int64}, Tuple{}}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Base.StepRange{Int64, Int64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Base.UnitRange{Int64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Bool, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), ColorTypes.RGBA{Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Float64, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Nothing, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), String, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Symbol, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Tuple{Int64, Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.slice_arg), Tuple{Int64, Int64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Array{Int64, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Array{String, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Array{Symbol, 2}, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, ColorTypes.RGB{Float64}, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Float64, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Plots.GridLayout, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Plots.Plot{Plots.GRBackend}, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, String, Int64})
|
||||
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Symbol, Int64})
|
||||
precompile(Tuple{typeof(Plots.straightline_data), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.straightline_data), Plots.Series, Int64})
|
||||
precompile(Tuple{typeof(Plots.straightline_data), Tuple{Int64, Int64}, Tuple{Float64, Float64}, Array{Float64, 1}, Array{Float64, 1}, Int64})
|
||||
precompile(Tuple{typeof(Plots.stroke), Int64, Int})
|
||||
precompile(Tuple{typeof(Plots.supported_markers), Plots.GRBackend})
|
||||
precompile(Tuple{typeof(Plots.supported_markers)})
|
||||
precompile(Tuple{typeof(Plots.supported_styles), Plots.GRBackend})
|
||||
precompile(Tuple{typeof(Plots.supported_styles)})
|
||||
precompile(Tuple{typeof(Plots.text), String, Int64, Symbol, Symbol})
|
||||
precompile(Tuple{typeof(Plots.text), String, Symbol, Int64, Int})
|
||||
precompile(Tuple{typeof(Plots.text), String, Symbol})
|
||||
precompile(Tuple{typeof(Plots.tickfont), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.tickfont), Plots.Axis})
|
||||
precompile(Tuple{typeof(Plots.title!), String})
|
||||
precompile(Tuple{typeof(Plots.titlefont), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.titlefont), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.toppad), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.tovec), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.transpose_z), Plots.Series, Array{Float64, 2}, Bool})
|
||||
precompile(Tuple{typeof(Plots.trueOrAllTrue), typeof(Plots.is3d), Symbol})
|
||||
precompile(Tuple{typeof(Plots.trueOrAllTrue), typeof(identity), Array{Symbol, 2}})
|
||||
precompile(Tuple{typeof(Plots.unzip), Array{Tuple{Float64, Float64, Float64}, 1}})
|
||||
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout, Array{Measures.Length{:mm, Float64}, 1}})
|
||||
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout, Array{Measures.Length{:mm, Float64}, 1}})
|
||||
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout})
|
||||
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout})
|
||||
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.Subplot{Plots.GRBackend}, Array{Measures.Length{:mm, Float64}, 1}})
|
||||
precompile(Tuple{typeof(Plots.update_inset_bboxes!), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.update_inset_bboxes!), Plots.Plot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.vline!), Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.wand_edges), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.warnOnUnsupported), Plots.GRBackend, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.warnOnUnsupported), Plots.GRBackend, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.warnOnUnsupported_args), Plots.GRBackend, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.warnOnUnsupported_args), Plots.GRBackend, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.warnOnUnsupported_scales), Plots.GRBackend, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.warnOnUnsupported_scales), Plots.GRBackend, Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.widen), Float64, Float64, Symbol})
|
||||
precompile(Tuple{typeof(Plots.wrap_surfaces), Base.Dict{Symbol, Any}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Array{Any, 1}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Bool})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Float64})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Int64})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Nothing})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Plots.SeriesAnnotations})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Array{Float64, 1}, Array{Float64, 1}}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Array{Symbol, 2}, Int64, Float64, Plots.Stroke}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Array{Symbol, 2}, Int64}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Float64, Array{Symbol, 2}, Int64}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Float64, Symbol}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Array{Symbol, 2}}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Float64, Symbol, Plots.Stroke}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Float64, Symbol}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol, Float64, Array{Symbol, 2}}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol, Symbol}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Plots.Shape, Int64, ColorTypes.RGBA{Float64}}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{String, Symbol}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{String, Tuple{Int64, Int64}, Base.StepRange{Int64, Int64}, Symbol}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Float64, Plots.Stroke}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Int64}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Symbol, Int64, Symbol, Float64}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Symbol, Symbol, Int64, Float64}})
|
||||
precompile(Tuple{typeof(Plots.wraptuple), Tuple{}})
|
||||
precompile(Tuple{typeof(Plots.xgrid!), Plots.Plot{Plots.GRBackend}, Symbol, Int})
|
||||
precompile(Tuple{typeof(Plots.xlims), Int64})
|
||||
precompile(Tuple{typeof(Plots.xlims), Int64})
|
||||
precompile(Tuple{typeof(Plots.xlims), Plots.Subplot{Plots.GRBackend}})
|
||||
precompile(Tuple{typeof(Plots.yaxis!), String, Symbol})
|
||||
precompile(Tuple{typeof(Plots.ylims), Int64})
|
||||
precompile(Tuple{typeof(Plots.ylims), Int64})
|
||||
precompile(Tuple{typeof(Plots.ylims), Plots.Subplot{Plots.GRBackend}})
|
||||
end
|
||||
|
||||
+116
-54
@@ -47,16 +47,47 @@ end
|
||||
num_series(x::AMat) = size(x,2)
|
||||
num_series(x) = 1
|
||||
|
||||
RecipesBase.apply_recipe(plotattributes::KW, ::Type{T}, plt::AbstractPlot) where {T} = throw(MethodError("Unmatched plot recipe: $T"))
|
||||
RecipesBase.apply_recipe(plotattributes::KW, ::Type{T}, plt::AbstractPlot) where {T} = throw(MethodError(T, "Unmatched plot recipe: $T"))
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
# for seriestype `line`, need to sort by x values
|
||||
|
||||
const POTENTIAL_VECTOR_ARGUMENTS = [
|
||||
:seriescolor, :seriesalpha,
|
||||
:linecolor, :linealpha, :linewidth, :linestyle, :line_z,
|
||||
:fillcolor, :fillalpha, :fill_z,
|
||||
:markercolor, :markeralpha, :markershape, :marker_z,
|
||||
:markerstrokecolor, :markerstrokealpha,
|
||||
:yerror, :yerror,
|
||||
:series_annotations, :fillrange
|
||||
]
|
||||
|
||||
@recipe function f(::Type{Val{:line}}, x, y, z)
|
||||
indices = sortperm(x)
|
||||
x := x[indices]
|
||||
y := y[indices]
|
||||
|
||||
# sort vector arguments
|
||||
for arg in POTENTIAL_VECTOR_ARGUMENTS
|
||||
if typeof(plotattributes[arg]) <: AVec
|
||||
plotattributes[arg] = _cycle(plotattributes[arg], indices)
|
||||
end
|
||||
end
|
||||
|
||||
# a tuple as fillrange has to be handled differently
|
||||
if typeof(plotattributes[:fillrange]) <: Tuple
|
||||
lower, upper = plotattributes[:fillrange]
|
||||
if typeof(lower) <: AVec
|
||||
lower = _cycle(lower, indices)
|
||||
end
|
||||
if typeof(upper) <: AVec
|
||||
upper = _cycle(upper, indices)
|
||||
end
|
||||
plotattributes[:fillrange] = (lower, upper)
|
||||
end
|
||||
|
||||
if typeof(z) <: AVec
|
||||
z := z[indices]
|
||||
end
|
||||
@@ -65,19 +96,6 @@ RecipesBase.apply_recipe(plotattributes::KW, ::Type{T}, plt::AbstractPlot) where
|
||||
end
|
||||
@deps line path
|
||||
|
||||
|
||||
function hvline_limits(axis::Axis)
|
||||
vmin, vmax = axis_limits(axis)
|
||||
if vmin >= vmax
|
||||
if isfinite(vmin)
|
||||
vmax = vmin + 1
|
||||
else
|
||||
vmin, vmax = 0.0, 1.1
|
||||
end
|
||||
end
|
||||
vmin, vmax
|
||||
end
|
||||
|
||||
@recipe function f(::Type{Val{:hline}}, x, y, z)
|
||||
n = length(y)
|
||||
newx = repeat(Float64[-1, 1, NaN], n)
|
||||
@@ -221,12 +239,13 @@ end
|
||||
@recipe function f(::Type{Val{:sticks}}, x, y, z)
|
||||
n = length(x)
|
||||
fr = plotattributes[:fillrange]
|
||||
if fr == nothing
|
||||
yaxis = plotattributes[:subplot][:yaxis]
|
||||
if fr === nothing
|
||||
sp = plotattributes[:subplot]
|
||||
yaxis = sp[:yaxis]
|
||||
fr = if yaxis[:scale] == :identity
|
||||
0.0
|
||||
else
|
||||
NaNMath.min(axis_limits(yaxis)[1], ignorenan_minimum(y))
|
||||
NaNMath.min(axis_limits(sp, :y)[1], ignorenan_minimum(y))
|
||||
end
|
||||
end
|
||||
newx, newy = zeros(3n), zeros(3n)
|
||||
@@ -272,13 +291,13 @@ end
|
||||
|
||||
# create segmented bezier curves in place of line segments
|
||||
@recipe function f(::Type{Val{:curves}}, x, y, z; npoints = 30)
|
||||
args = z != nothing ? (x,y,z) : (x,y)
|
||||
args = z !== nothing ? (x,y,z) : (x,y)
|
||||
newx, newy = zeros(0), zeros(0)
|
||||
fr = plotattributes[:fillrange]
|
||||
newfr = fr != nothing ? zeros(0) : nothing
|
||||
newz = z != nothing ? zeros(0) : nothing
|
||||
newfr = fr !== nothing ? zeros(0) : nothing
|
||||
newz = z !== nothing ? zeros(0) : nothing
|
||||
# lz = plotattributes[:line_z]
|
||||
# newlz = lz != nothing ? zeros(0) : nothing
|
||||
# newlz = lz !== nothing ? zeros(0) : nothing
|
||||
|
||||
# for each line segment (point series with no NaNs), convert it into a bezier curve
|
||||
# where the points are the control points of the curve
|
||||
@@ -287,13 +306,13 @@ end
|
||||
ts = range(0, stop = 1, length = npoints)
|
||||
nanappend!(newx, map(t -> bezier_value(_cycle(x,rng), t), ts))
|
||||
nanappend!(newy, map(t -> bezier_value(_cycle(y,rng), t), ts))
|
||||
if z != nothing
|
||||
if z !== nothing
|
||||
nanappend!(newz, map(t -> bezier_value(_cycle(z,rng), t), ts))
|
||||
end
|
||||
if fr != nothing
|
||||
if fr !== nothing
|
||||
nanappend!(newfr, map(t -> bezier_value(_cycle(fr,rng), t), ts))
|
||||
end
|
||||
# if lz != nothing
|
||||
# if lz !== nothing
|
||||
# lzrng = _cycle(lz, rng) # the line_z's for this segment
|
||||
# push!(newlz, 0.0)
|
||||
# append!(newlz, map(t -> lzrng[1+floor(Int, t * (length(rng)-1))], ts))
|
||||
@@ -302,16 +321,16 @@ end
|
||||
|
||||
x := newx
|
||||
y := newy
|
||||
if z == nothing
|
||||
if z === nothing
|
||||
seriestype := :path
|
||||
else
|
||||
seriestype := :path3d
|
||||
z := newz
|
||||
end
|
||||
if fr != nothing
|
||||
if fr !== nothing
|
||||
fillrange := newfr
|
||||
end
|
||||
# if lz != nothing
|
||||
# if lz !== nothing
|
||||
# # line_z := newlz
|
||||
# linecolor := (isa(plotattributes[:linecolor], ColorGradient) ? plotattributes[:linecolor] : cgrad())
|
||||
# end
|
||||
@@ -338,19 +357,19 @@ end
|
||||
|
||||
# compute half-width of bars
|
||||
bw = plotattributes[:bar_width]
|
||||
hw = if bw == nothing
|
||||
hw = if bw === nothing
|
||||
if nx > 1
|
||||
0.5*_bar_width*ignorenan_minimum(filter(x->x>0, diff(procx)))
|
||||
else
|
||||
0.5 * _bar_width
|
||||
end
|
||||
else
|
||||
Float64[0.5_cycle(bw,i) for i=1:length(procx)]
|
||||
Float64[0.5_cycle(bw,i) for i=eachindex(procx)]
|
||||
end
|
||||
|
||||
# make fillto a vector... default fills to 0
|
||||
fillto = plotattributes[:fillrange]
|
||||
if fillto == nothing
|
||||
if fillto === nothing
|
||||
fillto = 0
|
||||
end
|
||||
if (yscale in _logScales) && !all(_is_positive, fillto)
|
||||
@@ -472,7 +491,7 @@ end
|
||||
|
||||
@recipe function f(::Type{Val{:barbins}}, x, y, z)
|
||||
edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y)
|
||||
if (plotattributes[:bar_width] == nothing)
|
||||
if (plotattributes[:bar_width] === nothing)
|
||||
bar_width := diff(edge)
|
||||
end
|
||||
x := _bin_centers(edge)
|
||||
@@ -514,18 +533,20 @@ function _stepbins_path(edge, weights, baseline::Real, xscale::Symbol, yscale::S
|
||||
|
||||
last_w = eltype(weights)(NaN)
|
||||
|
||||
while it_tuple_e != nothing && it_tuple_w != nothing
|
||||
while it_tuple_e !== nothing && it_tuple_w !== nothing
|
||||
b, it_state_e = it_tuple_e
|
||||
w, it_state_w = it_tuple_w
|
||||
|
||||
if (log_scale_x && a ≈ 0)
|
||||
a = b/_logScaleBases[xscale]^3
|
||||
a = oftype(a, b/_logScaleBases[xscale]^3)
|
||||
end
|
||||
|
||||
if isnan(w)
|
||||
if !isnan(last_w)
|
||||
push!(x, a)
|
||||
push!(y, baseline)
|
||||
push!(x, NaN)
|
||||
push!(y, NaN)
|
||||
end
|
||||
else
|
||||
if isnan(last_w)
|
||||
@@ -538,8 +559,8 @@ function _stepbins_path(edge, weights, baseline::Real, xscale::Symbol, yscale::S
|
||||
push!(y, w)
|
||||
end
|
||||
|
||||
a = b
|
||||
last_w = w
|
||||
a = oftype(a, b)
|
||||
last_w = oftype(last_w, w)
|
||||
|
||||
it_tuple_e = iterate(edge, it_state_e)
|
||||
it_tuple_w = iterate(weights, it_state_w)
|
||||
@@ -586,12 +607,13 @@ end
|
||||
end
|
||||
Plots.@deps stepbins path
|
||||
|
||||
wand_edges(x...) = (@warn("Load the StatPlots package in order to use :wand bins. Defaulting to :auto", once = true); :auto)
|
||||
wand_edges(x...) = (@warn("Load the StatsPlots package in order to use :wand bins. Defaulting to :auto", once = true); :auto)
|
||||
|
||||
function _auto_binning_nbins(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) where N
|
||||
_cl(x) = ceil(Int, NaNMath.max(x, one(x)))
|
||||
max_bins = 10_000
|
||||
_cl(x) = min(ceil(Int, max(x, one(x))), max_bins)
|
||||
_iqr(v) = (q = quantile(v, 0.75) - quantile(v, 0.25); q > 0 ? q : oftype(q, 1))
|
||||
_span(v) = ignorenan_maximum(v) - ignorenan_minimum(v)
|
||||
_span(v) = maximum(v) - minimum(v)
|
||||
|
||||
n_samples = length(LinearIndices(first(vs)))
|
||||
|
||||
@@ -616,7 +638,7 @@ function _auto_binning_nbins(vs::NTuple{N,AbstractVector}, dim::Integer; mode::S
|
||||
elseif mode == :fd # Freedman–Diaconis rule
|
||||
_cl(_span(v) / (2 * _iqr(v) / nd))
|
||||
elseif mode == :wand
|
||||
wand_edges(v) # this makes this function not type stable, but the type instability does not propagate
|
||||
_cl(wand_edges(v)) # this makes this function not type stable, but the type instability does not propagate
|
||||
else
|
||||
error("Unknown auto-binning mode $mode")
|
||||
end
|
||||
@@ -635,11 +657,19 @@ _hist_edges(vs::NTuple{N,AbstractVector}, binning::Union{Integer, Symbol, Abstra
|
||||
_hist_norm_mode(mode::Symbol) = mode
|
||||
_hist_norm_mode(mode::Bool) = mode ? :pdf : :none
|
||||
|
||||
_filternans(vs::NTuple{1,AbstractVector}) = filter!.(isfinite, vs)
|
||||
function _filternans(vs::NTuple{N,AbstractVector}) where N
|
||||
_invertedindex(v, not) = [j for (i,j) in enumerate(v) if !(i ∈ not)]
|
||||
nots = union(Set.(findall.(!isfinite, vs))...)
|
||||
_invertedindex.(vs, Ref(nots))
|
||||
end
|
||||
|
||||
function _make_hist(vs::NTuple{N,AbstractVector}, binning; normed = false, weights = nothing) where N
|
||||
edges = _hist_edges(vs, binning)
|
||||
h = float( weights == nothing ?
|
||||
StatsBase.fit(StatsBase.Histogram, vs, edges, closed = :left) :
|
||||
StatsBase.fit(StatsBase.Histogram, vs, StatsBase.Weights(weights), edges, closed = :left)
|
||||
localvs = _filternans(vs)
|
||||
edges = _hist_edges(localvs, binning)
|
||||
h = float( weights === nothing ?
|
||||
StatsBase.fit(StatsBase.Histogram, localvs, edges, closed = :left) :
|
||||
StatsBase.fit(StatsBase.Histogram, localvs, StatsBase.Weights(weights), edges, closed = :left)
|
||||
)
|
||||
normalize!(h, mode = _hist_norm_mode(normed))
|
||||
end
|
||||
@@ -716,12 +746,14 @@ end
|
||||
edge_x, edge_y, weights = x, y, z.surf
|
||||
|
||||
float_weights = float(weights)
|
||||
if float_weights === weights
|
||||
float_weights = deepcopy(float_weights)
|
||||
end
|
||||
for (i, c) in enumerate(float_weights)
|
||||
if c == 0
|
||||
float_weights[i] = NaN
|
||||
if !plotattributes[:show_empty_bins]
|
||||
if float_weights === weights
|
||||
float_weights = deepcopy(float_weights)
|
||||
end
|
||||
for (i, c) in enumerate(float_weights)
|
||||
if c == 0
|
||||
float_weights[i] = NaN
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -966,7 +998,7 @@ function get_xy(o::OHLC, x, xdiff)
|
||||
end
|
||||
|
||||
# get the joined vector
|
||||
function get_xy(v::AVec{OHLC}, x = 1:length(v))
|
||||
function get_xy(v::AVec{OHLC}, x = eachindex(v))
|
||||
xdiff = 0.3ignorenan_mean(abs.(diff(x)))
|
||||
x_out, y_out = zeros(0), zeros(0)
|
||||
for (i,ohlc) in enumerate(v)
|
||||
@@ -1024,8 +1056,8 @@ end
|
||||
@assert length(g.args) == 1 && typeof(g.args[1]) <: AbstractMatrix
|
||||
seriestype := :spy
|
||||
mat = g.args[1]
|
||||
n,m = size(mat)
|
||||
Plots.SliceIt, 1:m, 1:n, Surface(mat)
|
||||
n,m = axes(mat)
|
||||
Plots.SliceIt, m, n, Surface(mat)
|
||||
end
|
||||
|
||||
@recipe function f(::Type{Val{:spy}}, x,y,z)
|
||||
@@ -1053,7 +1085,7 @@ end
|
||||
|
||||
# -------------------------------------------------
|
||||
|
||||
"Adds a+bx... straight line over the current plot, without changing the axis limits"
|
||||
"Adds ax+b... straight line over the current plot, without changing the axis limits"
|
||||
abline!(plt::Plot, a, b; kw...) = plot!(plt, [0, 1], [b, b+a]; seriestype = :straightline, kw...)
|
||||
|
||||
abline!(args...; kw...) = abline!(current(), args...; kw...)
|
||||
@@ -1069,6 +1101,12 @@ timeformatter(t) = string(Dates.Time(Dates.Nanosecond(t)))
|
||||
@recipe f(::Type{Date}, dt::Date) = (dt -> Dates.value(dt), dateformatter)
|
||||
@recipe f(::Type{DateTime}, dt::DateTime) = (dt -> Dates.value(dt), datetimeformatter)
|
||||
@recipe f(::Type{Dates.Time}, t::Dates.Time) = (t -> Dates.value(t), timeformatter)
|
||||
@recipe f(::Type{P}, t::P) where P <: Dates.Period = (t -> Dates.value(t), t -> string(P(t)))
|
||||
|
||||
# -------------------------------------------------
|
||||
# Characters
|
||||
|
||||
@recipe f(::Type{<:AbstractChar}, ::AbstractChar) = (string, string)
|
||||
|
||||
# -------------------------------------------------
|
||||
# Complex Numbers
|
||||
@@ -1147,9 +1185,33 @@ end
|
||||
seriestype := :shape
|
||||
|
||||
# create a filled polygon for each item
|
||||
for c=1:size(weights,2)
|
||||
for c=axes(weights,2)
|
||||
sx = vcat(weights[:,c], c==1 ? zeros(n) : reverse(weights[:,c-1]))
|
||||
sy = vcat(returns, reverse(returns))
|
||||
@series Plots.isvertical(plotattributes) ? (sx, sy) : (sy, sx)
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
areaplot([x,] y)
|
||||
areaplot!([x,] y)
|
||||
|
||||
Draw a stacked area plot of the matrix y.
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], fillalpha = [0.2 0.3 0.4])
|
||||
```
|
||||
"""
|
||||
@userplot AreaPlot
|
||||
|
||||
@recipe function f(a::AreaPlot)
|
||||
data = cumsum(a.args[end], dims=2)
|
||||
x = length(a.args) == 1 ? (axes(data, 1)) : a.args[1]
|
||||
seriestype := :line
|
||||
for i in axes(data, 2)
|
||||
@series begin
|
||||
fillrange := i > 1 ? data[:,i-1] : 0
|
||||
x, data[:,i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+112
-126
@@ -7,85 +7,76 @@
|
||||
# note: returns meta information... mainly for use with automatic labeling from DataFrames for now
|
||||
|
||||
const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}}
|
||||
const MaybeNumber = Union{Number, Missing}
|
||||
const MaybeString = Union{AbstractString, Missing}
|
||||
const DataPoint = Union{MaybeNumber, MaybeString}
|
||||
|
||||
all3D(plotattributes::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image, :plots_heatmap), get(plotattributes, :seriestype, :none))
|
||||
prepareSeriesData(x) = error("Cannot convert $(typeof(x)) to series data for plotting")
|
||||
prepareSeriesData(::Nothing) = nothing
|
||||
prepareSeriesData(f::Function) = f
|
||||
prepareSeriesData(a::AbstractArray{<:MaybeNumber}) = replace!(
|
||||
x -> ismissing(x) || isinf(x) ? NaN : x,
|
||||
map(float,a))
|
||||
prepareSeriesData(a::AbstractArray{<:MaybeString}) = replace(x -> ismissing(x) ? "" : x, a)
|
||||
prepareSeriesData(s::Surface{<:AMat{<:MaybeNumber}}) = Surface(prepareSeriesData(s.surf))
|
||||
prepareSeriesData(s::Surface) = s # non-numeric Surface, such as an image
|
||||
prepareSeriesData(v::Volume) = Volume(prepareSeriesData(v.v), v.x_extents, v.y_extents, v.z_extents)
|
||||
|
||||
# unknown
|
||||
convertToAnyVector(x, plotattributes::KW) = error("No user recipe defined for $(typeof(x))")
|
||||
|
||||
# missing
|
||||
convertToAnyVector(v::Nothing, plotattributes::KW) = Any[nothing], nothing
|
||||
# default: assume x represents a single series
|
||||
convertToAnyVector(x, plotattributes) = Any[prepareSeriesData(x)]
|
||||
|
||||
# fixed number of blank series
|
||||
convertToAnyVector(n::Integer, plotattributes::KW) = Any[zeros(0) for i in 1:n], nothing
|
||||
convertToAnyVector(n::Integer, plotattributes) = Any[zeros(0) for i in 1:n]
|
||||
|
||||
# numeric vector
|
||||
convertToAnyVector(v::AVec{T}, plotattributes::KW) where {T<:Number} = Any[v], nothing
|
||||
convertToAnyVector(v::AVec{Union{Missing, T}}, plotattributes::KW) where {T<:Number} = Any[replace(v, missing => NaN)], nothing
|
||||
|
||||
# string vector
|
||||
convertToAnyVector(v::AVec{T}, plotattributes::KW) where {T<:AbstractString} = Any[v], nothing
|
||||
convertToAnyVector(v::AVec{Union{Missing, T}}, plotattributes::KW) where {T<:AbstractString} = Any[replace(v, missing => "")], nothing
|
||||
|
||||
function convertToAnyVector(v::AMat, plotattributes::KW)
|
||||
v = handlemissings(v)
|
||||
if all3D(plotattributes)
|
||||
Any[Surface(v)]
|
||||
else
|
||||
Any[v[:,i] for i in 1:size(v,2)]
|
||||
end, nothing
|
||||
end
|
||||
|
||||
handlemissings(v::AMat) = v
|
||||
handlemissings(v::AMat{T}) where T <: Number = replace(v, missing => NaN)
|
||||
handlemissings(v::AMat{T}) where T <: String = replace(v, missing => "")
|
||||
|
||||
# function
|
||||
convertToAnyVector(f::Function, plotattributes::KW) = Any[f], nothing
|
||||
|
||||
# surface
|
||||
convertToAnyVector(s::Surface, plotattributes::KW) = Any[s], nothing
|
||||
|
||||
# volume
|
||||
convertToAnyVector(v::Volume, plotattributes::KW) = Any[v], nothing
|
||||
|
||||
# # vector of OHLC
|
||||
# convertToAnyVector(v::AVec{OHLC}, plotattributes::KW) = Any[v], nothing
|
||||
|
||||
# # dates
|
||||
convertToAnyVector(dts::AVec{D}, plotattributes::KW) where {D<:Union{Date,DateTime}} = Any[dts], nothing
|
||||
# vector of data points is a single series
|
||||
convertToAnyVector(v::AVec{<:DataPoint}, plotattributes) = Any[prepareSeriesData(v)]
|
||||
|
||||
# list of things (maybe other vectors, functions, or something else)
|
||||
function convertToAnyVector(v::AVec, plotattributes::KW)
|
||||
if all(x -> typeof(x) <: Number, v)
|
||||
# all real numbers wrap the whole vector as one item
|
||||
Any[convert(Vector{Float64}, v)], nothing
|
||||
function convertToAnyVector(v::AVec, plotattributes)
|
||||
if all(x -> x isa MaybeNumber, v)
|
||||
convertToAnyVector(Vector{MaybeNumber}(v), plotattributes)
|
||||
elseif all(x -> x isa MaybeString, v)
|
||||
convertToAnyVector(Vector{MaybeString}(v), plotattributes)
|
||||
else
|
||||
# something else... treat each element as an item
|
||||
vcat(Any[convertToAnyVector(vi, plotattributes)[1] for vi in v]...), nothing
|
||||
# Any[vi for vi in v], nothing
|
||||
vcat((convertToAnyVector(vi, plotattributes) for vi in v)...)
|
||||
end
|
||||
end
|
||||
|
||||
convertToAnyVector(t::Tuple, plotattributes::KW) = Any[t], nothing
|
||||
|
||||
|
||||
function convertToAnyVector(args...)
|
||||
error("In convertToAnyVector, could not handle the argument types: $(map(typeof, args[1:end-1]))")
|
||||
# Matrix is split into columns
|
||||
function convertToAnyVector(v::AMat{<:DataPoint}, plotattributes)
|
||||
if all3D(plotattributes)
|
||||
Any[prepareSeriesData(Surface(v))]
|
||||
else
|
||||
Any[prepareSeriesData(v[:, i]) for i in axes(v, 2)]
|
||||
end
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Fillranges & ribbons
|
||||
|
||||
|
||||
process_fillrange(range::Number, plotattributes) = [range]
|
||||
process_fillrange(range, plotattributes) = convertToAnyVector(range, plotattributes)
|
||||
|
||||
process_ribbon(ribbon::Number, plotattributes) = [ribbon]
|
||||
process_ribbon(ribbon, plotattributes) = convertToAnyVector(ribbon, plotattributes)
|
||||
# ribbon as a tuple: (lower_ribbons, upper_ribbons)
|
||||
process_ribbon(ribbon::Tuple{Any,Any}, plotattributes) = collect(zip(convertToAnyVector(ribbon[1], plotattributes),
|
||||
convertToAnyVector(ribbon[2], plotattributes)))
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
# TODO: can we avoid the copy here? one error that crops up is that mapping functions over the same array
|
||||
# result in that array being shared. push!, etc will add too many items to that array
|
||||
|
||||
compute_x(x::Nothing, y::Nothing, z) = 1:size(z,1)
|
||||
compute_x(x::Nothing, y, z) = 1:size(y,1)
|
||||
compute_x(x::Nothing, y::Nothing, z) = axes(z,1)
|
||||
compute_x(x::Nothing, y, z) = axes(y,1)
|
||||
compute_x(x::Function, y, z) = map(x, y)
|
||||
compute_x(x, y, z) = copy(x)
|
||||
|
||||
# compute_y(x::Void, y::Function, z) = error()
|
||||
compute_y(x::Nothing, y::Nothing, z) = 1:size(z,2)
|
||||
compute_y(x::Nothing, y::Nothing, z) = axes(z,2)
|
||||
compute_y(x, y::Function, z) = map(y, x)
|
||||
compute_y(x, y, z) = copy(y)
|
||||
|
||||
@@ -135,24 +126,17 @@ struct SliceIt end
|
||||
z = z.data
|
||||
end
|
||||
|
||||
xs, _ = convertToAnyVector(x, plotattributes)
|
||||
ys, _ = convertToAnyVector(y, plotattributes)
|
||||
zs, _ = convertToAnyVector(z, plotattributes)
|
||||
xs = convertToAnyVector(x, plotattributes)
|
||||
ys = convertToAnyVector(y, plotattributes)
|
||||
zs = convertToAnyVector(z, plotattributes)
|
||||
|
||||
|
||||
fr = pop!(plotattributes, :fillrange, nothing)
|
||||
fillranges, _ = if typeof(fr) <: Number
|
||||
([fr],nothing)
|
||||
else
|
||||
convertToAnyVector(fr, plotattributes)
|
||||
end
|
||||
fillranges = process_fillrange(fr, plotattributes)
|
||||
mf = length(fillranges)
|
||||
|
||||
rib = pop!(plotattributes, :ribbon, nothing)
|
||||
ribbons, _ = if typeof(rib) <: Number
|
||||
([fr],nothing)
|
||||
else
|
||||
convertToAnyVector(rib, plotattributes)
|
||||
end
|
||||
ribbons = process_ribbon(rib, plotattributes)
|
||||
mr = length(ribbons)
|
||||
|
||||
# @show zs
|
||||
@@ -193,8 +177,9 @@ _apply_type_recipe(plotattributes, v) = RecipesBase.apply_recipe(plotattributes,
|
||||
# This sort of recipe should return a pair of functions... one to convert to number,
|
||||
# and one to format tick values.
|
||||
function _apply_type_recipe(plotattributes, v::AbstractArray)
|
||||
isempty(v) && return Float64[]
|
||||
args = RecipesBase.apply_recipe(plotattributes, typeof(v[1]), v[1])[1].args
|
||||
isempty(skipmissing(v)) && return Float64[]
|
||||
x = first(skipmissing(v))
|
||||
args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args
|
||||
if length(args) == 2 && typeof(args[1]) <: Function && typeof(args[2]) <: Function
|
||||
numfunc, formatter = args
|
||||
Formatted(map(numfunc, v), formatter)
|
||||
@@ -292,12 +277,14 @@ end
|
||||
|
||||
@recipe f(n::Integer) = is3d(get(plotattributes,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing)
|
||||
|
||||
all3D(plotattributes::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image, :plots_heatmap), get(plotattributes, :seriestype, :none))
|
||||
|
||||
# return a surface if this is a 3d plot, otherwise let it be sliced up
|
||||
@recipe function f(mat::AMat{T}) where T<:Union{Integer,AbstractFloat}
|
||||
@recipe function f(mat::AMat{T}) where T<:Union{Integer,AbstractFloat,Missing}
|
||||
if all3D(plotattributes)
|
||||
n,m = size(mat)
|
||||
n,m = axes(mat)
|
||||
wrap_surfaces(plotattributes)
|
||||
SliceIt, 1:m, 1:n, Surface(mat)
|
||||
SliceIt, m, n, Surface(mat)
|
||||
else
|
||||
SliceIt, nothing, mat, nothing
|
||||
end
|
||||
@@ -307,53 +294,60 @@ end
|
||||
@recipe function f(fmt::Formatted{T}) where T<:AbstractMatrix
|
||||
if all3D(plotattributes)
|
||||
mat = fmt.data
|
||||
n,m = size(mat)
|
||||
n,m = axes(mat)
|
||||
wrap_surfaces(plotattributes)
|
||||
SliceIt, 1:m, 1:n, Formatted(Surface(mat), fmt.formatter)
|
||||
SliceIt, m, n, Formatted(Surface(mat), fmt.formatter)
|
||||
else
|
||||
SliceIt, nothing, fmt, nothing
|
||||
end
|
||||
end
|
||||
|
||||
# assume this is a Volume, so construct one
|
||||
@recipe function f(vol::AbstractArray{T,3}, args...) where T<:Number
|
||||
@recipe function f(vol::AbstractArray{T,3}, args...) where T<:Union{Number,Missing}
|
||||
seriestype := :volume
|
||||
SliceIt, nothing, Volume(vol, args...), nothing
|
||||
end
|
||||
|
||||
|
||||
# # images - grays
|
||||
function clamp_greys!(mat::AMat{T}) where T<:Gray
|
||||
for i in eachindex(mat)
|
||||
mat[i].val < 0 && (mat[i] = Gray(0))
|
||||
mat[i].val > 1 && (mat[i] = Gray(1))
|
||||
end
|
||||
mat
|
||||
end
|
||||
|
||||
@recipe function f(mat::AMat{T}) where T<:Gray
|
||||
n, m = size(mat)
|
||||
n, m = axes(mat)
|
||||
if is_seriestype_supported(:image)
|
||||
seriestype := :image
|
||||
yflip --> true
|
||||
SliceIt, 1:m, 1:n, Surface(mat)
|
||||
SliceIt, m, n, Surface(clamp_greys!(mat))
|
||||
else
|
||||
seriestype := :heatmap
|
||||
yflip --> true
|
||||
cbar --> false
|
||||
fillcolor --> ColorGradient([:black, :white])
|
||||
SliceIt, 1:m, 1:n, Surface(convert(Matrix{Float64}, mat))
|
||||
SliceIt, m, n, Surface(clamp!(convert(Matrix{Float64}, mat), 0., 1.))
|
||||
end
|
||||
end
|
||||
|
||||
# # images - colors
|
||||
|
||||
@recipe function f(mat::AMat{T}) where T<:Colorant
|
||||
n, m = size(mat)
|
||||
n, m = axes(mat)
|
||||
|
||||
if is_seriestype_supported(:image)
|
||||
seriestype := :image
|
||||
yflip --> true
|
||||
SliceIt, 1:m, 1:n, Surface(mat)
|
||||
SliceIt, m, n, Surface(mat)
|
||||
else
|
||||
seriestype := :heatmap
|
||||
yflip --> true
|
||||
cbar --> false
|
||||
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
|
||||
SliceIt, 1:m, 1:n, Surface(z)
|
||||
SliceIt, m, n, Surface(z)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -372,23 +366,29 @@ end
|
||||
|
||||
@recipe function f(shapes::AMat{Shape})
|
||||
seriestype --> :shape
|
||||
for j in 1:size(shapes,2)
|
||||
for j in axes(shapes,2)
|
||||
@series coords(vec(shapes[:,j]))
|
||||
end
|
||||
end
|
||||
|
||||
# Dicts: each entry is a data point (x,y)=(key,value)
|
||||
|
||||
@recipe f(d::AbstractDict) = collect(keys(d)), collect(values(d))
|
||||
|
||||
# function without range... use the current range of the x-axis
|
||||
|
||||
@recipe function f(f::FuncOrFuncs{F}) where F<:Function
|
||||
plt = plotattributes[:plot_object]
|
||||
xmin, xmax = try
|
||||
axis_limits(plt[1][:xaxis])
|
||||
catch
|
||||
xinv = invscalefunc(get(plotattributes, :xscale, :identity))
|
||||
xm = tryrange(f, xinv.([-5,-1,0,0.01]))
|
||||
xm, tryrange(f, filter(x->x>xm, xinv.([5,1,0.99, 0, -0.01])))
|
||||
xmin, xmax = if haskey(plotattributes, :xlims)
|
||||
plotattributes[:xlims]
|
||||
else
|
||||
try
|
||||
axis_limits(plt[1], :x)
|
||||
catch
|
||||
xinv = invscalefunc(get(plotattributes, :xscale, :identity))
|
||||
xm = tryrange(f, xinv.([-5,-1,0,0.01]))
|
||||
xm, tryrange(f, filter(x->x>xm, xinv.([5,1,0.99, 0, -0.01])))
|
||||
end
|
||||
end
|
||||
|
||||
f, xmin, xmax
|
||||
@@ -519,20 +519,25 @@ end
|
||||
# # special handling... xmin/xmax with parametric function(s)
|
||||
@recipe function f(f::Function, xmin::Number, xmax::Number)
|
||||
xscale, yscale = [get(plotattributes, sym, :identity) for sym=(:xscale,:yscale)]
|
||||
xs = _scaled_adapted_grid(f, xscale, yscale, xmin, xmax)
|
||||
xs, f
|
||||
_scaled_adapted_grid(f, xscale, yscale, xmin, xmax)
|
||||
end
|
||||
@recipe function f(fs::AbstractArray{F}, xmin::Number, xmax::Number) where F<:Function
|
||||
xscale, yscale = [get(plotattributes, sym, :identity) for sym=(:xscale,:yscale)]
|
||||
xs = Any[_scaled_adapted_grid(f, xscale, yscale, xmin, xmax) for f in fs]
|
||||
xs, fs
|
||||
xs = Array{Any}(undef, length(fs))
|
||||
ys = Array{Any}(undef, length(fs))
|
||||
for (i, (x, y)) in enumerate(_scaled_adapted_grid(f, xscale, yscale, xmin, xmax) for f in fs)
|
||||
xs[i] = x
|
||||
ys[i] = y
|
||||
end
|
||||
xs, ys
|
||||
end
|
||||
@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, u::AVec) where {F<:Function,G<:Function} = mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u)
|
||||
@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, umin::Number, umax::Number, n = 200) where {F<:Function,G<:Function} = fx, fy, range(umin, stop = umax, length = n)
|
||||
|
||||
function _scaled_adapted_grid(f, xscale, yscale, xmin, xmax)
|
||||
(xf, xinv), (yf, yinv) = ((scalefunc(s),invscalefunc(s)) for s in (xscale,yscale))
|
||||
xinv.(adapted_grid(yf∘f∘xinv, xf.((xmin, xmax))))
|
||||
xs, ys = adapted_grid(yf∘f∘xinv, xf.((xmin, xmax)))
|
||||
xinv.(xs), yinv.(ys)
|
||||
end
|
||||
|
||||
#
|
||||
@@ -547,36 +552,17 @@ end
|
||||
#
|
||||
#
|
||||
# # --------------------------------------------------------------------
|
||||
# # Lists of tuples and StaticArrays
|
||||
# # Lists of tuples and GeometryTypes.Points
|
||||
# # --------------------------------------------------------------------
|
||||
#
|
||||
# # if we get an unhandled tuple, just splat it in
|
||||
@recipe f(tup::Tuple) = tup
|
||||
|
||||
#
|
||||
# # (x,y) tuples
|
||||
@recipe f(xy::AVec{Tuple{R1,R2}}) where {R1<:Number,R2<:Number} = unzip(xy)
|
||||
@recipe f(xy::Tuple{R1,R2}) where {R1<:Number,R2<:Number} = [xy[1]], [xy[2]]
|
||||
@recipe f(v::AVec{<:Tuple}) = unzip(v)
|
||||
@recipe f(v::AVec{<:GeometryTypes.Point}) = unzip(v)
|
||||
@recipe f(tup::Tuple) = [tup]
|
||||
@recipe f(p::GeometryTypes.Point) = [p]
|
||||
|
||||
#
|
||||
# # (x,y,z) tuples
|
||||
@recipe f(xyz::AVec{Tuple{R1,R2,R3}}) where {R1<:Number,R2<:Number,R3<:Number} = unzip(xyz)
|
||||
@recipe f(xyz::Tuple{R1,R2,R3}) where {R1<:Number,R2<:Number,R3<:Number} = [xyz[1]], [xyz[2]], [xyz[3]]
|
||||
|
||||
# these might be points+velocity, or OHLC or something else
|
||||
@recipe f(xyuv::AVec{Tuple{R1,R2,R3,R4}}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv)
|
||||
@recipe f(xyuv::Tuple{R1,R2,R3,R4}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = [xyuv[1]], [xyuv[2]], [xyuv[3]], [xyuv[4]]
|
||||
|
||||
|
||||
#
|
||||
# # 2D StaticArrays
|
||||
@recipe f(xy::AVec{StaticArrays.SVector{2,T}}) where {T<:Number} = unzip(xy)
|
||||
@recipe f(xy::StaticArrays.SVector{2,T}) where {T<:Number} = [xy[1]], [xy[2]]
|
||||
|
||||
#
|
||||
# # 3D StaticArrays
|
||||
@recipe f(xyz::AVec{StaticArrays.SVector{3,T}}) where {T<:Number} = unzip(xyz)
|
||||
@recipe f(xyz::StaticArrays.SVector{3,T}) where {T<:Number} = [xyz[1]], [xyz[2]], [xyz[3]]
|
||||
# Special case for 4-tuples in :ohlc series
|
||||
@recipe f(xyuv::AVec{<:Tuple{R1,R2,R3,R4}}) where {R1,R2,R3,R4} = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv)
|
||||
|
||||
#
|
||||
# # --------------------------------------------------------------------
|
||||
@@ -597,7 +583,7 @@ end
|
||||
# end
|
||||
|
||||
splittable_kw(key, val, lengthGroup) = false
|
||||
splittable_kw(key, val::AbstractArray, lengthGroup) = (key != :group) && size(val,1) == lengthGroup
|
||||
splittable_kw(key, val::AbstractArray, lengthGroup) = !(key in (:group, :color_palette)) && length(axes(val,1)) == lengthGroup
|
||||
splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengthGroup))
|
||||
splittable_kw(key, val::SeriesAnnotations, lengthGroup) = splittable_kw(key, val.strs, lengthGroup)
|
||||
|
||||
@@ -611,7 +597,7 @@ end
|
||||
function groupedvec2mat(x_ind, x, y::AbstractArray, groupby, def_val = y[1])
|
||||
y_mat = Array{promote_type(eltype(y), typeof(def_val))}(undef, length(keys(x_ind)), length(groupby.groupLabels))
|
||||
fill!(y_mat, def_val)
|
||||
for i in 1:length(groupby.groupLabels)
|
||||
for i in eachindex(groupby.groupLabels)
|
||||
xi = x[groupby.groupIds[i]]
|
||||
yi = y[groupby.groupIds[i]]
|
||||
y_mat[getindex.(Ref(x_ind), xi), i] = yi
|
||||
@@ -644,7 +630,7 @@ group_as_matrix(t) = false
|
||||
if length(g.args) == 1
|
||||
x = zeros(Int, lengthGroup)
|
||||
for indexes in groupby.groupIds
|
||||
x[indexes] = 1:length(indexes)
|
||||
x[indexes] = eachindex(indexes)
|
||||
end
|
||||
last_args = g.args
|
||||
else
|
||||
@@ -652,7 +638,7 @@ group_as_matrix(t) = false
|
||||
last_args = g.args[2:end]
|
||||
end
|
||||
x_u = unique(sort(x))
|
||||
x_ind = Dict(zip(x_u, 1:length(x_u)))
|
||||
x_ind = Dict(zip(x_u, eachindex(x_u)))
|
||||
for (key,val) in plotattributes
|
||||
if splittable_kw(key, val, lengthGroup)
|
||||
:($key) := groupedvec2mat(x_ind, x, val, groupby)
|
||||
|
||||
@@ -0,0 +1,455 @@
|
||||
"""
|
||||
scatter(x,y)
|
||||
scatter!(x,y)
|
||||
|
||||
Make a scatter plot of y vs x.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> scatter([1,2,3],[4,5,6],markersize=[3,4,5],markercolor=[:red,:green,:blue])
|
||||
julia> scatter([(1,4),(2,5),(3,6)])
|
||||
```
|
||||
"""
|
||||
@shorthands scatter
|
||||
|
||||
"""
|
||||
bar(x,y)
|
||||
bar!(x,y)
|
||||
|
||||
Make a bar plot of y vs x.
|
||||
|
||||
# Arguments
|
||||
|
||||
- $(_document_argument("bar_position"))
|
||||
- $(_document_argument("bar_width"))
|
||||
- $(_document_argument("bar_edges"))
|
||||
- $(_document_argument("orientation"))
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> bar([1,2,3],[4,5,6],fillcolor=[:red,:green,:blue],fillalpha=[0.2,0.4,0.6])
|
||||
julia> bar([(1,4),(2,5),(3,6)])
|
||||
```
|
||||
"""
|
||||
@shorthands bar
|
||||
|
||||
@shorthands barh
|
||||
|
||||
"""
|
||||
histogram(x)
|
||||
histogram!(x)
|
||||
|
||||
Plot a histogram.
|
||||
|
||||
# Arguments
|
||||
|
||||
- `x`: AbstractVector of values to be binned
|
||||
- $(_document_argument("bins"))
|
||||
- `weights`: Vector of weights for the values in `x`, for weighted bin counts
|
||||
- $(_document_argument("normalize"))
|
||||
- $(_document_argument("bar_position"))
|
||||
- $(_document_argument("bar_width"))
|
||||
- $(_document_argument("bar_edges"))
|
||||
- $(_document_argument("orientation"))
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> histogram([1,2,1,1,4,3,8],bins=0:8)
|
||||
```
|
||||
"""
|
||||
@shorthands histogram
|
||||
|
||||
"""
|
||||
barhist(x)
|
||||
barhist!(x)
|
||||
|
||||
Make a histogram bar plot. See `histogram`.
|
||||
"""
|
||||
@shorthands barhist
|
||||
|
||||
"""
|
||||
stephist(x)
|
||||
stephist(x)
|
||||
|
||||
Make a histogram step plot (bin counts are represented using horizontal lines
|
||||
instead of bars). See `histogram`.
|
||||
"""
|
||||
@shorthands stephist
|
||||
|
||||
"""
|
||||
scatterhist(x)
|
||||
scatterhist!(x)
|
||||
|
||||
Make a histogram scatter plot (bin counts are represented using points
|
||||
instead of bars). See `histogram`.
|
||||
"""
|
||||
@shorthands scatterhist
|
||||
|
||||
"""
|
||||
histogram2d(x,y)
|
||||
histogram2d!(x,y)
|
||||
|
||||
Plot a two-dimensional histogram.
|
||||
|
||||
# Arguments
|
||||
|
||||
- `bins`: Number of bins (if an `Integer`) or bin edges (if an `AbtractVector`)
|
||||
- `weights`: Vector of weights for the values in `x`. Each entry of x contributes
|
||||
its weight to the height of its bin.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> histogram2d(randn(10_000),randn(10_000))
|
||||
```
|
||||
"""
|
||||
@shorthands histogram2d
|
||||
|
||||
"""
|
||||
density(x)
|
||||
density!(x)
|
||||
|
||||
Make a line plot of a kernel density estimate of x.
|
||||
|
||||
# Arguments
|
||||
|
||||
- `x`: AbstractVector of samples for probability density estimation
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> using StatsPlots
|
||||
julia> density(randn(100_000))
|
||||
```
|
||||
"""
|
||||
@shorthands density
|
||||
|
||||
"""
|
||||
heatmap(x,y,z)
|
||||
heatmap!(x,y,z)
|
||||
|
||||
Plot a heatmap of the rectangular array `z`.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> heatmap(randn(10,10))
|
||||
```
|
||||
"""
|
||||
@shorthands heatmap
|
||||
@shorthands plots_heatmap
|
||||
|
||||
"""
|
||||
hexbin(x,y)
|
||||
hexbin!(x,y)
|
||||
|
||||
Make a hexagonal binning plot (a histogram of the observations `(x[i],y[i])`
|
||||
with hexagonal bins)
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> hexbin(randn(10_000), randn(10_000))
|
||||
```
|
||||
"""
|
||||
@shorthands hexbin
|
||||
|
||||
"""
|
||||
sticks(x,y)
|
||||
sticks!(x,y)
|
||||
|
||||
Draw a stick plot of y vs x.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> sticks(1:10)
|
||||
```
|
||||
"""
|
||||
@shorthands sticks
|
||||
|
||||
"""
|
||||
hline(y)
|
||||
hline!(y)
|
||||
|
||||
Draw horizontal lines at positions specified by the values in
|
||||
the AbstractVector `y`
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> hline([-1,0,2])
|
||||
```
|
||||
"""
|
||||
@shorthands hline
|
||||
|
||||
"""
|
||||
vline(x)
|
||||
vline!(x)
|
||||
|
||||
Draw vertical lines at positions specified by the values in
|
||||
the AbstractVector `x`
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> vline([-1,0,2])
|
||||
```
|
||||
"""
|
||||
@shorthands vline
|
||||
|
||||
"""
|
||||
hspan(y)
|
||||
|
||||
Draw a rectangle between the horizontal line at position `y[1]`
|
||||
and the horizontal line at position `y[2]`. If `length(y) ≥ 4`,
|
||||
then further rectangles are drawn between `y[3]` and `y[4]`,
|
||||
`y[5]` and `y[6]`, and so on. If `length(y)` is odd, then the
|
||||
last entry of `y` is ignored.
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> hspan(1:6)
|
||||
```
|
||||
"""
|
||||
@shorthands hspan
|
||||
|
||||
"""
|
||||
vspan(x)
|
||||
|
||||
Draw a rectangle between the vertical line at position `x[1]`
|
||||
and the vertical line at position `x[2]`. If `length(x) ≥ 4`,
|
||||
then further rectangles are drawn between `x[3]` and `x[4]`,
|
||||
`x[5]` and `x[6]`, and so on. If `length(x)` is odd, then the
|
||||
last entry of `x` is ignored.
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> vspan(1:6)
|
||||
```
|
||||
"""
|
||||
@shorthands vspan
|
||||
|
||||
"""
|
||||
ohlc(x,y::Vector{OHLC})
|
||||
ohlc!(x,y::Vector{OHLC})
|
||||
|
||||
Make open-high-low-close plot. Each entry of y is represented by a vertical
|
||||
segment extending from the low value to the high value, with short horizontal
|
||||
segments on the left and right indicating the open and close values, respectively.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> meanprices = cumsum(randn(100))
|
||||
julia> y = OHLC[(p+rand(),p+1,p-1,p+rand()) for p in meanprices]
|
||||
julia> ohlc(y)
|
||||
```
|
||||
"""
|
||||
@shorthands ohlc
|
||||
|
||||
|
||||
"""
|
||||
contour(x,y,z)
|
||||
contour!(x,y,z)
|
||||
|
||||
Draw contour lines of the `Surface` z.
|
||||
|
||||
# Arguments
|
||||
- `levels`: Contour levels (if `AbstractVector`) or number of levels (if `Integer`)
|
||||
- `fill`: Bool. Fill area between contours or draw contours only (false by default)
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> x = y = range(-20, 20, length = 100)
|
||||
julia> contour(x, y, (x, y) -> x^2 + y^2)
|
||||
```
|
||||
"""
|
||||
@shorthands contour
|
||||
|
||||
"An alias for `contour` with fill = true."
|
||||
@shorthands contourf
|
||||
|
||||
|
||||
@shorthands contour3d
|
||||
|
||||
"""
|
||||
surface(x,y,z)
|
||||
surface!(x,y,z)
|
||||
|
||||
Draw a 3D surface plot.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> x = y = range(-3, 3, length = 100)
|
||||
julia> surface(x, y, (x, y) -> sinc(norm([x, y])))
|
||||
```
|
||||
"""
|
||||
@shorthands surface
|
||||
|
||||
"""
|
||||
wireframe(x,y,z)
|
||||
wireframe!(x,y,z)
|
||||
|
||||
Draw a 3D wireframe plot.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> wireframe(1:10,1:10,randn(10,10))
|
||||
```
|
||||
"""
|
||||
@shorthands wireframe
|
||||
|
||||
"""
|
||||
path3d(x,y,z)
|
||||
path3d!(x,y,z)
|
||||
|
||||
Plot a 3D path from `(x[1],y[1],z[1])` to `(x[2],y[2],z[2])`,
|
||||
..., to `(x[end],y[end],z[end])`.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> path3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
|
||||
```
|
||||
"""
|
||||
@shorthands path3d
|
||||
|
||||
"""
|
||||
scatter3d(x,y,z)
|
||||
scatter3d!(x,y,z)
|
||||
|
||||
Make a 3D scatter plot.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> scatter3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
|
||||
```
|
||||
"""
|
||||
@shorthands scatter3d
|
||||
|
||||
"""
|
||||
boxplot(x, y)
|
||||
boxplot!(x, y)
|
||||
|
||||
Make a box and whisker plot.
|
||||
|
||||
# Keyword arguments
|
||||
- `notch`: Bool. Notch the box plot? (false)
|
||||
- `range`: Real. Values more than range*IQR below the first quartile
|
||||
or above the third quartile are shown as outliers (1.5)
|
||||
- `outliers`: Bool. Show outliers? (true)
|
||||
- `whisker_width`: Real or Symbol. Length of whiskers (:match)
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> using StatsPlots
|
||||
julia> boxplot(repeat([1,2,3],outer=100),randn(300))
|
||||
```
|
||||
"""
|
||||
@shorthands boxplot
|
||||
|
||||
"""
|
||||
violin(x,y,z)
|
||||
violin!(x,y,z)
|
||||
|
||||
Make a violin plot.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> violin(repeat([1,2,3],outer=100),randn(300))
|
||||
```
|
||||
"""
|
||||
@shorthands violin
|
||||
|
||||
"""
|
||||
quiver(x,y,quiver=(u,v))
|
||||
quiver!(x,y,quiver=(u,v))
|
||||
|
||||
Make a quiver (vector field) plot. The `i`th vector extends
|
||||
from `(x[i],y[i])` to `(x[i] + u[i], y[i] + v[i])`.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> quiver([1,2,3],[3,2,1],quiver=([1,1,1],[1,2,3]))
|
||||
```
|
||||
"""
|
||||
@shorthands quiver
|
||||
|
||||
"""
|
||||
curves(x,y)
|
||||
curves!(x,y)
|
||||
|
||||
Draw a Bezier curve from `(x[1],y[1])` to `(x[end],y[end])`
|
||||
with control points `(x[2],y[2]), ..., (x[end-1],y[end]-1)`
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> curves([1,2,3,4],[1,1,2,4])
|
||||
```
|
||||
"""
|
||||
@shorthands curves
|
||||
|
||||
"Plot a pie diagram"
|
||||
pie(args...; kw...) = plot(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
|
||||
pie!(args...; kw...) = plot!(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
|
||||
|
||||
"Plot with seriestype :path3d"
|
||||
plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d)
|
||||
plot3d!(args...; kw...) = plot!(args...; kw..., seriestype = :path3d)
|
||||
|
||||
"Add title to an existing plot"
|
||||
title!(s::AbstractString; kw...) = plot!(; title = s, kw...)
|
||||
|
||||
"Add xlabel to an existing plot"
|
||||
xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...)
|
||||
|
||||
"Add ylabel to an existing plot"
|
||||
ylabel!(s::AbstractString; kw...) = plot!(; ylabel = s, kw...)
|
||||
|
||||
"Set xlims for an existing plot"
|
||||
xlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; xlims = lims, kw...)
|
||||
|
||||
"Set ylims for an existing plot"
|
||||
ylims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; ylims = lims, kw...)
|
||||
|
||||
"Set zlims for an existing plot"
|
||||
zlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; zlims = lims, kw...)
|
||||
|
||||
xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin,xmax), kw...)
|
||||
ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...)
|
||||
zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmin,zmax), kw...)
|
||||
|
||||
|
||||
"Set xticks for an existing plot"
|
||||
xticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; xticks = v, kw...)
|
||||
|
||||
"Set yticks for an existing plot"
|
||||
yticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; yticks = v, kw...)
|
||||
|
||||
xticks!(
|
||||
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...)
|
||||
yticks!(
|
||||
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; yticks = (ticks,labels), kw...)
|
||||
|
||||
"""
|
||||
annotate!(anns...)
|
||||
|
||||
Add annotations to an existing plot.
|
||||
|
||||
# Arguments
|
||||
|
||||
- `anns`: An `AbstractVector` of tuples of the form (x,y,text). The text object
|
||||
can be an String or PlotText
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> plot(1:10)
|
||||
julia> annotate!([(7,3,"(7,3)"),(3,7,text("hey", 14, :left, :top, :green))])
|
||||
```
|
||||
"""
|
||||
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
|
||||
annotate!(anns::AVec{T}; kw...) where {T<:Tuple} = plot!(; annotation = anns, kw...)
|
||||
|
||||
"Flip the current plots' x axis"
|
||||
xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...)
|
||||
|
||||
"Flip the current plots' y axis"
|
||||
yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...)
|
||||
|
||||
"Specify x axis attributes for an existing plot"
|
||||
xaxis!(args...; kw...) = plot!(; xaxis = args, kw...)
|
||||
|
||||
"Specify y axis attributes for an existing plot"
|
||||
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
|
||||
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
|
||||
ygrid!(args...; kw...) = plot!(; ygrid = args, kw...)
|
||||
+17
-34
@@ -4,39 +4,19 @@
|
||||
Specify the colour theme for plots.
|
||||
"""
|
||||
function theme(s::Symbol; kw...)
|
||||
defaults = _get_defaults(s)
|
||||
defaults = copy(PlotThemes._themes[s].defaults)
|
||||
_theme(s, defaults; kw...)
|
||||
end
|
||||
|
||||
function _get_defaults(s::Symbol)
|
||||
thm = PlotThemes._themes[s]
|
||||
if :defaults in fieldnames(typeof(thm))
|
||||
return thm.defaults
|
||||
else # old PlotTheme type
|
||||
defaults = KW(
|
||||
:bg => thm.bg_secondary,
|
||||
:bginside => thm.bg_primary,
|
||||
:fg => thm.lines,
|
||||
:fgtext => thm.text,
|
||||
:fgguide => thm.text,
|
||||
:fglegend => thm.text,
|
||||
:palette => thm.palette,
|
||||
)
|
||||
if thm.gradient != nothing
|
||||
push!(defaults, :gradient => thm.gradient)
|
||||
end
|
||||
return defaults
|
||||
end
|
||||
end
|
||||
|
||||
function _theme(s::Symbol, defaults::KW; kw...)
|
||||
# Reset to defaults to overwrite active theme
|
||||
reset_defaults()
|
||||
|
||||
# Set the theme's gradient as default
|
||||
if haskey(defaults, :gradient)
|
||||
if haskey(defaults, :colorgradient)
|
||||
PlotUtils.clibrary(:misc)
|
||||
PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s))
|
||||
pop!(defaults, :colorgradient)
|
||||
else
|
||||
PlotUtils.clibrary(:Plots)
|
||||
PlotUtils.default_cgrad(default = :sequential, sequential = :inferno)
|
||||
@@ -44,8 +24,8 @@ function _theme(s::Symbol, defaults::KW; kw...)
|
||||
|
||||
# maybe overwrite the theme's gradient
|
||||
kw = KW(kw)
|
||||
if haskey(kw, :gradient)
|
||||
kwgrad = pop!(kw, :gradient)
|
||||
if haskey(kw, :colorgradient)
|
||||
kwgrad = pop!(kw, :colorgradient)
|
||||
for clib in clibraries()
|
||||
if kwgrad in cgradients(clib)
|
||||
PlotUtils.clibrary(clib)
|
||||
@@ -74,11 +54,11 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
|
||||
|
||||
@recipe function showtheme(st::ShowTheme)
|
||||
thm, cfunc = _get_showtheme_args(st.args...)
|
||||
defaults = _get_defaults(thm)
|
||||
defaults = PlotThemes._themes[thm].defaults
|
||||
|
||||
# get the gradient
|
||||
gradient_colors = get(defaults, :gradient, cgrad(:inferno).colors)
|
||||
gradient = cgrad(cfunc.(RGB.(gradient_colors)))
|
||||
gradient_colors = get(defaults, :colorgradient, cgrad(:inferno).colors)
|
||||
colorgradient = cgrad(cfunc.(RGB.(gradient_colors)))
|
||||
|
||||
# get the palette
|
||||
palette = get(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17))
|
||||
@@ -86,7 +66,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
|
||||
|
||||
# apply the theme
|
||||
for k in keys(defaults)
|
||||
k in (:gradient, :palette) && continue
|
||||
k in (:colorgradient, :palette) && continue
|
||||
def = defaults[k]
|
||||
arg = get(_keyAliases, k, k)
|
||||
plotattributes[arg] = if typeof(def) <: Colorant
|
||||
@@ -139,27 +119,30 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
|
||||
@series begin
|
||||
subplot := 4
|
||||
seriestype := :heatmap
|
||||
seriescolor := gradient
|
||||
ticks := -5:5:5
|
||||
seriescolor := colorgradient
|
||||
xticks := (-2π:2π:2π, string.(-2:2:2, "π"))
|
||||
yticks := (-2π:2π:2π, string.(-2:2:2, "π"))
|
||||
x, y, z
|
||||
end
|
||||
|
||||
@series begin
|
||||
subplot := 5
|
||||
seriestype := :surface
|
||||
seriescolor := gradient
|
||||
seriescolor := colorgradient
|
||||
xticks := (-2π:2π:2π, string.(-2:2:2, "π"))
|
||||
yticks := (-2π:2π:2π, string.(-2:2:2, "π"))
|
||||
x, y, z
|
||||
end
|
||||
|
||||
n = 100
|
||||
ts = range(0, stop = 10π, length = n)
|
||||
x = ts .* cos.(ts)
|
||||
x = (0.1ts) .* cos.(ts)
|
||||
y = (0.1ts) .* sin.(ts)
|
||||
z = 1:n
|
||||
|
||||
@series begin
|
||||
subplot := 6
|
||||
seriescolor := gradient
|
||||
seriescolor := colorgradient
|
||||
linewidth := 3
|
||||
line_z := z
|
||||
x, y, z
|
||||
|
||||
+210
-138
@@ -26,7 +26,7 @@ function histogramHack(; kw...)
|
||||
plotattributes[:x] = midpoints
|
||||
plotattributes[:y] = float(counts)
|
||||
plotattributes[:seriestype] = :bar
|
||||
plotattributes[:fillrange] = plotattributes[:fillrange] == nothing ? 0.0 : plotattributes[:fillrange]
|
||||
plotattributes[:fillrange] = plotattributes[:fillrange] === nothing ? 0.0 : plotattributes[:fillrange]
|
||||
plotattributes
|
||||
end
|
||||
|
||||
@@ -38,12 +38,12 @@ function barHack(; kw...)
|
||||
plotattributes = KW(kw)
|
||||
midpoints = plotattributes[:x]
|
||||
heights = plotattributes[:y]
|
||||
fillrange = plotattributes[:fillrange] == nothing ? 0.0 : plotattributes[:fillrange]
|
||||
fillrange = plotattributes[:fillrange] === nothing ? 0.0 : plotattributes[:fillrange]
|
||||
|
||||
# estimate the edges
|
||||
dists = diff(midpoints) * 0.5
|
||||
edges = zeros(length(midpoints)+1)
|
||||
for i in 1:length(edges)
|
||||
for i in eachindex(edges)
|
||||
if i == 1
|
||||
edge = midpoints[1] - dists[1]
|
||||
elseif i == length(edges)
|
||||
@@ -56,7 +56,7 @@ function barHack(; kw...)
|
||||
|
||||
x = Float64[]
|
||||
y = Float64[]
|
||||
for i in 1:length(heights)
|
||||
for i in eachindex(heights)
|
||||
e1, e2 = edges[i:i+1]
|
||||
append!(x, [e1, e1, e2, e2])
|
||||
append!(y, [fillrange, heights[i], heights[i], fillrange])
|
||||
@@ -81,7 +81,7 @@ function sticksHack(; kw...)
|
||||
# these are the line vertices
|
||||
x = Float64[]
|
||||
y = Float64[]
|
||||
fillrange = plotattributesLine[:fillrange] == nothing ? 0.0 : plotattributesLine[:fillrange]
|
||||
fillrange = plotattributesLine[:fillrange] === nothing ? 0.0 : plotattributesLine[:fillrange]
|
||||
|
||||
# calculate the vertices
|
||||
yScatter = plotattributesScatter[:y]
|
||||
@@ -115,7 +115,6 @@ function regressionXY(x, y)
|
||||
end
|
||||
|
||||
function replace_image_with_heatmap(z::Array{T}) where T<:Colorant
|
||||
@show T, size(z)
|
||||
n, m = size(z)
|
||||
# idx = 0
|
||||
colors = ColorGradient(vec(z))
|
||||
@@ -146,16 +145,18 @@ end
|
||||
|
||||
Segments() = Segments(Float64)
|
||||
Segments(::Type{T}) where {T} = Segments(T[])
|
||||
Segments(p::Int) = Segments(NTuple{2,Float64}[])
|
||||
Segments(p::Int) = Segments(NTuple{p, Float64}[])
|
||||
|
||||
|
||||
# Segments() = Segments(zeros(0))
|
||||
|
||||
to_nan(::Type{Float64}) = NaN
|
||||
to_nan(::Type{NTuple{2,Float64}}) = (NaN, NaN)
|
||||
to_nan(::Type{NTuple{3,Float64}}) = (NaN, NaN, NaN)
|
||||
|
||||
coords(segs::Segments{Float64}) = segs.pts
|
||||
coords(segs::Segments{NTuple{2,Float64}}) = Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts]
|
||||
coords(segs::Segments{NTuple{3,Float64}}) = Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts], Float64[p[3] for p in segs.pts]
|
||||
|
||||
function Base.push!(segments::Segments{T}, vs...) where T
|
||||
if !isempty(segments.pts)
|
||||
@@ -183,22 +184,26 @@ end
|
||||
|
||||
mutable struct SegmentsIterator
|
||||
args::Tuple
|
||||
n::Int
|
||||
n1::Int
|
||||
n2::Int
|
||||
end
|
||||
|
||||
function iter_segments(args...)
|
||||
tup = Plots.wraptuple(args)
|
||||
n = maximum(map(length, tup))
|
||||
SegmentsIterator(tup, n)
|
||||
n1 = minimum(map(firstindex, tup))
|
||||
n2 = maximum(map(lastindex, tup))
|
||||
SegmentsIterator(tup, n1, n2)
|
||||
end
|
||||
|
||||
function iter_segments(series::Series)
|
||||
x, y, z = series[:x], series[:y], series[:z]
|
||||
if has_attribute_segments(series)
|
||||
if x === nothing
|
||||
return UnitRange{Int}[]
|
||||
elseif has_attribute_segments(series)
|
||||
if series[:seriestype] in (:scatter, :scatter3d)
|
||||
return [[i] for i in 1:length(y)]
|
||||
return [[i] for i in eachindex(y)]
|
||||
else
|
||||
return [i:(i + 1) for i in 1:(length(y) - 1)]
|
||||
return [i:(i + 1) for i in firstindex(y):lastindex(y)-1]
|
||||
end
|
||||
else
|
||||
segs = UnitRange{Int}[]
|
||||
@@ -212,36 +217,19 @@ end
|
||||
|
||||
# helpers to figure out if there are NaN values in a list of array types
|
||||
anynan(i::Int, args::Tuple) = any(a -> try isnan(_cycle(a,i)) catch MethodError false end, args)
|
||||
anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend)
|
||||
allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:iend)
|
||||
anynan(args::Tuple) = i -> anynan(i,args)
|
||||
anynan(istart::Int, iend::Int, args::Tuple) = any(anynan(args), istart:iend)
|
||||
allnan(istart::Int, iend::Int, args::Tuple) = all(anynan(args), istart:iend)
|
||||
|
||||
function Base.iterate(itr::SegmentsIterator, nextidx::Int = 1)
|
||||
nextidx > itr.n && return nothing
|
||||
if nextidx == 1 && !any(isempty,itr.args) && anynan(1, itr.args)
|
||||
nextidx = 2
|
||||
end
|
||||
function Base.iterate(itr::SegmentsIterator, nextidx::Int = itr.n1)
|
||||
i = findfirst(!anynan(itr.args), nextidx:itr.n2)
|
||||
i === nothing && return nothing
|
||||
nextval = nextidx + i - 1
|
||||
|
||||
i = istart = iend = nextidx
|
||||
j = findfirst(anynan(itr.args), nextval:itr.n2)
|
||||
nextnan = j === nothing ? itr.n2 + 1 : nextval + j - 1
|
||||
|
||||
# find the next NaN, and iend is the one before
|
||||
while i <= itr.n + 1
|
||||
if i > itr.n || anynan(i, itr.args)
|
||||
# done... array end or found NaN
|
||||
iend = i-1
|
||||
break
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
|
||||
# find the next non-NaN, and set nextidx
|
||||
while i <= itr.n
|
||||
if !anynan(i, itr.args)
|
||||
break
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
|
||||
istart:iend, i
|
||||
nextval:nextnan-1, nextnan
|
||||
end
|
||||
|
||||
# Find minimal type that can contain NaN and x
|
||||
@@ -273,6 +261,9 @@ _cycle(v, indices::AVec{Int}) = fill(v, length(indices))
|
||||
_cycle(grad::ColorGradient, idx::Int) = _cycle(grad.colors, idx)
|
||||
_cycle(grad::ColorGradient, indices::AVec{Int}) = _cycle(grad.colors, indices)
|
||||
|
||||
_as_gradient(grad::ColorGradient) = grad
|
||||
_as_gradient(c::Colorant) = ColorGradient([c,c])
|
||||
|
||||
makevec(v::AVec) = v
|
||||
makevec(v::T) where {T} = T[v]
|
||||
|
||||
@@ -283,18 +274,17 @@ maketuple(x::Tuple{T,S}) where {T,S} = x
|
||||
mapFuncOrFuncs(f::Function, u::AVec) = map(f, u)
|
||||
mapFuncOrFuncs(fs::AVec{F}, u::AVec) where {F<:Function} = [map(f, u) for f in fs]
|
||||
|
||||
unzip(xy::AVec{Tuple{X,Y}}) where {X,Y} = [t[1] for t in xy], [t[2] for t in xy]
|
||||
unzip(xyz::AVec{Tuple{X,Y,Z}}) where {X,Y,Z} = [t[1] for t in xyz], [t[2] for t in xyz], [t[3] for t in xyz]
|
||||
unzip(xyuv::AVec{Tuple{X,Y,U,V}}) where {X,Y,U,V} = [t[1] for t in xyuv], [t[2] for t in xyuv], [t[3] for t in xyuv], [t[4] for t in xyuv]
|
||||
for i in 2:4
|
||||
@eval begin
|
||||
unzip(v::Union{AVec{<:Tuple{Vararg{T,$i} where T}},
|
||||
AVec{<:GeometryTypes.Point{$i}}}) = $(Expr(:tuple, (:([t[$j] for t in v]) for j=1:i)...))
|
||||
end
|
||||
end
|
||||
|
||||
unzip(xy::AVec{StaticArrays.SVector{2,T}}) where {T} = T[t[1] for t in xy], T[t[2] for t in xy]
|
||||
unzip(xy::StaticArrays.SVector{2,T}) where {T} = T[xy[1]], T[xy[2]]
|
||||
|
||||
unzip(xyz::AVec{StaticArrays.SVector{3,T}}) where {T} = T[t[1] for t in xyz], T[t[2] for t in xyz], T[t[3] for t in xyz]
|
||||
unzip(xyz::StaticArrays.SVector{3,T}) where {T} = T[xyz[1]], T[xyz[2]], T[xyz[3]]
|
||||
|
||||
unzip(xyuv::AVec{StaticArrays.SVector{4,T}}) where {T} = T[t[1] for t in xyuv], T[t[2] for t in xyuv], T[t[3] for t in xyuv], T[t[4] for t in xyuv]
|
||||
unzip(xyuv::StaticArrays.SVector{4,T}) where {T} = T[xyuv[1]], T[xyuv[2]], T[xyuv[3]], T[xyuv[4]]
|
||||
unzip(v::Union{AVec{<:GeometryTypes.Point{N}},
|
||||
AVec{<:Tuple{Vararg{T,N} where T}}}) where N = error("$N-dimensional unzip not implemented.")
|
||||
unzip(v::Union{AVec{<:GeometryTypes.Point},
|
||||
AVec{<:Tuple}}) = error("Can't unzip points of different dimensions.")
|
||||
|
||||
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
|
||||
function _expand_limits(lims, x)
|
||||
@@ -356,8 +346,11 @@ const _scale_base = Dict{Symbol, Real}(
|
||||
:ln => ℯ,
|
||||
)
|
||||
|
||||
function _heatmap_edges(v::AVec)
|
||||
function _heatmap_edges(v::AVec, isedges::Bool = false)
|
||||
length(v) == 1 && return v[1] .+ [-0.5, 0.5]
|
||||
if isedges return v end
|
||||
# `isedges = true` means that v is a vector which already describes edges
|
||||
# and does not need to be extended.
|
||||
vmin, vmax = ignorenan_extrema(v)
|
||||
extra_min = (v[2] - v[1]) / 2
|
||||
extra_max = (v[end] - v[end - 1]) / 2
|
||||
@@ -365,43 +358,40 @@ function _heatmap_edges(v::AVec)
|
||||
end
|
||||
|
||||
"create an (n+1) list of the outsides of heatmap rectangles"
|
||||
function heatmap_edges(v::AVec, scale::Symbol = :identity)
|
||||
function heatmap_edges(v::AVec, scale::Symbol = :identity, isedges::Bool = false)
|
||||
f, invf = scalefunc(scale), invscalefunc(scale)
|
||||
map(invf, _heatmap_edges(map(f,v)))
|
||||
map(invf, _heatmap_edges(map(f,v), isedges))
|
||||
end
|
||||
|
||||
function calc_r_extrema(x, y)
|
||||
xmin, xmax = ignorenan_extrema(x)
|
||||
ymin, ymax = ignorenan_extrema(y)
|
||||
r = 0.5 * NaNMath.min(xmax - xmin, ymax - ymin)
|
||||
ignorenan_extrema(r)
|
||||
function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size::Tuple{Int, Int})
|
||||
nx, ny = length(x), length(y)
|
||||
# ismidpoints = z_size == (ny, nx) # This fails some tests, but would actually be
|
||||
# the correct check, since (4, 3) != (3, 4) and a missleading plot is produced.
|
||||
ismidpoints = prod(z_size) == (ny * nx)
|
||||
isedges = z_size == (ny - 1, nx - 1)
|
||||
if !ismidpoints && !isedges
|
||||
error("""Length of x & y does not match the size of z.
|
||||
Must be either `size(z) == (length(y), length(x))` (x & y define midpoints)
|
||||
or `size(z) == (length(y)+1, length(x)+1))` (x & y define edges).""")
|
||||
end
|
||||
x, y = heatmap_edges(x, xscale, isedges),
|
||||
heatmap_edges(y, yscale, isedges)
|
||||
return x, y
|
||||
end
|
||||
|
||||
function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y))
|
||||
function is_uniformly_spaced(v; tol=1e-6)
|
||||
dv = diff(v)
|
||||
maximum(dv) - minimum(dv) < tol * mean(abs.(dv))
|
||||
end
|
||||
|
||||
function convert_to_polar(theta, r, r_extrema = ignorenan_extrema(r))
|
||||
rmin, rmax = r_extrema
|
||||
theta, r = filter_radial_data(x, y, r_extrema)
|
||||
r = (r .- rmin) ./ (rmax .- rmin)
|
||||
x = r.*cos.(theta)
|
||||
y = r.*sin.(theta)
|
||||
x, y
|
||||
end
|
||||
|
||||
# Filters radial data for points within the axis limits
|
||||
function filter_radial_data(theta, r, r_extrema::Tuple{Real, Real})
|
||||
n = max(length(theta), length(r))
|
||||
rmin, rmax = r_extrema
|
||||
x, y = zeros(n), zeros(n)
|
||||
for i in 1:n
|
||||
x[i] = _cycle(theta, i)
|
||||
y[i] = _cycle(r, i)
|
||||
end
|
||||
points = map((a, b) -> (a, b), x, y)
|
||||
filter!(a -> a[2] >= rmin && a[2] <= rmax, points)
|
||||
x = map(a -> a[1], points)
|
||||
y = map(a -> a[2], points)
|
||||
x, y
|
||||
end
|
||||
|
||||
function fakedata(sz...)
|
||||
y = zeros(sz...)
|
||||
for r in 2:size(y,1)
|
||||
@@ -431,7 +421,7 @@ isvertical(series::Series) = isvertical(series.plotattributes)
|
||||
|
||||
ticksType(ticks::AVec{T}) where {T<:Real} = :ticks
|
||||
ticksType(ticks::AVec{T}) where {T<:AbstractString} = :labels
|
||||
ticksType(ticks::Tuple{T,S}) where {T<:AVec,S<:AVec} = :ticks_and_labels
|
||||
ticksType(ticks::Tuple{T,S}) where {T<:Union{AVec,Tuple},S<:Union{AVec,Tuple}} = :ticks_and_labels
|
||||
ticksType(ticks) = :invalid
|
||||
|
||||
limsType(lims::Tuple{T,S}) where {T<:Real,S<:Real} = :limits
|
||||
@@ -515,7 +505,7 @@ function make_fillrange_from_ribbon(kw::KW)
|
||||
rib1, rib2 = -first(rib), last(rib)
|
||||
# kw[:ribbon] = nothing
|
||||
kw[:fillrange] = make_fillrange_side(y, rib1), make_fillrange_side(y, rib2)
|
||||
(get(kw, :fillalpha, nothing) == nothing) && (kw[:fillalpha] = 0.5)
|
||||
(get(kw, :fillalpha, nothing) === nothing) && (kw[:fillalpha] = 0.5)
|
||||
end
|
||||
|
||||
#turn tuple of fillranges to one path
|
||||
@@ -527,7 +517,7 @@ function concatenate_fillrange(x,y::Tuple)
|
||||
end
|
||||
|
||||
function get_sp_lims(sp::Subplot, letter::Symbol)
|
||||
axis_limits(sp[Symbol(letter, :axis)])
|
||||
axis_limits(sp, letter)
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -561,14 +551,9 @@ zlims(sp_idx::Int = 1) = zlims(current(), sp_idx)
|
||||
|
||||
function get_clims(sp::Subplot)
|
||||
zmin, zmax = Inf, -Inf
|
||||
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface)
|
||||
for series in series_list(sp)
|
||||
for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z])
|
||||
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Real)
|
||||
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...)
|
||||
elseif (vals != nothing) && (eltype(vals) <: Real)
|
||||
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals)...)
|
||||
end
|
||||
if series[:colorbar_entry]
|
||||
zmin, zmax = _update_clims(zmin, zmax, get_clims(series)...)
|
||||
end
|
||||
end
|
||||
clims = sp[:clims]
|
||||
@@ -576,40 +561,82 @@ function get_clims(sp::Subplot)
|
||||
isfinite(clims[1]) && (zmin = clims[1])
|
||||
isfinite(clims[2]) && (zmax = clims[2])
|
||||
end
|
||||
return zmin < zmax ? (zmin, zmax) : (-0.1, 0.1)
|
||||
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
|
||||
end
|
||||
|
||||
_update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax)
|
||||
|
||||
function hascolorbar(series::Series)
|
||||
st = series[:seriestype]
|
||||
hascbar = st == :heatmap
|
||||
if st == :contour
|
||||
hascbar = (isscalar(series[:levels]) ? (series[:levels] > 1) : (length(series[:levels]) > 1)) && (length(unique(Array(series[:z]))) > 1)
|
||||
function get_clims(sp::Subplot, series::Series)
|
||||
zmin, zmax = if series[:colorbar_entry]
|
||||
get_clims(sp)
|
||||
else
|
||||
get_clims(series)
|
||||
end
|
||||
if series[:marker_z] != nothing || series[:line_z] != nothing || series[:fill_z] != nothing
|
||||
hascbar = true
|
||||
clims = sp[:clims]
|
||||
if is_2tuple(clims)
|
||||
isfinite(clims[1]) && (zmin = clims[1])
|
||||
isfinite(clims[2]) && (zmax = clims[2])
|
||||
end
|
||||
# no colorbar if we are creating a surface LightSource
|
||||
if xor(st == :surface, series[:fill_z] != nothing)
|
||||
hascbar = true
|
||||
end
|
||||
return hascbar
|
||||
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
|
||||
end
|
||||
|
||||
function hascolorbar(sp::Subplot)
|
||||
cbar = sp[:colorbar]
|
||||
hascbar = false
|
||||
if cbar != :none
|
||||
for series in series_list(sp)
|
||||
if hascolorbar(series)
|
||||
hascbar = true
|
||||
end
|
||||
function get_clims(series::Series)
|
||||
zmin, zmax = Inf, -Inf
|
||||
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface)
|
||||
for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z])
|
||||
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Union{Missing, Real})
|
||||
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...)
|
||||
elseif (vals !== nothing) && (eltype(vals) <: Union{Missing, Real})
|
||||
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals)...)
|
||||
end
|
||||
end
|
||||
hascbar
|
||||
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
|
||||
end
|
||||
|
||||
_update_clims(zmin, zmax, emin, emax) = NaNMath.min(zmin, emin), NaNMath.max(zmax, emax)
|
||||
|
||||
@enum ColorbarStyle cbar_gradient cbar_fill cbar_lines
|
||||
|
||||
function colorbar_style(series::Series)
|
||||
colorbar_entry = series[:colorbar_entry]
|
||||
if !(colorbar_entry isa Bool)
|
||||
@warn "Non-boolean colorbar_entry ignored."
|
||||
colorbar_entry = true
|
||||
end
|
||||
|
||||
if !colorbar_entry
|
||||
nothing
|
||||
elseif isfilledcontour(series)
|
||||
cbar_fill
|
||||
elseif iscontour(series)
|
||||
cbar_lines
|
||||
elseif series[:seriestype] ∈ (:heatmap,:surface) ||
|
||||
any(series[z] !== nothing for z ∈ [:marker_z,:line_z,:fill_z])
|
||||
cbar_gradient
|
||||
else
|
||||
nothing
|
||||
end
|
||||
end
|
||||
|
||||
hascolorbar(series::Series) = colorbar_style(series) !== nothing
|
||||
hascolorbar(sp::Subplot) = sp[:colorbar] != :none && any(hascolorbar(s) for s in series_list(sp))
|
||||
|
||||
iscontour(series::Series) = series[:seriestype] == :contour
|
||||
isfilledcontour(series::Series) = iscontour(series) && series[:fillrange] !== nothing
|
||||
|
||||
function contour_levels(series::Series, clims)
|
||||
iscontour(series) || error("Not a contour series")
|
||||
zmin, zmax = clims
|
||||
levels = series[:levels]
|
||||
if levels isa Integer
|
||||
levels = range(zmin, stop=zmax, length=levels+2)
|
||||
if !isfilledcontour(series)
|
||||
levels = levels[2:end-1]
|
||||
end
|
||||
end
|
||||
levels
|
||||
end
|
||||
|
||||
|
||||
|
||||
for comp in (:line, :fill, :marker)
|
||||
|
||||
compcolor = string(comp, :color)
|
||||
@@ -624,7 +651,7 @@ for comp in (:line, :fill, :marker)
|
||||
function $get_compcolor(series, cmin::Real, cmax::Real, i::Int = 1)
|
||||
c = series[$Symbol($compcolor)]
|
||||
z = series[$Symbol($comp_z)]
|
||||
if z == nothing
|
||||
if z === nothing
|
||||
isa(c, ColorGradient) ? c : plot_color(_cycle(c, i))
|
||||
else
|
||||
grad = isa(c, ColorGradient) ? c : cgrad()
|
||||
@@ -635,7 +662,7 @@ for comp in (:line, :fill, :marker)
|
||||
$get_compcolor(series, clims, i::Int = 1) = $get_compcolor(series, clims[1], clims[2], i)
|
||||
|
||||
function $get_compcolor(series, i::Int = 1)
|
||||
if series[$Symbol($comp_z)] == nothing
|
||||
if series[$Symbol($comp_z)] === nothing
|
||||
$get_compcolor(series, 0, 1, i)
|
||||
else
|
||||
$get_compcolor(series, get_clims(series[:subplot]), i)
|
||||
@@ -646,6 +673,9 @@ for comp in (:line, :fill, :marker)
|
||||
end
|
||||
end
|
||||
|
||||
single_color(c, v = 0.5) = c
|
||||
single_color(grad::ColorGradient, v = 0.5) = grad[v]
|
||||
|
||||
function get_linewidth(series, i::Int = 1)
|
||||
_cycle(series[:linewidth], i)
|
||||
end
|
||||
@@ -669,11 +699,11 @@ function has_attribute_segments(series::Series)
|
||||
for letter in (:x, :y, :z)
|
||||
# If we have NaNs in the data they define the segments and
|
||||
# SegmentsIterator is used
|
||||
series[letter] != nothing && NaN in collect(series[letter]) && return false
|
||||
series[letter] !== nothing && NaN in collect(series[letter]) && return false
|
||||
end
|
||||
series[:seriestype] == :shape && return false
|
||||
# ... else we check relevant attributes if they have multiple inputs
|
||||
return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z, :marker_z))
|
||||
return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :linestyle, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray for attr in (:line_z, :fill_z, :marker_z))
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
@@ -726,7 +756,7 @@ function with(f::Function, args...; kw...)
|
||||
|
||||
# save the backend
|
||||
if CURRENT_BACKEND.sym == :none
|
||||
pickDefaultBackend()
|
||||
_pick_default_backend()
|
||||
end
|
||||
oldbackend = CURRENT_BACKEND.sym
|
||||
|
||||
@@ -796,24 +826,24 @@ function debugplots(on = true)
|
||||
_debugMode.on = on
|
||||
end
|
||||
|
||||
debugshow(x) = show(x)
|
||||
debugshow(x::AbstractArray) = print(summary(x))
|
||||
debugshow(io, x) = show(io, x)
|
||||
debugshow(io, x::AbstractArray) = print(io, summary(x))
|
||||
|
||||
function dumpdict(plotattributes::KW, prefix = "", alwaysshow = false)
|
||||
function dumpdict(io::IO, plotattributes::KW, prefix = "", alwaysshow = false)
|
||||
_debugMode.on || alwaysshow || return
|
||||
println()
|
||||
println(io)
|
||||
if prefix != ""
|
||||
println(prefix, ":")
|
||||
println(io, prefix, ":")
|
||||
end
|
||||
for k in sort(collect(keys(plotattributes)))
|
||||
@printf("%14s: ", k)
|
||||
debugshow(plotattributes[k])
|
||||
println()
|
||||
debugshow(io, plotattributes[k])
|
||||
println(io)
|
||||
end
|
||||
println()
|
||||
println(io)
|
||||
end
|
||||
DD(plotattributes::KW, prefix = "") = dumpdict(plotattributes, prefix, true)
|
||||
|
||||
DD(io::IO, plotattributes::KW, prefix = "") = dumpdict(io, plotattributes, prefix, true)
|
||||
DD(plotattributes::KW, prefix = "") = DD(stdout, plotattributes, prefix)
|
||||
|
||||
function dumpcallstack()
|
||||
error() # well... you wanted the stacktrace, didn't you?!?
|
||||
@@ -1079,6 +1109,15 @@ legendfont(sp::Subplot) = font(
|
||||
sp[:legendfontcolor],
|
||||
)
|
||||
|
||||
legendtitlefont(sp::Subplot) = font(
|
||||
sp[:legendtitlefontfamily],
|
||||
sp[:legendtitlefontsize],
|
||||
sp[:legendtitlefontvalign],
|
||||
sp[:legendtitlefonthalign],
|
||||
sp[:legendtitlefontrotation],
|
||||
sp[:legendtitlefontcolor],
|
||||
)
|
||||
|
||||
tickfont(ax::Axis) = font(
|
||||
ax[:tickfontfamily],
|
||||
ax[:tickfontsize],
|
||||
@@ -1125,20 +1164,20 @@ function convert_sci_unicode(label::AbstractString)
|
||||
label
|
||||
end
|
||||
|
||||
function straightline_data(series)
|
||||
function straightline_data(series, expansion_factor = 1)
|
||||
sp = series[:subplot]
|
||||
xl, yl = isvertical(series) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp))
|
||||
x, y = series[:x], series[:y]
|
||||
n = length(x)
|
||||
if n == 2
|
||||
return straightline_data(xl, yl, x, y)
|
||||
return straightline_data(xl, yl, x, y, expansion_factor)
|
||||
else
|
||||
k, r = divrem(n, 3)
|
||||
if r == 0
|
||||
xdata, ydata = fill(NaN, n), fill(NaN, n)
|
||||
for i in 1:k
|
||||
inds = (3 * i - 2):(3 * i - 1)
|
||||
xdata[inds], ydata[inds] = straightline_data(xl, yl, x[inds], y[inds])
|
||||
xdata[inds], ydata[inds] = straightline_data(xl, yl, x[inds], y[inds], expansion_factor)
|
||||
end
|
||||
return xdata, ydata
|
||||
else
|
||||
@@ -1147,7 +1186,7 @@ function straightline_data(series)
|
||||
end
|
||||
end
|
||||
|
||||
function straightline_data(xl, yl, x, y)
|
||||
function straightline_data(xl, yl, x, y, expansion_factor = 1)
|
||||
x_vals, y_vals = if y[1] == y[2]
|
||||
if x[1] == x[2]
|
||||
error("Two identical points cannot be used to describe a straight line.")
|
||||
@@ -1168,29 +1207,28 @@ function straightline_data(xl, yl, x, y)
|
||||
end
|
||||
# expand the data outside the axis limits, by a certain factor too improve
|
||||
# plotly(js) and interactive behaviour
|
||||
factor = 100
|
||||
x_vals = x_vals .+ (x_vals[2] - x_vals[1]) .* factor .* [-1, 1]
|
||||
y_vals = y_vals .+ (y_vals[2] - y_vals[1]) .* factor .* [-1, 1]
|
||||
x_vals = x_vals .+ (x_vals[2] - x_vals[1]) .* expansion_factor .* [-1, 1]
|
||||
y_vals = y_vals .+ (y_vals[2] - y_vals[1]) .* expansion_factor .* [-1, 1]
|
||||
return x_vals, y_vals
|
||||
end
|
||||
|
||||
function shape_data(series)
|
||||
function shape_data(series, expansion_factor = 1)
|
||||
sp = series[:subplot]
|
||||
xl, yl = isvertical(series) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp))
|
||||
x, y = series[:x], series[:y]
|
||||
factor = 100
|
||||
for i in eachindex(x)
|
||||
if x[i] == -Inf
|
||||
x[i] = xl[1] - factor * (xl[2] - xl[1])
|
||||
x[i] = xl[1] - expansion_factor * (xl[2] - xl[1])
|
||||
elseif x[i] == Inf
|
||||
x[i] = xl[2] + factor * (xl[2] - xl[1])
|
||||
x[i] = xl[2] + expansion_factor * (xl[2] - xl[1])
|
||||
end
|
||||
end
|
||||
for i in eachindex(y)
|
||||
if y[i] == -Inf
|
||||
y[i] = yl[1] - factor * (yl[2] - yl[1])
|
||||
y[i] = yl[1] - expansion_factor * (yl[2] - yl[1])
|
||||
elseif y[i] == Inf
|
||||
y[i] = yl[2] + factor * (yl[2] - yl[1])
|
||||
y[i] = yl[2] + expansion_factor * (yl[2] - yl[1])
|
||||
end
|
||||
end
|
||||
return x, y
|
||||
@@ -1199,3 +1237,37 @@ end
|
||||
function construct_categorical_data(x::AbstractArray, axis::Axis)
|
||||
map(xi -> axis[:discrete_values][searchsortedfirst(axis[:continuous_values], xi)], x)
|
||||
end
|
||||
|
||||
_fmt_paragraph(paragraph::AbstractString;kwargs...) = _fmt_paragraph(IOBuffer(),paragraph,0;kwargs...)
|
||||
|
||||
function _fmt_paragraph(io::IOBuffer,
|
||||
remaining_text::AbstractString,
|
||||
column_count::Integer;
|
||||
fillwidth=60,
|
||||
leadingspaces=0)
|
||||
|
||||
kwargs = (fillwidth = fillwidth, leadingspaces = leadingspaces)
|
||||
|
||||
m = match(r"(.*?) (.*)",remaining_text)
|
||||
if isa(m,Nothing)
|
||||
if column_count + length(remaining_text) ≤ fillwidth
|
||||
print(io,remaining_text)
|
||||
String(take!(io))
|
||||
else
|
||||
print(io,"\n"*" "^leadingspaces*remaining_text)
|
||||
String(take!(io))
|
||||
end
|
||||
else
|
||||
if column_count + length(m[1]) ≤ fillwidth
|
||||
print(io,"$(m[1]) ")
|
||||
_fmt_paragraph(io,m[2],column_count + length(m[1]) + 1;kwargs...)
|
||||
else
|
||||
print(io,"\n"*" "^leadingspaces*"$(m[1]) ")
|
||||
_fmt_paragraph(io,m[2],leadingspaces;kwargs...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function _document_argument(S::AbstractString)
|
||||
_fmt_paragraph("`$S`: "*_arg_desc[Symbol(S)],leadingspaces = 6 + length(S))
|
||||
end
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
reference_images
|
||||
@@ -1,10 +0,0 @@
|
||||
StatPlots
|
||||
Images
|
||||
ImageMagick
|
||||
@osx QuartzImageIO
|
||||
FileIO
|
||||
GR 0.31.0
|
||||
RDatasets
|
||||
VisualRegressionTests
|
||||
UnicodePlots
|
||||
LaTeXStrings
|
||||
@@ -1,46 +0,0 @@
|
||||
using Pkg
|
||||
|
||||
# need this to use Conda
|
||||
# ENV["PYTHON"] = ""
|
||||
|
||||
to_add = [
|
||||
# PackageSpec(url="https://github.com/JuliaStats/KernelDensity.jl.git"),
|
||||
PackageSpec(name="PlotUtils", rev="master"),
|
||||
PackageSpec(name="RecipesBase", rev="master"),
|
||||
# PackageSpec(name="Blink", rev="master"),
|
||||
# PackageSpec(name="Rsvg", rev="master"),
|
||||
# PackageSpec(name="PlotlyJS", rev="master"),
|
||||
# PackageSpec(name="VisualRegressionTests", rev="master"),
|
||||
# PackageSpec("PyPlot"),
|
||||
# PackageSpec("InspectDR"),
|
||||
]
|
||||
|
||||
if isinteractive()
|
||||
Pkg.develop(PackageSpec(url="https://github.com/JuliaPlots/PlotReferenceImages.jl.git"))
|
||||
append!(to_add, [
|
||||
PackageSpec(name="FileIO"),
|
||||
PackageSpec(name="ImageMagick"),
|
||||
PackageSpec(name="UnicodePlots"),
|
||||
PackageSpec(name="VisualRegressionTests"),
|
||||
PackageSpec(name="Gtk"),
|
||||
# PlotlyJS:
|
||||
# PackageSpec(name="PlotlyJS"),
|
||||
# PackageSpec(name="Blink"),
|
||||
# PackageSpec(name="ORCA"),
|
||||
# PyPlot:
|
||||
# PackageSpec(name="PyPlot"),
|
||||
# PackageSpec(name="PyCall"),
|
||||
# PackageSpec(name="LaTeXStrings"),
|
||||
])
|
||||
else
|
||||
push!(to_add, PackageSpec(url="https://github.com/JuliaPlots/PlotReferenceImages.jl.git"))
|
||||
end
|
||||
|
||||
Pkg.add(to_add)
|
||||
|
||||
Pkg.build("ImageMagick")
|
||||
# Pkg.build("GR")
|
||||
# Pkg.build("Blink")
|
||||
# import Blink
|
||||
# Blink.AtomShell.install()
|
||||
# Pkg.build("PyPlot")
|
||||
+9
-73
@@ -1,92 +1,28 @@
|
||||
|
||||
using VisualRegressionTests
|
||||
# using ExamplePlots
|
||||
|
||||
if isinteractive()
|
||||
@eval Main import Gtk
|
||||
end
|
||||
|
||||
# import DataFrames, RDatasets
|
||||
|
||||
# don't let pyplot use a gui... it'll crash
|
||||
# note: Agg will set gui -> :none in PyPlot
|
||||
# ENV["MPLBACKEND"] = "Agg"
|
||||
# try
|
||||
# @eval import PyPlot
|
||||
# @info("Matplotlib version: $(PyPlot.matplotlib[:__version__])")
|
||||
# end
|
||||
|
||||
|
||||
using Plots
|
||||
# using StatPlots
|
||||
import PlotReferenceImages
|
||||
using Random
|
||||
using Test
|
||||
|
||||
default(size=(500,300))
|
||||
|
||||
|
||||
# TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that
|
||||
# is referenced in a button press callback (the button clicked callback will call notify() on that condition)
|
||||
|
||||
import Plots._current_plots_version
|
||||
|
||||
|
||||
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], tol = 1e-2)
|
||||
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = !is_ci(), sigma = [1,1], tol = 1e-2)
|
||||
Plots._debugMode.on = debug
|
||||
example = Plots._examples[idx]
|
||||
Plots.theme(:default)
|
||||
@info("Testing plot: $pkg:$idx:$(example.header)")
|
||||
backend(pkg)
|
||||
backend()
|
||||
|
||||
default(size=(500,300))
|
||||
# ensure consistent results
|
||||
Random.seed!(1234)
|
||||
|
||||
# reference image directory setup
|
||||
# refdir = joinpath(Pkg.dir("ExamplePlots"), "test", "refimg", string(pkg))
|
||||
refdir = joinpath(dirname(pathof(PlotReferenceImages)), "..", "Plots", string(pkg))
|
||||
fn = "ref$idx.png"
|
||||
|
||||
# firgure out version info
|
||||
vns = filter(x->x[1] != '.', readdir(refdir))
|
||||
versions = sort(VersionNumber.(vns), rev = true)
|
||||
versions = filter(v -> v <= _current_plots_version, versions)
|
||||
# @show refdir fn versions
|
||||
|
||||
newdir = joinpath(refdir, string(_current_plots_version))
|
||||
newfn = joinpath(newdir, fn)
|
||||
|
||||
# figure out which reference file we should compare to, by finding the highest versioned file
|
||||
reffn = nothing
|
||||
for v in versions
|
||||
tmpfn = joinpath(refdir, string(v), fn)
|
||||
if isfile(tmpfn)
|
||||
reffn = tmpfn
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# now we have the fn (if any)... do the comparison
|
||||
# @show reffn
|
||||
if reffn == nothing
|
||||
reffn = newfn
|
||||
end
|
||||
# @show reffn
|
||||
# return
|
||||
reffn = reference_file(pkg, idx, _current_plots_version)
|
||||
newfn = joinpath(reference_path(pkg, _current_plots_version), fn)
|
||||
|
||||
# test function
|
||||
func = (fn, idx) -> begin
|
||||
map(eval, example.exprs)
|
||||
expr = Expr(:block)
|
||||
append!(expr.args, example.exprs)
|
||||
eval(expr)
|
||||
png(fn)
|
||||
end
|
||||
|
||||
# try
|
||||
# run(`mkdir -p $newdir`)
|
||||
# catch err
|
||||
# display(err)
|
||||
# end
|
||||
# # reffn = joinpath(refdir, "ref$idx.png")
|
||||
|
||||
# the test
|
||||
vtest = VisualTest(func, reffn, idx)
|
||||
test_images(vtest, popup=popup, sigma=sigma, tol=tol, newfn = newfn)
|
||||
@@ -100,7 +36,7 @@ function image_comparison_facts(pkg::Symbol;
|
||||
tol = 1e-2) # acceptable error (percent)
|
||||
for i in 1:length(Plots._examples)
|
||||
i in skip && continue
|
||||
if only == nothing || i in only
|
||||
if only === nothing || i in only
|
||||
@test image_comparison_tests(pkg, i, debug=debug, sigma=sigma, tol=tol) |> success == true
|
||||
end
|
||||
end
|
||||
|
||||
+106
-127
@@ -1,103 +1,76 @@
|
||||
module PlotsTests
|
||||
import ImageMagick
|
||||
using VisualRegressionTests
|
||||
using Plots
|
||||
using Random
|
||||
using Test
|
||||
using FileIO
|
||||
using Gtk
|
||||
using LibGit2
|
||||
using GeometryTypes
|
||||
|
||||
include("test_pgfplotsx.jl")
|
||||
|
||||
reference_dir(args...) = joinpath(homedir(), ".julia", "dev", "PlotReferenceImages", args...)
|
||||
|
||||
function reference_file(backend, i, version)
|
||||
refdir = reference_dir("Plots", string(backend))
|
||||
fn = "ref$i.png"
|
||||
versions = sort(VersionNumber.(readdir(refdir)), rev = true)
|
||||
|
||||
reffn = joinpath(refdir, string(version), fn)
|
||||
for v in versions
|
||||
tmpfn = joinpath(refdir, string(v), fn)
|
||||
if isfile(tmpfn)
|
||||
reffn = tmpfn
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return reffn
|
||||
end
|
||||
|
||||
reference_path(backend, version) = reference_dir("Plots", string(backend), string(version))
|
||||
|
||||
if !isdir(reference_dir())
|
||||
mkpath(reference_dir())
|
||||
LibGit2.clone("https://github.com/JuliaPlots/PlotReferenceImages.jl.git", reference_dir())
|
||||
end
|
||||
|
||||
include("add_packages.jl")
|
||||
include("imgcomp.jl")
|
||||
|
||||
# don't actually show the plots
|
||||
Random.seed!(1234)
|
||||
default(show=false, reuse=true)
|
||||
img_tol = isinteractive() ? 1e-2 : 10e-2
|
||||
is_ci() = get(ENV, "CI", "false") == "true"
|
||||
img_tol = is_ci() ? 10e-2 : 10e-2
|
||||
|
||||
@testset "GR" begin
|
||||
ENV["PLOTS_TEST"] = "true"
|
||||
ENV["GKSwstype"] = "100"
|
||||
@test gr() == Plots.GRBackend()
|
||||
@test backend() == Plots.GRBackend()
|
||||
@testset "Backends" begin
|
||||
|
||||
@static if Sys.islinux()
|
||||
image_comparison_facts(:gr, tol=img_tol, skip = [25, 30])
|
||||
@testset "GR" begin
|
||||
ENV["PLOTS_TEST"] = "true"
|
||||
ENV["GKSwstype"] = "100"
|
||||
@test gr() == Plots.GRBackend()
|
||||
@test backend() == Plots.GRBackend()
|
||||
|
||||
@static if Sys.islinux()
|
||||
image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
|
||||
end
|
||||
end
|
||||
|
||||
@testset "UnicodePlots" begin
|
||||
@test unicodeplots() == Plots.UnicodePlotsBackend()
|
||||
@test backend() == Plots.UnicodePlotsBackend()
|
||||
|
||||
# lets just make sure it runs without error
|
||||
p = plot(rand(10))
|
||||
@test isa(p, Plots.Plot) == true
|
||||
@test isa(display(p), Nothing) == true
|
||||
p = bar(randn(10))
|
||||
@test isa(p, Plots.Plot) == true
|
||||
@test isa(display(p), Nothing) == true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# @static if isinteractive()
|
||||
# @testset "PyPlot" begin
|
||||
# @test pyplot() == Plots.PyPlotBackend()
|
||||
# @test backend() == Plots.PyPlotBackend()
|
||||
#
|
||||
# image_comparison_facts(:pyplot, tol=img_tol, skip = [2, 25, 30, 31])
|
||||
# end
|
||||
# end
|
||||
|
||||
@testset "UnicodePlots" begin
|
||||
@test unicodeplots() == Plots.UnicodePlotsBackend()
|
||||
@test backend() == Plots.UnicodePlotsBackend()
|
||||
|
||||
# lets just make sure it runs without error
|
||||
@test isa(plot(rand(10)), Plots.Plot) == true
|
||||
end
|
||||
|
||||
# The plotlyjs testimages return a connection error on travis:
|
||||
# connect: connection refused (ECONNREFUSED)
|
||||
|
||||
# @static if isinteractive()
|
||||
# @testset "PlotlyJS" begin
|
||||
# @test plotlyjs() == Plots.PlotlyJSBackend()
|
||||
# @test backend() == Plots.PlotlyJSBackend()
|
||||
#
|
||||
# image_comparison_facts(:plotlyjs,
|
||||
# skip=[
|
||||
# 2, # animation (skipped for speed)
|
||||
# 25,
|
||||
# 27, # (polar plots) takes very long / not working
|
||||
# 30,
|
||||
# 31, # animation (skipped for speed)
|
||||
# ],
|
||||
# tol=img_tol)
|
||||
# end
|
||||
# end
|
||||
|
||||
# InspectDR returns that error on travis:
|
||||
# ERROR: LoadError: InitError: Cannot open display:
|
||||
# in Gtk.GLib.GError(::Gtk.##229#230) at /home/travis/.julia/v0.5/Gtk/src/GLib/gerror.jl:17
|
||||
|
||||
# @testset "InspectDR" begin
|
||||
# @test inspectdr() == Plots.InspectDRBackend()
|
||||
# @test backend() == Plots.InspectDRBackend()
|
||||
#
|
||||
# image_comparison_facts(:inspectdr,
|
||||
# skip=[
|
||||
# 2, # animation
|
||||
# 6, # heatmap not defined
|
||||
# 10, # heatmap not defined
|
||||
# 22, # contour not defined
|
||||
# 23, # pie not defined
|
||||
# 27, # polar plot not working
|
||||
# 28, # heatmap not defined
|
||||
# 31, # animation
|
||||
# ],
|
||||
# tol=img_tol)
|
||||
# end
|
||||
|
||||
|
||||
# @testset "Plotly" begin
|
||||
# @test plotly() == Plots.PlotlyBackend()
|
||||
# @test backend() == Plots.PlotlyBackend()
|
||||
#
|
||||
# # # until png generation is reliable on OSX, just test on linux
|
||||
# # @static Sys.islinux() && image_comparison_facts(:plotly, only=[1,3,4,7,8,9,10,11,12,14,15,20,22,23,27], tol=img_tol)
|
||||
# end
|
||||
|
||||
# @testset "PlotlyJS" begin
|
||||
# @test plotlyjs() == Plots.PlotlyJSBackend()
|
||||
# @test backend() == Plots.PlotlyJSBackend()
|
||||
#
|
||||
# # as long as we can plot anything without error, it should be the same as Plotly
|
||||
# image_comparison_facts(:plotlyjs, only=[1], tol=img_tol)
|
||||
# end
|
||||
|
||||
|
||||
|
||||
|
||||
@testset "Axes" begin
|
||||
p = plot()
|
||||
axis = p.subplots[1][:xaxis]
|
||||
@@ -113,46 +86,52 @@ end
|
||||
end
|
||||
|
||||
@testset "NoFail" begin
|
||||
histogram([1, 0, 0, 0, 0, 0])
|
||||
plots = [histogram([1, 0, 0, 0, 0, 0]),
|
||||
plot([missing]),
|
||||
plot([missing; 1:4]),
|
||||
plot([fill(missing,10); 1:4]),
|
||||
plot([1 1; 1 missing]),
|
||||
plot(["a" "b"; missing "d"], [1 2; 3 4])]
|
||||
for plt in plots
|
||||
display(plt)
|
||||
end
|
||||
@test_nowarn plot(x->x^2,0,2)
|
||||
end
|
||||
|
||||
# tests for preprocessing recipes
|
||||
@testset "EmptyAnim" begin
|
||||
anim = @animate for i in []
|
||||
end
|
||||
|
||||
# @testset "recipes" begin
|
||||
@test_throws ArgumentError gif(anim)
|
||||
end
|
||||
|
||||
# user recipe
|
||||
@testset "Segments" begin
|
||||
function segments(args...)
|
||||
segs = UnitRange{Int}[]
|
||||
for seg in iter_segments(args...)
|
||||
push!(segs,seg)
|
||||
end
|
||||
segs
|
||||
end
|
||||
|
||||
# type T end
|
||||
# @recipe function f(::T)
|
||||
# line := (3,0.3,:red)
|
||||
# marker := (20,0.5,:blue,:o)
|
||||
# bg := :yellow
|
||||
# rand(10)
|
||||
# end
|
||||
# plot(T())
|
||||
nan10 = fill(NaN,10)
|
||||
@test segments(11:20) == [1:10]
|
||||
@test segments([NaN]) == []
|
||||
@test segments(nan10) == []
|
||||
@test segments([nan10; 1:5]) == [11:15]
|
||||
@test segments([1:5;nan10]) == [1:5]
|
||||
@test segments([nan10; 1:5; nan10; 1:5; nan10]) == [11:15, 26:30]
|
||||
@test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10]
|
||||
@test segments([nan10; 1:15], [1:15; nan10]) == [11:15]
|
||||
end
|
||||
|
||||
# plot recipe
|
||||
|
||||
# @recipe function f(::Type{Val{:hiplt}},plt::Plot)
|
||||
# line := (3,0.3,:red)
|
||||
# marker := (20,0.5,:blue,:o)
|
||||
# t := :path
|
||||
# bg:=:green
|
||||
# ()
|
||||
# end
|
||||
# plot(rand(10),t=:hiplt)
|
||||
|
||||
# series recipe
|
||||
|
||||
# @recipe function f(::Type{Val{:hi}},x,y,z)
|
||||
# line := (3,0.3,:red)
|
||||
# marker := (20,0.5,:blue,:o)
|
||||
# t := :path
|
||||
# ()
|
||||
# end
|
||||
# plot(rand(10),t=:hiplt)
|
||||
|
||||
# end
|
||||
|
||||
|
||||
end # module
|
||||
@testset "Utils" begin
|
||||
zipped = ([(1,2)], [("a","b")], [(1,"a"),(2,"b")],
|
||||
[(1,2),(3,4)], [(1,2,3),(3,4,5)], [(1,2,3,4),(3,4,5,6)],
|
||||
[(1,2.0),(missing,missing)], [(1,missing),(missing,"a")],
|
||||
[(missing,missing)], [(missing,missing,missing),("a","b","c")])
|
||||
for z in zipped
|
||||
@test isequal(collect(zip(Plots.unzip(z)...)), z)
|
||||
@test isequal(collect(zip(Plots.unzip(GeometryTypes.Point.(z))...)), z)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import SnoopCompile
|
||||
|
||||
### Log the compiles
|
||||
# This only needs to be run once (to generate "/tmp/plots_compiles.csv")
|
||||
|
||||
# SnoopCompile.@snoop "/tmp/plots_compiles.csv" begin
|
||||
# include(joinpath(dirname(@__FILE__), "runtests.jl"))
|
||||
# end
|
||||
|
||||
# ----------------------------------------------------------
|
||||
|
||||
### Parse the compiles and generate precompilation scripts
|
||||
# This can be run repeatedly to tweak the scripts
|
||||
|
||||
# IMPORTANT: we must have the module(s) defined for the parcelation
|
||||
# step, otherwise we will get no precompiles for the Plots module
|
||||
using Plots
|
||||
|
||||
data = SnoopCompile.read("/tmp/plots_compiles.csv")
|
||||
|
||||
# The Plots tests are run inside a module PlotsTest, so all
|
||||
# the precompiles get credited to PlotsTest. Credit them to Plots instead.
|
||||
subst = Dict("PlotsTests"=>"Plots")
|
||||
|
||||
# Blacklist helps fix problems:
|
||||
# - MIME uses type-parameters with symbols like :image/png, which is
|
||||
# not parseable
|
||||
blacklist = ["MIME"]
|
||||
|
||||
# Use these two lines if you want to create precompile functions for
|
||||
# individual packages
|
||||
pc, discards = SnoopCompile.parcel(data[end:-1:1,2], subst=subst, blacklist=blacklist)
|
||||
SnoopCompile.write("/tmp/precompile", pc)
|
||||
|
||||
pdir = joinpath(dirname(@__FILE__), "..")
|
||||
run(`cp /tmp/precompile/precompile_Plots.jl $pdir/src/precompile.jl`)
|
||||
@@ -0,0 +1,166 @@
|
||||
using Plots, Test
|
||||
pgfplotsx()
|
||||
|
||||
function create_plot( args...; kwargs... )
|
||||
pgfx_plot = plot(args...; kwargs...)
|
||||
return pgfx_plot, repr("application/x-tex", pgfx_plot)
|
||||
end
|
||||
|
||||
function create_plot!( args...; kwargs... )
|
||||
pgfx_plot = plot!(args...; kwargs...)
|
||||
return pgfx_plot, repr("application/x-tex", pgfx_plot)
|
||||
end
|
||||
|
||||
@testset "PGFPlotsX" begin
|
||||
pgfx_plot = plot(1:5)
|
||||
Plots._update_plot_object(pgfx_plot)
|
||||
@test pgfx_plot.o.the_plot isa PGFPlotsX.TikzDocument
|
||||
@test pgfx_plot.series_list[1].plotattributes[:quiver] === nothing
|
||||
axis = Plots.pgfx_axes(pgfx_plot.o)[1]
|
||||
@test count( x-> x isa PGFPlotsX.Plot, axis.contents ) == 1
|
||||
@test !haskey(axis.contents[1].options.dict, "fill")
|
||||
|
||||
@testset "3D docs example" begin
|
||||
n = 100
|
||||
ts = range(0, stop=8π, length=n)
|
||||
x = ts .* map(cos, ts)
|
||||
y = (0.1ts) .* map(sin, ts)
|
||||
z = 1:n
|
||||
pl = plot(x, y, z, zcolor=reverse(z), m=(10, 0.8, :blues, Plots.stroke(0)), leg=false, cbar=true, w=5)
|
||||
pgfx_plot = plot!(pl, zeros(n), zeros(n), 1:n, w=10)
|
||||
Plots._update_plot_object(pgfx_plot)
|
||||
if @test_nowarn(haskey(Plots.pgfx_axes(pgfx_plot.o)[1].options.dict, "colorbar") == true)
|
||||
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colorbar"] === nothing
|
||||
end
|
||||
end # testset
|
||||
@testset "Color docs example" begin
|
||||
y = rand(100)
|
||||
plot(0:10:100, rand(11, 4), lab="lines", w=3, palette=:grays, fill=0, α=0.6)
|
||||
pl = scatter!(y, zcolor=abs.(y .- 0.5), m=(:heat, 0.8, Plots.stroke(1, :green)), ms=10 * abs.(y .- 0.5) .+ 4, lab="grad")
|
||||
Plots._update_plot_object(pl)
|
||||
axis = Plots.pgfx_axes(pl.o)[1]
|
||||
@test count( x->x isa PGFPlotsX.LegendEntry, axis.contents ) == 5
|
||||
@test count( x->x isa PGFPlotsX.Plot, axis.contents ) == 108 # each marker is its own plot, fillranges create 2 plot-objects
|
||||
marker = axis.contents[15]
|
||||
@test marker isa PGFPlotsX.Plot
|
||||
@test marker.options["mark"] == "*"
|
||||
@test marker.options["mark options"]["color"] == RGBA{Float64}( colorant"green", 0.8)
|
||||
@test marker.options["mark options"]["line width"] == 1
|
||||
end # testset
|
||||
@testset "Plot in pieces" begin
|
||||
plot(rand(100) / 3, reg=true, fill=(0, :green))
|
||||
scatter!(rand(100), markersize=6, c=:orange)
|
||||
end # testset
|
||||
@testset "Marker types" begin
|
||||
markers = filter((m->begin
|
||||
m in Plots.supported_markers()
|
||||
end), Plots._shape_keys)
|
||||
markers = reshape(markers, 1, length(markers))
|
||||
n = length(markers)
|
||||
x = (range(0, stop=10, length=n + 2))[2:end - 1]
|
||||
y = repeat(reshape(reverse(x), 1, :), n, 1)
|
||||
scatter(x, y, m=(8, :auto), lab=map(string, markers), bg=:linen, xlim=(0, 10), ylim=(0, 10))
|
||||
end # testset
|
||||
@testset "Layout" begin
|
||||
plot(Plots.fakedata(100, 10), layout=4, palette=[:grays :blues :heat :lightrainbow], bg_inside=[:orange :pink :darkblue :black])
|
||||
end # testset
|
||||
@testset "Polar plots" begin
|
||||
Θ = range(0, stop=1.5π, length=100)
|
||||
r = abs.(0.1 * randn(100) + sin.(3Θ))
|
||||
plot(Θ, r, proj=:polar, m=2)
|
||||
end # testset
|
||||
@testset "Drawing shapes" begin
|
||||
verts = [(-1.0, 1.0), (-1.28, 0.6), (-0.2, -1.4), (0.2, -1.4), (1.28, 0.6), (1.0, 1.0), (-1.0, 1.0), (-0.2, -0.6), (0.0, -0.2), (-0.4, 0.6), (1.28, 0.6), (0.2, -1.4), (-0.2, -1.4), (0.6, 0.2), (-0.2, 0.2), (0.0, -0.2), (0.2, 0.2), (-0.2, -0.6)]
|
||||
x = 0.1:0.2:0.9
|
||||
y = 0.7 * rand(5) .+ 0.15
|
||||
plot(x, y, line=(3, :dash, :lightblue), marker=(Shape(verts), 30, RGBA(0, 0, 0, 0.2)), bg=:pink, fg=:darkblue, xlim=(0, 1), ylim=(0, 1), leg=false)
|
||||
end # testset
|
||||
@testset "Histogram 2D" begin
|
||||
histogram2d(randn(10000), randn(10000), nbins=20)
|
||||
end # testset
|
||||
@testset "Heatmap-like" begin
|
||||
xs = [string("x", i) for i = 1:10]
|
||||
ys = [string("y", i) for i = 1:4]
|
||||
z = float((1:4) * reshape(1:10, 1, :))
|
||||
pgfx_plot = heatmap(xs, ys, z, aspect_ratio=1)
|
||||
Plots._update_plot_object(pgfx_plot)
|
||||
if @test_nowarn(haskey(Plots.pgfx_axes(pgfx_plot.o)[1].options.dict, "colorbar") == true)
|
||||
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colorbar"] === nothing
|
||||
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colormap name"] == "plots1"
|
||||
end
|
||||
|
||||
pgfx_plot = wireframe(xs, ys, z, aspect_ratio=1)
|
||||
# TODO: clims are wrong
|
||||
end # testset
|
||||
@testset "Contours" begin
|
||||
x = 1:0.5:20
|
||||
y = 1:0.5:10
|
||||
f(x, y) = begin
|
||||
(3x + y ^ 2) * abs(sin(x) + cos(y))
|
||||
end
|
||||
X = repeat(reshape(x, 1, :), length(y), 1)
|
||||
Y = repeat(y, 1, length(x))
|
||||
Z = map(f, X, Y)
|
||||
p2 = contour(x, y, Z)
|
||||
p1 = contour(x, y, f, fill=true)
|
||||
plot(p1, p2)
|
||||
# TODO: colorbar for filled contours
|
||||
end # testset
|
||||
@testset "Varying colors" begin
|
||||
t = range(0, stop=1, length=100)
|
||||
θ = (6π) .* t
|
||||
x = t .* cos.(θ)
|
||||
y = t .* sin.(θ)
|
||||
p1 = plot(x, y, line_z=t, linewidth=3, legend=false)
|
||||
p2 = scatter(x, y, marker_z=((x, y)->begin
|
||||
x + y
|
||||
end), color=:bluesreds, legend=false)
|
||||
plot(p1, p2)
|
||||
end # testset
|
||||
@testset "Framestyles" begin
|
||||
scatter(fill(randn(10), 6), fill(randn(10), 6), framestyle=[:box :semi :origin :zerolines :grid :none], title=[":box" ":semi" ":origin" ":zerolines" ":grid" ":none"], color=permutedims(1:6), layout=6, label="", markerstrokewidth=0, ticks=-2:2)
|
||||
# TODO: support :semi
|
||||
end # testset
|
||||
@testset "Quiver" begin
|
||||
x = -2pi:0.2:2*pi
|
||||
y = sin.(x)
|
||||
|
||||
u = ones(length(x))
|
||||
v = cos.(x)
|
||||
arrow_plot = plot( x, y, quiver = (u, v), arrow = true )
|
||||
# TODO: could adjust limits to fit arrows if too long, but how?
|
||||
# TODO: get latex available on CI
|
||||
# mktempdir() do path
|
||||
# @test_nowarn savefig(arrow_plot, path*"arrow.pdf")
|
||||
# end
|
||||
end # testset
|
||||
@testset "Annotations" begin
|
||||
y = rand(10)
|
||||
plot(y, annotations=(3, y[3], Plots.text("this is \\#3", :left)), leg=false)
|
||||
annotate!([(5, y[5], Plots.text("this is \\#5", 16, :red, :center)), (10, y[10], Plots.text("this is \\#10", :right, 20, "courier"))])
|
||||
annotation_plot = scatter!(range(2, stop=8, length=6), rand(6), marker=(50, 0.2, :orange), series_annotations=["series", "annotations", "map", "to", "series", Plots.text("data", :green)])
|
||||
# mktempdir() do path
|
||||
# @test_nowarn savefig(annotation_plot, path*"annotation.pdf")
|
||||
# end
|
||||
end # testset
|
||||
@testset "Ribbon" begin
|
||||
aa = rand(10)
|
||||
bb = rand(10)
|
||||
cc = rand(10)
|
||||
conf = [aa-cc bb-cc]
|
||||
ribbon_plot = plot(collect(1:10),fill(1,10), ribbon=(conf[:,1],conf[:,2]))
|
||||
Plots._update_plot_object(ribbon_plot)
|
||||
axis = Plots.pgfx_axes(ribbon_plot.o)[1]
|
||||
plots = filter(x->x isa PGFPlotsX.Plot, axis.contents)
|
||||
@test length(plots) == 4
|
||||
@test !haskey(plots[1].options.dict, "fill")
|
||||
@test !haskey(plots[2].options.dict, "fill")
|
||||
@test !haskey(plots[3].options.dict, "fill")
|
||||
@test haskey(plots[4].options.dict, "fill")
|
||||
@test ribbon_plot.o !== nothing
|
||||
@test ribbon_plot.o.the_plot !== nothing
|
||||
# mktempdir() do path
|
||||
# @test_nowarn savefig(ribbon_plot, path*"ribbon.svg")
|
||||
# end
|
||||
end # testset
|
||||
end # testset
|
||||
Reference in New Issue
Block a user