Compare commits

...

986 Commits

Author SHA1 Message Date
Simon Christ cfe5ba24a6 1.16.4 [skip ci] 2021-06-09 15:54:34 +02:00
Simon Christ be1c263df9 no markers on fillranges (#3563) 2021-06-09 15:53:52 +02:00
Fons van der Plas 203af856cd embeddable_html (#3559) 2021-06-09 09:01:40 +02:00
Fred Callaway 019a742c84 Respect :widen when passing :lims (#3552)
* Respect :widen when passing :lims

Previously, the limits were not widened when passing a tuple or
:round to lims (ignoring the widen argument). Fixes #3339

* Add default widen=:auto, which matches default before 43e9a342

* If widen is a Bool, it always determines whether widening occurs.
* If widen is :auto (the defualt), widening occurs for appropriate
  seriestypes, unless lims were set manually

* Update test/test_axes.jl

Co-authored-by: Simon Christ <SimonChrist@gmx.de>

* fix docs for lims and widen interaction

* Update .zenodo.json

* Update test/test_axes.jl

xlims != ylims

Co-authored-by: Simon Christ <SimonChrist@gmx.de>

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2021-06-07 20:46:49 +02:00
Simon Christ 5330776040 1.16.3 [skip ci] 2021-06-07 19:56:24 +02:00
Simon Christ fcdb3c1c0d remove markers from fillranges (#3553) 2021-06-07 18:29:36 +02:00
Simon Christ cc290818d7 fix setting marker = :none without seriestype (#3550) 2021-06-07 15:55:43 +02:00
Simon Christ 14b3852060 add :symmetric docs 2021-06-04 22:09:51 +02:00
Simon Christ 387f918080 [skip ci] 2021-06-04 17:29:13 +02:00
Simon Christ d0d95c6cc7 1.16.2 [skip ci] 2021-06-04 17:09:25 +02:00
Simon Christ d51059f0e9 set projection for 3dquivers (#3544)
* set projection for 3dquivers

* fix test
2021-06-04 17:08:33 +02:00
Simon Christ 4723c513be 1.16.1 [skip ci] 2021-06-04 15:39:51 +02:00
Simon Christ d1373d8b89 fix fontfamily (#3542)
* fix fontfamily

* Update test_defaults.jl
2021-06-04 15:36:40 +02:00
Simon Christ 9f51b96269 1.16.0 [skip ci] 2021-06-03 19:00:39 +02:00
t-bltg 601df0c9a9 GR: allow explicit guidefontrotation (#3529)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-06-03 19:00:06 +02:00
github-actions[bot] 700b5782ec Update precompile_*.jl file (#3536)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-06-03 17:36:51 +02:00
Simon Christ 6a62d96751 axis limits = :symmetric (#2600)
* allow axis-lims = :symmetric

* remove show

* add test
2021-06-03 17:35:42 +02:00
Simon Christ 25b57cfb55 Run tests of GraphRecipes and StatsPlots (#3519)
* run tests of StatsPlots and GraphRecipes

* one environment each

* correct paths
2021-06-03 11:08:37 +02:00
github-actions[bot] fb390d1872 Update precompile_*.jl file (#3535)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-06-03 10:58:38 +02:00
Simon Christ 5fafddb995 fix fontrotation being interpreted as fontsize (#3533)
* fix convenience font functions

* correct size argument
2021-06-02 22:12:30 +02:00
Simon Christ 697e5a87cf 1.15.3 [skip ci] 2021-06-02 16:29:59 +02:00
github-actions[bot] 77ba81de19 Update precompile_*.jl file (#3530) [skip ci]
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-06-02 16:14:02 +02:00
Simon Christ e43f3ee373 Drop compat for older GR versions (#3526) 2021-06-02 08:24:42 +02:00
Simon Christ 8f055fef3d 1.15.2 [skip ci] 2021-05-20 20:43:29 +02:00
Simon Christ ce530ef518 fix vector of shapes (#3517) 2021-05-20 20:42:31 +02:00
BerndR 827462dc21 NaN checking in backends/gr.jl (#3514)
* Updated .zenodo.json infos

* resolved NaN-checking
2021-05-19 20:33:33 +02:00
github-actions[bot] 1ecec912a1 Update precompile_*.jl file (#3508) [skip ci]
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-05-19 08:53:17 +02:00
Simon Christ ca8e775b83 1.15.1[skip ci] 2021-05-19 08:29:08 +02:00
Fons van der Plas c0e50588d3 Minor cleanup plotlyjs (#3510) 2021-05-19 08:28:03 +02:00
Simon Christ de7717b85f Fix too many legend entries (#3511)
* add test

* fix legend entries
2021-05-19 08:27:41 +02:00
Simon Christ a1311e5c60 all the names [skip ci] 2021-05-18 18:21:45 +02:00
Simon Christ 4069b73563 Update .zenodo.json 2021-05-17 17:58:12 +02:00
Simon Christ a7d6e93af3 1.15.0 [skip ci] 2021-05-17 09:57:18 +02:00
Simon Christ 058983165e change DOI [skip ci] 2021-05-17 09:55:47 +02:00
Simon Christ 97036e689e Create .zenodo.json (#3482)
* Create .zenodo.json

* Update .zenodo.json

Co-authored-by: Daniel Schwabeneder <daschw@disroot.org>

* add members, classify contributors

* Apply suggestions from code review

Co-authored-by: Daniel Schwabeneder <daschw@disroot.org>

* add all names

Co-authored-by: Daniel Schwabeneder <daschw@disroot.org>
2021-05-17 09:43:23 +02:00
github-actions[bot] d3589db840 Update precompile_*.jl file (#3484)
Co-authored-by: daschw <daschw@users.noreply.github.com>
2021-05-14 22:03:29 +02:00
Simon Christ 15bd9c537d Create docs on pushing to master (#3494)
* Create docs.yml

* Update docs.yml

* Update docs.yml

* Create docs.yml

* Update docs.yml

* [skip ci]

* [skip ci]

* [skip ci]

* [skip ci]

* Update docs.yml

* Update docs.yml

* Update docs.yml

* Update docs.yml

* fix pgfplotsx

* fix pyplot

* remove push workflow (should work without)

* conditionally fix pyplot

* change env-vars

* fix

* fix ref

* clean up and cache artifacts

* add Documenter_key to environment

* fix parentheses

* "one last fix"

* dev => add

* fix marker example

* exclude 50 for plotly

* install ms fonts

* only trigger on master

* remove REF pretending
2021-05-14 22:00:09 +02:00
Daniel Schwabeneder 27764bbc67 Merge pull request #3497 from giordano/mg/animate-while
Allow `while`-block in at-animate macro
2021-05-14 19:19:05 +02:00
Mosè Giordano 788e28d18a Allow while-block in at-animate macro 2021-05-13 10:14:03 +01:00
Asim H Dar d544647b1b Update plotly.jl (#3491)
Tiny typo
2021-05-12 18:36:14 +02:00
Simon Christ 3cb81d6d04 fix alpha for surface (#3489) 2021-05-12 18:35:19 +02:00
Yuval 61f2d825b6 Merge pull request #3468 from yha/several-nans-fix
Fix for plotting a vector of (at least two) NaNs
2021-05-11 17:56:33 +03:00
Daniel Schwabeneder 5df64bd45b Merge pull request #3463 from gustaphe/fontdefaults
Add annotation font defaults/settings
2021-05-11 01:03:09 +02:00
Simon Christ 7e997da6bd 1.14.0 [skip ci] 2021-05-10 19:53:10 +02:00
Simon Christ 35658bf4fe fix tests 2021-05-07 08:14:37 +02:00
Simon Christ f355ff9904 clean up pgfx-legends duplications 2021-05-06 21:27:24 +02:00
github-actions[bot] 8893782b13 [AUTO] Update precompiles (#3471)
* add legend stylings

* fix center and default case

* Update precompile_*.jl file

Co-authored-by: Simon Christ <simonchrist@gmx.de>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-05-04 20:54:43 +02:00
Simon Christ 78f7db138f add legend stylings (#3470)
* add legend stylings

* fix center and default case
2021-05-04 20:54:11 +02:00
yha 23567964e7 undo accidental change 2021-05-03 19:45:48 +03:00
yha 0c7f7ba011 Fix for plotting a vector of (at least two) NaNs 2021-05-03 19:44:11 +03:00
David Gustavsson 4731477920 Add annotation font defaults 2021-05-01 20:39:55 +02:00
Daniel Schwabeneder 57ba6aa5a9 Merge pull request #3458 from daschw/tickmarks
add `tick_direction=:none` option to hide tick marks
2021-04-29 10:54:54 +02:00
Simon Christ 3c472f24b5 add DOI badge 2021-04-28 22:20:34 +02:00
Daniel Schwabeneder 5a4651a0ec clean changes in recipes.jl 2021-04-28 20:35:00 +02:00
Daniel Schwabeneder 7bb2132b18 add tick_direction=:none option to hide tick labels 2021-04-28 20:27:50 +02:00
Daniel Schwabeneder fd50469e20 Merge pull request #3430 from ma-laforge/idr_layout
Update plot areas for the given font sizes.
2021-04-28 18:42:14 +02:00
Daniel Schwabeneder e3d13aa17a Merge pull request #3436 from gustaphe/master
Generalize Shape
2021-04-28 18:40:57 +02:00
Simon Christ 476de3d2a2 1.13.2 [skip ci] 2021-04-28 09:52:54 +02:00
Yuval c986bfa1e6 Merge pull request #3443 from yha/plotly-shapes-fix
Fix shapes series on plotly
2021-04-27 13:05:32 +03:00
github-actions[bot] dfd8fada9d [AUTO] Update precompiles (#3455)
* incorporate colorbar ticks and ticklabel styles

* fix colorbar showing

* Update precompile_*.jl file

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-04-27 10:35:28 +02:00
Simon Christ d4298bf1cc 1.13.1 [skip ci] 2021-04-27 10:35:12 +02:00
Simon Christ 02437562a7 colorbar improvements for pgfplotsx (#3441)
* incorporate colorbar ticks and ticklabel styles

* fix colorbar showing
2021-04-27 09:50:49 +02:00
Benoit Pasquier 8cf268a390 Add ticks getter functions (#3435)
* Add ticks getter functions

* Add tick-getter functions for Plot objects

* Fix boiler-plate code in get_ticks

* Bump minor version + add tests

* Remove kwargs and add subplot test

* Add docstrings

* bump minor version
2021-04-23 08:52:17 +02:00
Simon Christ fbf3878ca5 1.12.0 [skip ci] 2021-04-20 11:21:54 +02:00
yha e449d3221c Fix shapes series on plotly 2021-04-18 13:41:10 +03:00
David Gustavsson a359f21325 Generalize Shape 2021-04-14 09:34:06 +02:00
MA Laforge 9da550ba3b Update plot areas for the given font sizes.
Also:
Layout changes are made to defaults instead of user-overwrites.
2021-04-10 14:57:39 -04:00
Daniel Schwabeneder 0a7035979f Merge pull request #3412 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-04-10 12:59:18 +02:00
Daniel Schwabeneder 6376d40ae2 Merge pull request #3423 from matthieugomez/master
correct scatterpath + add linearfit
2021-04-10 12:58:26 +02:00
matthieugomez 67f4d79c4a simpler formula for yhat 2021-04-08 10:11:09 -07:00
matthieugomez 50adb6cd9c Update recipes.jl 2021-04-07 14:42:12 -07:00
matthieugomez 64f3d589b6 correct scatterpath + add linearfit
correct scatterpath so that color does not change (see https://github.com/JuliaPlots/Plots.jl/issues/1495). Add linearfit.
2021-04-07 14:39:41 -07:00
isentropic 07b05e075e Update precompile_*.jl file 2021-04-05 05:16:17 +00:00
Zhanibek 1ceb3a561f pyplot, rawticklabels extra_kwarg added 2021-04-05 13:56:00 +09:00
Daniel Schwabeneder e1e0f8d1c9 Merge pull request #3411 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-04-01 19:59:59 +02:00
Daniel Schwabeneder f39ba03da5 Merge pull request #3409 from daschw/bar
fix multiple legend in pgfplotsx bar plots
2021-04-01 19:59:06 +02:00
daschw 7d7212ba3e Update precompile_*.jl file 2021-04-01 17:56:06 +00:00
Daniel Schwabeneder 17a942998d Merge pull request #3407 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-04-01 19:29:45 +02:00
Daniel Schwabeneder 6a829e2b1a Merge pull request #3405 from JuliaPlots/compathelper/new_version/2021-04-01-00-46-46-673-1268091602
CompatHelper: bump compat for "Latexify" to "0.15"
2021-04-01 19:29:28 +02:00
Daniel Schwabeneder 011591ff55 Merge branch 'master' into compathelper/new_version/2021-04-01-00-46-46-673-1268091602 2021-04-01 19:29:06 +02:00
Daniel Schwabeneder c56654c6cf fix multiple legend in pgfplotsx bar plots 2021-04-01 17:21:29 +02:00
daschw 90255913a4 Update precompile_*.jl file 2021-04-01 15:09:56 +00:00
Daniel Schwabeneder 67d7b4d771 Merge pull request #3406 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/compathelper/new_version/2021-04-01-00-46-46-673-1268091602
[AUTO] Update precompiles
2021-04-01 16:52:44 +02:00
Daniel Schwabeneder 3051ce9e57 Merge pull request #3402 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-04-01 16:52:29 +02:00
daschw 09e90c0ca6 Update precompile_*.jl file 2021-04-01 01:04:15 +00:00
github-actions[bot] dbe9a2c52b CompatHelper: bump compat for "Latexify" to "0.15" 2021-04-01 00:46:50 +00:00
Daniel Schwabeneder 56a0673713 Merge pull request #3403 from daschw/release
new release [skip ci]
2021-03-31 15:44:38 +02:00
Daniel Schwabeneder 22f1dd72c9 new release [skip ci] 2021-03-31 15:43:05 +02:00
daschw 9ad3654d4f Update precompile_*.jl file 2021-03-31 12:29:51 +00:00
Daniel Schwabeneder d2c85bdff9 Merge pull request #3398 from hustf/fix#3397
Bugfix and test, issue #3397
2021-03-31 14:12:22 +02:00
Daniel Schwabeneder ec7a912b58 Merge pull request #3395 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-03-31 14:10:53 +02:00
jheinen b63e41904b Update precompile_*.jl file 2021-03-31 10:00:08 +00:00
Josef Heinen 78f078ccc2 Update Project.toml 2021-03-31 11:42:35 +02:00
hustf 727ced25f1 modified: src/axes.jl #3397 fix varname
modified:   test/test_recipes.jl #3397 test all framestyles effect
2021-03-29 12:29:47 +02:00
Daniel Schwabeneder 378cabcb73 Merge pull request #3394 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-03-29 01:27:14 +02:00
daschw f4fb0862ea Update precompile_*.jl file 2021-03-28 23:23:17 +00:00
Daniel Schwabeneder cda8dae829 Merge pull request #3392 from daschw/release
bugfix release
2021-03-29 01:12:54 +02:00
Daniel Schwabeneder 86c400500e Merge pull request #3393 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-03-29 01:06:05 +02:00
daschw 23f8ba1db8 Update precompile_*.jl file 2021-03-28 23:02:09 +00:00
Daniel Schwabeneder 014b86a44c bugfix release 2021-03-29 00:50:05 +02:00
Daniel Schwabeneder 0ac71c6b1e Merge pull request #3391 from daschw/actions
update github actions
2021-03-29 00:48:30 +02:00
Daniel Schwabeneder 29604fd7f2 don't test on 1.5 2021-03-29 00:47:41 +02:00
Daniel Schwabeneder 53272b8a9d test on 1.5 2021-03-29 00:32:25 +02:00
Daniel Schwabeneder a0b104f563 run CompileBot on 1.6 2021-03-29 00:31:41 +02:00
Daniel Schwabeneder 9581a7cc49 Merge pull request #3388 from RPigott/spines
Fix PyPlot spines iteration
2021-03-29 00:27:42 +02:00
Daniel Schwabeneder 7d22d84595 support both MPL 3.3 and 3.4 2021-03-29 00:21:15 +02:00
Daniel Schwabeneder bf23b8f7a1 Merge pull request #3390 from daschw/gr-guides
fix guide positions in GR
2021-03-28 23:50:40 +02:00
Daniel Schwabeneder 005dcbc77a Merge pull request #3387 from olegshtch/webio-plotlyjs-integration
Use PlotlyJS's integration with WebIO
2021-03-28 23:50:19 +02:00
Daniel Schwabeneder ad1216639a Merge branch 'master' into webio-plotlyjs-integration 2021-03-28 23:31:32 +02:00
Daniel Schwabeneder ce778ff7be add test image 2021-03-28 23:20:09 +02:00
Daniel Schwabeneder 711a8448dc fix guidepostitions in GR 2021-03-28 23:09:52 +02:00
Daniel Schwabeneder 0a84ff8caf Merge pull request #3377 from mmikhasenko/master
guide label alignment
2021-03-28 21:29:04 +02:00
Daniel Schwabeneder 23cbfe9378 Merge pull request #3382 from david-macmahon/stepmid-branch
Add support for `seriestype=:stepmid`
2021-03-28 21:27:12 +02:00
Daniel Schwabeneder 1cb434ac26 Merge pull request #3374 from ma-laforge/idr_layout
Conform to InspectDR's new layout API in v0.4.0.
2021-03-28 21:03:49 +02:00
Daniel Schwabeneder 138a2fa34a Merge pull request #3359 from daschw/pyplot
fix line_z on pyplot
2021-03-28 21:02:19 +02:00
Daniel Schwabeneder 60c59a4be0 Merge pull request #3385 from pgagarinov/master
ADD: happy-path test for #3365
2021-03-28 20:04:36 +02:00
Ronan Pigott bea1378ff1 fix PyPlot spines iteration 2021-03-27 14:00:15 -07:00
Oleg Shchelykalnov d46f59e4be Add tests for PlotlyJS backend 2021-03-27 14:45:38 +03:00
Oleg Shchelykalnov 52da386df1 Use PlotlyJS's integration with WebIO 2021-03-27 14:00:18 +03:00
Peter Gagarinov bb26bb0557 ADD: happy-path test for #3365 2021-03-27 00:34:15 +03:00
David MacMahon b3bf5db9bc Add new "Steps Types" example/test plot 53
This new example/test plot showcases the various step-like
`seriestype`s: `:steppre`, `:stepmid`, and `:steppost`.
2021-03-26 11:12:14 -07:00
David MacMahon 074c56867d Revert "Add :stepmid to line types example plot"
This reverts commit 0d528b7c82.
2021-03-26 10:49:19 -07:00
Daniel Schwabeneder 71fd38fe26 Merge pull request #3367 from daschw/bar
fix bar for unsorted x input
2021-03-26 18:31:00 +01:00
Misha Mikhasenko 4841c13311 typo: axis 2021-03-25 17:36:23 +01:00
Misha Mikhasenko 89dea71874 Merge branch 'master' of https://github.com/mmikhasenko/Plots.jl 2021-03-25 14:44:07 +01:00
Misha Mikhasenko 1a9532f9fc merged 2021-03-25 14:42:45 +01:00
Misha Mikhasenko 2b3fa980ee alighment 2021-03-25 14:34:52 +01:00
David MacMahon 0d528b7c82 Add :stepmid to line types example plot 2021-03-24 23:27:16 -07:00
David MacMahon c2cb60ff12 Make Plots backends aware of new :stepmid option 2021-03-24 23:25:57 -07:00
David MacMahon ddf6aa9760 Make Plots framework aware of new :stepmid option 2021-03-24 23:24:31 -07:00
David MacMahon 50f1106cd7 Add recipe for seriestype=:stepmid 2021-03-24 20:47:14 -07:00
David MacMahon 3bb406e0ea Add :mid support to make_steps 2021-03-24 20:35:08 -07:00
David MacMahon 10fa36cdd9 Use even to tweak length of make_steps output
If `even` in false, `make_steps` returns an odd-length (2n-1) Vector as
it did before.  If even is `true`, `make_steps` now returns an
even-length (2n) Vector whose first (2n-1) elements are the same as
before and whose final element is the same as the final element of the
input Vector.
2021-03-24 20:21:12 -07:00
David MacMahon 0508d05299 Remove conditional from make_steps for loop 2021-03-24 20:16:53 -07:00
David MacMahon 59a1faf590 Add even arg to make_steps
This is in preparation for `:stepmid` support.
2021-03-24 19:56:29 -07:00
Zhanibek c0824bdc62 Colorbar enhancements (#3346)
* CompatHelper: bump compat for "Showoff" to "1.0"

* fix series-segments for empty series

* fix wireframe on pyplot

* colorbar redesign

* minimal working version

* reduce code duplication for colorbar ticks

* fix aspect_ratio in GR with legend=:outertopright

* fix GR test failure

* new release [skip ci]

* colorbar scale supported

* Added weights example to ? histogram

Helps to clarify the use of weights (which differs from StatsBase functions)

* Update precompile_*.jl file

* minor version bump [skip ci]

* working prototype

* fixed formatting, added colorbar docs

* colorbar redesign

* minimal working version

* reduce code duplication for colorbar ticks

* fix GR test failure

* colorbar scale supported

* working prototype

* fixed formatting, added colorbar docs

Co-authored-by: Daniel Schwabeneder <daschw@disroot.org>
2021-03-25 11:22:07 +09:00
MA Laforge 606b86c962 Conform to InspectDR's new layout API in v0.4.0. 2021-03-24 19:28:52 -04:00
Daniel Schwabeneder a50661dd44 fix bar for unsorted x input 2021-03-23 22:11:16 +01:00
Daniel Schwabeneder 34f4d318ea fix line_z on pyplot 2021-03-20 11:13:39 +01:00
Daniel Schwabeneder 9fc1d574cd Merge pull request #3333 from JuliaPlots/compathelper/new_version/2021-03-05-00-27-43-476-2803635382
CompatHelper: bump compat for "Showoff" to "1.0"
2021-03-20 09:14:58 +01:00
Daniel Schwabeneder 9300dffcc3 Merge pull request #3352 from daschw/release
new release
2021-03-18 22:10:54 +01:00
Daniel Schwabeneder 796f9ef47b Merge pull request #3354 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-03-18 22:10:22 +01:00
Daniel Schwabeneder da2dc2cb1b minor version bump [skip ci] 2021-03-18 22:01:46 +01:00
Daniel Schwabeneder f76390c20d Merge pull request #3350 from daschw/gr-aspect
fix aspect_ratio in GR with legend=:outertopright
2021-03-16 10:39:23 +01:00
mkborregaard ef82e53eef Update precompile_*.jl file 2021-03-15 14:56:12 +00:00
Michael Krabbe Borregaard 219939525c Merge pull request #3353 from jo-fleck/histogram_doc_weights
Added weights example to ? histogram
2021-03-15 15:38:29 +01:00
jo-fleck ae99ed2588 Added weights example to ? histogram
Helps to clarify the use of weights (which differs from StatsBase functions)
2021-03-15 14:09:24 +01:00
Daniel Schwabeneder 8e13bb4ccc new release [skip ci] 2021-03-14 19:20:45 +01:00
Daniel Schwabeneder 66db3ceae0 fix aspect_ratio in GR with legend=:outertopright 2021-03-14 17:41:54 +01:00
Daniel Schwabeneder 060162c356 Merge pull request #3344 from daschw/py-wireframe
fix wireframe on pyplot
2021-03-12 21:49:42 +01:00
Daniel Schwabeneder 271d93c1ed Merge pull request #3340 from daschw/series-segments
fix series-segments for empty series
2021-03-12 21:49:26 +01:00
Daniel Schwabeneder 664af999cd fix wireframe on pyplot 2021-03-10 22:15:06 +01:00
Daniel Schwabeneder a1ace08d22 Merge pull request #3332 from korsbo/nk/pgfplotsx_dpi
Enable `dpi`  option for `pgfplotsx()` PNGs.
2021-03-06 12:39:31 +01:00
Daniel Schwabeneder 4d5f76b80d Merge pull request #3330 from yha/segment-example-no-cycle
No implicit cycling in example
2021-03-06 12:38:30 +01:00
Daniel Schwabeneder b8c2d62c32 Merge pull request #3329 from gustaphe/annotations
Bar chart series_annotations
2021-03-06 12:38:07 +01:00
Daniel Schwabeneder 6201dfe580 Merge pull request #3324 from gustaphe/legendangle
[WIP] position legend at angle
2021-03-06 12:37:35 +01:00
Daniel Schwabeneder d44b7e89e7 fix series-segments for empty series 2021-03-06 12:03:50 +01:00
github-actions[bot] 08e3224f8f CompatHelper: bump compat for "Showoff" to "1.0" 2021-03-05 00:27:46 +00:00
Niklas Korsbo e9b78e7191 Enable dpi option for pgfplotsx() PNGs. 2021-03-03 10:46:24 +01:00
yha f418acf387 No implicit cycling in example 2021-03-03 00:00:25 +02:00
Yuval f097549e3b Merge pull request #3320 from yha/segments-nan-attr
Fix for "segmented" attributes with NaNs
2021-03-02 23:21:57 +02:00
yha c8b882d17a rename local var 2021-03-02 22:56:56 +02:00
Yuval dbbece413c Merge branch 'master' into segments-nan-attr 2021-03-02 15:29:43 +02:00
David Gustavsson 9cee7a2c47 Documentation for legend angle 2021-03-02 11:53:47 +01:00
David Gustavsson d6a72a5df5 Add legend angle to pyplot 2021-03-02 10:19:26 +01:00
David Gustavsson 37252ec562 Correct anchor order 2021-03-02 10:07:49 +01:00
David Gustavsson 1d3e0a5d5d Better legend anchor algorithm 2021-03-02 08:02:39 +01:00
Yuval a85c10dcdd Merge pull request #13 from yha/Test_SnoopCompile_AutoPR_refs/heads/segments-nan-attr
[AUTO] Update precompiles
2021-03-01 03:37:27 +02:00
yha 97caa18fb4 Update precompile_*.jl file 2021-03-01 01:33:16 +00:00
yha 6af91c7f71 warning and hint on mismatched attr lengths 2021-03-01 03:23:19 +02:00
yha e9cd69ea2f Fix Shape vector recipe 2021-03-01 02:17:42 +02:00
David Gustavsson 6724a3a2fe Centralize utility functions, add legend-angle to plotly, pgfplotsx 2021-02-28 23:40:06 +01:00
David Gustavsson a75d309d20 Labels for horizontal bars 2021-02-28 09:20:20 +01:00
David Gustavsson 5cc08a17b6 Series annotations for bar plots 2021-02-28 08:57:54 +01:00
Daniel Schwabeneder 2220dbc465 Merge pull request #3326 from daschw/release
release
2021-02-25 20:16:03 +01:00
Daniel Schwabeneder 66250acfaa release 2021-02-25 19:38:08 +01:00
Daniel Schwabeneder 395cc9294b Merge pull request #3316 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-02-25 19:36:51 +01:00
jheinen 3f13a186e7 Update precompile_*.jl file 2021-02-25 18:13:34 +00:00
Josef Heinen 2d8b2332fb Update Project.toml
Add GR v0.55.0
2021-02-25 18:56:00 +01:00
David Gustavsson 2cee039dbc Add polar legend position 2021-02-25 15:08:33 +01:00
David Gustavsson 6193519b1f Correct erroneous offset for legend=:outerbottom 2021-02-25 12:20:59 +01:00
Yuval 65dac58338 Merge pull request #12 from yha/Test_SnoopCompile_AutoPR_refs/heads/segments-nan-attr
[AUTO] Update precompiles
2021-02-25 02:57:19 +02:00
yha 164725079d Update precompile_*.jl file 2021-02-25 00:53:00 +00:00
yha 42b3c5625f Fix for "segmented" attributes with NaNs 2021-02-25 02:33:11 +02:00
Daniel Schwabeneder cd851df28a Merge pull request #3314 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-02-20 17:05:36 +01:00
daschw 57b0a81c1c Update precompile_*.jl file 2021-02-19 21:51:22 +00:00
Daniel Schwabeneder 1ef15934cc Merge pull request #3313 from daschw/surface
Surface fixes
2021-02-19 22:35:31 +01:00
Daniel Schwabeneder 0a6edd5d60 fix gr test example 2021-02-19 22:08:02 +01:00
Daniel Schwabeneder e8437d76fd fix fillalpha for surface on pgfplotsx 2021-02-19 21:22:57 +01:00
Daniel Schwabeneder 2e2f7044e2 fix surface on pgfplotsx 2021-02-19 21:20:51 +01:00
Daniel Schwabeneder 100da5ccae fix fillalpha for surface on pyplot 2021-02-19 20:59:48 +01:00
Daniel Schwabeneder d59f6c96d5 fix surface for pyplot 2021-02-19 20:26:18 +01:00
Daniel Schwabeneder 0628fb9dc3 enable transparency for surface with GR 2021-02-19 18:59:47 +01:00
Daniel Schwabeneder 6b71bd961d Merge pull request #3308 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-02-19 12:48:15 +01:00
daschw 9569f34ae0 Update precompile_*.jl file 2021-02-16 21:16:45 +00:00
Daniel Schwabeneder d830f64cbc Merge pull request #3307 from daschw/release
up version
2021-02-16 21:59:02 +01:00
Daniel Schwabeneder dd785c3bd3 up version 2021-02-16 21:57:58 +01:00
Daniel Schwabeneder 663d556a06 Merge pull request #3306 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-02-16 21:56:36 +01:00
Daniel Schwabeneder e06a51b420 Merge pull request #3299 from fhagemann/master
Implement non-uniform polar heatmaps with the GR backend
2021-02-16 21:54:58 +01:00
daschw da3e0294cd Update precompile_*.jl file 2021-02-16 20:03:15 +00:00
Daniel Schwabeneder 57e98ac12d Merge pull request #3302 from sethaxen/hexbinextrakws
Support extra_kwargs in hexbins for PyPlot
2021-02-16 20:46:24 +01:00
Daniel Schwabeneder 740f231d5f Merge pull request #3300 from isentropic/master
twin, mirror fixes
2021-02-16 20:45:18 +01:00
Daniel Schwabeneder cf96ddcd30 fix typo in polar heatmap test example 2021-02-16 20:41:32 +01:00
Daniel Schwabeneder ec532b2cbb update test example for polar heatmaps 2021-02-16 20:09:13 +01:00
Seth Axen 7989673eb4 Allow mincnt 2021-02-15 14:53:50 -08:00
Seth Axen 897a5eee87 Allow edgecolors to override linewidth 2021-02-15 14:53:40 -08:00
Seth Axen 0665ff907c Use semicolon 2021-02-15 14:53:22 -08:00
Seth Axen 1fc0892551 Allow extrakws for hexbin 2021-02-15 14:53:10 -08:00
zhanibek 8d7375dc4f twin, mirror fixes 2021-02-15 15:21:26 +09:00
Felix Hagemann 2594b577d7 Adjust heatmap_edges for polar heatmaps 2021-02-14 00:02:49 +01:00
Felix Hagemann 9b174084f7 Implement non-uniform polar heatmaps with the GR backend 2021-02-13 17:56:03 +01:00
Daniel Schwabeneder d196952571 Merge pull request #3292 from daschw/gr-surface
remove black lines from GR surface with equal-length x, y, and z input
2021-02-10 21:22:07 +01:00
Daniel Schwabeneder df8fe4d28b remove black lines from GR surface with equal-length x, y, and z input 2021-02-10 18:42:04 +01:00
Daniel Schwabeneder 76cf8f0f3d Merge pull request #3291 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-02-09 19:55:33 +01:00
daschw 748a913ce2 Update precompile_*.jl file 2021-02-09 18:49:13 +00:00
Daniel Schwabeneder 10f0e83a38 Merge pull request #3290 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-02-09 19:32:49 +01:00
daschw 9531fdd122 Update precompile_*.jl file 2021-02-09 18:30:24 +00:00
Daniel Schwabeneder 65a84a7215 Merge pull request #3288 from jebej/nospec
add `@nospecialize` annotations
2021-02-09 18:44:07 +01:00
Jeremy Bejanin a6d42d3e0f add @nospecialize annotations 2021-02-09 10:27:17 -05:00
Daniel Schwabeneder 23ae2c5a17 Merge pull request #3283 from daschw/limits
use existing limits for functions
2021-02-09 00:04:46 +01:00
Daniel Schwabeneder 0e03d7ff95 use existing limits for functions 2021-02-08 22:52:40 +01:00
Daniel Schwabeneder f656179d54 Merge pull request #3281 from daschw/release
RecipesPipeline compat
2021-02-08 14:47:30 +01:00
Daniel Schwabeneder 33c734a60b RecipesPipeline compact 2021-02-07 19:58:40 +01:00
Daniel Schwabeneder 781e6d2a16 Merge pull request #3273 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-02-07 19:40:31 +01:00
Daniel Schwabeneder 4f270fc6dc Merge pull request #3274 from briochemc/patch-1
Fix typos in plot docstring
2021-02-07 19:39:48 +01:00
Daniel Schwabeneder 19bb7340f1 Merge pull request #3277 from jebej/no-early-stringify
don't stringify argument to `warn_on_recipe_aliases!` early
2021-02-07 19:38:05 +01:00
Jeremy Bejanin 4ac81d12df don't stringify argument to warn_on_recipe_aliases! early
needs matching RecipesPipeline changes
2021-02-07 12:07:04 -05:00
Benoit Pasquier 8bd76ee4bd Fix typos in plot docstring 2021-02-06 10:39:15 +11:00
daschw 8ae0d8c808 Update precompile_*.jl file 2021-02-05 16:39:50 +00:00
Daniel Schwabeneder b66e134838 Merge pull request #3272 from daschw/release
bugfix release
2021-02-05 17:23:49 +01:00
Daniel Schwabeneder 6dbf004d5f bugfix release 2021-02-05 17:22:37 +01:00
Daniel Schwabeneder 928c6d5e6c Merge pull request #3253 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-02-05 17:19:13 +01:00
daschw c478c3c9f0 Update precompile_*.jl file 2021-02-01 19:39:11 +00:00
Daniel Schwabeneder a04946e832 Merge pull request #3262 from ma-laforge/idr_ticks
Add support for custom tick labels
2021-02-01 20:24:59 +01:00
Daniel Schwabeneder f9ff2c8962 Merge pull request #3267 from sefffal/master
Fix typo preventing minor ticks from working in 3D plots
2021-02-01 20:21:06 +01:00
Daniel Schwabeneder 8190d1fdfc Merge pull request #3268 from ianshmean/ib/benchmark_tweaks
Benchmark CI tweaks
2021-02-01 19:40:25 +01:00
Ian cc005c6246 limit plot and display tests to one run 2021-01-31 23:09:23 -05:00
William Thompson 97c43eb031 Fix typo to allow minor ticks in 3D plots 2021-01-31 11:47:15 -08:00
MA Laforge 3907ae7f21 Add support for custom tick labels
Also:
 - Correctly register changes to "plot.layout"
 - Fix deprecated use of series[:marker[stroke][color/alpha]].
2021-01-30 13:36:16 -05:00
Josef Heinen c402161845 Update Project.toml 2021-01-27 16:20:25 +01:00
Daniel Schwabeneder 6fb0d69cb3 Merge pull request #3252 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-01-26 21:34:33 +00:00
daschw 1a4bceace7 Update precompile_*.jl file 2021-01-26 21:32:50 +00:00
Daniel Schwabeneder 651548526a Merge pull request #3250 from daschw/release
bugfix release
2021-01-26 21:18:24 +00:00
Daniel Schwabeneder 1f6089d715 Merge pull request #3251 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-01-26 21:18:14 +00:00
daschw 5dde27eb08 Update precompile_*.jl file 2021-01-26 20:35:13 +00:00
Daniel Schwabeneder 52ba52f4e4 Merge pull request #3249 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-01-26 20:17:19 +00:00
daschw 60dbf77a96 Update precompile_*.jl file 2021-01-26 19:57:14 +00:00
Daniel Schwabeneder 880190cea1 Merge pull request #3246 from aminya/Single_CompileBot
CompileBot use default precompile path
2021-01-26 10:30:58 +00:00
Amin Yahyaabadi e591332b71 Let the bot generate the includer file 2021-01-26 03:08:16 -06:00
Amin Yahyaabadi 2b44cb5a35 Delete old precompiles 2021-01-26 02:53:30 -06:00
Amin Yahyaabadi d538c4387f CompileBot use default precompile path 2021-01-26 02:49:10 -06:00
Daniel Schwabeneder 60bc127925 bugfix release 2021-01-25 18:09:27 +01:00
Daniel Schwabeneder e6cc826174 Merge pull request #3229 from jks-liu/pr_requirejs_plotlyjs
Proper Plotly JavaScript setup in IJulia
2021-01-25 17:06:48 +00:00
Daniel Schwabeneder f257c563fb Merge pull request #3243 from daschw/tests
fix tests
2021-01-25 16:39:43 +00:00
Daniel Schwabeneder 8a2a41f75b Merge pull request #3242 from KristofferC/kc/reenable_precompilation
reenable precompiles
2021-01-25 16:39:18 +00:00
Daniel Schwabeneder da1b9adc17 env as string 2021-01-25 16:28:17 +01:00
Daniel Schwabeneder 9d3514224e use GKSwstype environment variable to avoid GKS warnings in tests 2021-01-25 16:16:28 +01:00
Kristoffer Carlsson 142bb8cc56 Update benchmark.yml 2021-01-25 16:11:28 +01:00
Daniel Schwabeneder fb27704d2b fix tests 2021-01-25 16:10:09 +01:00
KristofferC 96ed4b2616 reenable precompiles 2021-01-25 14:49:30 +01:00
Daniel Schwabeneder 6d4353d0b1 Merge pull request #3234 from daschw/spy
fix defaults in spy recipe
2021-01-25 08:28:47 +00:00
Daniel Schwabeneder a2be60b5d1 Merge pull request #3240 from ianshmean/ib/ci_benchmark_2
Add basic CI Benchmarking via BenchmarkCI - Pt. 2
2021-01-25 08:27:56 +00:00
Ian d92990a5f0 tweaks to benchmarks order-insensitive 2021-01-24 16:49:09 -05:00
Daniel Schwabeneder 99ca1074de Merge pull request #3239 from ianshmean/ib/ci_benchmark
Add basic CI Benchmarking via BenchmarkCI
2021-01-24 21:02:02 +00:00
Ian 8a908c0de8 do load test in separate session 2021-01-24 15:54:18 -05:00
Ian 3c9580fb2f fixes 2021-01-24 15:45:49 -05:00
Ian 309f2db3b1 run entire load_plot_display in separate julia instance 2021-01-24 15:21:23 -05:00
Ian 0b8755db4b add benchmark gitignores 2021-01-24 14:48:37 -05:00
Ian ac2fbadc07 add missing GKS_ENCODING env var 2021-01-24 14:31:27 -05:00
Ian 535d95334c fix to use Ubuntu TESTCMD 2021-01-24 14:24:11 -05:00
Ian 6332aecc60 Update Project.toml 2021-01-24 14:18:18 -05:00
Ian 8efe35f5f8 add benchmark/Project.toml 2021-01-24 14:14:04 -05:00
Ian 493ab0c6b4 add basic CI Benchmarking 2021-01-24 14:01:04 -05:00
Daniel Schwabeneder fa8d437836 widen axis limits 2021-01-22 18:16:13 +01:00
Daniel Schwabeneder e95ddc3ef8 fix defaults in spy recipe 2021-01-22 18:05:40 +01:00
Jks Liu 50a6dd9fb3 let plotly config and use in same cell in case of config cell re-run or is deleted 2021-01-20 22:51:17 +08:00
Jks Liu 509a8cdc7e Config plotly.js during init
plotly.js will be loaded only once, only when first time used

plots show correctly when page re-load or re-open
2021-01-18 22:59:16 +08:00
Jks Liu 672b3a6038 Merge branch 'pr_fix_plotly_file_name' into pr_requirejs_plotlyjs
Const variable for filename of plotly.js
2021-01-18 21:03:09 +08:00
Jks Liu 4bcafe3f51 const variable for plotly JavaScript file name 2021-01-12 22:09:48 +08:00
Daniel Schwabeneder 49eba0bf2f Merge pull request #3218 from daschw/gr_guides
Increase the margins between axes and guides on GR
2021-01-12 09:49:42 +01:00
Jks Liu d0e01a8d88 Correct version string of plotly cache file name 2021-01-11 22:48:04 +08:00
Daniel Schwabeneder eb1c126dbc remove unnecessary line 2021-01-09 21:51:30 +01:00
Daniel Schwabeneder 6c8fb87635 increase gr guide margins on 3d plots 2021-01-09 21:50:54 +01:00
Daniel Schwabeneder 7b8609ea1a Merge pull request #3189 from isentropic/pyplot
various pyplot fixes
2021-01-09 19:17:42 +01:00
Daniel Schwabeneder f478a649a0 Merge pull request #3213 from daschw/release
release 1.10.1
2021-01-07 00:25:14 +01:00
Daniel Schwabeneder 85ca402790 release 1.10.1 2021-01-06 23:02:48 +01:00
Lia Siegelman 2ebc97d92a fix for [BUG] #3135 mp4/mov animations can't be opened with QuickTime or Safari (#3209)
* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

* try a fix for codec animate function

Co-authored-by: Lia Siegelman <lsiegelman@ucsd.edu>
2021-01-05 21:40:21 +01:00
Daniel Schwabeneder 2bda216d8a Merge pull request #3207 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-01-04 17:57:26 +01:00
daschw ca7f69eaa3 Update precompile_*.jl file 2021-01-01 22:08:33 +00:00
Daniel Schwabeneder fcbfda10fb Merge pull request #3206 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2021-01-01 22:54:37 +01:00
Daniel Schwabeneder 51df476015 Merge pull request #3205 from daschw/pgfx-legendfont
respect legendfontcolor in pgfplotsx
2021-01-01 22:53:12 +01:00
daschw c08555a638 Update precompile_*.jl file 2020-12-31 08:35:42 +00:00
Daniel Schwabeneder 93825e2c86 Merge pull request #3201 from JuliaPlots/compathelper/new_version/2020-12-26-00-35-02-072-2106613790
CompatHelper: bump compat for "Reexport" to "1.0"
2020-12-31 09:21:30 +01:00
Daniel Schwabeneder c64bbf826c Merge pull request #3191 from daschw/datetimelims
allow more types in `lims!` functions
2020-12-31 09:20:52 +01:00
Daniel Schwabeneder 91608a6eab respect legendfontcolor in pgfplotsx 2020-12-31 09:17:39 +01:00
Simon Christ 8cc6d9d487 1.10.0 2020-12-29 22:03:03 +01:00
Daniel Schwabeneder 17f3faf672 simplify signature 2020-12-29 11:36:59 +01:00
github-actions[bot] 2e25d86daa CompatHelper: bump compat for "Reexport" to "1.0" 2020-12-26 00:35:07 +00:00
Rik Huijzer 0f349be952 Avoid comparing findfirst to nothing (#3200) 2020-12-23 23:35:11 +01:00
Daniel Schwabeneder 8f0d4c4145 Merge pull request #3184 from ThatcherC/component-tests
WIP: More component tests and some shorthands tests
2020-12-17 19:01:58 +01:00
Daniel Schwabeneder d61bbcce56 allow more types in lims! functions 2020-12-17 18:20:56 +01:00
Thatcher Chamberlin 2b376a0e4a Merge branch 'master' of https://github.com/JuliaPlots/Plots.jl into component-tests 2020-12-12 13:49:30 -05:00
zhanibek 62af64f08a various pyplot fixes 2020-12-10 18:48:17 +09:00
Daniel Schwabeneder 882bb1b517 Merge pull request #3178 from jks-liu/pr_extra_mime_only_html
Set extra mime only when HTML format
2020-12-09 13:19:51 +01:00
Daniel Schwabeneder a403f9e44b Merge pull request #3180 from ThatcherC/date-xlims
Fix #1531, Let xlims be set to Dates or DateTimes
2020-12-09 13:18:00 +01:00
jaakkor2 0c4623873c Handle basex, basey, linthreshx, linthreshy deprecated in matplotlib 3.3 (#3183)
See https://matplotlib.org/3.3.0/api/api_changes.html
2020-12-08 17:50:30 +09:00
Thatcher Chamberlin d1671ea6f0 recheck coverage 2020-12-07 22:01:29 -05:00
Thatcher Chamberlin f905d6b697 Fixed rotate test and added series_annotation tests 2020-12-07 21:23:26 -05:00
Thatcher Chamberlin bc144b64c8 Added Shape rotation tests 2020-12-07 20:52:46 -05:00
Thatcher Chamberlin 10c94c739d Merge branch 'component-tests' of https://github.com/ThatcherC/Plots.jl into component-tests 2020-12-07 20:01:50 -05:00
Thatcher Chamberlin 38ada46a43 Added an auto-label test 2020-12-07 20:01:09 -05:00
Thatcher Chamberlin 0e73bcdc4e Added some tests for shorthands.jl 2020-12-07 20:00:55 -05:00
Thatcher Chamberlin e57a9349f6 Added font scaling tests 2020-12-07 11:21:51 -05:00
Thatcher Chamberlin 120d63f53f Merge branch 'date-xlims' of https://github.com/ThatcherC/Plots.jl into date-xlims 2020-12-07 10:53:55 -05:00
Thatcher Chamberlin b885687187 Now closing plots after display calls 2020-12-07 10:52:48 -05:00
Thatcher Chamberlin 80285061c9 Removed CI env check in Dates tests 2020-12-07 10:52:48 -05:00
Thatcher Chamberlin fa48e5c490 Moved Dates tests to be before backend tests 2020-12-07 10:52:48 -05:00
Thatcher Chamberlin 1fcdac4c9e Added second condition to skip display checks 2020-12-07 10:51:49 -05:00
Thatcher Chamberlin 352df39026 Added checks around display checks to see if we're in CI 2020-12-07 10:51:49 -05:00
Thatcher Chamberlin 9ab4c31d5c Added comments about possible alternate solutions 2020-12-07 10:51:49 -05:00
Thatcher Chamberlin e9e6750481 Removed a println 2020-12-07 10:51:49 -05:00
Thatcher Chamberlin bb3e053eb3 Added fix for case where lims are Date/DateTime s 2020-12-07 10:51:49 -05:00
Thatcher Chamberlin 0bc41f22bb Added display checks to Date/DateTime tests to ensure they are able to be displayed 2020-12-07 10:51:49 -05:00
Thatcher Chamberlin de03c3bca8 Added tests for plots where xlims are Dates and DateTimes 2020-12-07 10:51:49 -05:00
Thatcher Chamberlin f2b8e8512e Added font scaling tests 2020-12-07 10:10:43 -05:00
Daniel Schwabeneder 4c95ca5089 Merge pull request #3182 from ThatcherC/component-tests
WIP: Units Tests and Code Coverage for src/components.jl
2020-12-07 16:03:47 +01:00
Thatcher Chamberlin 9ba633bb59 retrigger checks 2020-12-07 08:26:48 -05:00
Thatcher Chamberlin 0b932ecb17 Added unit tests for src/components.jl 2020-12-06 22:39:56 -05:00
Thatcher Chamberlin f6627f3c5c Now closing plots after display calls 2020-12-06 18:54:53 -05:00
Thatcher Chamberlin 06a823a3be Removed CI env check in Dates tests 2020-12-06 15:21:15 -05:00
Thatcher Chamberlin 8c49652add Moved Dates tests to be before backend tests 2020-12-06 15:20:11 -05:00
Thatcher Chamberlin 0849471bf6 Added second condition to skip display checks 2020-12-06 14:50:16 -05:00
Thatcher Chamberlin e9a4231a5f Added checks around display checks to see if we're in CI 2020-12-06 14:30:11 -05:00
Thatcher Chamberlin c9b1de33f6 Added comments about possible alternate solutions 2020-12-06 13:35:25 -05:00
Thatcher Chamberlin 2013215ef2 Removed a println 2020-12-06 13:35:00 -05:00
Thatcher Chamberlin 8a3ee7bb75 Added fix for case where lims are Date/DateTime s 2020-12-06 13:30:14 -05:00
Thatcher Chamberlin eea73202e2 Added display checks to Date/DateTime tests to ensure they are able to be displayed 2020-12-06 13:27:30 -05:00
Thatcher Chamberlin cd450f49d4 Added tests for plots where xlims are Dates and DateTimes 2020-12-06 13:26:26 -05:00
Jks Liu 4b0d69b6a4 Set extra mine only when HTML format
Extra mine is not used by other format
2020-12-04 23:41:36 +08:00
wg030 02008284aa Update hdf5.jl (#3175) 2020-12-01 23:50:59 +01:00
Daniel Schwabeneder c857d59400 Merge pull request #3169 from JuliaPlots/Test_SnoopCompile_AutoPR_refs/heads/master
[AUTO] Update precompiles
2020-11-27 18:30:58 +01:00
Daniel Schwabeneder b5c8474e3f Merge pull request #3167 from jmert/offsetarrays_sticks
Support plotting `OffsetArray`s for `:sticks` series type
2020-11-27 18:27:06 +01:00
BeastyBlacksmith aafb34f5f5 Update precompile_*.jl file 2020-11-27 12:26:52 +00:00
Amin Yahyaabadi 8451b8da0f Fix CI + Use the triggering branch name in the SnoopCompile branch (#3082)
* Use the triggering branch name in the SnoopCompile branch

* fix set-env deprecation
2020-11-27 13:12:30 +01:00
Justin Willmert 94ca183a5b Support plotting OffsetArrays for :sticks series type 2020-11-26 12:54:37 -06:00
Simon Christ 2774b155b4 1.9.1 [skip ci] 2020-11-16 10:04:47 +01:00
willtebbutt 99dff99504 pgfplotsx, no font size (#3154)
Co-authored-by: Will Tebbutt <will.tebbutt@invenialabs.co.uk>
2020-11-16 10:03:28 +01:00
Simon Christ 10e83b63b6 fix grid for 3d quivers (#3150) 2020-11-13 22:00:32 +01:00
Simon Christ 2ef9bb1c0b 1.9.0 [skip ci] 2020-11-13 13:05:27 +01:00
Simon Christ a955ded5c8 add 3dquiver to pgfplotsx (#3146)
* add 3dquiver to pgfplotsx

* fix 3d quiver

* remove skip from examples
2020-11-13 11:54:46 +01:00
Daniel Schwabeneder 5861b1f11f Merge pull request #3134 from kellertuer/quiver3
Proposes a 3D quiver
2020-11-13 11:38:42 +01:00
Ronny Bergmann 7e8eb5af31 Merge branch 'quiver3' of github.com:kellertuer/Plots.jl into quiver3 2020-11-13 09:30:56 +01:00
Ronny Bergmann abebbdd54a fixes two checks for 3D to work properly. 2020-11-13 09:29:43 +01:00
Daniel Schwabeneder d1aa2097be Merge branch 'master' into quiver3 2020-11-13 09:26:26 +01:00
Daniel Schwabeneder 9c0b2ea090 add 3d quiver test example 2020-11-13 08:38:52 +01:00
daschw 60a7e41442 Update precompile_*.jl file 2020-11-13 08:38:52 +01:00
daschw a38e4734ac Update precompile_*.jl file 2020-11-13 08:38:52 +01:00
Daniel Schwabeneder 40e13793e8 add new test example 2020-11-13 08:38:52 +01:00
Daniel Schwabeneder 5d26068eae fix limits in GR image 2020-11-13 08:38:52 +01:00
Simon Christ ac8e1d7f21 add linestyle to contour plots (#3139)
* add linestyle to contour plots

* Update precompile_*.jl file (#3140)

Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-11-13 08:38:52 +01:00
Josef Heinen f3b6221daa Update Project.toml
Bump version
2020-11-13 08:38:52 +01:00
Josef Heinen 501f33f5c1 Fix SVG scaling problem 2020-11-13 08:38:52 +01:00
Daniel Schwabeneder 967bc89a6d Merge pull request #3143 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-11-12 23:38:33 +01:00
daschw 3b367f8759 Update precompile_*.jl file 2020-11-12 14:40:16 +00:00
Daniel Schwabeneder c43c19a24f Merge pull request #3131 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-11-12 15:27:11 +01:00
daschw 445f27a525 Update precompile_*.jl file 2020-11-12 14:24:11 +00:00
Daniel Schwabeneder e7212961dd Merge pull request #3142 from daschw/gr-image
Fix plotting images with custom axes in GR
2020-11-12 15:08:22 +01:00
Daniel Schwabeneder 1402ff5ea0 add new test example 2020-11-12 14:34:18 +01:00
Simon Christ 693c014064 add linestyle to contour plots (#3139)
* add linestyle to contour plots

* Update precompile_*.jl file (#3140)

Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-11-12 13:53:42 +01:00
Daniel Schwabeneder 32e681d158 fix limits in GR image 2020-11-12 12:48:49 +01:00
Josef Heinen d3315a5dae Update Project.toml
Bump version
2020-11-10 18:37:41 +01:00
Josef Heinen 591d485e09 Fix SVG scaling problem 2020-11-10 18:34:14 +01:00
Ronny Bergmann d3f2a55b59 adds 3d quiver if z component is present. 2020-11-10 11:24:24 +01:00
Daniel Schwabeneder 092c7376c8 Merge pull request #3129 from daschw/tagbot
Tagbot & minor release
2020-11-09 23:35:14 +01:00
Daniel Schwabeneder dafd0a620f Merge pull request #3130 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-11-09 23:21:04 +01:00
daschw e9970637e0 Update precompile_*.jl file 2020-11-09 22:19:00 +00:00
Daniel Schwabeneder 405daa3cfd minor version bump 2020-11-09 23:13:22 +01:00
Daniel Schwabeneder d77899c5a1 update tagbot action 2020-11-09 23:11:35 +01:00
Daniel Schwabeneder 711754edbc Merge pull request #3128 from daschw/pgf-nothing
fix 'no method matching any(::Function, ::Nothing)' error in pgfplotsx
2020-11-09 23:07:21 +01:00
Daniel Schwabeneder 3725a8d387 Merge pull request #3115 from daschw/inference
`@nospecialize`
2020-11-09 23:05:03 +01:00
Daniel Schwabeneder 93998fee00 fix 'no method matching any(::Function, ::Nothing)' error in pgfplotsx 2020-11-09 18:21:00 +01:00
Josef Heinen 9ee2e65225 Update Project.toml
add GR 0.53.0
2020-11-06 16:39:40 +01:00
Daniel Schwabeneder e5d9b8ba48 Merge pull request #3113 from daschw/plotly-legend
Switch to plotly-latest
2020-10-31 23:25:52 +01:00
Daniel Schwabeneder d9c2b7bf37 change to plotly v1.57.1 2020-10-31 22:49:37 +01:00
Daniel Schwabeneder dee3ed263c bump RecipesPipeline compat 2020-10-31 21:26:00 +01:00
Daniel Schwabeneder dc7bdc6f69 add some @nospecialize 2020-10-31 21:07:31 +01:00
Daniel Schwabeneder e21f40bd9a move warn_on_recipe_aliases to RecipesPipeline 2020-10-31 18:51:33 +01:00
Daniel Schwabeneder fe2bae37f3 Merge pull request #3112 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-10-31 13:39:51 +01:00
Daniel Schwabeneder e7c7daff0c use plotly-latest 2020-10-31 13:37:11 +01:00
daschw 6df6b40d3d Update precompile_*.jl file 2020-10-31 12:36:21 +00:00
Daniel Schwabeneder 6286c67c01 add legendtitle to plotly 2020-10-31 13:27:19 +01:00
Daniel Schwabeneder d89b93fe8f Merge pull request #3109 from daschw/compilebot
Simplify CompileBot
2020-10-31 13:24:00 +01:00
Daniel Schwabeneder e5959d97e4 Merge pull request #46 from daschw/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-10-28 23:04:40 +01:00
daschw 7a809697c4 Update precompile_*.jl file 2020-10-28 22:02:41 +00:00
Daniel Schwabeneder 2a4f00b80a Merge pull request #3105 from daschw/discrete-ticks
more regular automatic categorical ticks
2020-10-28 22:59:22 +01:00
Daniel Schwabeneder a18809b922 Merge pull request #45 from daschw/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-10-28 22:48:52 +01:00
daschw dcae18cde2 Update precompile_*.jl file 2020-10-28 21:47:21 +00:00
Daniel Schwabeneder 059fbdfb6d else_os and else_version 2020-10-28 22:31:22 +01:00
Daniel Schwabeneder 978ffb799b use only yml_path in BotConfig 2020-10-28 22:14:17 +01:00
Daniel Schwabeneder ec97ec3994 only run compilebot on linux with julia 1.5 2020-10-28 22:09:05 +01:00
Daniel Schwabeneder 6cbdd696cd add unit tests 2020-10-28 21:59:05 +01:00
Daniel Schwabeneder e15da664b0 Merge pull request #3104 from daschw/geometrybasics
remove dependency on discontinued GeometryTypes
2020-10-28 09:52:25 +01:00
Daniel Schwabeneder 16b9fc08ac more regular automatic categorical ticks 2020-10-27 20:16:45 +01:00
Daniel Schwabeneder 5660ea9501 remove dependency on discontinued GeometryTypes 2020-10-27 11:19:50 +01:00
Daniel Schwabeneder 8ce603d3eb Merge pull request #3097 from daschw/gr-clims
ensure non-identical clims for gr
2020-10-24 21:13:25 +02:00
Daniel Schwabeneder 54fdd4e177 update spy recipe 2020-10-24 00:02:47 +02:00
Daniel Schwabeneder 9b24b38767 Merge pull request #3092 from fhagemann/pyplot
fix missing z for 3d markerplots in PyPlot
2020-10-23 22:22:12 +02:00
Daniel Schwabeneder 00351ebcf1 hopefully more type-stable in general 2020-10-23 22:16:19 +02:00
Daniel Schwabeneder d3343c43a1 ensure non-identical clims for gr 2020-10-23 22:12:10 +02:00
Daniel Schwabeneder c0b375a153 Merge pull request #3096 from daschw/gr-fonts
add more fonts for gr backend
2020-10-23 21:33:33 +02:00
Daniel Schwabeneder f5cb54f223 add more fonts for gr backend 2020-10-23 20:56:56 +02:00
Simon Christ e95b2a2a8f 1.7.3 2020-10-23 09:29:04 +02:00
Fredrik Bagge Carlson 8ee5ee062e Safeguard against nothing arg to isfile in standalone_html_window (#3094)
Fixes #3093
2020-10-23 09:27:22 +02:00
Simon Christ d34b33b4ae 1.7.2 2020-10-23 00:06:07 +02:00
Simon Christ fdbeace33a fix jupyter (#3090)
* fix jupyter

* Update runtests.jl

* Update runtests.jl
2020-10-23 00:05:40 +02:00
Felix Hagemann 26f877ec47 fix missing z for 3d markerplots in PyPlot 2020-10-22 22:27:23 +02:00
Daniel Schwabeneder 8dc3d9805a Merge pull request #3088 from daschw/pyplot-polar
fix pyplot polar heatmap size
2020-10-22 08:55:15 +02:00
Daniel Schwabeneder 08932633d0 fix pyplot polar heatmap size 2020-10-21 23:20:34 +02:00
Simon Christ 959fee92a6 1.7.1 2020-10-21 13:19:37 +02:00
Benjamin Lungwitz 70c4954e16 fixed concatinations of string and nothing (#3087) 2020-10-21 13:18:51 +02:00
Simon Christ dffb699fca add compat for Scratch [skip ci] 2020-10-21 09:38:51 +02:00
Simon Christ 08f993a67f 1.7.0 [skip ci] 2020-10-20 21:28:25 +02:00
github-actions[bot] c4ee343ef2 Update precompile_*.jl file (#3041)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-10-20 21:27:02 +02:00
Simon Christ 17acb45653 Replace artifact by scratchspace (#3067)
* replace build.jl by Artifacts.toml

* check ENV

* fix it

* fix condition

* restore ===

* replace Artifact by Scratchspace

* correct Project.toml

* update CI

* Update ci.yml

* Update SnoopCompile.yml

* add tests

* improve tests

* fix
2020-10-20 17:54:08 +02:00
Simon Christ 842b8fa70d add add_attributes macro (#3069)
* add add_attributes macro

* add underscore

* add non_underscore and plural aliases
2020-10-20 17:53:44 +02:00
Simon Christ e236005d72 add mesh3d support (#3076)
* add mesh3d support

* correct example string
2020-10-17 21:40:11 +02:00
Daniel Schwabeneder c7955420e3 Merge pull request #3074 from daschw/gr-guides
fix guide position in 3d plots in GR
2020-10-17 09:08:58 +02:00
Daniel Schwabeneder c9b186c6ac Merge pull request #3075 from aminya/CompileBot
use CompileBot 1
2020-10-17 08:49:13 +02:00
Daniel Schwabeneder 072b6f42f6 add test example 2020-10-17 08:35:49 +02:00
aminya 86bec68b42 use CompileBot 1 2020-10-16 19:34:40 -05:00
Daniel Schwabeneder 2a09bd8266 fix z axis rotation 2020-10-16 18:35:47 +02:00
Daniel Schwabeneder 2be5756cb8 fix guide position in 3d plots in GR 2020-10-16 18:19:31 +02:00
Simon Christ 015b48eede fix attributes passing (#3073) 2020-10-16 16:58:35 +02:00
Daniel Schwabeneder 7fe6a69a21 Merge pull request #3066 from daschw/gr-polar
Fix polar heatmap on GR
2020-10-15 10:04:59 +02:00
Daniel Schwabeneder 60dcfa9a90 up version 2020-10-15 09:32:20 +02:00
Daniel Schwabeneder 3d2f7571a0 add polar heatmap example 2020-10-15 09:06:41 +02:00
Daniel Schwabeneder 86c26085b3 fix polar heatmap on GR 2020-10-15 09:01:12 +02:00
Daniel Schwabeneder 2d5ad2828b Merge pull request #3064 from daschw/pyplot-fixes
Pyplot fixes
2020-10-14 21:33:13 +02:00
Daniel Schwabeneder bae04d05a3 up version 2020-10-14 21:31:48 +02:00
Daniel Schwabeneder bd287f4656 fix pyplot image 2020-10-14 21:30:04 +02:00
Jinay Jain 638fe6d245 Fix typo in grid layout documentation comment (#3061) 2020-10-14 14:52:07 +02:00
Daniel Schwabeneder 3f05dc3570 Merge pull request #3060 from daschw/py-surface
fix pyplot
2020-10-14 07:43:10 +02:00
Daniel Schwabeneder 44150ccbe4 fix 3d plotting in pyplot 2020-10-13 23:47:45 +02:00
Daniel Schwabeneder c15483d593 Merge pull request #3056 from daschw/transpose_z
Remove `transpose_z` and simplify integration of Surfaces in backends
2020-10-12 22:21:10 +02:00
Simon Christ 363f401474 Fix loading of themes (#3057)
* Fix loading of themes

Fix #3053 

Needs test

* Create test_defaults.jl

* Update runtests.jl

* Update test_defaults.jl

* Update test_defaults.jl

* Update test_defaults.jl

* Update test_defaults.jl

* Update test_defaults.jl
2020-10-12 17:25:40 +02:00
Daniel Schwabeneder a532c97ce2 remove transpose_z from precompiles 2020-10-12 12:08:15 +02:00
Daniel Schwabeneder df07dc9377 actually remove transpose_z 2020-10-12 01:16:59 +02:00
Daniel Schwabeneder 9cf9edffe0 remove transpose_z 2020-10-12 01:10:56 +02:00
Daniel Schwabeneder 2ef13c19ea Merge pull request #3047 from daschw:pyplot-3d
Fix 3d plotting with pyplot
2020-10-07 23:20:28 +02:00
Daniel Schwabeneder 103f0b28ac up version 2020-10-07 23:12:51 +02:00
Daniel Schwabeneder f157c8dc3f fix 3d plotting with pyplot 2020-10-07 23:11:51 +02:00
Daniel Schwabeneder ade0a2dfdc Merge pull request #3027 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-10-06 13:00:10 +02:00
Daniel Schwabeneder 71189e113e Merge pull request #3040 from daschw/release
minor release [skip-ci]
2020-10-06 12:59:31 +02:00
Daniel Schwabeneder 9fe1f55410 minor release [skip-ci] 2020-10-06 12:57:18 +02:00
daschw 827dba1991 Update precompile_*.jl file 2020-10-06 09:23:24 +00:00
Daniel Schwabeneder 6ac7b41eb0 Merge pull request #3039 from daschw/plotly-marker
fix plotly not showing the second marker
2020-10-06 10:52:20 +02:00
Daniel Schwabeneder 4c7156ca5e fix plotly not showing the second marker 2020-10-06 10:28:08 +02:00
Daniel Schwabeneder 9dfc33dc12 Merge pull request #3037 from JuliaPlots/compathelper/new_version/2020-10-06-00-29-10-104-1364269850
CompatHelper: add new compat entry for "Latexify" at version "0.14"
2020-10-06 09:51:44 +02:00
github-actions[bot] 317069e2a8 CompatHelper: add new compat entry for "Latexify" at version "0.14" 2020-10-06 00:29:15 +00:00
Daniel Schwabeneder cb54dc071f Merge pull request #3034 from isentropic/pyplot-deprecations
matplotlib warnings
2020-10-06 00:35:18 +02:00
Daniel Schwabeneder b413f0d44e Merge pull request #3025 from Moelf/lims_warning
warn against `lims` being AbstractRange
2020-10-06 00:34:48 +02:00
Daniel Schwabeneder 1784d6179a Merge pull request #3033 from daschw/minor-fixes
Minor clean-up
2020-10-06 00:34:23 +02:00
Daniel Schwabeneder 954f002dfe Merge pull request #3020 from JuliaPlots/bbs/latexify
latexify unicode
2020-10-06 00:33:55 +02:00
Moelf 083fe89905 alternative approach 2020-10-05 00:54:48 -04:00
zhanibek 5906d1c8a5 matplotlib warnings 2020-10-05 12:07:29 +09:00
Daniel Schwabeneder bd46b51b94 remove some more type piracies and use === when comparing to nothing 2020-10-04 18:10:52 +02:00
Daniel Schwabeneder 63e73bc9f0 Merge pull request #3032 from daschw/gr-heatmap
fix heatmap with x and y specifying edges in gr
2020-10-04 17:06:50 +02:00
Daniel Schwabeneder 915eafcea0 move operation definitions for pct to PlotMeasures module 2020-10-04 16:10:51 +02:00
Daniel Schwabeneder 63d9363505 Revert "move operation definitions for pct to PlotMeasures module"
This reverts commit 8e85bdb32f20e1c7e0d508e04e9442caa92bfc8a.
2020-10-04 16:10:51 +02:00
Daniel Schwabeneder 721b4b1312 move operation definitions for pct to PlotMeasures module 2020-10-04 16:10:51 +02:00
Daniel Schwabeneder f96e239bc0 remove Measures type piracy 2020-10-04 16:10:51 +02:00
Daniel Schwabeneder a13e137770 !== nothing 2020-10-04 16:10:41 +02:00
Daniel Schwabeneder 6a1af1c888 add explanation 2020-10-04 15:02:38 +02:00
Daniel Schwabeneder 729219f5a0 fix heatmap with x and y specifying edges in gr 2020-10-04 14:56:41 +02:00
Moelf bdcc8cdb8d Alternative approach 2020-10-03 15:33:19 -04:00
Daniel Schwabeneder 23b852da8f Merge pull request #3030 from daschw/plotly-3d
fix multiple subplots with 3d in plotly
2020-10-03 13:40:45 +02:00
Daniel Schwabeneder 8255096bce fix multiple subplots with 3d in plotly 2020-10-03 12:51:34 +02:00
github-actions[bot] abde25efe0 Update precompile_*.jl file (#3026)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-10-02 23:26:20 +02:00
Simon Christ efb5816bc1 replace build.jl by Artifacts.toml (#3023)
* replace build.jl by Artifacts.toml

* check ENV

* fix it
2020-10-02 22:10:53 +02:00
Moelf 994b543add add slice_arg for AbstractRange 2020-10-02 15:08:59 -04:00
Simon Christ bb11c62413 latexify unicode 2020-10-02 10:27:20 +02:00
Simon Christ b8222b46fe 1.6.8 [skip ci] 2020-10-01 22:10:52 +02:00
Amin Yahyaabadi 1f6244195a Rename SnoopCompileBot to CompileBot (#3018) 2020-10-01 21:16:42 +02:00
BerndR f4fe4b8a05 Changed labeling-behaviour of :sticks (#3017)
* Changed labeling-behaviour of :sticks

* Further adaptions to make sticks-label behavior as expected

* Fixed for linecolor-attribute

* Deleted some debugging println()

* Changed primary-ness in sticks+marker

Co-authored-by: bernd_uni <bernd.riederer@student.tugraz.at>
2020-10-01 20:55:12 +02:00
Daniel Schwabeneder 514a7c4fff Merge pull request #3016 from bernd1995/bernd1995-plotly-marker_z
Fixed plotly_colorbar_hack() to avoid additional marker
2020-09-30 12:04:01 +02:00
bernd_uni 75e65bff8c Fixed plotly_colorbar_hack() to avoid additional marker 2020-09-30 11:19:49 +02:00
Daniel Schwabeneder f03e8bbc83 Merge pull request #3015 from alusiani/fixhspan
fix horizontal range of hspan()
2020-09-29 14:15:02 +02:00
isentropic fc54177029 text.usetex option hack pyplot (#2893)
* text.usetex option hack

* pyplot ticklabel fixes
2020-09-29 14:26:58 +09:00
Alberto Lusiani 5a932146cf fix horizontal range of hspan() 2020-09-28 23:37:38 +02:00
Simon Christ ba09334845 1.6.7 [skip ci] 2020-09-28 14:12:56 +02:00
Simon Christ 5ccf1e965e fix NaNs in heatmaps (#3007)
* fix NaNHeatmaps

* fix histogram2D

* remove show

* Update precompile_*.jl file (#3008)

Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>

* add a dimensionalty check

* Update precompile_*.jl file (#3010)

Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-27 21:22:43 +02:00
Daniel Schwabeneder e932c76d93 Merge pull request #2962 from Moelf/master
fix error bars in log scale
2020-09-25 09:47:27 +02:00
Daniel Schwabeneder 078a675d1a Merge pull request #3002 from bernd1995/bernd1995-sticks3d
Added support for 3d-plots of seriestype sticks
2020-09-24 08:59:36 +02:00
bernd_uni 408aad6e35 Added support for 3d-plots of seriestype sticks 2020-09-23 15:39:03 +02:00
Simon Christ f4c15b4b5b 1.6.6 [skip ci] 2020-09-22 00:46:26 +02:00
Daniel Schwabeneder d0c709a014 Merge pull request #2999 from daschw/plotly-offset
fix ribbon/fillrange with OffsetArrays in plotly
2020-09-21 23:13:35 +02:00
Daniel Schwabeneder bf8b828957 Merge pull request #2998 from daschw/gr-ticks
GR: handle tick labels for `ticks == nothing`
2020-09-21 22:19:20 +02:00
Daniel Schwabeneder 3964cc19a6 fix ribbon/fillrange with OffsetArrays in plotly 2020-09-21 22:15:47 +02:00
Daniel Schwabeneder 3e14a0db95 gr: handle tick labels for ticks == nothing 2020-09-21 21:37:07 +02:00
Daniel Schwabeneder 11f3715453 Merge pull request #2997 from daschw/plotlybase
Replace ORCA with Plotlybase
2020-09-21 21:35:07 +02:00
Daniel Schwabeneder e7ab664120 add src/backends/plotlybase.jl 2020-09-21 19:58:52 +02:00
Daniel Schwabeneder 2aa3e1a5fc replace ORCA with PlotlyBase 2020-09-21 19:57:04 +02:00
Daniel Schwabeneder f58100b400 Merge pull request #2995 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-21 13:25:30 +03:00
daschw b918c509ac Update precompile_*.jl file 2020-09-21 09:05:51 +00:00
Daniel Schwabeneder 08a4b34c22 Merge pull request #2994 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-21 11:40:20 +03:00
daschw becd95b9b5 Update precompile_*.jl file 2020-09-20 21:51:32 +00:00
Daniel Schwabeneder f0612ad1b3 Merge pull request #2993 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-20 23:49:43 +03:00
BeastyBlacksmith 46fbff72db Update precompile_*.jl file 2020-09-20 19:24:38 +00:00
Simon Christ 0536be3bf7 add arrow support (#2989)
* add arrow support

* correctly handle arrow.side = :both
2020-09-20 20:59:06 +02:00
Daniel Schwabeneder 86561b0af0 Merge pull request #2991 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-20 21:50:04 +03:00
daschw 747181c370 Update precompile_*.jl file 2020-09-19 08:49:29 +00:00
Daniel Schwabeneder c3f8710175 Merge pull request #2987 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-19 11:25:24 +03:00
daschw 4cfcef1066 Update precompile_*.jl file 2020-09-19 08:20:09 +00:00
Daniel Schwabeneder ab0cfd09a4 Merge pull request #2960 from daschw/gr-cleanup
reorganize GR backend code
2020-09-19 10:55:04 +03:00
Moelf cef5b0293e fix error bars in log scale 2020-09-18 09:27:58 -04:00
Daniel Schwabeneder 363c842ab4 redo #2988 2020-09-18 10:23:12 +02:00
Simon Christ 33832fef70 1.6.5 [skip ci] 2020-09-18 10:07:15 +02:00
Daniel Schwabeneder 51527705de extract gr_draw_<seriestype> functions 2020-09-18 09:43:53 +02:00
Daniel Schwabeneder 44bd1812e0 don't run optimize_ticks multiple times 2020-09-18 09:43:53 +02:00
Daniel Schwabeneder 1e536dda4b reorganize axes drawing 2020-09-18 09:43:21 +02:00
Daniel Schwabeneder 6a03da5837 extract legend functions and viewport updating from gr_display 2020-09-18 09:38:29 +02:00
Daniel Schwabeneder 9df962fcce clean up gr_set_tickfont 2020-09-18 09:38:28 +02:00
Jerry Ling b46e460d12 fine tune distance between axis and ticks text (#2988) 2020-09-18 09:26:04 +02:00
github-actions[bot] e1755dcee7 [AUTO] Update precompiles (#2984)
* add tests

* fix vline, vspan with dates

* add limit tests for vline and vspan

* fix 1.3 tests

* Update precompile_*.jl file

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-17 17:50:25 +02:00
Simon Christ 87c44e231b fix vline & vspan (#2985)
* add tests

* fix vline, vspan with dates

* add limit tests for vline and vspan

* fix 1.3 tests
2020-09-17 17:34:16 +02:00
github-actions[bot] c81fe1ea76 Update precompile_*.jl file (#2981)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-16 15:56:37 +02:00
Simon Christ 49555ecc2f Letterswap (#2979)
* Fix vline, histogram, barhist, stephist axis letter

* Fix vspan + move vline y values to shorthands

* Fix histograms with @one_arg_shorthands + fix vspan

* Add tests for axis letter

* move swap to _plot

* use RecipesBase approach

* restore formatters

* fix and format pgfx-tests

* update compat

* Update precompile_*.jl file (#2982)

Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>

Co-authored-by: Benoit Pasquier <briochemc@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-16 14:37:26 +02:00
github-actions[bot] 0425f656ae Update precompile_*.jl file (#2978)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-16 10:03:55 +02:00
Simon Christ 8fabc5f861 delete precompiles 2020-09-16 09:33:19 +02:00
github-actions[bot] 0deb8f6469 Update precompile_*.jl file (#2977)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-15 23:37:59 +02:00
github-actions[bot] df12ddb629 Update precompile_*.jl file (#2976)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-15 23:04:42 +02:00
github-actions[bot] 33f2f75b00 Update precompile_*.jl file (#2975)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-15 22:31:12 +02:00
github-actions[bot] 12e0616712 Update precompile_*.jl file (#2974)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-15 22:00:46 +02:00
github-actions[bot] a9eeb451fc Update precompile_*.jl file (#2973)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-15 21:24:56 +02:00
github-actions[bot] b854f1cc16 Update precompile_*.jl file (#2972)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-15 20:13:28 +02:00
github-actions[bot] 31fb9f09b4 [AUTO] Update precompiles (#2950)
* fix segments

* Update precompile_*.jl file

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-15 18:15:56 +02:00
Simon Christ 3ba712dde0 pgfx fix segments (#2970) 2020-09-15 18:13:46 +02:00
Simon Christ d38379defb 1.6.4 [skip ci] 2020-09-14 09:17:58 +02:00
jaakkor2 3431833a9d bump compat for "GeometryBasics" to "0.3.1" (#2968)
CompatHelper PR to add "0.3" failed https://github.com/JuliaPlots/Plots.jl/pull/2935, but should be fixed in https://github.com/JuliaGeometry/GeometryBasics.jl/pull/83, after which GeometryBasics 0.3.1 was released.
2020-09-14 09:16:51 +02:00
Simon Christ 9c4890d794 Backend refactor (#2965)
* isolate :path

* factor out legend addition

* ported series coordinates code

* fix 3d-like seriestypes

* common add_series

* fix bar

* fix contour

* fix scatter

* Update precompile_*.jl file (#2966)

Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-09-13 19:29:49 +02:00
Yuval 52cb6fbd3a Merge pull request #2958 from yha/txt-no-prepare
Don't prepare_output for text/plain MIME
2020-09-07 19:05:37 +03:00
yha b91aa2bbfc Don't prepare_output for text/plain MIME 2020-09-07 17:33:36 +03:00
Josef Heinen c392cc1227 Update Project.toml 2020-09-03 19:28:07 +02:00
Josef Heinen a5cd06f3de Merge pull request #2953 from jheinen/master
bump compat for "GR" to "0.52.0"
2020-09-03 19:16:03 +02:00
Josef Heinen f2e128e8b6 bump compat for "GR" to "0.52.0" 2020-09-03 19:13:58 +02:00
Daniel Schwabeneder a87a5db6d9 Merge pull request #2949 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-02 17:30:46 +02:00
daschw 744f4d3db9 Update precompile_*.jl file 2020-09-02 14:12:02 +00:00
Daniel Schwabeneder d2c6b800d8 Merge pull request #2948 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-02 15:21:45 +02:00
daschw 1f4a471340 Update precompile_*.jl file 2020-09-02 08:05:20 +00:00
Daniel Schwabeneder 6b57149619 Merge pull request #2947 from daschw/gr-ticks
fix gr_text for non-string input
2020-09-02 09:29:25 +02:00
Daniel Schwabeneder 94e4005b0b Merge pull request #14 from daschw/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-02 09:27:42 +02:00
daschw 5e15ef8ccb Update precompile_*.jl file 2020-09-01 23:11:50 +00:00
Daniel Schwabeneder b1d509cba0 patch release 2020-09-01 23:48:31 +02:00
Daniel Schwabeneder 6a3d5202e6 fix gr_text for non-string input 2020-09-01 23:47:32 +02:00
Daniel Schwabeneder ea25f373bd Merge pull request #2946 from daschw/tests
reduce animation test examples size
2020-09-01 23:39:42 +02:00
Daniel Schwabeneder e223e9c736 Merge pull request #9 from daschw/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-09-01 23:38:14 +02:00
daschw f9053ae06f Update precompile_*.jl file 2020-09-01 20:18:47 +00:00
Daniel Schwabeneder 46b4a202e5 number examples 2020-09-01 21:18:25 +02:00
Daniel Schwabeneder 79e6096142 make animation examples in tests smaller 2020-09-01 20:35:09 +02:00
Daniel Schwabeneder 08ca46748a Merge pull request #2942 from daschw/version
fix version
2020-08-31 21:21:11 +02:00
Daniel Schwabeneder 5b5e298b84 fix version 2020-08-31 21:20:22 +02:00
Daniel Schwabeneder 773f364e0d Merge pull request #2941 from daschw/marker-segments
update apple precompiles
2020-08-31 21:02:48 +02:00
Daniel Schwabeneder 531e705301 Merge pull request #7 from daschw/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-08-31 21:00:42 +02:00
Daniel Schwabeneder b7fedc42d3 Merge pull request #2940 from daschw/marker-segments
Fix marker shapes with segments
2020-08-31 20:57:38 +02:00
Daniel Schwabeneder 3301c4b9e0 patch release [skip ci] 2020-08-31 20:57:01 +02:00
daschw 312661aae5 Update precompile_*.jl file 2020-08-31 18:41:06 +00:00
Daniel Schwabeneder 977838b573 Merge pull request #6 from daschw/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-08-31 20:04:52 +02:00
daschw 4052ce83a2 Update precompile_*.jl file 2020-08-31 17:45:22 +00:00
Daniel Schwabeneder 3136c8f999 add new test example 2020-08-31 19:21:42 +02:00
Daniel Schwabeneder 0b91d51a40 fix marker shapes with segments on gr, pyplot and plotly 2020-08-31 18:55:17 +02:00
Daniel Schwabeneder 8ffac4d20e Merge pull request #2933 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-08-27 01:32:37 +02:00
daschw 85bdca8f1a Update precompile_*.jl file 2020-08-26 23:21:27 +00:00
Daniel Schwabeneder 6ae2d8a291 Merge pull request #2932 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-08-26 23:58:11 +02:00
daschw 9334711e19 Update precompile_*.jl file 2020-08-26 16:51:18 +00:00
Daniel Schwabeneder aa6712c9df Merge pull request #2931 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-08-26 18:26:34 +02:00
yha 7515491698 Update precompile_*.jl file 2020-08-26 15:58:43 +00:00
Yuval 0230e29c62 Merge pull request #2898 from yha/tick-format
Tick formating fixes
2020-08-26 18:33:43 +03:00
Yuval d1cfdd7d3d Merge branch 'master' into tick-format 2020-08-26 17:47:27 +03:00
github-actions[bot] 293fd6caaf Update precompile_*.jl file (#2928)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2020-08-24 18:57:06 +02:00
Simon Christ f97bfbba9d 1.6.1 [skip ci] 2020-08-24 18:32:00 +02:00
ma-laforge 76429cde7a HDF5-Plots Clean up: Easier to understand/maintain. (#2924)
* Clean up code: Easier to understand/maintain.

Also:
Reduce line count for code.
Add namespace (module) to use shorter function/variable names.
Improve auto-generation of readers/writers for arbitrary structs.
Remove a few manually-written readers/writers for simple structs.
Write Plots.jl version -> VERSION_INFO to help user identify reader of outdated file formats.
Add support for:
 - Arrow
 - ColorScheme, ColorPalette
 - ContinuousColorGradient, CategoricalColorGradient
 - datetimeformatter

* Update precompile_*.jl file

Co-authored-by: ma-laforge <ma-laforge@users.noreply.github.com>
2020-08-24 18:22:54 +02:00
Yuval 66986a0cbd Merge pull request #7 from aminya/SnoopCompile_AutoPR
Snoop compile auto pr
2020-08-23 10:38:43 +03:00
aminya ccec5053b3 Update precompile_*.jl file 2020-08-23 04:30:04 +00:00
Amin Yahyaabadi 72e3cac531 remove old precompiles 2020-08-22 17:26:49 -05:00
Amin Yahyaabadi 24267ed286 Merge pull request #20 from yha/tick-format 2020-08-22 17:26:10 -05:00
Yuval c9b8475a9c Merge pull request #5 from yha/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-08-23 00:15:21 +03:00
yha a90ec5975d Update precompile_*.jl file 2020-08-22 19:21:01 +00:00
Yuval 71ee8d362f Merge pull request #4 from yha/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-08-22 21:58:25 +03:00
yha abb7eb04a6 Update precompile_*.jl file 2020-08-22 18:56:02 +00:00
yha bd7f0dc8d4 Merge branch 'tick-format' of https://github.com/yha/Plots.jl into tick-format 2020-08-22 21:26:35 +03:00
yha f23e6c224d precompiles 2020-08-22 21:26:35 +03:00
yha 449d35ebf2 Tick label formatting fixes 2020-08-22 21:26:35 +03:00
Simon Christ 1b70fb18e4 fix extra series in lens! (#2919)
* fix extra series in lens!

* include tests
2020-08-18 12:42:14 +02:00
Daniel Schwabeneder 960e7dbcd9 Merge pull request #2918 from aminya/pin_upload
pin upload action version
2020-08-18 11:38:31 +02:00
Amin Yahyaabadi 2dee74a3c5 pin upload action version 2020-08-17 10:07:40 -05:00
Daniel Schwabeneder 9d78772660 Merge pull request #2913 from aminya/xfvb
Fixing xfvb issues
2020-08-17 15:38:35 +02:00
Amin Yahyaabadi b44735830a xfvb --auto-servernum 2020-08-17 05:44:58 -05:00
Daniel Schwabeneder 448589413b Merge pull request #2910 from aminya/SnoopCompile2
SnoopCompileBot 2
2020-08-17 12:21:45 +02:00
Amin Yahyaabadi f870b01245 temporary: rev master 2020-08-14 19:13:42 -05:00
Amin Yahyaabadi 48de7e33a5 use SnoopCompile 2 2020-08-14 19:12:13 -05:00
Simon Christ d6bebe1ce2 1.6.0 2020-08-14 14:31:34 +02:00
Adrian Dawid e2c387894f Add :mesh3d series type for Plotly (#2909)
* Add :mesh3d seriestype (in theory)

* Make it work in practice

* Clean up code

* Add support for arbitrary 3d mesh

* Add fallback for other backends

* Add shorthand

* Change i,j,k to series keyword

* Small bugfix

* Update shorthands example

* Add mesh3d example

* Add some documentation to example

* Make color work

* Move mesh3d example and add to skip list

* Update fallback recipie

* Update example

* Update src/args.jl

Co-authored-by: Simon Christ <SimonChrist@gmx.de>

* Update src/backends/plotly.jl

Co-authored-by: Simon Christ <SimonChrist@gmx.de>

* Update src/examples.jl

Co-authored-by: Simon Christ <SimonChrist@gmx.de>

* Cosmetic changes

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2020-08-14 14:26:16 +02:00
Simon Christ bf85afe9d6 unite titlefonts (#2363)
* change default `plot_title`

* add fontkwargs for colorbar_title, plot_title and window_title

* add utility functions

* adjust default colorbar title fontsize

* remove window-title attributes and edit description

* add match_map entries

* remove plot_fontfamily add match for colorbar_fontfamily

* add process_any_label

* add tests

* add magic arguments

* adjust tests

* fix subplot args
2020-08-13 11:31:17 +02:00
Simon Christ 217e67fb7f 1.5.9 [skip ci] 2020-08-11 10:58:03 +02:00
ztangent 3053bb4cc2 Fix error when setting animation loop count (#2904)
When creating an animation with a custom loop count, via, e.g., `gif(anim; loop=-1)`, so `mov(anim; loop=-1)`, FFMPEG throws the following error:

```
[image2 demuxer @ 000001fdf77ec280] Unable to parse option value "-1" as boolean
[image2 demuxer @ 000001fdf77ec280] Error setting option loop to value -1. 
```

This PR fixes the error by moving the `-loop` flag to after the `-i` input flag in the call to `ffmpeg_exe`. I believe the error is caused because the `-loop` flag occuring before `-i` controls how the input is interpreted, whereas the `-loop` flag occuring after `-i` controls how many loops are in the output.
2020-08-11 10:31:29 +02:00
Simon Christ 8dcff1f73d Update SnoopCompile.yml (#2902) 2020-08-07 22:36:29 +02:00
Simon Christ c73a5aaabc fix saving as .tikz (#2901) 2020-08-07 12:45:50 +02:00
github-actions[bot] 806d4671ce CompatHelper: bump compat for "FFMPEG" to "0.4" (#2891)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-05 10:18:47 +02:00
Simon Christ c4a64351ca set version to 1.5.8 [skip ci] 2020-08-04 11:05:28 +02:00
Simon Christ 345bceb526 conserve extra_kwargs (#2885)
* conserve extra_kwargs

* Update test_pgfplotsx.jl

* remove wraptuples

* Update test_pgfplotsx.jl

* Update test_pgfplotsx.jl

* Update test_pgfplotsx.jl

* Update test_pgfplotsx.jl

* Revert "remove wraptuples"

This reverts commit 6d66d69692.

* Auto stash before revert of "remove wraptuples"
2020-08-01 00:34:04 +02:00
Simon Christ 5673ced5d7 set version to 1.5.7 [skip ci] 2020-07-28 10:23:15 +02:00
Simon Christ a929903a63 Update SnoopCompile.yml (#2873)
* Update SnoopCompile.yml

I don't think we need to run on all branches and nightly.
Also we don't have benchmarks, right?

* Update SnoopCompile.yml
2020-07-27 09:34:32 +02:00
Maaz Bin Tahir Saeed b9cf8c3928 Fix guides not being considered in calculating plot area (#2878) 2020-07-26 21:43:22 +02:00
Simon Christ 9b573dce49 set version to 1.5.6 [skip ci] 2020-07-23 11:59:08 +02:00
isentropic c2bb17cece pyplot fonts fixed (#2858) 2020-07-23 11:57:24 +02:00
Maaz Bin Tahir Saeed 7e122bdfea Fix #2848: Legend :top should start below axis spine (#2870)
* Account for adding dy to ymax in legend pos

* Subtract x legend offset from :right symbols
2020-07-23 09:48:14 +02:00
Yuval 1ee999af33 Merge pull request #2867 from yha/animation-no-yuv
Don't use `-pix_fmt yuv420p` when calling ffmpeg
2020-07-22 19:49:03 +03:00
Daniel Schwabeneder 381f14b657 Merge pull request #2869 from MLH-Fellowship/diaga-2808
Fix #2808: Make legend width proportional to plot size
2020-07-22 14:02:15 +02:00
Diaga 3fec5ae1cf Include legend width changes for shapes and increase width 2020-07-21 18:27:06 +05:00
Diaga b154a1a3e4 Make white space and marker pos dynamic 2020-07-21 14:19:20 +05:00
Yuval cef0a55870 Merge pull request #2866 from yha/offset-fillrange
Support offset vectors as fillrange and ribbon
2020-07-20 12:35:00 +03:00
yha 61e80e96cf Don't use yuv240p format for video 2020-07-20 01:05:14 +03:00
yha 0db321aecc Support offset vectors as fillrange and ribbon 2020-07-20 00:12:47 +03:00
Daniel Schwabeneder 8b7f87506a Merge pull request #2865 from daschw/pyplot-image
fix wrong image limits in pyplot (fix #2864)
2020-07-16 23:36:45 +02:00
Simon Christ f9f6e0ff57 remove show comments 2020-07-16 21:25:46 +02:00
Daniel Schwabeneder 6f36d0998f fix wrong image limits in pyplot (fix #2864) 2020-07-16 20:17:02 +02:00
Josef Heinen 943bdca05e Update Project.toml 2020-07-15 21:19:28 +02:00
Josef Heinen bece65e922 Update Project.toml 2020-07-15 21:17:25 +02:00
Simon Christ 2fb315af0e fix typo 2020-07-13 10:09:43 +02:00
Simon Christ 849c2911a7 fix ribbon, fillbetween distinction 2020-07-09 22:07:04 +02:00
Simon Christ fa720d6ad4 patch release [skip ci] 2020-07-09 12:32:04 +02:00
Simon Christ 1ab681f509 fix ribbons (#2853)
* fix ribbons

* fix tests
2020-07-09 12:23:27 +02:00
Daniel Schwabeneder 0d776fd09d Merge pull request #2850 from daschw/gr-error
fix yerror and marker_z
2020-07-08 08:58:12 +02:00
Daniel Schwabeneder 45e33f5b6f fix yerror and marker_z 2020-07-07 21:44:47 +02:00
Daniel Schwabeneder 1c4910f90e Merge pull request #2807 from MLH-Fellowship/diaga-issue-2202-2330
Fix #2330, #2202: Position legends closer to the borders
2020-07-07 20:55:00 +02:00
Simon Christ 2f4eb7b558 change z buffer for surface plots (#2843) 2020-07-04 19:37:42 +02:00
Daniel Schwabeneder 07ed5e7162 Merge pull request #2846 from daschw/release
patch release
2020-07-04 12:17:23 +02:00
Daniel Schwabeneder 03716289c3 patch release [skip ci] 2020-07-04 12:16:13 +02:00
Daniel Schwabeneder 0d38f34e54 Merge pull request #2844 from daschw/errorbar
fix errorbar color
2020-07-03 17:09:17 +02:00
Daniel Schwabeneder 2544808000 update errorbar example 2020-07-03 16:31:03 +02:00
Diaga 02ca049bc6 Remove static offsets for ypos 2020-07-03 18:52:54 +05:00
Daniel Schwabeneder cd20518323 fix errorbar color for scatter 2020-07-03 15:40:46 +02:00
Diaga ff7235e9b8 Remove constant offsets for xpos 2020-07-03 17:56:13 +05:00
Daniel Schwabeneder fb5307ace6 Merge pull request #2840 from daschw/release
patch release
2020-07-02 16:42:47 +02:00
Lakshya Khatri e3512b0f0d Add label for label=0 kwarg (#2837)
* Add label for `label=0` kwarg

* Fix ambiguous comparision of label with 0

* Add methods for handling plot labels

* Remove type annotations for series indexes

* Replace label conversion code with shorter version

* Handel symbol args for labels in more consistent manner

* Broadcast label_to_string to handle Array of labels

Co-authored-by: Simon Christ <SimonChrist@gmx.de>

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2020-07-02 16:32:37 +02:00
Diaga 376fae0d79 Make legend offset calculation dynamic 2020-07-02 18:12:23 +05:00
Daniel Schwabeneder e0e240bfd2 bump version [skip ci] 2020-07-02 14:41:04 +02:00
Daniel Schwabeneder 079152a69a Merge pull request #2839 from daschw/precompile
include precompile_includer.jl
2020-07-02 14:39:20 +02:00
Daniel Schwabeneder ffed7ebc21 undo version change in SnoopCompile.jl 2020-07-02 13:55:10 +02:00
Daniel Schwabeneder cc7c0f1251 change julia 1.5.0 version 2020-07-02 13:51:57 +02:00
Daniel Schwabeneder 30c683b201 include prercompile_includer.jl manually 2020-07-02 13:50:26 +02:00
Daniel Schwabeneder c3fa7c8941 Merge pull request #2836 from daschw/windows-tests
Make tests pass on windows julia 1.3
2020-07-01 12:07:20 +02:00
Daniel Schwabeneder ddc89e54f1 fix undefined is_ci 2020-07-01 10:32:04 +02:00
Simon Christ ed2d5be538 patch version [skip ci] 2020-07-01 10:28:22 +02:00
Moritz Schauer c0adba6615 Update arg_desc.jl (#2830)
Mention aspect_ratio = :none
2020-07-01 10:23:28 +02:00
Simon Christ 22cf3e127e keep size when plotting in juno (#2826) 2020-07-01 10:22:52 +02:00
Daniel Schwabeneder 0a929d6022 try to fix tests on windows julia 1.3 2020-07-01 09:44:27 +02:00
Daniel Schwabeneder 698f9d8c9e Merge pull request #2835 from JuliaPlots/SnoopCompile_AutoPR
[AUTO] Update precompiles
2020-07-01 09:44:00 +02:00
github-actions[bot] f97a5153b0 Update precompile_*.jl file 2020-07-01 07:40:42 +00:00
Daniel Schwabeneder 065089a1a3 Merge pull request #2832 from daschw/snoopibot
Use SnoopCompileBot
2020-07-01 09:16:54 +02:00
Daniel Schwabeneder 79fac7a85e use '1.5.0-rc1' until 1.5 is released 2020-07-01 00:27:59 +02:00
Daniel Schwabeneder a46ffbe218 update 1.5 version specification in SnoopCompile.yml 2020-07-01 00:06:38 +02:00
Daniel Schwabeneder dc81c6aa8c Update .github/workflows/SnoopCompile.yml 2020-06-30 23:43:55 +02:00
Daniel Schwabeneder fc89578536 Update .github/workflows/SnoopCompile.yml
Co-authored-by: Amin Yahyaabadi <aminyahyaabadi74@gmail.com>
2020-06-30 23:35:51 +02:00
Daniel Schwabeneder 6425ff8f4c Update deps/SnoopCompile/snoop_bot.jl
Co-authored-by: Amin Yahyaabadi <aminyahyaabadi74@gmail.com>
2020-06-30 23:22:35 +02:00
Daniel Schwabeneder 032f76c69b Update deps/SnoopCompile/snoop_bench.jl
Co-authored-by: Amin Yahyaabadi <aminyahyaabadi74@gmail.com>
2020-06-30 23:22:22 +02:00
Daniel Schwabeneder ebaa965604 Merge pull request #2833 from daschw/compathelper
update compathelper config
2020-06-30 22:00:08 +02:00
Daniel Schwabeneder fa44e39030 update compathelper config 2020-06-30 21:57:17 +02:00
Daniel Schwabeneder a2aad6be66 don't run on 1.5 2020-06-30 21:23:00 +02:00
Daniel Schwabeneder 3f521b3322 multios and run on 1.5 2020-06-30 21:18:04 +02:00
Daniel Schwabeneder 16618430ed be explicit about julia versions 2020-06-30 19:25:59 +02:00
Daniel Schwabeneder 4f791a394e don't display plotly plots 2020-06-30 18:37:32 +02:00
Daniel Schwabeneder cfab4e35cc skip statsplots testimages 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder 3ea521793b add env variables for GR 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder 2511d2128b actually use xvfb-run 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder d0920ac919 add GKS_ENCODING env variable 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder acd6cfabc1 string instead of versionnumber 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder 86b92698cc xvfb-run and update versions 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder fb402d9901 don't include precompile_loader 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder ddcf443f89 remove nightly in snoop_bot.jl 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder 3dd3808895 don't run snoopcompilebot on nightly 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder 12df81f390 automate updating of precompilation files using SnoopCompileBot 2020-06-30 18:28:44 +02:00
Daniel Schwabeneder dbd28bc57b Merge pull request #2829 from daschw/ci
update versions in github actions ci
2020-06-30 18:25:51 +02:00
Daniel Schwabeneder 171c2f8e33 Merge pull request #2828 from daschw/grays
fix recipe for arrays of grays
2020-06-30 17:22:29 +02:00
Daniel Schwabeneder 88c94e11b9 update versions in github actions ci 2020-06-30 17:03:55 +02:00
Daniel Schwabeneder 949e245e15 fix recipe for arrays of grays 2020-06-30 16:28:09 +02:00
Daniel Schwabeneder f1db5d6502 Merge pull request #2827 from KristofferC/patch-1
allow JSON 1.0
2020-06-30 15:56:41 +02:00
Kristoffer Carlsson 94086a0ed1 allow JSON 1.0 2020-06-30 14:48:52 +02:00
Simon Christ 8d67577711 minor bump [skip ci] 2020-06-29 23:06:12 +02:00
Daniel Schwabeneder 657f6224d1 Merge pull request #2799 from isentropic/fixedlayouts
layouts fixed
2020-06-29 18:22:53 +02:00
Daniel Schwabeneder d98481fca8 Merge pull request #2821 from daschw/juliaversion
Update julia version
2020-06-29 18:21:57 +02:00
Daniel Schwabeneder 1c694ca81c don't test twice for julia v1 2020-06-27 14:15:50 +02:00
Daniel Schwabeneder c52d5e44c7 allow failures on julia 1.3 windows 2020-06-27 13:08:22 +02:00
Daniel Schwabeneder f2a2797c34 require julia 1.3 2020-06-27 12:56:59 +02:00
Daniel Schwabeneder d14fac5d1e try julia 1.3 2020-06-27 12:14:49 +02:00
Daniel Schwabeneder 2f8e27ab01 use matrix.julia_version for naming ci jobs 2020-06-27 11:09:41 +02:00
Daniel Schwabeneder 2dce036477 require julia 1.2 and update ci 2020-06-27 11:06:43 +02:00
Simon Christ f98ef14f15 bump version [skip ci] 2020-06-26 17:08:03 +02:00
Daniel Schwabeneder c1ccf16830 Merge pull request #2815 from daschw/test-nightly
Fix nightly tests
2020-06-25 23:36:48 +02:00
Daniel Schwabeneder 0b31e26007 use StableRNGs for testing 2020-06-25 22:14:52 +02:00
Daniel Schwabeneder 96ec035811 Merge pull request #2813 from JuliaPlots/compathelper/new_version/2020-06-25-10-06-52-376-899956638
CompatHelper: add new compat entry for "GeometryBasics" at version "0.2"
2020-06-25 14:25:36 +02:00
github-actions[bot] 474f0f922d CompatHelper: add new compat entry for "GeometryBasics" at version "0.2" 2020-06-25 10:06:53 +00:00
Yuval 2fcbb093ac Merge pull request #2800 from yha/geometry-basics
Recipe for GeometryBasics.Point
2020-06-25 13:06:19 +03:00
Josef Heinen 8e3f76cb6f gr: fix problem with ugly exponents (#2810) 2020-06-24 16:38:57 +02:00
isentropic 07146e84e5 line caps, legendbox (#2802) 2020-06-24 14:34:02 +09:00
Rashika Karki 47590b2538 Fix position of legend (#2806)
* Fix position of legend

* Fix var name
2020-06-23 10:59:27 +09:00
Diaga d036794576 Fix #2330, #2202: Position legends closer to the borders 2020-06-22 17:45:23 +05:00
Daniel Schwabeneder b6234a9ea0 Merge pull request #2805 from MLH-Fellowship/rashika-issue-2775
Add outer legend for Plotly
2020-06-22 10:40:01 +02:00
Rashika d1b2c7f751 Add outer legend for Plotly 2020-06-22 09:39:24 +05:45
yha d353dca531 Recipe for GeometryBasics.Point 2020-06-18 21:18:34 +03:00
Simon Christ 709a8a9609 bump version [skip ci] 2020-06-18 14:33:13 +02:00
Zhanibek 0942b14905 layouts fixed 2020-06-18 14:17:10 +09:00
Rashika Karki d6af1da35a Fix #2771: Add aliases (#2791)
* Fix #2771: Add aliases

* Added function to add aliases from vector
2020-06-17 14:37:01 +02:00
Daniel Schwabeneder bbbee44c66 Merge pull request #2793 from daschw/gr-3d
add legend line in GR for 3d paths
2020-06-17 14:25:37 +02:00
Daniel Schwabeneder 9499cef25d add legend line in GR for 3d paths 2020-06-17 11:54:53 +02:00
Simon Christ 7c8952fadf bump version [skip ci] 2020-06-17 11:19:26 +02:00
isentropic 8b2d3e926a better exopnents (#2786) 2020-06-17 11:18:03 +02:00
Fons van der Plas fb40ed1f59 Plotly fixed version (#2779)
* Fixed version for plotly.js dependency

* Fixed version for plotly.js dependency - .gitignore update
2020-06-17 11:17:37 +02:00
isentropic e88654cca5 pyplot colorbar positioning (#2772) 2020-06-17 11:17:18 +02:00
Maaz Bin Tahir Saeed a9b9b3c357 Fix #2377, #2785, #2369: Legend positioning fix for multiple plots (#2784)
* Fix 2377: Legend positioning fix for multiple vertical plots

* Fix #2785: Legend positioning for multiple horizontal plots
2020-06-17 11:16:37 +02:00
Simon Christ 99c8bfe12d bump version [skip ci] 2020-06-16 09:44:37 +02:00
Simon Christ 3eb2b783dc keep LaTeXStrings to be LaTeXStrings (#2781) 2020-06-16 09:39:07 +02:00
Daniel Schwabeneder a20b275eaf Merge pull request #2788 from jheinen/master
gr: fix polar heatmap problem
2020-06-16 09:23:43 +02:00
Josef Heinen c29694ae70 gr: fix polar heatmap problem 2020-06-15 12:53:57 +02:00
Simon Christ ebc93b6935 remove Pkg (#2776)
* remove Pkg

* remove using Pkg
2020-06-10 12:03:13 +02:00
isentropic 7dcbe911b1 Legends documentation and some todos (#2770)
* improve legends documentation

* todo additional legend positions

* Update plotly.jl

removed todo
2020-06-09 13:30:06 +02:00
Simon Christ c2df99cc66 remove showgradient and showlibrary (#2769) 2020-06-09 08:38:43 +02:00
isentropic a992effa5e scalefontsize fixed (#2765) 2020-06-09 08:37:39 +02:00
Simon Christ e49eb9bc83 update badges (#2761)
* update badges

* Update README.md
[skip ci]
2020-06-06 10:13:25 +02:00
Daniel Schwabeneder f2d7d394bb Merge pull request #2760 from daschw/gr-heatmap
improve nonuniform heatmap performance on GR
2020-06-05 19:55:16 +02:00
Daniel Schwabeneder 87d40cd34d improve nonuniform heatmap performance on GR 2020-06-05 18:23:48 +02:00
Daniel Schwabeneder 5f24f88f12 Merge pull request #2757 from daschw/release
bump version [skip ci]
2020-06-04 13:34:07 +02:00
Daniel Schwabeneder 9c465b58db bump version [skip ci] 2020-06-04 13:33:15 +02:00
Daniel Schwabeneder ad4a00c055 Merge pull request #2755 from jamblejoe/fix/spy
Plots.findnz for sparse and non-sparse matrices
2020-06-04 13:31:30 +02:00
Daniel Schwabeneder 54671c15d7 Merge pull request #2751 from isentropic/plotly-legends
plotly legend fixes
2020-06-04 11:42:20 +02:00
Daniel Schwabeneder fff8f84acf Merge pull request #2748 from daschw/tests
Remove travis and appveyour config files
2020-06-04 00:25:17 +02:00
Daniel Schwabeneder 4d8ea50f69 Merge pull request #2754 from daschw/current-stable
Add missing commits
2020-06-04 00:24:19 +02:00
Goran Nakerst 43f31cbc98 Plots.findnz for sparse and non-sparse matrices 2020-06-03 23:06:23 +01:00
Daniel Schwabeneder d98e76e36d Merge remote-tracking branch 'origin/master' into current-stable 2020-06-03 23:29:41 +02:00
Zhanibek e2a5e40019 plotly legend fixes 2020-06-03 16:08:53 +09:00
Daniel Schwabeneder 3c2c2c18d7 Remove travis and appveyour config files 2020-06-01 09:58:22 +02:00
Daniel Schwabeneder 0ee1d867c9 Merge pull request #2745 from aminya/GitHubActions
GitHub actions
2020-06-01 09:46:34 +02:00
Amin Yahyaabadi b145ea9ef5 typo 2020-05-31 02:38:38 -05:00
Daniel Schwabeneder 73971896ee Merge pull request #2744 from giordano/patch-1
Remove duplicate entries in the Project file
2020-05-31 09:29:42 +02:00
Amin Yahyaabadi f5f4128e30 Add ci.yml 2020-05-30 20:41:23 -05:00
Mosè Giordano 70dfa52a9a Remove duplicate entries in the Project files 2020-05-31 01:05:04 +01:00
Josef Heinen 2e53c57114 bump GR version 2020-05-29 16:49:51 +02:00
Simon Christ 0485b1313a bump version [skip ci] 2020-05-29 15:16:15 +02:00
Daniel Schwabeneder f0f28086a9 Merge pull request #2740 from daschw/vline
fix infinite objects with log scale
2020-05-29 10:50:04 +02:00
Daniel Schwabeneder 580ac8a9d1 fix infinite objects with log scale 2020-05-29 09:42:44 +02:00
Daniel Schwabeneder 84fc6b0be0 Merge pull request #2739 from mileslucas/patch-1
fix type restriction in process_clims
2020-05-28 08:37:13 +02:00
Miles Lucas de81220c01 fix namespace 2020-05-27 12:16:20 -10:00
Miles Lucas ee1f948448 add process_clims tests 2020-05-27 12:00:53 -10:00
Miles Lucas 995c7d349e fix type restriction in process_clims 2020-05-27 11:55:49 -10:00
Simon Christ 4389160a6a bumb version [skip ci] 2020-05-27 15:23:48 +02:00
Simon Christ 8c6295658b fix showaxis fix (#2737)
* also replace axis syms

* process showaxis

* fix axis keyword
2020-05-27 15:23:02 +02:00
Simon Christ a270e342b7 bump version [skip ci] 2020-05-26 20:41:45 +02:00
Simon Christ 42e2266530 Fix showaxis (#2733)
* also replace axis syms

* include test_axes [skip ci]

* Create test_axes.jl

* process showaxis
2020-05-26 20:40:44 +02:00
Cornelius-G 02e6d729c1 add attribute fillalpha to contourf seriestype for pyplot backend (#2732) 2020-05-26 18:37:58 +02:00
Tim Holy baac9a0578 Remove explicit Revise.track from atsign-require blocks (#2734)
* Remove explicit Revise.track from atsign-require blocks

Since Revise 2.4, it has no longer been necessary to explicitly call
Revise.track, as Revise handles this internally.

Also related: https://github.com/timholy/Revise.jl/pull/487,
which checks to see whether Revise.track was called via atsign-require
and if so return without doing anything.

* Bump Requires [compat] to 1
2020-05-26 18:37:13 +02:00
Simon Christ b73dd46521 bump version [skip ci] 2020-05-25 15:01:42 +02:00
isentropic 7bbb2070a7 pyplot colorbar fixes (#2722)
* pyplot colorbar fixes

* pyplot colorbar fixes

* pyplot: sligtly reworked colorbars

* pyplot 3d color bar fixes

* pyplot 3d color bar fixes
2020-05-25 15:00:56 +02:00
Simon Christ 8859518f2d update compat bounds (#2727) 2020-05-25 10:05:33 +02:00
Simon Christ 7f063c71b5 bump version [skip ci] 2020-05-21 12:35:16 +02:00
hhaensel 1e9691a7c0 Add support for mathjax (latex) and extra_plot_kwargs in plotly backend (#2719)
* support mathjax header in plotly backend

* support extra_plot_kwargs in plotly backend

* correct local file parameter to `file:///`

* corrections proposed by @BeastyBlacksmith

* include extra_kwargs for subplots

* don't merge subplot extra_kwargs

Co-authored-by: Helmut Haensel <M136270@eu.merckgroup.com>
Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2020-05-21 12:32:25 +02:00
Simon Christ e5269bcf95 bump version [skip ci] 2020-05-20 15:56:25 +02:00
Simon Christ fdd76a6ca1 Update bug.md 2020-05-20 15:55:52 +02:00
Simon Christ d19525c269 improve title- and legendlocation (#2718)
* improve titlelocation

* fix default case

* improve legend position
2020-05-20 14:55:19 +02:00
Simon Christ 593331dec2 change default alignment in legends (#2714) 2020-05-19 21:20:14 +02:00
Simon Christ b780d90097 minor bump [skip ci] 2020-05-19 13:04:49 +02:00
Simon Christ 2f9ce790e4 deprecate pgfplots (#2711)
* deprecate pgfplots

* Update backends.jl

* Update backends.jl

* Rename src/backends/pgfplots.jl to src/backends/deprecated/pgfplots.jl

* Update init.jl
2020-05-19 13:03:54 +02:00
Simon Christ d8f4519b0c bump version [skip ci] 2020-05-17 10:29:13 +02:00
Simon Christ 702e41f55d add all guide_positions (#2710)
* add all guide_positions

* remove show
2020-05-17 10:28:21 +02:00
Simon Christ 682ac29fcd fix clims (#2709) 2020-05-16 20:10:39 +02:00
Simon Christ c6ce23d0af bump version [skip ci] 2020-05-14 14:45:00 +02:00
Daniel Schwabeneder 9ae7d2dd9d Merge pull request #2700 from daschw/pgfx-colorbar
pgfplotsx colorbar improvements
2020-05-14 14:17:41 +02:00
isentropic 6ec05628d5 python depthshade (#2703)
* python depthshade

* python depthshade
2020-05-14 12:26:18 +02:00
Daniel Schwabeneder f26ebdc2f1 remove unused color strings 2020-05-13 17:21:18 +02:00
Daniel Schwabeneder c97255fc08 don't make colorbars thinner 2020-05-13 17:03:52 +02:00
Daniel Schwabeneder 9d1ede016b make colorbars thinner 2020-05-13 17:03:52 +02:00
Daniel Schwabeneder 7eb8f2452c colorbar positions :top, :bottom and :left and colorbar tickfont fixes 2020-05-13 17:03:52 +02:00
Daniel Schwabeneder 0a6e691222 allow disabling the colorbar in pgfplotsx 2020-05-13 17:03:52 +02:00
jamblejoe 238aca6a78 added description for argument legendtitle (#2697) 2020-05-12 18:32:21 +02:00
Simon Christ 1f039b3adc bump version [skip ci] 2020-05-11 16:52:42 +02:00
Simon Christ 219465d599 fix contours (#2692)
* fix 2d-contour

* fix filled contours (colorbar is off)

* activate fixed examples
2020-05-11 16:52:00 +02:00
Simon Christ 1963cee94a fix it again (#2694) 2020-05-11 16:51:38 +02:00
Simon Christ ae43e05f6f bump version [skip ci] 2020-05-09 13:10:32 +02:00
Simon Christ 5cd2ba7296 Delete tmpplotsave.hdf5 2020-05-09 13:09:53 +02:00
isentropic 4a00018f25 pyplot hexbin (#2679)
* pyplot hexbin

* pyplot hexbin changes
2020-05-09 13:07:32 +02:00
Simon Christ 32c725e770 error bars behind in scatterplots (#2677)
* errors behind for :scatter

* fix plots with no seriestype
2020-05-09 13:05:15 +02:00
Daniel Schwabeneder 4e2ee35125 Merge pull request #2684 from daschw/gr-ticklabel
fix numeric gr ticklabels
2020-05-08 10:15:04 +02:00
Daniel Schwabeneder 35b0751714 fix numeric gr ticklabels 2020-05-07 18:17:47 +02:00
Zh 28ebc0ccd8 pyplot hexbin 2020-05-07 03:02:00 +09:00
Simon Christ 3d693d88e0 Change color handling of error recipes (#2675)
* fix iteration of segments

* fix error vector arg detection

* change color handling of recipes
2020-05-06 18:21:54 +02:00
Daniel Schwabeneder 6ddf31d465 Merge pull request #2673 from komi1230/master
Removed arrow3d from gr.jl in backends/
2020-05-05 20:50:40 +02:00
Yusuke Kominami 5c1ea707ca removed unnecessary args 2020-05-06 01:24:20 +09:00
Yusuke Kominami a6669f89a0 removed arrow3d 2020-05-05 23:18:03 +09:00
Simon Christ 2a2d509c36 Version bump
[skip ci]
2020-05-05 10:26:56 +02:00
isentropic fd4efb3f33 PyPlot: z-axis guidefontrotation only works for short labels Fix 2641 (#2667) 2020-05-05 10:26:01 +02:00
isentropic e90ab0b898 PyPlot fix contour labels (#2668) 2020-05-05 10:25:12 +02:00
Simon Christ 44367c54da fix quiver (#2670) 2020-05-05 10:24:15 +02:00
Daniel Schwabeneder 3273a65889 Merge pull request #2657 from mileslucas/climsfunc
allow passing a function to `clims`
2020-05-05 08:18:07 +02:00
Miles Lucas 0aa606d835 fix typo in get_clims function docstring 2020-05-04 11:05:53 -10:00
Simon Christ 40848e7432 fix error recipes (#2665)
* fix scatterbins

* fix zerror
2020-05-04 18:16:29 +02:00
Michael Krabbe Borregaard fe4cc4d58c update patch version 2020-05-04 18:12:20 +02:00
Daniel Schwabeneder 56f90ffaf3 Merge pull request #2663 from dietercastel/webm
Added webm support for animations.
2020-05-03 19:28:49 +02:00
Daniel Schwabeneder dfb556339f Merge pull request #2662 from daschw/plotarea
GR size fixes
2020-05-03 15:54:56 +02:00
Daniel Schwabeneder 61f5a7f437 fix extra_kwargs docs string 2020-05-03 15:39:51 +02:00
Daniel Schwabeneder 3be9b8d076 fix outer legend font size 2020-05-03 15:37:12 +02:00
Daniel Schwabeneder 2a138dee40 fix get_size and get_thickness_scaling for series 2020-05-03 15:37:12 +02:00
Daniel Schwabeneder 712ef74b81 remove const _gr_plot_size, _gr_point_mult and _gr_thickness_scaling 2020-05-03 15:37:12 +02:00
Daniel Schwabeneder ba8ca424cf remove gloabal viewport_plotarea in gr 2020-05-03 15:37:12 +02:00
Dieter Castel c6784a779b Added webm support for animations. 2020-05-03 15:31:55 +02:00
Simon Christ d667cb7e57 update documentation of extra_kwargs 2020-05-03 15:10:34 +02:00
Miles Lucas 10a5c2ed1d fix bug with Tuple clims and fix typos 2020-05-01 00:10:27 -10:00
Miles Lucas 8cce78c890 fix typos 2020-04-30 23:38:52 -10:00
Miles Lucas 294ade8aad refactor get_clims calls to use operators 2020-04-30 23:32:30 -10:00
Miles Lucas a59e8411c9 update clims arg description 2020-04-30 22:30:03 -10:00
Daniel Schwabeneder d973f437ef Merge pull request #2653 from daschw/segments
make segments for vectors of markersize and markerstrokewidth
2020-04-30 14:05:45 +02:00
Josef Heinen d5ce2c1431 Merge remote-tracking branch 'upstream/master' 2020-04-30 13:25:06 +02:00
Josef Heinen 834e2a99e3 add actual GR version 2020-04-30 13:18:32 +02:00
Daniel Schwabeneder f8e9e33347 Merge pull request #2650 from daschw/pyplot
pyplot legend marker fixes
2020-04-30 13:17:53 +02:00
Daniel Schwabeneder a0c7781296 make segments for vectors of markersize and markerstrokewidth 2020-04-30 13:16:33 +02:00
Daniel Schwabeneder 2ea998983d fix legend marker for vector of markersizes [skip ci] 2020-04-30 10:04:04 +02:00
Daniel Schwabeneder e44b220b84 fix legend marker linewidth for steppre and steppost [skip ci] 2020-04-30 10:03:21 +02:00
Daniel Schwabeneder 756cccb114 remove lines in legend markers for scatter plots in pyplot [skip ci] 2020-04-30 09:46:13 +02:00
Simon Christ af9982b804 minor bump [skip ci] 2020-04-29 11:47:54 +02:00
Simon Christ 1b946a18d2 passing of extra keywords to pgfplotsx (#2200)
* transfer commit

* extra_kwargs gets populated

* make extra_kwargs a series kw.

* turn extra_kwargs into Dict of Dicts

* pass to pgfplotsx-backend

* add test

* change to dict

* it even works

* cleanup

* undo pgfplots changes

* all of them

* fix tests

* add pgfplotsx tests and special handling of :add

Co-authored-by: Simon Christ <Simon.Christ@mpikg.mpg.de>
2020-04-29 11:43:57 +02:00
Simon Christ a397bfd549 bump version [skip ci]
@JuliaRegistrator register
2020-04-29 11:33:36 +02:00
isentropic d276ac6857 pyplot: legend marker scales independently (#2616)
* pyplot: legend marker scales independently

* pyplot: marker size scales correctly

* pyplot: marker size scales correctly

* pyplot: marker size scales correctly

* pyplot: lw in legend scales with legendfont

* pyplot: legendmarker size 0.8
2020-04-29 11:32:22 +02:00
Daniel Schwabeneder 475d1c2398 Merge pull request #2646 from daschw/release
bump version [skip ci]
2020-04-28 22:06:42 +02:00
Daniel Schwabeneder d6ae848aec bump version [skip ci] 2020-04-28 22:05:36 +02:00
Daniel Schwabeneder 8976fc4ae4 Merge pull request #2644 from daschw/pie
Implement pie as series recipe
2020-04-28 22:01:42 +02:00
Daniel Schwabeneder 095191f8e6 Merge pull request #2645 from daschw/zulip
add zulip chat link to readme
2020-04-28 21:58:55 +02:00
Daniel Schwabeneder 83ad031c13 add zulip chat link to readme 2020-04-28 21:44:24 +02:00
Daniel Schwabeneder 2b1673df6f Merge pull request #2643 from daschw/legendmarker
(Legend) marker scaling for GR
2020-04-28 21:17:10 +02:00
Daniel Schwabeneder b867ad58f8 update precompiles 2020-04-28 20:48:09 +02:00
Daniel Schwabeneder 8b897c3460 implement pie series recipe 2020-04-28 20:48:09 +02:00
Daniel Schwabeneder e5cb36af7a fix legend linewidth 2020-04-28 20:46:44 +02:00
Daniel Schwabeneder cdaa10be27 update precompile file 2020-04-28 19:40:30 +02:00
Daniel Schwabeneder fe3813b5af scale GR markers with thickness_scaling 2020-04-28 19:20:18 +02:00
Daniel Schwabeneder 311bbdc99b scale GR legend markers and lines with legend fontsize 2020-04-28 19:15:42 +02:00
Daniel Schwabeneder c90fa4d63c Merge pull request #2639 from daschw/inspectdr
fix inspectdr
2020-04-27 15:44:22 +02:00
Daniel Schwabeneder 04c1c6c0ed fix inspectdr 2020-04-27 15:17:41 +02:00
Daniel Schwabeneder 47a8294d99 Merge pull request #2637 from daschw/const
Fix most redefining constant warnings in backend code.
2020-04-26 22:13:11 +02:00
Daniel Schwabeneder f3cf8d884a bump version 2020-04-26 21:48:54 +02:00
Daniel Schwabeneder fe2d46d1eb fix pgfx_get_ functions 2020-04-26 21:43:55 +02:00
Daniel Schwabeneder a0ba0e232e remove unused dict 2020-04-26 21:25:49 +02:00
Daniel Schwabeneder 6565515446 update precompiles 2020-04-26 20:59:56 +02:00
Daniel Schwabeneder 65b0f44626 move missing hdf5 type to backends 2020-04-26 20:57:56 +02:00
Daniel Schwabeneder b80ba99100 move remaining const to backends.jl 2020-04-26 20:49:02 +02:00
Daniel Schwabeneder 60980f7f7f remove const in pyplot 2020-04-26 20:25:38 +02:00
Daniel Schwabeneder 5132bebc7f remove const in plotlyjs 2020-04-26 20:16:31 +02:00
Daniel Schwabeneder 275738e7ea remove const in plotly 2020-04-26 20:15:14 +02:00
Daniel Schwabeneder 5759fd61ea remove const in pgfplotsx - 1 more left 2020-04-26 20:03:19 +02:00
Daniel Schwabeneder 577acbdeb6 remove const in ORCA 2020-04-26 19:38:47 +02:00
Daniel Schwabeneder 4d94725797 remove const in inspectdr 2020-04-26 19:37:20 +02:00
Daniel Schwabeneder ad4f92e36d remove some const in hdf5 - 4 more left 2020-04-26 19:30:22 +02:00
Daniel Schwabeneder 577ac33826 remove some const in gr 2020-04-26 19:15:16 +02:00
Simon Christ 3275719f12 fix topleft legend 2020-04-26 15:20:00 +02:00
Daniel Schwabeneder f636edf4c0 Merge pull request #2635 from daschw/colorschemes
fix _as_gradient(::Colorant)
2020-04-26 10:47:13 +02:00
Daniel Schwabeneder 84039a79de bump version 2020-04-26 10:46:26 +02:00
Daniel Schwabeneder d64ba707e9 fix _as_gradient(::Colorant) 2020-04-25 10:43:09 +02:00
Daniel Schwabeneder 703bdf6cfe Merge pull request #2564 from daschw/colorschemes
Switch to ColorSchemes
2020-04-24 22:16:14 +02:00
Daniel Schwabeneder e7f79e9144 fix vector of colors as gradient 2020-04-24 21:32:25 +02:00
Daniel Schwabeneder 79fd7f282d generate precompiles 2020-04-24 21:21:23 +02:00
Daniel Schwabeneder 3078a44fce fix nonuniform heatmap in GR 2020-04-24 21:21:23 +02:00
Daniel Schwabeneder ba4f2665e0 fix range on julia 1.0 2020-04-24 21:21:23 +02:00
Daniel Schwabeneder 5504f59098 remove ColorSchemes dep and bump version 2020-04-24 21:21:12 +02:00
Daniel Schwabeneder 265439fb2b update colorschemes integration 2020-04-24 21:20:07 +02:00
Daniel Schwabeneder 450b36bdde small cleanup in utils 2020-04-24 21:20:07 +02:00
Daniel Schwabeneder f1e7e3a4de integrate colorpalettes in pgfplotsx 2020-04-24 21:20:07 +02:00
Daniel Schwabeneder becfa33ee8 pyplot and plotly integration of ColorPalettes 2020-04-24 21:20:07 +02:00
Daniel Schwabeneder ec5fa44f2a fix plotly ColorSchemes integration 2020-04-24 21:20:07 +02:00
Daniel Schwabeneder 3152d4b4fe fix tests for gr 2020-04-24 21:20:07 +02:00
Daniel Schwabeneder 66d2e4746a implement ColorSchemes integration in PlotUtils 2020-04-24 21:20:07 +02:00
Daniel Schwabeneder 39b10f05b9 Merge pull request #2625 from daschw/unsupported
Add option to suppress `warn_on_unsupported`
2020-04-24 20:52:15 +02:00
Daniel Schwabeneder 5739acd044 Merge pull request #2624 from daschw/default
don't reset defaults with backend()
2020-04-24 20:28:55 +02:00
Daniel Schwabeneder d1fb11ce97 add option to avoid warning on unsupported arguments 2020-04-24 20:10:17 +02:00
Daniel Schwabeneder aa46f584b6 don't warn on unsupported args for unicodeplots 2020-04-24 20:10:17 +02:00
Daniel Schwabeneder 7c87cbb425 don't reset defaults with backend() 2020-04-24 20:01:38 +02:00
isentropic 09de2ebc0e Minorgrid and minorticks for pyplot (#2621)
* Minor grids for pyplot

* Minorgrid and minorticks setup for pyplot
2020-04-24 17:15:00 +02:00
Simon Christ 64f7dc1aed Issue templates (#2623)
* Create bug.md

* Rename .github/ISSUE_TEMPLATES/bug.md to .github/ISSUE_TEMPLATE/bug.md

* Create feature request

* Rename feature request to feature request.md

* add inspectdr
2020-04-24 14:17:39 +02:00
Daniel Schwabeneder 122b4d91a8 Merge pull request #2619 from jamblejoe/patch-titlelocation
changed title_location -> titlelocation
2020-04-23 21:08:39 +02:00
Daniel Schwabeneder d9efbbcf5b Merge pull request #2622 from daschw/errorbar
fix errorbars with string axes
2020-04-23 21:07:37 +02:00
Daniel Schwabeneder d3629f3cfe remove show 2020-04-23 20:37:02 +02:00
Daniel Schwabeneder a9c659aa21 fix errorbars with string axes 2020-04-23 20:35:32 +02:00
Goran Nakerst 5d37264487 changed title_location -> titlelocation 2020-04-23 13:48:42 +01:00
Daniel Schwabeneder 2fc6f9220d Merge pull request #2614 from jamblejoe/patch-1
Add documentation for legend=(x,y)
2020-04-23 08:44:53 +02:00
jamblejoe c976a6de83 Add documentation for legend=(x,y)
Added documentation in arg_desc.jl for placing legends via legend=(x,y) where x,y are Real.
2020-04-23 00:07:28 +01:00
Daniel Schwabeneder 08c0f6d9a3 Merge pull request #2612 from daschw/savefig
fix savefig extensions
2020-04-23 00:01:58 +02:00
Daniel Schwabeneder fafb0d9510 format code to tab length of 4 2020-04-22 23:43:38 +02:00
Daniel Schwabeneder df6fa6fd68 fix double extensions in savefig 2020-04-22 23:37:31 +02:00
Daniel Schwabeneder 8b5fc95443 bump version 2020-04-22 19:30:02 +02:00
Daniel Schwabeneder 4e877a206e fix double extensions in savefig 2020-04-22 19:28:12 +02:00
Daniel Schwabeneder c428dcdb3e Merge pull request #2611 from daschw/default
Fix `default()`
2020-04-22 19:01:24 +02:00
Daniel Schwabeneder 77b5951037 fix savefig for .tex extension 2020-04-22 19:00:20 +02:00
Daniel Schwabeneder a1c59b7904 fix default 2020-04-22 18:20:22 +02:00
Simon Christ 8ae8d74c42 bump version
[skip ci]
2020-04-21 18:53:52 +02:00
Simon Christ eba4d2442c don't add .tex to .tikz (#2607)
* don't add .tex to .tikz

If we reach this point, we already checked if the extension is existent.
This used to append `.tex` if saving as `.tikz` file, which is unwanted.

* Update output.jl

* convert symbol to string
2020-04-21 17:47:28 +02:00
Daniel Schwabeneder d1938c5e94 Merge pull request #2608 from isentropic/isen-dev2
Make the legendbox square as in GR in pyplot
2020-04-21 16:53:28 +02:00
Zh 3dbe5cc3a2 Make the legendbox square as in GR 2020-04-21 21:35:37 +09:00
Daniel Schwabeneder 7a6617efe3 Merge pull request #2605 from isentropic/isen-dev
Tick marks now scale according to thickness_scaling
2020-04-20 19:30:32 +02:00
Zh 123eb15434 Merge remote-tracking branch 'origin/isen-dev' into isen-dev 2020-04-21 01:35:07 +09:00
Zh df13011bd3 Tick marks now scale properly with thickness_scaling 2020-04-21 01:34:11 +09:00
Zh 3368fd2c98 Tick marks now scale properly with thickness_scaling 2020-04-21 01:33:52 +09:00
Daniel Schwabeneder 5a78c492bc Merge pull request #2602 from daschw/release
bump version
2020-04-19 23:01:33 +02:00
Daniel Schwabeneder 8e98d1dfde bump version [skip ci] 2020-04-19 23:00:24 +02:00
Simon Christ 2373dda3c4 allow :auto as limit (#2599) 2020-04-19 17:05:04 +02:00
Daniel Schwabeneder 0456ddfe3a Merge pull request #2594 from isentropic/isen-dev2
[pyplot] marker adjustments in the legend
2020-04-19 10:33:35 +02:00
Daniel Schwabeneder fe0858ebcf Merge pull request #2597 from daschw/annotations
fix annotate! shorthands
2020-04-18 19:26:31 +02:00
Daniel Schwabeneder 6bc38eaea3 fix annotate! shorthands 2020-04-18 19:01:42 +02:00
Zh 43456b09f6 [pyplot] marker adjustments 2020-04-18 14:20:24 +09:00
Daniel Schwabeneder fae1cb4884 Merge pull request #2588 from daschw/webio
fix WebIO error for PlotlyJS
2020-04-16 16:54:40 +02:00
Simon Christ 9b4c66be9a adjust markersize (#2589)
* fix px to pt conversion for markers

* fix test

* bump version [skip ci]

@JuliaRegistrator register
2020-04-16 15:13:21 +02:00
Daniel Schwabeneder 2d29ab7017 fix WebIO error for PlotlyJS 2020-04-16 13:22:36 +02:00
Daniel Schwabeneder 3b3a09302f Merge pull request #2584 from isentropic/isen-dev2
Isen dev2
2020-04-16 09:59:29 +02:00
Simon Christ fe92a384b7 fix point meta for colorbars (#2586) 2020-04-16 00:09:28 +02:00
Daniel Schwabeneder befe20700a Merge pull request #2585 from daschw/span
fix vspan and hspan
2020-04-15 22:07:01 +02:00
Daniel Schwabeneder 41b34e59c7 fix vspan and hspan (copy in shape_data) 2020-04-15 19:53:31 +02:00
Zh c01ee17d88 pyplot markercolor 2020-04-16 01:21:05 +09:00
Zh 8c9422f470 py_get<component>color removal;
marker stroke, adjustments
2020-04-16 00:32:33 +09:00
Zh 7c88256ca4 Merge branch 'master' into isen-dev2 2020-04-15 23:33:39 +09:00
Zh f5fe2692e2 Merge branch 'master' into isen-dev 2020-04-15 23:33:26 +09:00
Josef Heinen d00920ca0e Update gr.jl 2020-04-15 15:16:00 +02:00
Daniel Schwabeneder ef36c6bd0a Merge pull request #2581 from daschw/pgfplotsx
add legendtitle for pgfplotsx
2020-04-15 10:53:08 +02:00
Daniel Schwabeneder a64d84ae70 bump version 2020-04-15 10:36:25 +02:00
Daniel Schwabeneder 9c1b30f774 add legendtitle for pgfplotsx 2020-04-15 10:35:29 +02:00
Daniel Schwabeneder ebfe97a692 Merge pull request #2578 from isentropic/isen-dev
fixing default guidefontrotation direction for pyplot
2020-04-15 08:59:51 +02:00
Zh d8c4210e8f fixing default guidefontrotation direction for pyplot 2020-04-14 20:10:39 +09:00
Daniel Schwabeneder a9c0073aff Merge pull request #2571 from JuliaPlots/as/minorchecks
Check finiteness of upper and lower limit in minor ticks
2020-04-13 19:11:28 +02:00
Anshul Singhvi d04bb42f7b Check finiteness of upper and lower limit in minor ticks 2020-04-13 14:49:23 +05:30
Daniel Schwabeneder bf849d90a7 Merge pull request #2569 from daschw/pyplot
fix pyplot shape markers
2020-04-12 17:26:30 +02:00
Daniel Schwabeneder 95157004b6 fix pyplot shape markers 2020-04-12 17:20:46 +02:00
Daniel Schwabeneder c861664aea Merge pull request #2566 from daschw/release
bump version
2020-04-12 10:10:17 +02:00
Daniel Schwabeneder 72983102e3 bump version 2020-04-12 09:40:24 +02:00
Daniel Schwabeneder 693aaa51d7 Merge pull request #2565 from isentropic/isen-dev
guidefontrotation fix for pyplot
2020-04-12 09:39:17 +02:00
Zh 41a32f7782 guidefontrotation fix for pyplot 2020-04-12 16:01:52 +09:00
Daniel Schwabeneder 5d99c19de1 Merge pull request #2562 from daschw/plotly
fix scale_func for plotly
2020-04-11 17:03:44 +02:00
Daniel Schwabeneder d942660f91 fix scale_func for plotly 2020-04-11 17:01:23 +02:00
Josef Heinen c238d42e83 gr: added initial support for GR vector fonts 2020-04-11 09:50:59 +02:00
Josef Heinen 03a27994d5 Merge remote-tracking branch 'upstream/master' 2020-04-11 09:42:47 +02:00
Daniel Schwabeneder 1f7773ae4c Merge pull request #2561 from mbfstudios/pgfplotsx-fix-minor-ticks
Fix error when setting minor ticks. See #2560
2020-04-10 23:52:16 +02:00
Mats 4a5c82ec7f Fix error when setting minor ticks
Fix type error when specifying number of minor ticks for PGFPlotsX backend.
2020-04-10 22:44:31 +02:00
Daniel Schwabeneder 70f207f5cc Merge pull request #2557 from JuliaPlots/ds/rewrite
Use RecipesPipeline
2020-04-10 20:46:38 +02:00
Daniel Schwabeneder a1cd3d8f95 don't require julia 1.1 2020-04-10 19:47:09 +02:00
Daniel Schwabeneder 848b53e7d7 fix 3d plots 2020-04-10 19:45:11 +02:00
Daniel Schwabeneder 987456760c update precompiles 2020-04-10 19:22:45 +02:00
Daniel Schwabeneder 4c43f0ea2f be explicit about RecipesPipeline imports 2020-04-10 19:06:53 +02:00
Daniel Schwabeneder 7d69795364 require julia version 1.1 2020-04-10 16:14:59 +02:00
Daniel Schwabeneder 059985c91c revert travis test command 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder 9fe3428a55 update Project.toml 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder 92d8bd7836 move some recipes to recipepipeline 2020-04-10 16:09:49 +02:00
Sebastian Micluța-Câmpeanu 2a88ab7726 Rename to RecipesPipeline 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder d8f516a456 fix recipepipeline url in travis 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder 28ce7d7995 add recipepipeline manually in travis 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder b6139e2403 remove include 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder 80ec6f03b4 depend on RecipePipeline 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder 330739298c update and enable precompiles 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder bd9cd64e7a move remaining user recipes in series.jl to recipes.jl 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder f73b281996 extract the recipe pipeline into separate submodule 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder f180c666d2 rename some functions 2020-04-10 16:09:49 +02:00
Daniel Schwabeneder 908779f0c6 Merge pull request #2559 from daschw/gr-box
Fix axis arguments in PLOTS_DEFAULTS
2020-04-10 16:07:11 +02:00
Daniel Schwabeneder 345c3bc928 bump version 2020-04-10 16:05:06 +02:00
Daniel Schwabeneder bbdf1dcc0e fix axis agruments in PLOTS_DEFAULTS 2020-04-10 16:04:17 +02:00
Daniel Schwabeneder 5da2d85420 Merge pull request #2558 from daschw/gr-box
fix axis limits with GR framestyle border
2020-04-10 16:02:46 +02:00
Daniel Schwabeneder 5f524d039f fix axis limits with GR framestyle border 2020-04-10 15:15:36 +02:00
Josef Heinen a05d31a472 Merge remote-tracking branch 'upstream/master' 2020-04-07 09:21:52 +02:00
Josef Heinen 9f7474476a Merge remote-tracking branch 'upstream/master' 2020-04-05 17:09:49 +02:00
Josef Heinen 5f744dac68 Merge remote-tracking branch 'upstream/master' 2020-04-02 17:31:20 +02:00
Josef Heinen c3a9eb8866 Merge remote-tracking branch 'upstream/master' 2020-03-31 11:50:03 +02:00
Josef Heinen a6aa39e3cc Merge remote-tracking branch 'upstream/master' 2020-03-30 10:37:53 +02:00
Josef Heinen 1c66f4bf90 Merge remote-tracking branch 'upstream/master' 2020-03-29 10:45:41 +02:00
Josef Heinen d9dba5091b Merge remote-tracking branch 'upstream/master' 2020-03-26 12:57:48 +01:00
Josef Heinen c94746f3f2 Merge remote-tracking branch 'upstream/master' 2020-03-24 10:41:52 +01:00
Josef Heinen b6dddcb15b Merge remote-tracking branch 'upstream/master' 2020-03-22 09:10:11 +01:00
Josef Heinen 2849082f1f Merge remote-tracking branch 'upstream/master' 2020-03-19 10:35:14 +01:00
Josef Heinen 038cf2b133 Merge remote-tracking branch 'upstream/master' 2020-03-18 16:16:21 +01:00
Josef Heinen a9e2a5f639 Merge remote-tracking branch 'upstream/master' 2020-03-18 08:38:35 +01:00
Josef Heinen c9421be214 Merge pull request #10 from jheinen/compathelper/new_version/2020-03-13-16-05-59-376-460145100
CompatHelper: bump compat for "GR" to "0.48"
2020-03-13 17:07:18 +01:00
github-actions[bot] 9fc707bd94 CompatHelper: bump compat for "GR" to "0.48" 2020-03-13 16:06:00 +00:00
Josef Heinen 236cc4671e Merge remote-tracking branch 'upstream/master' 2020-03-10 12:02:49 +01:00
Josef Heinen a301366ef6 Merge remote-tracking branch 'upstream/master' 2020-03-07 10:53:02 +01:00
Josef Heinen c1959cb993 Merge remote-tracking branch 'upstream/master' 2020-02-29 12:16:47 +01:00
Josef Heinen ecf71a43d3 Merge pull request #8 from jheinen/compathelper/new_version/2020-02-27-15-07-43-107-2999057488
CompatHelper: bump compat for "GR" to "0.47"
2020-02-27 17:51:30 +01:00
github-actions[bot] b65dfc6767 CompatHelper: bump compat for "GR" to "0.47" 2020-02-27 15:07:44 +00:00
70 changed files with 7938 additions and 6890 deletions
+6
View File
@@ -0,0 +1,6 @@
# Set default behaviour to automatically normalize line endings.
* text=auto
# Force bash scripts to always use lf line endings so that if a repo is accessed
# in Unix via a file share from Windows, the scripts will work.
*.sh text eol=lf
+32
View File
@@ -0,0 +1,32 @@
---
name: Bug report
about: Create a bug report
title: "[BUG]"
labels: bug
assignees: ''
---
<!-- Please search existing issues to avoid duplicates. -->
## Details
### Backends
This bug occurs on ( insert `x` below )
Backend | yes | no | untested
-------------|-----|-----|---------
gr (default) | | |
pyplot | | |
plotly | | |
plotlyjs | | |
pgfplotsx | | |
inspectdr | | |
### Versions
Plots.jl version:
Backend version (`]st -m <backend(s)>`):
Output of `versioninfo()`:
+10
View File
@@ -0,0 +1,10 @@
---
name: Feature request
about: Suggest a feature or enhancement
title: "[FR]"
labels: feature request
assignees: ''
---
Please search existing issues to avoid duplicates.
+3 -10
View File
@@ -2,23 +2,16 @@ name: CompatHelper
on:
schedule:
- cron: '00 * * * *'
- cron: '00 00 * * *'
jobs:
CompatHelper:
runs-on: ${{ matrix.os }}
strategy:
matrix:
julia-version: [1.2.0]
julia-arch: [x86]
os: [ubuntu-latest]
runs-on: 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 }}
COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }} # optional
run: julia -e 'using CompatHelper; CompatHelper.main()'
+89
View File
@@ -0,0 +1,89 @@
name: SnoopCompile
on:
push:
branches:
# - 'master' # NOTE: to run the bot only on pushes to master
defaults:
run:
shell: bash
jobs:
SnoopCompile:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
env:
GKS_ENCODING: "utf8"
GKSwstype: "100"
PLOTS_TEST: "true"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version: # NOTE: the versions below should match those in your botconfig
- '1'
os: # NOTE: should match the os setting of your botconfig
- ubuntu-latest
arch:
- x64
steps:
# Setup environment
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.version }}
- name: Install dependencies
run: |
julia --project -e 'using Pkg; Pkg.instantiate();'
julia -e 'using Pkg; Pkg.add( PackageSpec(name = "CompileBot", version = "1") ); Pkg.develop(PackageSpec(; path=pwd())); using CompileBot; CompileBot.addtestdep();'
# TESTCMD
- name: Default TESTCMD
run: echo "TESTCMD=julia" >> $GITHUB_ENV
- name: Ubuntu TESTCMD
if: startsWith(matrix.os,'ubuntu')
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
# Generate precompile files
- name: Generating precompile files
run: $TESTCMD --project -e 'include("deps/SnoopCompile/snoop_bot.jl")' # NOTE: must match path
# Run benchmarks
- name: Running Benchmark
run: $TESTCMD --project -e 'include("deps/SnoopCompile/snoop_bench.jl")' # NOTE: optional, if have benchmark file
- name: Upload all
uses: actions/upload-artifact@v2.0.1
with:
path: ./
Create_PR:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
needs: SnoopCompile
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download all
uses: actions/download-artifact@v2
- name: CompileBot postprocess
run: julia -e 'using Pkg; Pkg.add( PackageSpec(name = "CompileBot", version = "1") ); using CompileBot; CompileBot.postprocess();'
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Update precompile_*.jl file
title: "[AUTO] Update precompiles"
labels: SnoopCompile
branch: "Test_SnoopCompile_AutoPR_${{ github.ref }}"
Skip:
if: "contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- name: Skip CI 🚫
run: echo skip ci
+5 -2
View File
@@ -1,9 +1,12 @@
name: TagBot
on:
schedule:
- cron: 0 * * * *
issue_comment:
types:
- created
workflow_dispatch:
jobs:
TagBot:
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
runs-on: ubuntu-latest
steps:
- uses: JuliaRegistries/TagBot@v1
+34
View File
@@ -0,0 +1,34 @@
name: Run benchmarks
on:
pull_request:
jobs:
Benchmark:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
env:
GKS_ENCODING: "utf8"
GKSwstype: "100"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: 1
## Setup
- name: Ubuntu TESTCMD
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
- name: Install Plots dependencies
uses: julia-actions/julia-buildpkg@latest
- name: Install Benchmarking dependencies
run: julia -e 'using Pkg; pkg"add PkgBenchmark BenchmarkCI@0.1"'
- name: Run benchmarks
run: $TESTCMD -e 'using BenchmarkCI; BenchmarkCI.judge()'
- name: Print judgement
run: julia -e 'using BenchmarkCI; BenchmarkCI.displayjudgement()'
- name: Post results
run: julia -e 'using BenchmarkCI; BenchmarkCI.postjudge()'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+89
View File
@@ -0,0 +1,89 @@
name: ci
on:
push:
pull_request:
defaults:
run:
shell: bash
jobs:
CI:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
env:
GKS_ENCODING: "utf8"
GKSwstype: "100"
name: Julia ${{ matrix.version }} - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.version == 'nightly' }}
strategy:
fail-fast: false
matrix:
version:
- '1'
- 'nightly'
os:
- ubuntu-latest
- windows-latest
- macos-latest
arch:
- x64
# - x86
steps:
# Setup environment
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.version }}
- name: Cache artifacts
uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
## maybe required if we ever want to run graphical tests for plotly
# OS Dependencies
# - name: Ubuntu OS dependencies
# if: startsWith(matrix.os,'ubuntu')
# run: |
# ./test/install_wkhtmltoimage.sh
# TESTCMD
- name: Default TESTCMD
run: echo "TESTCMD=julia" >> $GITHUB_ENV
- name: Ubuntu TESTCMD
if: startsWith(matrix.os,'ubuntu')
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
# Julia Dependencies
- name: Install Julia dependencies
uses: julia-actions/julia-buildpkg@latest
# Run tests
- name: Run Graphical test
run: |
$TESTCMD --project -e 'using Pkg; Pkg.test(coverage=true);'
$TESTCMD -e 'using Pkg; Pkg.activate(tempdir()); Pkg.develop(path=abspath(".")); Pkg.add("StatsPlots"); Pkg.test("StatsPlots");'
$TESTCMD -e 'using Pkg; Pkg.activate(tempdir()); Pkg.develop(path=abspath(".")); Pkg.add("GraphRecipes"); Pkg.test("GraphRecipes");'
- name: Codecov
uses: julia-actions/julia-uploadcodecov@latest
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Skip:
if: "contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- name: Skip CI 🚫
run: echo skip ci
+50
View File
@@ -0,0 +1,50 @@
name: docs
on:
push:
branches:
- master
tags: '*'
jobs:
Build_docs:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
with:
repository: JuliaPlots/PlotDocs.jl
- uses: julia-actions/setup-julia@v1
- name: Cache artifacts
uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- name: Install dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y qt5-default \
ttf-mscorefonts-installer \
poppler-utils \
pdf2svg \
texlive-latex-base \
texlive-binaries \
texlive-pictures \
texlive-latex-extra \
texlive-luatex \
ghostscript-x \
libgconf2-4
sudo fc-cache -vr
- name: build documentation
env:
PYTHON: ""
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
run: |
xvfb-run julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.add(PackageSpec(name="Plots", rev=split(ENV["GITHUB_REF"], "/", limit=3)[3])); Pkg.instantiate()'
xvfb-run julia --color=yes --project=docs/ -e 'withenv("GITHUB_REPOSITORY" => "JuliaPlots/PlotDocs.jl") do; include("docs/make.jl"); end'
+4 -1
View File
@@ -4,9 +4,12 @@
.DS_Store
examples/.ipynb_checkpoints/*
examples/meetup/.ipynb_checkpoints/*
deps/plotly-latest.min.js
deps/plotly-*
deps/build.log
deps/deps.jl
Manifest.toml
dev/
test/tmpplotsave.hdf5
/.benchmarkci
/benchmark/*.json
.vscode/
-44
View File
@@ -1,44 +0,0 @@
# Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
os:
- linux
# - osx
julia:
- 1.0
- 1
- nightly
matrix:
allow_failures:
- julia: nightly
addons:
apt:
packages:
- at-spi2-core
- libgtk-3-dev
- xauth
- xvfb
env:
- GKS_ENCODING="utf8"
cache:
directories:
- $HOME/.julia/artifacts
sudo: required
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pwd ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./test/install_wkhtmltoimage.sh ; fi
notifications:
email: true
after_success:
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; 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)'
+697
View File
@@ -0,0 +1,697 @@
{
"title": "Plots.jl",
"license": "MIT",
"creators": [
{
"affiliation": "Elemental Cognition",
"name": "Tom Breloff"
}
],
"contributors":[
{
"affiliation": "TU Wien",
"name": "Daniel Schwabeneder",
"orcid": "0000-0002-0412-0777",
"type": "ProjectLeader"
},
{
"affiliation": "GLOBE Institute",
"name": "Michael Krabbe Borregaard",
"type": "ProjectLeader"
},
{
"affiliation": "Leibniz Universit\u00e4t Hannover",
"name": "Simon Christ",
"orcid": "0000-0002-5866-1472",
"type": "ProjectLeader"
},
{
"affiliation": "Forschungszentrum J\u00fclich",
"name": "Josef Heinen",
"orcid": "0000-0001-6509-1925",
"type": "ProjectMember"
},
{
"name": "Yuval",
"type": "Other"
},
{
"name": "Andrew Palugniok",
"type": "ProjectMember"
},
{
"affiliation": "@beacon-biosignals",
"name": "Simon Danisch",
"type": "Other"
},
{
"affiliation": "Veos Digital (https://veos.digital/)",
"name": "Pietro Vertechi",
"type": "ProjectMember"
},
{
"affiliation": "Korea Advanced Inst. of Science and Technology (KAIST)",
"name": "Zhanibek Omarov",
"type": "ProjectMember",
"orcid": "0000-0002-8783-8791"
},
{
"name": "Thatcher Chamberlin",
"type": "Other"
},
{
"name": "@ma-laforge",
"type": "ProjectMember"
},
{
"affiliation": "Massachusetts Institute of Technology",
"name": "Christopher Rackauckas",
"orcid": "0000-0001-5850-0663",
"type": "Other"
},
{
"affiliation": "Max Planck Institute for Physics",
"name": "Oliver Schulz",
"type": "Other"
},
{
"affiliation": "@JuliaComputing",
"name": "Sebastian Pfitzner",
"type": "Other"
},
{
"name": "Takafumi Arakaki",
"type": "Other"
},
{
"affiliation": "University of Manitoba",
"name": "Amin Yahyaabadi",
"type": "Other"
},
{
"name": "Jack Devine",
"type": "Other"
},
{
"name": "Sebastian Pech",
"type": "Other"
},
{
"affiliation": "@JuliaComputing",
"name": "Patrick Kofod Mogensen",
"type": "Other",
"orcid": "0000-0002-4910-1932"
},
{
"name": "Samuel S. Watson",
"type": "Other"
},
{
"affiliation": "UC Davis",
"name": "Naoki Saito",
"orcid": "0000-0001-5234-4719",
"type": "Other"
},
{
"affiliation": "University of Southern California (USC)",
"name": "Benoit Pasquier",
"orcid": "0000-0002-3838-5976",
"type": "Other"
},
{
"affiliation": "NTNU Trondheim",
"name": "Ronny Bergmann",
"orcid": "0000-0001-8342-7218",
"type": "Other"
},
{
"name": "Andy Nowacki",
"affiliation": "University of Leeds",
"orcid": "0000-0001-7669-7383",
"type": "Other"
},
{
"name": "Ian Butterworth",
"type": "Other"
},
{
"affiliation": "Lund University",
"name": "David Gustavsson",
"type": "Other"
},
{
"name": "Anshul Singhvi",
"type": "Other"
},
{
"name": "david-macmahon",
"type": "Other"
},
{
"name": "Fredrik Ekre",
"type": "Other"
},
{
"name": "Maaz Bin Tahir Saeed",
"type": "Other"
},
{
"name": "Kristoffer Carlsson",
"type": "Other"
},
{
"name": "Will Kearney",
"type": "Other"
},
{
"name": "Niklas Korsbo",
"type": "Other"
},
{
"name": "Miles Lucas",
"type": "Other"
},
{
"name": "@Godisemo",
"type": "Other"
},
{
"name": "Florian Oswald",
"type": "Other"
},
{
"name": "Diego Javier Zea",
"type": "Other"
},
{
"name": "@WillRam",
"type": "Other"
},
{
"name": "Fedor Bezrukov",
"type": "Other"
},
{
"name": "Spencer Lyon",
"type": "Other"
},
{
"name": "Darwin Darakananda",
"type": "Other"
},
{
"name": "Lukas Hauertmann",
"type": "Other"
},
{
"name": "Huckleberry Febbo",
"type": "Other"
},
{
"name": "@H-M-H",
"type": "Other"
},
{
"name": "Josh Day",
"type": "Other"
},
{
"name": "@wfgra",
"type": "Other"
},
{
"name": "Sheehan Olver",
"type": "Other"
},
{
"name": "Jerry Ling",
"type": "Other"
},
{
"name": "Jks Liu",
"type": "Other"
},
{
"name": "Seth Axen",
"type": "Other"
},
{
"name": "@o01eg",
"type": "Other"
},
{
"name": "Sebastian Micluța-Câmpeanu",
"type": "Other"
},
{
"name": "Tim Holy",
"type": "Other"
},
{
"name": "Tony Kelman",
"type": "Other"
},
{
"name": "Antoine Levitt",
"type": "Other"
},
{
"name": "Iblis Lin",
"type": "Other"
},
{
"name": "Harry Scholes",
"type": "Other"
},
{
"name": "@djsegal",
"type": "Other"
},
{
"name": "Goran Nakerst",
"type": "Other"
},
{
"name": "Felix Hagemann",
"type": "Other"
},
{
"name": "Matthieu Gomez",
"type": "Other"
},
{
"name": "@biggsbiggsby",
"type": "Other"
},
{
"name": "Jonathan Anderson",
"type": "Other"
},
{
"name": "Michael Kraus",
"type": "Other"
},
{
"name": "Carlo Lucibello",
"type": "Other"
},
{
"name": "Robin Deits",
"type": "Other"
},
{
"name": "Misha Mkhasenko",
"type": "Other"
},
{
"name": "Benoît Legat",
"type": "Other"
},
{
"name": "Steven G. Johnson",
"type": "Other"
},
{
"name": "John Verzani",
"type": "Other"
},
{
"name": "Mattias Fält",
"type": "Other"
},
{
"name": "Rashika Karki",
"type": "Other"
},
{
"name": "Morten Piibeleht",
"type": "Other"
},
{
"name": "Filippo Vicentini",
"type": "Other"
},
{
"name": "David Anthoff",
"type": "Other"
},
{
"name": "Leon Wabeke",
"type": "Other"
},
{
"name": "Yusuke Kominami",
"type": "Other"
},
{
"name": "Oscar Dowson",
"type": "Other"
},
{
"name": "Max G",
"type": "Other"
},
{
"name": "Fabian Greimel",
"type": "Other"
},
{
"name": "Jérémy",
"type": "Other"
},
{
"name": "Pearl Li",
"type": "Other"
},
{
"name": "David P. Sanders",
"type": "Other"
},
{
"name": "Asbjørn Nilsen Riseth",
"type": "Other"
},
{
"name": "Jan Weidner",
"type": "Other"
},
{
"name": "@jakkor2",
"type": "Other"
},
{
"name": "Pablo Zubieta",
"type": "Other"
},
{
"name": "Hamza Yusuf Çakır",
"type": "Other"
},
{
"name": "John Rinehart",
"type": "Other"
},
{
"name": "Martin Biel",
"type": "Other"
},
{
"name": "Moritz Schauer",
"type": "Other"
},
{
"name": "Moesè Giodano",
"type": "Other"
},
{
"name": "@olegshtch",
"type": "Other"
},
{
"name": "Leon Shen",
"type": "Other"
},
{
"name": "Jeff Fessler",
"type": "Other"
},
{
"name": "@hustf",
"type": "Other"
},
{
"name": "Asim H Dar",
"type": "Other"
},
{
"name": "@8uurg",
"type": "Other"
},
{
"name": "Abel Siqueira",
"type": "Other"
},
{
"name": "Adrian Dawid",
"type": "Other"
},
{
"name": "Alberto Lusiani",
"type": "Other"
},
{
"name": "Balázs Mezei",
"type": "Other"
},
{
"name": "Ben Ide",
"type": "Other"
},
{
"name": "Benjamin Lungwitz",
"type": "Other"
},
{
"affiliation": "University of Graz",
"name": "Bernd Riederer",
"type": "Other",
"orcid": "0000-0001-8390-0087"
},
{
"name": "Christina Lee",
"type": "Other"
},
{
"name": "Christof Stocker",
"type": "Other"
},
{
"name": "Christoph Finkensiep",
"type": "Other"
},
{
"name": "@Cornelius-G",
"type": "Other"
},
{
"name": "Daniel Høegh",
"type": "Other"
},
{
"name": "Denny Biasiolli",
"type": "Other"
},
{
"name": "Dieter Castel",
"type": "Other"
},
{
"name": "Elliot Saba",
"type": "Other"
},
{
"name": "Fengyang Wang",
"type": "Other"
},
{
"name": "Fons van der Plas",
"type": "Other"
},
{
"name": "Fredrik Bagge Carlson",
"type": "Other"
},
{
"name": "Graham Smith",
"type": "Other"
},
{
"name": "Hayato Ikoma",
"type": "Other"
},
{
"name": "Hessam Mehr",
"type": "Other"
},
{
"name": "@InfiniteChai",
"type": "Other"
},
{
"name": "Jack Dunn",
"type": "Other"
},
{
"name": "Jeff Bezanson",
"type": "Other"
},
{
"name": "Jeff Eldredge",
"type": "Other"
},
{
"name": "Jinay Jain",
"type": "Other"
},
{
"name": "Johan Blåbäck",
"type": "Other"
},
{
"name": "@jmert",
"type": "Other"
},
{
"name": "Lakshya Khatri",
"type": "Other"
},
{
"name": "Lia Siegelmann",
"type": "Other"
},
{
"name": "@marekkukan-tw",
"type": "Other"
},
{
"affiliation": "ETH Zurich",
"name": "Mauro Werder",
"type": "Other",
"orcid": "0000-0003-0137-9377"
},
{
"name": "Maxim Grechkin",
"type": "Other"
},
{
"name": "Michael Cawte",
"type": "Other"
},
{
"name": "@milesfrain",
"type": "Other"
},
{
"name": "Nicholas Bauer",
"type": "Other"
},
{
"name": "Nicolau Leal Werneck",
"type": "Other"
},
{
"name": "@nilshg",
"type": "Other"
},
{
"name": "Oliver Evans",
"type": "Other"
},
{
"name": "Peter Gagarinov",
"type": "Other"
},
{
"name": "Páll Haraldsson",
"type": "Other"
},
{
"name": "Rik Huijzer",
"type": "Other"
},
{
"name": "Romain Franconville",
"type": "Other"
},
{
"name": "Ronan Pigott",
"type": "Other"
},
{
"name": "Roshan Shariff",
"type": "Other"
},
{
"name": "Scott Thomas",
"type": "Other"
},
{
"name": "Sebastian Rollén",
"type": "Other"
},
{
"name": "Seth Bromberger",
"type": "Other"
},
{
"name": "Siva Swaminathan",
"type": "Other"
},
{
"name": "Tim DuBois",
"type": "Other"
},
{
"name": "Travis DePrato",
"type": "Other"
},
{
"name": "Will Thompson",
"type": "Other"
},
{
"name": "Yakir Luc Gagnon",
"type": "Other"
},
{
"name": "Benjamin Chislett",
"type": "Other"
},
{
"name": "@hhaensel",
"type": "Other"
},
{
"name": "@improbable22",
"type": "Other"
},
{
"name": "Johannes Fleck",
"type": "Other"
},
{
"name": "Peter Czaban",
"type": "Other"
},
{
"name": "@innerlee",
"type": "Other"
},
{
"name": "Mats Cronqvist",
"type": "Other"
},
{
"name": "Shi Pengcheng",
"type": "Other"
},
{
"name": "@wg030",
"type": "Other"
},
{
"affiliation": "University of Cambridge",
"name": "Will Tebbutt",
"type": "Other"
},
{
"name": "@t-bltg",
"type": "Other"
}
{
"name": "Fred Callaway",
"type": "Other"
}
],
"upload_type": "software"
}
+23 -17
View File
@@ -1,7 +1,7 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "1.0.6"
version = "1.16.4"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
@@ -10,20 +10,22 @@ 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"
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
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"
RecipesPipeline = "01d81517-befc-4cb6-b9ec-a95719d0359c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Scratch = "6c6a2e73-6563-6170-7368-637461726353"
Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
@@ -32,26 +34,28 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[compat]
Contour = "0.5"
FFMPEG = "0.2, 0.3"
FFMPEG = "0.2, 0.3, 0.4"
FixedPointNumbers = "0.6, 0.7, 0.8"
GR = "0.46, 0.47, 0.48"
GeometryTypes = "0.7, 0.8"
JSON = "0.21"
GR = "0.53, 0.54, 0.55, 0.57"
GeometryBasics = "0.2, 0.3.1"
JSON = "0.21, 1"
Latexify = "0.14, 0.15"
Measures = "0.3"
NaNMath = "0.3"
PGFPlotsX = "1.2.0"
PlotThemes = "1"
PlotUtils = "0.6.5"
PlotThemes = "2"
PlotUtils = "1"
RecipesBase = "1"
Reexport = "0.2"
Requires = "0.5, 1.0"
Showoff = "0.3.1"
RecipesPipeline = "0.3"
Reexport = "0.2, 1.0"
Requires = "1"
Scratch = "1"
Showoff = "0.3.1, 1.0"
StatsBase = "0.32, 0.33"
julia = "1"
julia = "1.5"
[extras]
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44"
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
@@ -59,13 +63,15 @@ Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"
[targets]
test = ["FileIO", "GeometryTypes", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "HDF5", "Random", "RDatasets", "StaticArrays", "StatsPlots", "Test", "UnicodePlots", "VisualRegressionTests"]
test = ["Distributions", "FileIO", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"]
+8 -8
View File
@@ -1,10 +1,7 @@
# Plots
[travis-img]: https://img.shields.io/travis/JuliaPlots/Plots.jl?logo=travis
[travis-url]: https://travis-ci.org/JuliaPlots/Plots.jl
[appveyor-img]: https://ci.appveyor.com/api/projects/status/github/juliaplots/plots.jl?branch=master&svg=true
[appveyor-url]: https://ci.appveyor.com/project/mkborregaard/plots-jl
[gh-ci-img]: https://github.com/JuliaPlots/Plots.jl/workflows/ci/badge.svg?branch=master
[gh-ci-url]: https://github.com/JuliaPlots/Plots.jl/actions?query=workflow%3Aci
[pkgeval-img]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/P/Plots.svg
[pkgeval-url]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/report.html
@@ -15,13 +12,16 @@
[docs-img]: https://img.shields.io/badge/docs-stable-blue.svg
[docs-url]: http://docs.juliaplots.org/latest/
[![][travis-img]][travis-url]
[![][appveyor-img]][appveyor-url]
[![][gh-ci-img]][gh-ci-url]
[![][pkgeval-img]][pkgeval-url]
[![][gitter-img]][gitter-url]
[![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://julialang.zulipchat.com/#narrow/stream/236493-plots)
[![][docs-img]][docs-url]
[![Codecov](https://codecov.io/gh/JuliaPlots/Plots.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaPlots/Plots.jl)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4725317.svg)](https://doi.org/10.5281/zenodo.4725317)
This is the DOI for all Versions, please follow the link to get the DOI for a specific version.
#### Created by Tom Breloff (@tbreloff)
#### Maintained by the [JuliaPlots members](https://github.com/orgs/JuliaPlots/people)
-46
View File
@@ -1,46 +0,0 @@
environment:
matrix:
- julia_version: 1.0
- julia_version: 1
- julia_version: nightly
platform:
- x86 # 32-bit
- x64 # 64-bit
# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
matrix:
allow_failures:
- julia_version: nightly
branches:
only:
- master
- /release-.*/
cache:
- '%USERPROFILE%\.julia\artifacts'
notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false
install:
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
build_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
test_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
+5
View File
@@ -0,0 +1,5 @@
[deps]
BenchmarkCI = "20533458-34a3-403d-a444-e18f38190b5b"
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
PkgBenchmark = "32113eaa-f34f-5b0d-bd6c-c81e245fc73d"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
+10
View File
@@ -0,0 +1,10 @@
using BenchmarkTools
using Plots
const SUITE = BenchmarkGroup()
julia_cmd = split(get(ENV, "TESTCMD", Base.JLOptions().julia_bin))
SUITE["load_plot_display"] = @benchmarkable run(`$julia_cmd --startup-file=no --project -e 'using Plots; display(plot(1:0.1:10, sin.(1:0.1:10)))'`)
SUITE["load"] = @benchmarkable run(`$julia_cmd --startup-file=no --project -e 'using Plots'`)
SUITE["plot"] = @benchmarkable p = plot(1:0.1:10, sin.(1:0.1:10)) samples=1 evals=1
SUITE["display"] = @benchmarkable display(p) setup=(p = plot(1:0.1:10, sin.(1:0.1:10))) samples=1 evals=1
+401
View File
@@ -0,0 +1,401 @@
# Use
# @warnpcfail precompile(args...)
# if you want to be warned when a precompile directive fails
macro warnpcfail(ex::Expr)
modl = __module__
file = __source__.file === nothing ? "?" : String(__source__.file)
line = __source__.line
quote
$(esc(ex)) || @warn """precompile directive
$($(Expr(:quote, ex)))
failed. Please report an issue in $($modl) (after checking for duplicates) or remove this directive.""" _file=$file _line=$line
end
end
const __bodyfunction__ = Dict{Method,Any}()
# Find keyword "body functions" (the function that contains the body
# as written by the developer, called after all missing keyword-arguments
# have been assigned values), in a manner that doesn't depend on
# gensymmed names.
# `mnokw` is the method that gets called when you invoke it without
# supplying any keywords.
function __lookup_kwbody__(mnokw::Method)
function getsym(arg)
isa(arg, Symbol) && return arg
@assert isa(arg, GlobalRef)
return arg.name
end
f = get(__bodyfunction__, mnokw, nothing)
if f === nothing
fmod = mnokw.module
# The lowered code for `mnokw` should look like
# %1 = mkw(kwvalues..., #self#, args...)
# return %1
# where `mkw` is the name of the "active" keyword body-function.
ast = Base.uncompressed_ast(mnokw)
if isa(ast, Core.CodeInfo) && length(ast.code) >= 2
callexpr = ast.code[end-1]
if isa(callexpr, Expr) && callexpr.head == :call
fsym = callexpr.args[1]
if isa(fsym, Symbol)
f = getfield(fmod, fsym)
elseif isa(fsym, GlobalRef)
if fsym.mod === Core && fsym.name === :_apply
f = getfield(mnokw.module, getsym(callexpr.args[2]))
elseif fsym.mod === Core && fsym.name === :_apply_iterate
f = getfield(mnokw.module, getsym(callexpr.args[3]))
else
f = getfield(fsym.mod, fsym.name)
end
else
f = missing
end
else
f = missing
end
else
f = missing
end
__bodyfunction__[mnokw] = f
end
return f
end
function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:label, :blank), Tuple{Symbol, Bool}},Type{EmptyLayout}})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:label, :width, :height), Tuple{Symbol, Symbol, Length{:pct, Float64}}},Type{EmptyLayout}})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{GridLayout}},Type{Subplot},GRBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{GridLayout}},Type{Subplot},PlotlyBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{Subplot{GRBackend}}},Type{Subplot},GRBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{Subplot{PlotlyBackend}}},Type{Subplot},PlotlyBackend})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Int64})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Tuple{Int64, Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Vector{Int64}}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:flip,), Tuple{Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{Symbol}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{typeof(datetimeformatter)}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Float64, Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Float64, Float64}, Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid,), Tuple{Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:gridlinewidth, :grid, :gridalpha, :gridstyle, :foreground_color_grid), Tuple{Int64, Bool, Float64, Symbol, RGBA{Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide,), Tuple{String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide_position, :guidefontvalign, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guidefonthalign, :guide_position, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims, :flip, :ticks, :guide), Tuple{Tuple{Int64, Int64}, Bool, StepRange{Int64, Int64}, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Float64, Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:rotation,), Tuple{Int64}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:scale, :guide), Tuple{Symbol, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{Nothing}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{UnitRange{Int64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:shape,), Tuple{Symbol}},typeof(default)})
Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:titlefont, :legendfontsize, :guidefont, :tickfont, :guide, :framestyle, :yminorgrid), Tuple{Tuple{Int64, String}, Int64, Tuple{Int64, Symbol}, Tuple{Int64, Symbol}, String, Symbol, Bool}},typeof(default)})
Base.precompile(Tuple{Core.kwftype(typeof(font)),NamedTuple{(:family, :pointsize, :halign, :valign, :rotation, :color), Tuple{String, Int64, Symbol, Symbol, Float64, RGBA{Float64}}},typeof(font)})
Base.precompile(Tuple{Core.kwftype(typeof(font)),NamedTuple{(:family, :pointsize, :valign, :halign, :rotation, :color), Tuple{String, Int64, Symbol, Symbol, Float64, RGBA{Float64}}},typeof(font)})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRange{Int64, Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),Vector{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:halign, :valign, :rotation, :color), Tuple{Symbol, Symbol, Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(hline!)),Any,typeof(hline!),Any})
Base.precompile(Tuple{Core.kwftype(typeof(pie)),Any,typeof(pie),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{GRBackend},Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:annotation,), Tuple{Vector{Tuple{Int64, Float64, PlotText}}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{GRBackend},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{PlotlyBackend},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Function,Float64,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Plot{GRBackend},Function,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{GRBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Vector{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:xgrid,), Tuple{Tuple{Symbol, Symbol, Int64, Symbol, Float64}}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis,), Tuple{Tuple{String, Symbol}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:annotations, :leg), Tuple{Tuple{Int64, Float64, PlotText}, Bool}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:arrow,), Tuple{Int64}},typeof(plot),Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bins, :weights, :seriestype), Tuple{Symbol, Vector{Int64}, Symbol}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:color, :line, :marker), Tuple{Matrix{Symbol}, Tuple{Symbol, Int64}, Tuple{Matrix{Symbol}, Int64, Float64, Stroke}}},typeof(plot),Vector{Vector{T} where T}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:connections, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vararg{Vector{Int64}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill, :seriestype), Tuple{Bool, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks, :seriestype), Tuple{Matrix{Symbol}, Matrix{String}, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Int64, String, Int64, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Vector{Float64}},Vector{Vector{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:grid, :title), Tuple{Tuple{Symbol, Symbol, Symbol, Int64, Float64}, String}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:lab, :w, :palette, :fill, :α), Tuple{String, Int64, PlotUtils.ContinuousColorGradient, Int64, Float64}},typeof(plot),StepRange{Int64, Int64},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend), Tuple{Matrix{String}, String, String, Int64, Symbol}},typeof(plot),Vector{Function},Float64,Vararg{Float64, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label,), Tuple{Matrix{String}}},typeof(plot),Vector{AbstractVector{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :group, :linetype, :linecolor), Tuple{GridLayout, Vector{String}, Matrix{Symbol}, Symbol}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :palette, :bg_inside), Tuple{Int64, Matrix{PlotUtils.ContinuousColorGradient}, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :t, :leg, :ticks, :border), Tuple{GridLayout, Matrix{Symbol}, Bool, Nothing, Symbol}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :title, :titlelocation, :left_margin, :bottom_margin, :xrotation), Tuple{GridLayout, Matrix{String}, Symbol, Matrix{AbsoluteLength}, AbsoluteLength, Int64}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xguide, :yguide, :xguidefonthalign, :yguidefontvalign, :xguideposition, :yguideposition, :ymirror, :xmirror, :legend, :seriestype), Tuple{Int64, String, String, Matrix{Symbol}, Matrix{Symbol}, Symbol, Matrix{Symbol}, Matrix{Bool}, Matrix{Bool}, Bool, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xlims), Tuple{GridLayout, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Vector{Tuple{Int64, Real}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :lab, :ms), Tuple{Tuple{Matrix{Symbol}, Int64}, Matrix{String}, Int64}},typeof(plot),Vector{Vector{T} where T},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :label, :legendtitle), Tuple{Tuple{Int64, Matrix{Symbol}}, Matrix{String}, String}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :leg, :fill), Tuple{Int64, Bool, Tuple{Int64, Symbol}}},typeof(plot),Function,Function,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :marker, :bg, :fg, :xlim, :ylim, :leg), Tuple{Tuple{Int64, Symbol, Symbol}, Tuple{Shape{Float64, Float64}, Int64, RGBA{Float64}}, Symbol, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Bool}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line_z, :linewidth, :legend), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int64, Bool}},typeof(plot),Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:m, :markersize, :lab, :bg, :xlim, :ylim, :seriestype), Tuple{Matrix{Symbol}, Int64, Matrix{String}, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker,), Tuple{Bool}},typeof(plot),Vector{Union{Missing, Int64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker_z, :color, :legend, :seriestype), Tuple{typeof(+), Symbol, Bool, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :markersize, :marker_z, :line_z, :linewidth), Tuple{Matrix{Symbol}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :seriestype, :label), Tuple{Symbol, Symbol, String}},typeof(plot),UnitRange{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :show_empty_bins, :normed, :aspect_ratio, :seriestype), Tuple{Tuple{Int64, Int64}, Bool, Bool, Int64, Symbol}},typeof(plot),Vector{ComplexF64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:proj, :m), Tuple{Symbol, Int64}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:projection, :seriestype), Tuple{Symbol, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},UnitRange{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:quiver, :seriestype), Tuple{Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Vararg{Vector{Float64}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:reg, :fill), Tuple{Bool, Tuple{Int64, Symbol}}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Int64}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Tuple{LinRange{Float64}, LinRange{Float64}}}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{typeof(sqrt)}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color), Tuple{Matrix{Symbol}, Vector{Symbol}, Int64, Vector{Symbol}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{OHLC}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},Vararg{Vector{Float64}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :l, :seriestype), Tuple{String, Float64, Symbol}},typeof(plot),Vector{String},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{String}},typeof(plot),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{String}},typeof(plot),Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:xaxis, :background_color, :leg), Tuple{Tuple{String, Tuple{Int64, Int64}, StepRange{Int64, Int64}, Symbol}, RGB{Float64}, Bool}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:yflip, :aspect_ratio), Tuple{Bool, Symbol}},typeof(plot),Vector{Float64},Vector{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:zcolor, :m, :leg, :cbar, :w), Tuple{StepRange{Int64, Int64}, Tuple{Int64, Float64, Symbol, Stroke}, Bool, Bool, Int64}},typeof(plot),Vector{Float64},Vector{Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(portfoliocomposition)),Any,typeof(portfoliocomposition),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(scatter!)),Any,typeof(scatter!),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(scatter!)),Any,typeof(scatter!),Any})
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip,), Tuple{Vector{Int64}}},typeof(test_examples),Symbol})
Base.precompile(Tuple{Type{GridLayout},Int64,Vararg{Int64, N} where N})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},AbstractVector{OHLC}})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},PortfolioComposition})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barbins}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barhist}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bar}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bins2d}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:histogram2d}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hline}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:lens}},AbstractPlot})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:pie}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:quiver}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:spy}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:steppre}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:sticks}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vline}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:xerror}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Vector{ComplexF64}})
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{GRBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{PlotlyBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{GRBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{PlotlyBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_attributes!),Plot{GRBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{GRBackend},DefaultsDict,Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{GRBackend},Dict{Symbol, Any},Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{PlotlyBackend},DefaultsDict,Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{PlotlyBackend},Dict{Symbol, Any},Symbol,Any})
Base.precompile(Tuple{typeof(_bin_centers),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Int64},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Nothing},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{PlotUtils.ContinuousColorGradient},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Symbol},String})
Base.precompile(Tuple{typeof(_cycle),Base.OneTo{Int64},Vector{Int64}})
Base.precompile(Tuple{typeof(_cycle),StepRange{Int64, Int64},Vector{Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},StepRange{Int64, Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},UnitRange{Int64}})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
Base.precompile(Tuple{typeof(_heatmap_edges),Vector{Float64},Bool,Bool})
Base.precompile(Tuple{typeof(_plot!),Plot,Any,Any})
Base.precompile(Tuple{typeof(_preprocess_barlike),DefaultsDict,Base.OneTo{Int64},Vector{Float64}})
Base.precompile(Tuple{typeof(_preprocess_binlike),DefaultsDict,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(_update_min_padding!),GridLayout})
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{GRBackend},Subplot{GRBackend},Dict{Symbol, Any},Int64,Bool})
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{PlotlyBackend},Subplot{PlotlyBackend},Dict{Symbol, Any},Int64,Bool})
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{GRBackend},Vector{Any}})
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{PlotlyBackend},Vector{Any}})
Base.precompile(Tuple{typeof(backend),PlotlyBackend})
Base.precompile(Tuple{typeof(bbox),AbsoluteLength,AbsoluteLength,AbsoluteLength,AbsoluteLength})
Base.precompile(Tuple{typeof(bbox),Float64,Float64,Float64,Float64})
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64})
Base.precompile(Tuple{typeof(contour),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(convertLegendValue),Symbol})
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Int64, Float64}})
Base.precompile(Tuple{typeof(create_grid),Expr})
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64},Vararg{Vector{Float64}, N} where N})
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{typeof(error_zipit),Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}})
Base.precompile(Tuple{typeof(expand_extrema!),Axis,Base.OneTo{Int64}})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_ticks),StepRange{Int64, Int64},Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_ticks),UnitRange{Int64},Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_xy),OHLC{Float64},Int64,Float64})
Base.precompile(Tuple{typeof(get_xy),Vector{OHLC}})
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Float64, Float64, Float64, Int64, Float64, Float64, Float64, Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_display),Subplot{GRBackend},AbsoluteLength,AbsoluteLength,Vector{Float64}})
Base.precompile(Tuple{typeof(gr_draw_colorbar),GRColorbar,Subplot{GRBackend},Tuple{Float64, Float64},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_draw_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_heatmap),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Float64,Float64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Shape{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Int64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},UnitRange{Int64},Tuple{Vector{Float64}, Vector{Float64}},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRange{Int64, Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Float64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_shapes),Series,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_fill_viewport),Vector{Float64},RGBA{Float64}})
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Float64}, Vector{String}},Int64})
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Int64}, Vector{String}},Int64})
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_label_ticks_3d),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_polaraxes),Int64,Float64,Subplot{GRBackend}})
Base.precompile(Tuple{typeof(gr_polyline),Vector{Float64},Vector{Float64},Function})
Base.precompile(Tuple{typeof(gr_set_gradient),PlotUtils.ContinuousColorGradient})
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}}})
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Float64, Float64, Float64, Int64, Float64, Float64, Float64, Float64}}})
Base.precompile(Tuple{typeof(gr_viewport_from_bbox),Subplot{GRBackend},BoundingBox{Tuple{AbsoluteLength, AbsoluteLength}, Tuple{AbsoluteLength, AbsoluteLength}},AbsoluteLength,AbsoluteLength,Vector{Float64}})
Base.precompile(Tuple{typeof(heatmap_edges),Base.OneTo{Int64},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Symbol,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Symbol,Tuple{Int64, Int64},Bool})
Base.precompile(Tuple{typeof(heatmap_edges),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),UnitRange{Int64},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol,UnitRange{Int64},Symbol,Tuple{Int64, Int64},Bool})
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol,Vector{Float64},Symbol,Tuple{Int64, Int64},Bool})
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol})
Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}})
Base.precompile(Tuple{typeof(layout_args),Int64})
Base.precompile(Tuple{typeof(make_fillrange_side),UnitRange{Int64},LinRange{Float64}})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Function})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Symbol})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Float64},Symbol,Symbol})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Int64},Symbol,Symbol})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),StepRange{Int64, Int64},Tuple{Int64, Int64},Symbol,Symbol})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),UnitRange{Int64},Tuple{Float64, Float64},Symbol,Symbol})
Base.precompile(Tuple{typeof(partialcircle),Int64,Float64,Int64})
Base.precompile(Tuple{typeof(plot),Any,Any,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(plot),Any})
Base.precompile(Tuple{typeof(processFillArg),Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(processGridArg!),DefaultsDict,Bool,Symbol})
Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Matrix{Symbol}})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Matrix{Symbol}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},RGBA{Float64}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Shape{Float64, Float64}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Stroke})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol})
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}})
Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{Bool},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{Int64},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{PlotUtils.ContinuousColorGradient},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{RGBA{Float64}},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{String},Int64})
Base.precompile(Tuple{typeof(spy),Any})
Base.precompile(Tuple{typeof(straightline_data),Tuple{Float64, Float64},Tuple{Float64, Float64},Vector{Float64},Vector{Float64},Int64})
Base.precompile(Tuple{typeof(stroke),Int64,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(text),String,Int64,Symbol,Vararg{Symbol, N} where N})
Base.precompile(Tuple{typeof(text),String,Symbol,Int64,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(title!),AbstractString})
Base.precompile(Tuple{typeof(unzip),Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{typeof(vline!),Any})
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
Base.precompile(Tuple{typeof(yaxis!),Any,Any})
let fbody = try __lookup_kwbody__(which(gr_polyline, (Vector{Float64},Vector{Float64},typeof(GR.fillarea),))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Symbol,Symbol,typeof(gr_polyline),Vector{Float64},Vector{Float64},typeof(GR.fillarea),))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Any,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Any,))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Any,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Any,Vararg{Any, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Any,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Any,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Any,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Any,Vararg{Any, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Plot,Plot,Vararg{Plot, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Plot,Plot,Vararg{Plot, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(text, (String,Int64,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(text),String,Int64,Vararg{Any, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(text, (String,Symbol,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(text),String,Symbol,Vararg{Any, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(title!, (AbstractString,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(title!),AbstractString,))
end
end
end
+4
View File
@@ -0,0 +1,4 @@
using Plots
Plots.test_examples(:gr, skip = Plots._backend_skips[:gr])
Plots.test_examples(:plotly, skip = Plots._backend_skips[:plotly], disp = false)
+8
View File
@@ -0,0 +1,8 @@
using CompileBot
snoop_bench(
BotConfig(
"Plots",
),
joinpath(@__DIR__, "precompile_script.jl"),
)
+8
View File
@@ -0,0 +1,8 @@
using CompileBot
snoop_bot(
BotConfig(
"Plots",
),
joinpath(@__DIR__, "precompile_script.jl"),
)
-18
View File
@@ -1,18 +0,0 @@
#TODO: download https://cdn.plot.ly/plotly-latest.min.js to deps/ if it doesn't exist
file_path = ""
if get(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL", "false") == "true"
global file_path
local_fn = joinpath(dirname(@__FILE__), "plotly-latest.min.js")
if !isfile(local_fn)
@info("Cannot find deps/plotly-latest.min.js... downloading latest version.")
download("https://cdn.plot.ly/plotly-latest.min.js", local_fn)
isfile(local_fn) && (file_path = local_fn)
else
file_path = local_fn
end
end
open("deps.jl", "w") do io
println(io, "const plotly_local_file_path = $(repr(file_path))")
end
-53
View File
@@ -1,53 +0,0 @@
# 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
project_flag = string("--project=", joinpath(homedir(), ".julia", "dev", "Plots"))
log_path = joinpath(tempdir(), "compiles.log")
precompiles_path = joinpath(tempdir(), "precompile")
# run examples with GR backend, logging what needs to be compiled
SnoopCompile.@snoopc project_flag log_path begin
using Plots
Plots.test_examples(:gr)
Plots.test_examples(:plotly, skip = Plots._backend_skips[:plotly])
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)
+44 -20
View File
@@ -8,9 +8,9 @@ const _current_plots_version = VersionNumber(split(first(filter(line -> occursin
using Reexport
import GeometryTypes
import GeometryBasics
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random
import SparseArrays: findnz
using SparseArrays
using FFMPEG
@@ -25,17 +25,6 @@ import JSON
using Requires
if isfile(joinpath(@__DIR__, "..", "deps", "deps.jl"))
include(joinpath(@__DIR__, "..", "deps", "deps.jl"))
else
# This is a bit dirty, but I don't really see why anyone should be forced
# to build Plots, while it will just include exactly the below line
# as long as `ENV["PLOTS_HOST_DEPENDENCY_LOCAL"] = "true"` is not set.
# If the above env is set + `plotly_local_file_path == ""``,
# it will warn in the __init__ function to run build
const plotly_local_file_path = ""
end
export
grid,
bbox,
@@ -108,6 +97,7 @@ export
gif,
mov,
mp4,
webm,
animate,
@animate,
@gif,
@@ -123,7 +113,11 @@ export
center,
BezierCurve,
plotattr
plotattr,
scalefontsize,
scalefontsizes,
resetfontsizes
# ---------------------------------------------------------
@@ -160,6 +154,12 @@ const BBox = Measures.Absolute2DBox
# allow pixels and percentages
const px = AbsoluteLength(0.254)
const pct = Length{:pct, Float64}(1.0)
Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value)
Base.:*(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * m1.value)
Base.:/(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value / m2.value)
Base.:/(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value / m1.value)
export BBox, BoundingBox, mm, cm, inch, px, pct, pt, w, h
end
@@ -167,15 +167,39 @@ using .PlotMeasures
import .PlotMeasures: Length, AbsoluteLength, Measure, width, height
# ---------------------------------------------------------
import RecipesPipeline
import RecipesPipeline: SliceIt,
DefaultsDict,
Formatted,
AbstractSurface,
Surface,
Volume,
is3d,
is_surface,
needs_3d_axes,
group_as_matrix, # for StatsPlots
reset_kw!,
pop_kw!,
scale_func,
inverse_scale_func,
unzip,
dateformatter,
datetimeformatter,
timeformatter
# Use fixed version of Plotly instead of the latest one for stable dependency
# Ref: https://github.com/JuliaPlots/Plots.jl/pull/2779
const _plotly_min_js_filename = "plotly-1.57.1.min.js"
include("types.jl")
include("utils.jl")
include("components.jl")
include("colorbars.jl")
include("axes.jl")
include("args.jl")
include("components.jl")
include("themes.jl")
include("plot.jl")
include("pipeline.jl")
include("series.jl")
include("layouts.jl")
include("subplots.jl")
include("recipes.jl")
@@ -188,6 +212,7 @@ include("output.jl")
include("ijulia.jl")
include("fileio.jl")
include("init.jl")
include("legend.jl")
include("backends/plotly.jl")
include("backends/gr.jl")
@@ -205,8 +230,8 @@ let PlotOrSubplot = Union{Plot, Subplot}
global xlims!(plt::PlotOrSubplot, xmin::Real, xmax::Real; kw...) = plot!(plt; xlims = (xmin,xmax), kw...)
global ylims!(plt::PlotOrSubplot, ymin::Real, ymax::Real; kw...) = plot!(plt; ylims = (ymin,ymax), kw...)
global zlims!(plt::PlotOrSubplot, zmin::Real, zmax::Real; kw...) = plot!(plt; zlims = (zmin,zmax), kw...)
global xticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) where {T<:Real} = plot!(plt; xticks = ticks, kw...)
global yticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) where {T<:Real} = plot!(plt; yticks = ticks, kw...)
global xticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) = plot!(plt; xticks = ticks, kw...)
global yticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) = plot!(plt; yticks = ticks, kw...)
global xticks!(plt::PlotOrSubplot,
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; xticks = (ticks,labels), kw...)
global yticks!(plt::PlotOrSubplot,
@@ -226,7 +251,6 @@ end
const CURRENT_BACKEND = CurrentBackend(:none)
include("precompile.jl")
_precompile_()
include("precompile_includer.jl")
end # module
+9 -7
View File
@@ -24,6 +24,7 @@ end
giffn() = (isijulia() ? "tmp.gif" : tempname()*".gif")
movfn() = (isijulia() ? "tmp.mov" : tempname()*".mov")
mp4fn() = (isijulia() ? "tmp.mp4" : tempname()*".mp4")
webmfn() = (isijulia() ? "tmp.webm" : tempname()*".webm")
mutable struct FrameIterator
itr
@@ -63,6 +64,7 @@ file_extension(fn) = Base.Filesystem.splitext(fn)[2][2:end]
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...)
webm(anim::Animation, fn = webmfn(); kw...) = buildanimation(anim, fn, false; kw...)
ffmpeg_framerate(fps) = "$fps"
ffmpeg_framerate(fps::Rational) = "$(fps.num)/$(fps.den)"
@@ -88,15 +90,15 @@ function buildanimation(anim::Animation, fn::AbstractString,
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"
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`)
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -lavfi "$palette" -loop $loop -y $fn`)
else
# generate a colorpalette first so ffmpeg does not have to guess it
ffmpeg_exe(`-v $verbose_level -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
# then apply the palette to get better results
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`)
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -loop $loop -y $fn`)
end
else
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -vf format=yuv420p -loop $loop -y $fn`)
end
show_msg && @info("Saved animation to ", fn)
@@ -110,8 +112,8 @@ function Base.show(io::IO, ::MIME"text/html", agif::AnimatedGif)
ext = file_extension(agif.filename)
if ext == "gif"
html = "<img src=\"data:image/gif;base64," * base64encode(read(agif.filename)) * "\" />"
elseif ext in ("mov", "mp4")
mimetype = ext == "mov" ? "video/quicktime" : "video/mp4"
elseif ext in ("mov", "mp4","webm")
mimetype = ext == "mov" ? "video/quicktime" : "video/$ext"
html = "<video controls><source src=\"data:$mimetype;base64," *
base64encode(read(agif.filename)) *
"\" type = \"$mimetype\"></video>"
@@ -135,8 +137,8 @@ end
# -----------------------------------------------
function _animate(forloop::Expr, args...; callgif = false)
if forloop.head != :for
error("@animate macro expects a for-block. got: $(forloop.head)")
if forloop.head (:for, :while)
error("@animate macro expects a for- or while-block. got: $(forloop.head)")
end
# add the call to frame to the end of each iteration
+174 -151
View File
@@ -2,162 +2,185 @@
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.",
: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.",
:linestyle => "Symbol. Style of the line (for path and bar stroke). Choose from $(_allStyles)",
: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 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).",
:markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.",
:markeralpha => "Number in [0,1]. The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor.",
:markersize => "Number or AbstractVector. Size (radius pixels) of the markers.",
:markerstrokestyle => "Symbol. Style of the marker stroke (border). Choose from $(_allStyles)",
: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(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",
:y => "Various. Input data. Second Dimension",
: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}, 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)",
: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?",
: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.",
:colorbar_entry => "Bool. Include this series in the color bar? Set to `false` to exclude.",
: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.",
:linestyle => "Symbol. Style of the line (for path and bar stroke). Choose from $(_allStyles)",
: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 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).",
:markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.",
:markeralpha => "Number in [0,1]. The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor.",
:markersize => "Number or AbstractVector. Size (radius pixels) of the markers.",
:markerstrokestyle => "Symbol. Style of the marker stroke (border). Choose from $(_allStyles)",
: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(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",
:y => "Various. Input data. Second Dimension",
: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}, 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)",
: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?",
: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.",
: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)",
:background_color => "Color Type. Base color for all backgrounds.",
:background_color_outside => "Color Type or `:match` (matches `:background_color`). Color outside the plot area(s)",
:foreground_color => "Color Type. Base color for all foregrounds.",
:size => "NTuple{2,Int}. (width_px, height_px) of the whole Plot",
:pos => "NTuple{2,Int}. (left_px, top_px) position of the GUI window (note: currently unimplemented)",
:window_title => "String. Title of the window.",
:show => "Bool. Should this command open/refresh a GUI/display? This allows displaying in scripts or functions without explicitly calling `display`",
:layout => "Integer (number of subplots), NTuple{2,Integer} (grid dimensions), AbstractLayout (for example `grid(2,2)`), or the return from the `@layout` macro. This builds the layout of subplots.",
: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.",
: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.",
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",
:plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)",
:background_color => "Color Type. Base color for all backgrounds.",
:background_color_outside => "Color Type or `:match` (matches `:background_color`). Color outside the plot area(s)",
:foreground_color => "Color Type. Base color for all foregrounds.",
:size => "NTuple{2,Int}. (width_px, height_px) of the whole Plot",
:pos => "NTuple{2,Int}. (left_px, top_px) position of the GUI window (note: currently unimplemented)",
:window_title => "String. Title of the standalone gui-window.",
:show => "Bool. Should this command open/refresh a GUI/display? This allows displaying in scripts or functions without explicitly calling `display`",
:layout => "Integer (number of subplots), NTuple{2,Integer} (grid dimensions), AbstractLayout (for example `grid(2,2)`), or the return from the `@layout` macro. This builds the layout of subplots.",
: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.",
: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 => "Either one of (`:plot`, `:subplot`, `:series`) to specify for which element extra keyword args are collected or a KW (Dict{Symbol,Any}) to pass a map of extra keyword args which may be specific to a backend. Default: `:series`.\n Example: `pgfplotsx(); scatter(1:5, extra_kwargs=Dict(:subplot=>Dict(\"axis line shift\" => \"10pt\"))`",
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",
:warn_on_unsupported => "Bool. Warn on unsupported attributes, series types and marker shapes",
# subplot args
:title => "String. Subplot title.",
:title_location => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`",
:titlefontfamily => "String or Symbol. Font family of subplot title.",
:titlefontsize => "Integer. Font pointsize of subplot title.",
:titlefonthalign => "Symbol. Font horizontal alignment of subplot title: :hcenter, :left, :right or :center",
:titlefontvalign => "Symbol. Font vertical alignment of subplot title: :vcenter, :top, :bottom or :center",
:titlefontrotation => "Real. Font rotation of subplot title",
:titlefontcolor => "Color Type. Font color of subplot title",
:background_color_subplot => "Color Type or `:match` (matches `:background_color`). Base background color of the subplot.",
:background_color_legend => "Color Type or `:match` (matches `:background_color_subplot`). Background color of the legend.",
:background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).",
:foreground_color_subplot => "Color Type or `:match` (matches `:foreground_color`). Base foreground color of the subplot.",
:foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
:foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.",
:color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.",
:legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` , `:inline` (note: only some may be supported in each backend)",
:legendfontfamily => "String or Symbol. Font family of legend entries.",
:legendfontsize => "Integer. Font pointsize of legend entries.",
:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center",
: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 `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.",
:right_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the right of the subplot.",
:bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.",
:subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.",
:colorbar_title => "String. Title of colorbar.",
:framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)",
:camera => "NTuple{2, Real}. Sets the view angle (azimuthal, elevation) for 3D plots",
:title => "String. Subplot title.",
:titlelocation => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`",
:titlefontfamily => "String or Symbol. Font family of subplot title.",
:titlefontsize => "Integer. Font pointsize of subplot title.",
:titlefonthalign => "Symbol. Font horizontal alignment of subplot title: :hcenter, :left, :right or :center",
:titlefontvalign => "Symbol. Font vertical alignment of subplot title: :vcenter, :top, :bottom or :center",
:titlefontrotation => "Real. Font rotation of subplot title",
:titlefontcolor => "Color Type. Font color of subplot title",
:background_color_subplot => "Color Type or `:match` (matches `:background_color`). Base background color of the subplot.",
:background_color_legend => "Color Type or `:match` (matches `:background_color_subplot`). Background color of the legend.",
:background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).",
:foreground_color_subplot => "Color Type or `:match` (matches `:foreground_color`). Base foreground color of the subplot.",
:foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
:foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.",
:color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.",
:legend => "Bool (show the legend?) or (x,y) tuple or Symbol (legend position) or angle or (angle,inout) tuple. Bottom left corner of legend is placed at (x,y). Symbol values: `:none`; `:best`; `:inline`; `:inside`; `:legend`; any valid combination of `:(outer ?)(top/bottom ?)(right/left ?)`, i.e.: `:top`, `:topright`, `:outerleft`, `:outerbottomright` ... (note: only some may be supported in each backend). Legend is positioned at (angle degrees) (so (90,:outer) is roughly equivalent to :outertop), close to the inside of the axes or the outside if inout=:outer.",
:legendfontfamily => "String or Symbol. Font family of legend entries.",
:legendfontsize => "Integer. Font pointsize of legend entries.",
:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center",
: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",
:legendtitle => "String. Legend title.",
: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`, NTuple{2,Number}, or a function that takes series data in and returns NTuple{2,Number}. Fixes the limits of the colorbar.",
:colorbar_fontfamily => "String or Symbol. Font family of colobar entries.",
:colorbar_ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
:colorbar_tickfontfamily => "String or Symbol. Font family of colorbar tick labels.",
:colorbar_tickfontsize => "Integer. Font pointsize of colorbar tick entries.",
:colorbar_tickfontcolor => "Color Type. Font color of colorbar tick entries",
:colorbar_scale => "Symbol. Scale of the colorbar axis: `:none`, `:ln`, `:log2`, `:log10`",
:colorbar_formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.",
: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.",
:annotationfontfamily => "String or Symbol. Font family of annotations.",
:annotationfontsize => "Integer. Font pointsize of annotations.",
:annotationhalign => "Symbol. horizontal alignment of annotations, :hcenter, :left, :right or :center.",
:annotationvalign => "Symbol. Vertical alignment of annotations, :vcenter, :top, :bottom or :center.",
:annotationrotation => "Float. Rotation of annotations in degrees.",
:annotationcolor => "Colorant or :match. Color of annotations.",
:projection => "Symbol or String. '3d' or 'polar'",
:aspect_ratio => "Symbol (:equal or :none) or Number. Plot area is resized so that 1 y-unit is the same size as `aspect_ratio` x-units. With `:none`, images inherit aspect ratio of the plot area.",
: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.",
:right_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the right of the subplot.",
:bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.",
:subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.",
:colorbar_title => "String. Title of colorbar.",
:framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)",
:camera => "NTuple{2, Real}. Sets the view angle (azimuthal, elevation) for 3D plots",
# axis args
: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.",
: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",
:tickfontvalign => "Symbol. Font vertical alignment of tick labels: :vcenter, :top, :bottom or :center",
:tickfontrotation => "Real. Font rotation of tick labels",
:tickfontcolor => "Color Type. Font color of tick labels",
:guidefontfamily => "String or Symbol. Font family of axes guides.",
:guidefontsize => "Integer. Font pointsize of axes guides.",
:guidefonthalign => "Symbol. Font horizontal alignment of axes guides: :hcenter, :left, :right or :center",
:guidefontvalign => "Symbol. Font vertical alignment of axes guides: :vcenter, :top, :bottom or :center",
:guidefontrotation => "Real. Font rotation of axes guides",
:guidefontcolor => "Color Type. Font color of axes guides",
:foreground_color_axis => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis ticks.",
:foreground_color_border => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of plot area border (spines).",
:foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.",
:foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).",
:mirror => "Bool. Switch the side of the tick labels (right or top).",
:grid => "Bool, Symbol, String or `nothing`. Show the grid lines? `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`",
:foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.",
:gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.",
:gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)",
:gridlinewidth => "Number. Width of the grid lines (in pixels)",
: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]
`:symmetric` sets the limits to be symmetric around zero.
Set widen=true to widen the specified limits (as occurs when lims are not specified).
""",
: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",
:tickfontvalign => "Symbol. Font vertical alignment of tick labels: :vcenter, :top, :bottom or :center",
:tickfontrotation => "Real. Font rotation of tick labels",
:tickfontcolor => "Color Type. Font color of tick labels",
:guidefontfamily => "String or Symbol. Font family of axes guides.",
:guidefontsize => "Integer. Font pointsize of axes guides.",
:guidefonthalign => "Symbol. Font horizontal alignment of axes guides: :hcenter, :left, :right or :center",
:guidefontvalign => "Symbol. Font vertical alignment of axes guides: :vcenter, :top, :bottom or :center",
:guidefontrotation => "Real. Font rotation of axes guides",
:guidefontcolor => "Color Type. Font color of axes guides",
:foreground_color_axis => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis ticks.",
:foreground_color_border => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of plot area border (spines).",
:foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.",
:foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).",
:mirror => "Bool. Switch the side of the tick labels (right or top).",
:grid => "Bool, Symbol, String or `nothing`. Show the grid lines? `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`",
:foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.",
:gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.",
:gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)",
:gridlinewidth => "Number. Width of the grid lines (in pixels)",
:foreground_color_minor_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of minor grid lines.",
:minorgrid => "Bool. Adds minor grid lines and ticks to the plot. Set minorticks to change number of gridlines",
:minorticks => "Integer. Intervals to divide the gap between major ticks into",
:minorgridalpha => "Number in [0,1]. The alpha/opacity override for the minorgrid lines.",
:minorgridstyle => "Symbol. Style of the minor grid lines. Choose from $(_allStyles)",
:minorgridlinewidth => "Number. Width of the minor grid lines (in pixels)",
: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.",
:minorgrid => "Bool. Adds minor grid lines and ticks to the plot. Set minorticks to change number of gridlines",
:minorticks => "Integer. Intervals to divide the gap between major ticks into",
:minorgridalpha => "Number in [0,1]. The alpha/opacity override for the minorgrid lines.",
:minorgridstyle => "Symbol. Style of the minor grid lines. Choose from $(_allStyles)",
:minorgridlinewidth => "Number. Width of the minor grid lines (in pixels)",
:tick_direction => "Symbol. Direction of the ticks. `:in`, `:out` or `:none`",
:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`",
:widen => """
Bool or :auto. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders.
Defaults to `:auto`, which widens unless limits were manually set.
""",
:draw_arrow => "Bool. Draw arrow at the end of the axis.",
)
+459 -313
View File
File diff suppressed because it is too large Load Diff
+398 -470
View File
File diff suppressed because it is too large Load Diff
+99 -39
View File
@@ -1,5 +1,3 @@
using Pkg
struct NoBackend <: AbstractBackend end
const _backendType = Dict{Symbol, DataType}(:none => NoBackend)
@@ -30,7 +28,7 @@ macro init_backend(s)
esc(quote
struct $T <: AbstractBackend end
export $sym
$sym(; kw...) = (default(; kw...); backend($T()))
$sym(; kw...) = (default(; reset = false, kw...); backend($T()))
backend_name(::$T) = Symbol($str)
backend_package_name(pkg::$T) = backend_package_name(Symbol($str))
push!(_backends, Symbol($str))
@@ -104,7 +102,7 @@ end
# 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)
# TODO: something different when `is3d(sp) == true`
# TODO: something different when `RecipesPipeline.is3d(sp) == true`
leftpad = tick_padding(sp, sp[:yaxis]) + sp[:left_margin] + guide_padding(sp[:yaxis])
toppad = sp[:top_margin] + title_padding(sp)
rightpad = sp[:right_margin]
@@ -190,11 +188,15 @@ function backend(sym::Symbol)
end
end
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize]
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize, :pgfplots]
function warn_on_deprecated_backend(bsym::Symbol)
if bsym in _deprecated_backends
@warn("Backend $bsym has been deprecated.")
if bsym == :pgfplots
@warn("Backend $bsym has been deprecated. Use pgfplotsx instead.")
else
@warn("Backend $bsym has been deprecated.")
end
end
end
@@ -314,7 +316,6 @@ const _gr_attr = merge_with_base_supported([
:layout,
:title, :window_title,
:guide, :lims, :ticks, :scale, :flip,
:match_dimensions,
:titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign,
:titlefontrotation, :titlefontcolor,
:legendfontfamily, :legendfontsize, :legendfonthalign, :legendfontvalign,
@@ -341,10 +342,18 @@ const _gr_attr = merge_with_base_supported([
:contour_labels,
])
const _gr_seriestype = [
:path, :scatter, :straightline,
:heatmap, :pie, :image,
:contour, :path3d, :scatter3d, :surface, :wireframe, :volume,
:shape
:path,
:scatter,
:straightline,
:heatmap,
:image,
:contour,
:path3d,
:scatter3d,
:surface,
:wireframe,
:volume,
:shape,
]
const _gr_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
const _gr_marker = _allMarkers
@@ -357,10 +366,10 @@ is_marker_supported(::GRBackend, shape::Shape) = true
function _initialize_backend(pkg::PlotlyBackend)
try
@eval Main begin
import ORCA
import PlotlyBase
end
catch
@info "For saving to png with the Plotly backend ORCA has to be installed."
@info "For saving to png with the Plotly backend PlotlyBase has to be installed."
end
end
@@ -378,7 +387,7 @@ const _plotly_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :markerstrokestyle,
:fillrange, :fillcolor, :fillalpha,
:bins,
:title, :title_location,
:title, :titlelocation,
:titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign,
:titlefontcolor,
:legendfontfamily, :legendfontsize, :legendfontcolor,
@@ -408,9 +417,18 @@ const _plotly_attr = merge_with_base_supported([
])
const _plotly_seriestype = [
:path, :scatter, :pie, :heatmap,
:contour, :surface, :wireframe, :path3d, :scatter3d, :shape, :scattergl,
:straightline
:path,
:scatter,
:heatmap,
:contour,
:surface,
:wireframe,
:path3d,
:scatter3d,
:shape,
:scattergl,
:straightline,
:mesh3d
]
const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot]
const _plotly_marker = [
@@ -453,7 +471,6 @@ const _pgfplots_attr = merge_with_base_supported([
:polar,
# :normalize, :weights, :contours,
:aspect_ratio,
# :match_dimensions,
:tick_direction,
:framestyle,
:camera,
@@ -469,7 +486,7 @@ const _pgfplots_scale = [:identity, :ln, :log2, :log10]
function _initialize_backend(pkg::PlotlyJSBackend)
@eval Main begin
import PlotlyJS, ORCA
import PlotlyJS
export PlotlyJS
end
end
@@ -505,7 +522,7 @@ const _pyplot_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
:fillrange, :fillcolor, :fillalpha,
:bins, :bar_width, :bar_edges, :bar_position,
:title, :title_location, :titlefont,
:title, :titlelocation, :titlefont,
:window_title,
:guide, :guide_position, :lims, :ticks, :scale, :flip, :rotation,
:titlefontfamily, :titlefontsize, :titlefontcolor,
@@ -514,6 +531,10 @@ const _pyplot_attr = merge_with_base_supported([
:guidefontfamily, :guidefontsize, :guidefontcolor,
:grid, :gridalpha, :gridstyle, :gridlinewidth,
:legend, :legendtitle, :colorbar, :colorbar_title, :colorbar_entry,
:colorbar_ticks, :colorbar_tickfontfamily, :colorbar_tickfontsize,
:colorbar_tickfonthalign, :colorbar_tickfontvalign,
:colorbar_tickfontrotation, :colorbar_tickfontcolor,
:colorbar_scale,
:marker_z, :line_z, :fill_z,
:levels,
:ribbon, :quiver, :arrow,
@@ -522,7 +543,6 @@ const _pyplot_attr = merge_with_base_supported([
:polar,
:normalize, :weights,
:contours, :aspect_ratio,
:match_dimensions,
:clims,
:inset_subplots,
:dpi,
@@ -533,12 +553,23 @@ const _pyplot_attr = merge_with_base_supported([
:contour_labels,
])
const _pyplot_seriestype = [
:path, :steppre, :steppost, :shape, :straightline,
:scatter, :hexbin, #:histogram2d, :histogram,
# :bar,
:heatmap, :pie, :image,
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
]
:path,
:steppre,
:stepmid,
:steppost,
:shape,
:straightline,
:scatter,
:hexbin,
:heatmap,
:image,
:contour,
:contour3d,
:path3d,
:scatter3d,
:surface,
:wireframe,
]
const _pyplot_style = [:auto, :solid, :dash, :dot, :dashdot]
const _pyplot_marker = vcat(_allMarkers, :pixel)
const _pyplot_scale = [:identity, :ln, :log2, :log10]
@@ -568,6 +599,9 @@ const _unicodeplots_style = [:auto, :solid]
const _unicodeplots_marker = [:none, :auto, :circle]
const _unicodeplots_scale = [:identity]
# Additional constants
const _canvas_type = Ref(:auto)
# ------------------------------------------------------------------------------
# hdf5
@@ -582,7 +616,7 @@ const _hdf5_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
:fillrange, :fillcolor, :fillalpha,
:bins, :bar_width, :bar_edges, :bar_position,
:title, :title_location, :titlefont,
:title, :titlelocation, :titlefont,
:window_title,
:guide, :lims, :ticks, :scale, :flip, :rotation,
:tickfont, :guidefont, :legendfont,
@@ -595,23 +629,45 @@ const _hdf5_attr = merge_with_base_supported([
:polar,
:normalize, :weights,
:contours, :aspect_ratio,
:match_dimensions,
:clims,
:inset_subplots,
:dpi,
:colorbar_title,
])
const _hdf5_seriestype = [
:path, :steppre, :steppost, :shape, :straightline,
:scatter, :hexbin, #:histogram2d, :histogram,
# :bar,
:heatmap, :pie, :image,
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
]
:path,
:steppre,
:stepmid,
:steppost,
:shape,
:straightline,
:scatter,
:hexbin,
:heatmap,
:image,
:contour,
:contour3d,
:path3d,
:scatter3d,
:surface,
:wireframe,
]
const _hdf5_style = [:auto, :solid, :dash, :dot, :dashdot]
const _hdf5_marker = vcat(_allMarkers, :pixel)
const _hdf5_scale = [:identity, :ln, :log2, :log10]
# Additional constants
#Dict has problems using "Types" as keys. Initialize in "_initialize_backend":
const HDF5PLOT_MAP_STR2TELEM = Dict{String, Type}()
const HDF5PLOT_MAP_TELEM2STR = Dict{Type, String}()
#Don't really like this global variable... Very hacky
mutable struct HDF5Plot_PlotRef
ref::Union{Plot, Nothing}
end
const HDF5PLOT_PLOTREF = HDF5Plot_PlotRef(nothing)
# ------------------------------------------------------------------------------
# inspectdr
@@ -629,7 +685,7 @@ const _inspectdr_attr = merge_with_base_supported([
:markerstrokestyle, #Causes warning not to have it... what is this?
:fillcolor, :fillalpha, #:fillrange,
# :bins, :bar_width, :bar_edges, :bar_position,
:title, :title_location,
:title, :titlelocation,
:window_title,
:guide, :lims, :scale, #:ticks, :flip, :rotation,
:titlefontfamily, :titlefontsize, :titlefontcolor,
@@ -646,7 +702,6 @@ const _inspectdr_attr = merge_with_base_supported([
:polar,
# :normalize, :weights,
# :contours, :aspect_ratio,
:match_dimensions,
# :clims,
# :inset_subplots,
:dpi,
@@ -654,7 +709,7 @@ const _inspectdr_attr = merge_with_base_supported([
])
const _inspectdr_style = [:auto, :solid, :dash, :dot, :dashdot]
const _inspectdr_seriestype = [
:path, :scatter, :shape, :straightline, #, :steppre, :steppost
:path, :scatter, :shape, :straightline, #, :steppre, :stepmid, :steppost
]
#see: _allMarkers, _shape_keys
const _inspectdr_marker = Symbol[
@@ -707,7 +762,6 @@ const _pgfplotsx_attr = merge_with_base_supported([
:ticks,
:scale,
:flip,
:match_dimensions,
:titlefontfamily,
:titlefontsize,
:titlefonthalign,
@@ -770,8 +824,10 @@ const _pgfplotsx_seriestype = [
:surface,
:wireframe,
:heatmap,
:mesh3d,
:contour,
:contour3d,
:quiver,
:shape,
:steppre,
:stepmid,
@@ -792,6 +848,7 @@ const _pgfplotsx_marker = [
:rtriangle,
:cross,
:xcross,
:x,
:star5,
:pentagon,
:hline,
@@ -800,3 +857,6 @@ const _pgfplotsx_marker = [
]
const _pgfplotsx_scale = [:identity, :ln, :log2, :log10]
is_marker_supported(::PGFPlotsXBackend, shape::Shape) = true
# additional constants
const _pgfplotsx_series_ids = KW()
@@ -166,7 +166,7 @@ function pgf_series(sp::Subplot, series::Series)
# function args
args = if st == :contour
plotattributes[:z].surf, plotattributes[:x], plotattributes[:y]
elseif is3d(st)
elseif RecipesPipeline.is3d(st)
plotattributes[:x], plotattributes[:y], plotattributes[:z]
elseif st == :straightline
straightline_data(series)
@@ -271,7 +271,7 @@ function pgf_fillrange_series(series, i, fillrange, args...)
push!(style, _pgf_series_extrastyle[st])
end
kw[:style] = join(style, ',')
func = is3d(series) ? PGFPlots.Linear3 : PGFPlots.Linear
func = RecipesPipeline.is3d(series) ? PGFPlots.Linear3 : PGFPlots.Linear
return func(pgf_fillrange_args(fillrange, args...)...; kw...)
end
@@ -444,7 +444,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
# add to style/kw for each axis
for letter in (:x, :y, :z)
if letter != :z || is3d(sp)
if letter != :z || RecipesPipeline.is3d(sp)
axisstyle, axiskw = pgf_axis(sp, letter)
append!(style, axisstyle)
merge!(kw, axiskw)
@@ -494,7 +494,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
if any(s[:seriestype] == :contour for s in series_list(sp))
kw[:view] = "{0}{90}"
kw[:colorbar] = !(sp[:colorbar] in (:none, :off, :hide, false))
elseif is3d(sp)
elseif RecipesPipeline.is3d(sp)
azim, elev = sp[:camera]
kw[:view] = "{$(azim)}{$(elev)}"
end
+1133 -1183
View File
File diff suppressed because it is too large Load Diff
+492 -512
View File
File diff suppressed because it is too large Load Diff
+101 -41
View File
@@ -17,9 +17,6 @@ Add in functionality to Plots.jl:
is_marker_supported(::InspectDRBackend, shape::Shape) = true
_inspectdr_to_pixels(bb::BoundingBox) =
InspectDR.BoundingBox(to_pixels(left(bb)), to_pixels(right(bb)), to_pixels(top(bb)), to_pixels(bottom(bb)))
#Do we avoid Map to avoid possible pre-comile issues?
function _inspectdr_mapglyph(s::Symbol)
s == :rect && return :square
@@ -79,6 +76,58 @@ end
# ---------------------------------------------------------------------------
function _inspectdr_getaxisticks(ticks, gridlines, xfrm)
TickCustom = InspectDR.TickCustom
_xfrm(coord) = InspectDR.axis2aloc(Float64(coord), xfrm.spec) #Ensure Float64 - in case
ttype = ticksType(ticks)
if ticks == :native
#keep current
elseif ttype == :ticks_and_labels
pos = ticks[1]; labels = ticks[2]; nticks = length(ticks[1])
newticks = TickCustom[TickCustom(_xfrm(pos[i]), labels[i]) for i in 1:nticks]
gridlines = InspectDR.GridLinesCustom(gridlines)
gridlines.major = newticks
gridlines.minor = []
gridlines.displayminor = false
elseif ttype == :ticks
nticks = length(ticks)
gridlines.major = Float64[_xfrm(t) for t in ticks]
gridlines.minor = []
gridlines.displayminor = false
elseif isnothing(ticks)
gridlines.major = []
gridlines.minor = []
else #Assume ticks == :native
#keep current
end
return gridlines #keep current
end
function _inspectdr_setticks(sp::Subplot, plot, strip, xaxis, yaxis)
InputXfrm1D = InspectDR.InputXfrm1D
_get_ticks(axis) = :native == axis[:ticks] ? (:native) : get_ticks(sp, axis)
wantnative(ticks) = (:native == ticks)
xticks = _get_ticks(xaxis)
yticks = _get_ticks(yaxis)
if wantnative(xticks) && wantnative(yticks)
#Don't "eval" tick values
return
end
#TODO: Allow InspectDR to independently "eval" x or y ticks
ext = InspectDR.getextents_aloc(plot, 1)
grid = InspectDR._eval(strip.grid, plot.xscale, strip.yscale, ext)
grid.xlines = _inspectdr_getaxisticks(xticks, grid.xlines, InputXfrm1D(plot.xscale))
grid.ylines = _inspectdr_getaxisticks(yticks, grid.ylines, InputXfrm1D(strip.yscale))
strip.grid = grid
end
# ---------------------------------------------------------------------------
function _inspectdr_getscale(s::Symbol, yaxis::Bool)
#TODO: Support :asinh, :sqrt
kwargs = yaxis ? (:tgtmajor=>8, :tgtminor=>2) : () #More grid lines on y-axis
@@ -167,6 +216,7 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
st = series[:seriestype]
sp = series[:subplot]
plot = sp.o
clims = get_clims(sp, series)
#Don't do anything without a "subplot" object: Will process later.
if nothing == plot; return; end
@@ -237,7 +287,7 @@ For st in :shape:
color = linecolor, fillcolor = fillcolor
)
end
elseif st in (:path, :scatter, :straightline) #, :steppre, :steppost)
elseif st in (:path, :scatter, :straightline) #, :steppre, :stepmid, :steppost)
#NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think).
linewidth = series[:linewidth]
#More efficient & allows some support for markerstrokewidth:
@@ -256,8 +306,8 @@ For st in :shape:
wfrm.glyph = InspectDR.glyph(
shape = _inspectdr_mapglyph(series[:markershape]),
size = _inspectdr_mapglyphsize(series[:markersize]),
color = _inspectdr_mapcolor(plot_color(series[:markerstrokecolor], series[:markerstrokealpha])),
fillcolor = _inspectdr_mapcolor(plot_color(series[:markercolor], series[:markeralpha])),
color = _inspectdr_mapcolor(plot_color(get_markerstrokecolor(series), get_markerstrokealpha(series))),
fillcolor = _inspectdr_mapcolor(plot_color(get_markercolor(series, clims), get_markeralpha(series))),
)
end
@@ -288,8 +338,8 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
ygrid_show = yaxis[:grid]
strip.grid = InspectDR.GridRect(
vmajor=xgrid_show, # vminor=xgrid_show,
hmajor=ygrid_show, # hminor=ygrid_show,
vmajor=xgrid_show, # vminor=xgrid_show,
hmajor=ygrid_show, # hminor=ygrid_show,
)
plot.xscale = _inspectdr_getscale(xaxis[:scale], false)
@@ -302,38 +352,48 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
xmin, xmax = -rmax, rmax
ymin, ymax = -rmax, rmax
end
plot.xext = InspectDR.PExtents1D() #reset
strip.yext = InspectDR.PExtents1D() #reset
plot.xext_full = InspectDR.PExtents1D(xmin, xmax)
strip.yext_full = InspectDR.PExtents1D(ymin, ymax)
#Set current extents = full extents (needed for _eval(strip.grid,...))
plot.xext = plot.xext_full
strip.yext = strip.yext_full
_inspectdr_setticks(sp, plot, strip, xaxis, yaxis)
a = plot.annotation
a.title = sp[:title]
a.xlabel = xaxis[:guide]; a.ylabels = [yaxis[:guide]]
l = plot.layout
l[:frame_canvas].fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
l[:frame_data].fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
l[:frame_data].line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
l[:font_title] = InspectDR.Font(sp[:titlefontfamily],
#Modify base layout of new object:
l = plot.layout.defaults = deepcopy(InspectDR.defaults.plotlayout)
#IMPORTANT: Must deepcopy to ensure we don't change layouts of other plots.
#Works because plot uses defaults (not user-overwritten `layout.values`)
l.frame_canvas.fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
l.frame_data.fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
l.frame_data.line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
l.font_title = InspectDR.Font(sp[:titlefontfamily],
_inspectdr_mapptsize(sp[:titlefontsize]),
color = _inspectdr_mapcolor(sp[:titlefontcolor])
)
#Cannot independently control fonts of axes with InspectDR:
l[:font_axislabel] = InspectDR.Font(xaxis[:guidefontfamily],
l.font_axislabel = InspectDR.Font(xaxis[:guidefontfamily],
_inspectdr_mapptsize(xaxis[:guidefontsize]),
color = _inspectdr_mapcolor(xaxis[:guidefontcolor])
)
l[:font_ticklabel] = InspectDR.Font(xaxis[:tickfontfamily],
l.font_ticklabel = InspectDR.Font(xaxis[:tickfontfamily],
_inspectdr_mapptsize(xaxis[:tickfontsize]),
color = _inspectdr_mapcolor(xaxis[:tickfontcolor])
)
l[:enable_legend] = (sp[:legend] != :none)
#l[:halloc_legend] = 150 #TODO: compute???
l[:font_legend] = InspectDR.Font(sp[:legendfontfamily],
l.enable_legend = (sp[:legend] != :none)
#l.halloc_legend = 150 #TODO: compute???
l.font_legend = InspectDR.Font(sp[:legendfontfamily],
_inspectdr_mapptsize(sp[:legendfontsize]),
color = _inspectdr_mapcolor(sp[:legendfontcolor])
)
l[:frame_legend].fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
l.frame_legend.fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
#_round!() ensures values use integer spacings (looks better on screen):
InspectDR._round!(InspectDR.autofit2font!(l, legend_width=10.0)) #10 "em"s wide
return
end
# called just before updating layout bounding boxes... in case you need to prep
@@ -347,8 +407,9 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend})
#Don't use window_title... probably not what you want.
#mplot.title = plt[:window_title]
end
mplot.layout[:frame].fillcolor = _inspectdr_mapcolor(plt[:background_color_outside])
mplot.layout[:frame].fillcolor = _inspectdr_mapcolor(plt[:background_color_outside])
mplot.layout[:frame] = mplot.layout[:frame] #register changes
resize!(mplot.subplots, length(plt.subplots))
nsubplots = length(plt.subplots)
for (i, sp) in enumerate(plt.subplots)
@@ -412,11 +473,16 @@ end
function _update_plot_object(plt::Plot{InspectDRBackend})
mplot = _inspectdr_getmplot(plt.o)
if nothing == mplot; return; end
mplot.bblist = InspectDR.BoundingBox[]
for (i, sp) in enumerate(plt.subplots)
graphbb = _inspectdr_to_pixels(plotarea(sp))
plot = mplot.subplots[i]
plot.plotbb = InspectDR.plotbounds(plot.layout.values, graphbb)
figw, figh = sp.plt[:size]
pcts = bbox_to_pcts(sp.bbox, figw*px, figh*px)
_left, _bottom, _width, _height = pcts
ymax = 1.0-_bottom
ymin = ymax - _height
bb = InspectDR.BoundingBox(_left, _left+_width, ymin, ymax)
push!(mplot.bblist, bb)
end
gplot = _inspectdr_getgui(plt.o)
@@ -429,29 +495,23 @@ end
# ----------------------------------------------------------------
const _inspectdr_mimeformats_dpi = Dict(
"image/png" => "png"
)
const _inspectdr_mimeformats_nodpi = Dict(
"image/svg+xml" => "svg",
"application/eps" => "eps",
"image/eps" => "eps",
# "application/postscript" => "ps", #TODO: support once Cairo supports PSSurface
"application/pdf" => "pdf"
)
_inspectdr_show(io::IO, mime::MIME, ::Nothing, w, h) =
throw(ErrorException("Cannot show(::IO, ...) plot - not yet generated"))
function _inspectdr_show(io::IO, mime::MIME, mplot, w, h)
InspectDR._show(io, mime, mplot, Float64(w), Float64(h))
end
for (mime, fmt) in _inspectdr_mimeformats_dpi
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend})
dpi = plt[:dpi]#TODO: support
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
end
function _show(io::IO, mime::MIME{Symbol("image/png")}, plt::Plot{InspectDRBackend})
dpi = plt[:dpi] # TODO: support
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
end
for (mime, fmt) in _inspectdr_mimeformats_nodpi
for (mime, fmt) in (
"image/svg+xml" => "svg",
"application/eps" => "eps",
"image/eps" => "eps",
# "application/postscript" => "ps", # TODO: support once Cairo supports PSSurface
"application/pdf" => "pdf",
)
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend})
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
end
-24
View File
@@ -1,24 +0,0 @@
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
+654 -429
View File
File diff suppressed because it is too large Load Diff
+270 -152
View File
@@ -1,46 +1,33 @@
# https://plot.ly/javascript/getting-started
is_subplot_supported(::PlotlyBackend) = true
# is_string_supported(::PlotlyBackend) = true
const _plotly_framestyles = [:box, :axes, :zerolines, :grid, :none]
const _plotly_framestyle_defaults = Dict(:semi => :box, :origin => :zerolines)
function _plotly_framestyle(style::Symbol)
if style in _plotly_framestyles
if style in (:box, :axes, :zerolines, :grid, :none)
return style
else
default_style = get(_plotly_framestyle_defaults, style, :axes)
@warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was cosen instead.")
default_style = get((semi = :box, origin = :zerolines), style, :axes)
@warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was chosen instead.")
default_style
end
end
# --------------------------------------------------------------------------------------
const plotly_remote_file_path = "https://cdn.plot.ly/plotly-latest.min.js"
# if isatom()
# import Atom
# Atom.@msg evaljs(_js_code)
# end
using UUIDs
# ----------------------------------------------------------------
const _plotly_legend_pos = KW(
:right => [1., 0.5],
:left => [0., 0.5],
:top => [0.5, 1.],
:bottom => [0.5, 0.],
:bottomleft => [0., 0.],
:bottomright => [1., 0.],
:topright => [1., 1.],
:topleft => [0., 1.]
)
plotly_legend_pos(pos::Symbol) = get(_plotly_legend_pos, pos, [1.,1.])
plotly_legend_pos(v::Tuple{S,T}) where {S<:Real, T<:Real} = v
function labelfunc(scale::Symbol, backend::PlotlyBackend)
texfunc = labelfunc_tex(scale)
function (x)
tex_x = texfunc(x)
sup_x = replace( tex_x, r"\^{(.*)}"=>s"<sup>\1</sup>" )
# replace dash with \minus (U+2212)
replace(sup_x, "-" => "")
end
end
function plotly_font(font::Font, color = font.color)
KW(
@@ -133,16 +120,17 @@ end
# this method gets the start/end in percentage of the canvas for this axis direction
function plotly_domain(sp::Subplot, letter)
function plotly_domain(sp::Subplot)
figw, figh = sp.plt[:size]
pcts = bbox_to_pcts(sp.plotarea, figw*px, figh*px)
pcts = plotly_apply_aspect_ratio(sp, sp.plotarea, pcts)
i1,i2 = (letter == :x ? (1,3) : (2,4))
[pcts[i1], pcts[i1]+pcts[i2]]
x_domain = [pcts[1], pcts[1] + pcts[3]]
y_domain = [pcts[2], pcts[2] + pcts[4]]
return x_domain, y_domain
end
function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
letter = axis[:letter]
framestyle = sp[:framestyle]
ax = KW(
@@ -155,20 +143,16 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
:zerolinecolor => rgba_string(axis[:foreground_color_axis]),
:showline => framestyle in (:box, :axes) && axis[:showaxis],
:linecolor => rgba_string(plot_color(axis[:foreground_color_axis])),
:ticks => axis[:tick_direction] == :out ? "outside" : "inside",
:ticks => axis[:tick_direction] === :out ? "outside" :
axis[:tick_direction] === :in ? "inside" : "",
:mirror => framestyle == :box,
:showticklabels => axis[:showaxis],
)
if letter in (:x,:y)
ax[:domain] = plotly_domain(sp, letter)
if is3d(sp)
# don't link 3d axes for synchronized interactivity
x_idx = y_idx = sp[:subplot_index]
else
x_idx, y_idx = plotly_link_indicies(plt, sp)
end
ax[:anchor] = "$(letter==:x ? "y$(y_idx)" : "x$(x_idx)")"
if anchor !== nothing
ax[:anchor] = anchor
end
if domain !== nothing
ax[:domain] = domain
end
ax[:tickangle] = -axis[:rotation]
@@ -176,7 +160,7 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
lims = axis_limits(sp, letter)
if axis[:ticks] != :native || axis[:lims] != :auto
ax[:range] = map(scalefunc(axis[:scale]), lims)
ax[:range] = map(RecipesPipeline.scale_func(axis[:scale]), lims)
end
if !(axis[:ticks] in (nothing, :none, false))
@@ -245,7 +229,7 @@ function plotly_layout(plt::Plot)
# but vertically just below the top of the subplot bounding box
if sp[:title] != ""
bb = plotarea(sp)
tpos = sp[:title_location]
tpos = sp[:titlelocation]
xmm = if tpos == :left
left(bb)
elseif tpos == :right
@@ -263,46 +247,42 @@ function plotly_layout(plt::Plot)
# set to supported framestyle
sp[:framestyle] = _plotly_framestyle(sp[:framestyle])
# if any(is3d, seriesargs)
if is3d(sp)
azim = sp[:camera][1] - 90 #convert azimuthal to match GR behaviour
theta = 90 - sp[:camera][2] #spherical coordinate angle from z axis
plotattributes_out[:scene] = KW(
Symbol("xaxis$(spidx)") => plotly_axis(plt, sp[:xaxis], sp),
Symbol("yaxis$(spidx)") => plotly_axis(plt, sp[:yaxis], sp),
Symbol("zaxis$(spidx)") => plotly_axis(plt, sp[:zaxis], sp),
#2.6 multiplier set camera eye such that whole plot can be seen
:camera => KW(
:eye => KW(
:x => cosd(azim)*sind(theta)*2.6,
:y => sind(azim)*sind(theta)*2.6,
:z => cosd(theta)*2.6,
),
),
)
elseif ispolar(sp)
if ispolar(sp)
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
spidx == y_idx ? plotattributes_out[Symbol("yaxis$(y_idx)")] = plotly_axis(plt, sp[:yaxis], sp) : nothing
x_domain, y_domain = plotly_domain(sp)
if RecipesPipeline.is3d(sp)
azim = sp[:camera][1] - 90 #convert azimuthal to match GR behaviour
theta = 90 - sp[:camera][2] #spherical coordinate angle from z axis
plotattributes_out[Symbol(:scene, spidx)] = KW(
:domain => KW(:x => x_domain, :y => y_domain),
Symbol("xaxis$(spidx)") => plotly_axis(sp[:xaxis], sp),
Symbol("yaxis$(spidx)") => plotly_axis(sp[:yaxis], sp),
Symbol("zaxis$(spidx)") => plotly_axis(sp[:zaxis], sp),
#2.6 multiplier set camera eye such that whole plot can be seen
:camera => KW(
:eye => KW(
:x => cosd(azim)*sind(theta)*2.6,
:y => sind(azim)*sind(theta)*2.6,
:z => cosd(theta)*2.6,
),
),
)
else
plotattributes_out[Symbol("xaxis$(x_idx)")] =
plotly_axis(sp[:xaxis], sp, string("y", y_idx) , x_domain)
# don't allow yaxis to be reupdated/reanchored in a linked subplot
if spidx == y_idx
plotattributes_out[Symbol("yaxis$(y_idx)")] =
plotly_axis(sp[:yaxis], sp, string("x", x_idx), y_domain)
end
end
end
# legend
plotattributes_out[:showlegend] = sp[:legend] != :none
xpos,ypos = plotly_legend_pos(sp[:legend])
if sp[:legend] != :none
plotattributes_out[:legend] = KW(
:bgcolor => rgba_string(sp[:background_color_legend]),
:bordercolor => rgba_string(sp[:foreground_color_legend]),
:font => plotly_font(legendfont(sp)),
:tracegroupgap => 0,
:x => xpos,
:y => ypos
)
end
plotly_add_legend!(plotattributes_out, sp)
# annotations
for ann in sp[:annotations]
@@ -342,38 +322,132 @@ function plotly_layout(plt::Plot)
plotattributes_out[:hovermode] = "none"
end
plotattributes_out
plotattributes_out = recursive_merge(plotattributes_out, plt.attr[:extra_plot_kwargs])
end
function plotly_add_legend!(plotattributes_out::KW, sp::Subplot)
plotattributes_out[:showlegend] = sp[:legend] != :none
legend_position = plotly_legend_pos(sp[:legend])
if sp[:legend] != :none
plotattributes_out[:legend] = KW(
:bgcolor => rgba_string(sp[:background_color_legend]),
:bordercolor => rgba_string(sp[:foreground_color_legend]),
:borderwidth => 1,
:traceorder => "normal",
:xanchor => legend_position.xanchor,
:yanchor => legend_position.yanchor,
:font => plotly_font(legendfont(sp)),
:tracegroupgap => 0,
:x => legend_position.coords[1],
:y => legend_position.coords[2],
:title => KW(
:text => sp[:legendtitle] === nothing ? "" : string(sp[:legendtitle]),
:font => plotly_font(legendtitlefont(sp)),
),
)
end
end
function plotly_legend_pos(pos::Symbol)
xleft = 0.07
ybot = 0.07
ytop = 1.0
xcenter = 0.55
ycenter = 0.52
center = 0.5
youtertop = 1.1
youterbot = -0.15
xouterright = 1.05
xouterleft = -0.15
plotly_legend_position_mapping = (
right = (coords = [1.0, ycenter], xanchor = "right", yanchor = "middle"),
left = (coords = [xleft, ycenter], xanchor = "left", yanchor = "middle"),
top = (coords = [xcenter, ytop], xanchor = "center", yanchor = "top"),
bottom = (coords = [xcenter, ybot], xanchor = "center", yanchor = "bottom"),
bottomleft = (coords = [xleft, ybot], xanchor = "left", yanchor = "bottom"),
bottomright = (coords = [1.0, ybot], xanchor = "right", yanchor = "bottom"),
topright = (coords = [1.0, 1.0], xanchor = "right", yanchor = "top"),
topleft = (coords = [xleft, 1.0], xanchor = "left", yanchor = "top"),
outertop =(coords = [center, youtertop ], xanchor = "upper", yanchor = "middle"),
outerbottom =(coords = [center, youterbot], xanchor = "lower", yanchor = "middle"),
outerleft =(coords = [xouterleft, center], xanchor = "left", yanchor = "top"),
outerright =(coords = [xouterright, center], xanchor = "right", yanchor = "top"),
outertopleft =(coords = [xouterleft, ytop], xanchor = "upper", yanchor = "left"),
outertopright = (coords = [xouterright, ytop], xanchor = "upper", yanchor = "right"),
outerbottomleft =(coords = [xouterleft, ybot], xanchor = "lower", yanchor = "left"),
outerbottomright =(coords = [xouterright, ybot], xanchor = "lower", yanchor = "right"),
default = (coords = [1.0, 1.0], xanchor = "auto", yanchor = "auto")
)
legend_position = get(plotly_legend_position_mapping, pos, plotly_legend_position_mapping.default)
end
plotly_legend_pos(v::Tuple{S,T}) where {S<:Real, T<:Real} = (coords=v, xanchor="left", yanchor="top")
plotly_legend_pos(theta::Real) = plotly_legend_pos((theta, :inner))
function plotly_legend_pos(v::Tuple{S,Symbol}) where S<:Real
(s,c) = sincosd(v[1])
xanchors = ["left", "center", "right"]
yanchors = ["bottom", "middle", "top"]
if v[2] === :inner
rect = (0.07,0.5,1.0,0.07,0.52,1.0)
xanchor = xanchors[legend_anchor_index(c)]
yanchor = yanchors[legend_anchor_index(s)]
else
rect = (-0.15,0.5,1.05,-0.15,0.52,1.1)
xanchor = xanchors[4-legend_anchor_index(c)]
yanchor = yanchors[4-legend_anchor_index(s)]
end
return (coords=legend_pos_from_angle(v[1],rect...), xanchor=xanchor, yanchor=yanchor)
end
function plotly_layout_json(plt::Plot)
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 eachindex(grad.colors)]
end
plotly_colorscale(c::Colorant,α) = plotly_colorscale(_as_gradient(c),α)
function plotly_colorscale(c::AbstractVector{<:RGBA}, α)
plotly_colorscale(cg::ColorGradient, α = nothing) =
[[v, rgba_string(plot_color(cg.colors[v], α))] for v in cg.values]
function plotly_colorscale(c::AbstractVector{<:Colorant}, α = nothing)
if length(c) == 1
return [[0.0, rgba_string(plot_color(c[1], α))], [1.0, rgba_string(plot_color(c[1], α))]]
return [
[0.0, rgba_string(plot_color(c[1], α))],
[1.0, rgba_string(plot_color(c[1], α))],
]
else
vals = range(0.0, stop=1.0, length=length(c))
vals = range(0.0, stop = 1.0, length = length(c))
return [[vals[i], rgba_string(plot_color(c[i], α))] for i in eachindex(c)]
end
end
# plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha)
function plotly_colorscale(cg::PlotUtils.CategoricalColorGradient, α = nothing)
n = length(cg)
cinds = repeat(1:n, inner = 2)
vinds = vcat((i:(i + 1) for i in 1:n)...)
return [
[cg.values[vinds[i]], rgba_string(plot_color(color_list(cg)[cinds[i]], α))]
for i in eachindex(cinds)
]
end
plotly_colorscale(c, α = nothing) = plotly_colorscale(_as_gradient(c), α)
const _plotly_markers = KW(
:rect => "square",
:xcross => "x",
:x => "x",
:utriangle => "triangle-up",
:dtriangle => "triangle-down",
:star5 => "star-triangle-up",
:vline => "line-ns",
:hline => "line-ew",
get_plotly_marker(k, def) = get(
(
rect = "square",
xcross = "x",
x = "x",
utriangle = "triangle-up",
dtriangle = "triangle-down",
star5 = "star-triangle-up",
vline = "line-ns",
hline = "line-ew",
),
k,
def,
)
# find indicies of axes to which the supblot links to
@@ -408,8 +482,8 @@ function plotly_data(series::Series, letter::Symbol, data)
data
end
if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe)
plotly_surface_data(series, data)
if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe, :mesh3d)
handle_surface(data)
else
plotly_data(data)
end
@@ -419,10 +493,6 @@ plotly_data(v::AbstractArray) = v
plotly_data(surf::Surface) = surf.surf
plotly_data(v::AbstractArray{R}) where {R<:Rational} = float(v)
plotly_surface_data(series::Series, a::AbstractVector) = a
plotly_surface_data(series::Series, a::AbstractMatrix) = transpose_z(series, a, false)
plotly_surface_data(series::Series, a::Surface) = plotly_surface_data(series, a.surf)
function plotly_native_data(axis::Axis, data::AbstractArray)
if !isempty(axis[:discrete_values])
construct_categorical_data(data, axis)
@@ -463,9 +533,17 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out = KW()
# these are the axes that the series should be mapped to
x_idx, y_idx = plotly_link_indicies(plt, sp)
plotattributes_out[:xaxis] = "x$(x_idx)"
plotattributes_out[:yaxis] = "y$(y_idx)"
if RecipesPipeline.is3d(sp)
spidx = length(plt.subplots) > 1 ? sp[:subplot_index] : ""
plotattributes_out[:xaxis] = "x$spidx"
plotattributes_out[:yaxis] = "y$spidx"
plotattributes_out[:zaxis] = "z$spidx"
plotattributes_out[:scene] = "scene$spidx"
else
x_idx, y_idx = length(plt.subplots) > 1 ? plotly_link_indicies(plt, sp) : ("", "")
plotattributes_out[:xaxis] = "x$(x_idx)"
plotattributes_out[:yaxis] = "y$(y_idx)"
end
plotattributes_out[:showlegend] = should_add_to_legend(series)
if st == :straightline
@@ -515,7 +593,7 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series)
elseif st in (:surface, :wireframe)
plotattributes_out[:type] = "surface"
plotattributes_out[:type] = "surface"
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
if st == :wireframe
plotattributes_out[:hidesurface] = true
@@ -530,17 +608,34 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
plotattributes_out[:opacity] = series[:fillalpha]
if series[:fill_z] !== nothing
plotattributes_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z])
plotattributes_out[:surfacecolor] = handle_surface(series[:fill_z])
end
plotattributes_out[:showscale] = hascolorbar(sp)
end
elseif st == :mesh3d
plotattributes_out[:type] = "mesh3d"
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
elseif st == :pie
plotattributes_out[:type] = "pie"
plotattributes_out[:labels] = pie_labels(sp, series)
plotattributes_out[:values] = y
plotattributes_out[:hoverinfo] = "label+percent+name"
if series[:connections] !== nothing
if typeof(series[:connections]) <: Tuple{Array,Array,Array}
i,j,k = series[:connections]
if !(length(i) == length(j) == length(k))
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
end
plotattributes_out[:i] = i
plotattributes_out[:j] = j
plotattributes_out[:k] = k
else
throw(ArgumentError("Argument connections has to be a tuple of three arrays."))
end
end
plotattributes_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
plotattributes_out[:color] = rgba_string(plot_color(series[:fillcolor], series[:fillalpha]))
plotattributes_out[:opacity] = series[:fillalpha]
if series[:fill_z] !== nothing
plotattributes_out[:surfacecolor] = handle_surface(series[:fill_z])
end
plotattributes_out[:showscale] = hascolorbar(sp)
else
@warn("Plotly: seriestype $st isn't supported.")
return KW()
@@ -550,7 +645,7 @@ function plotly_series(plt::Plot, series::Series)
if hasmarker
inds = eachindex(x)
plotattributes_out[:marker] = KW(
:symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])),
:symbol => get_plotly_marker(series[:markershape], string(series[:markershape])),
# :opacity => series[:markeralpha],
:size => 2 * _cycle(series[:markersize], inds),
:color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))),
@@ -568,7 +663,7 @@ function plotly_series(plt::Plot, series::Series)
end
function plotly_series_shapes(plt::Plot, series::Series, clims)
segments = iter_segments(series)
segments = series_segments(series)
plotattributes_outs = Vector{KW}(undef, length(segments))
# TODO: create a plotattributes_out for each polygon
@@ -587,7 +682,8 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
for (letter, data) in zip((:x, :y), shape_data(series, 100))
)
for (i,rng) in enumerate(segments)
for (k, segment) in enumerate(segments)
i, rng = segment.attr_index, segment.range
length(rng) < 2 && continue
# to draw polygons, we actually draw lines with fill
@@ -606,10 +702,10 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
:dash => string(get_linestyle(series, i)),
)
end
plotattributes_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
plotattributes_out[:showlegend] = k==1 ? should_add_to_legend(series) : false
plotly_polar!(plotattributes_out, series)
plotly_hover!(plotattributes_out, _cycle(series[:hover], i))
plotattributes_outs[i] = plotattributes_out
plotattributes_outs[k] = plotattributes_out
end
if series[:fill_z] !== nothing
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill))
@@ -630,12 +726,16 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
hasfillrange = st in (:path, :scatter, :scattergl, :straightline) &&
(isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple))
segments = iter_segments(series)
segments = collect(series_segments(series, st))
plotattributes_outs = fill(KW(), (hasfillrange ? 2 : 1 ) * length(segments))
for (i,rng) in enumerate(segments)
needs_scatter_fix = !isscatter && hasmarker && !any(isnan,y) && length(segments) > 1
for (k, segment) in enumerate(segments)
i, rng = segment.attr_index, segment.range
plotattributes_out = deepcopy(plotattributes_base)
plotattributes_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
plotattributes_out[:showlegend] = k==1 ? should_add_to_legend(series) : false
plotattributes_out[:legendgroup] = series[:label]
# set the type
@@ -669,13 +769,15 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
# add "marker"
if hasmarker
mcolor = rgba_string(plot_color(get_markercolor(series, clims, i), get_markeralpha(series, i)))
lcolor = rgba_string(plot_color(get_markerstrokecolor(series, i), get_markerstrokealpha(series, i)))
plotattributes_out[:marker] = KW(
:symbol => get(_plotly_markers, _cycle(series[:markershape], i), string(_cycle(series[:markershape], i))),
# :opacity => series[:markeralpha],
:symbol => get_plotly_marker(_cycle(series[:markershape], i), string(_cycle(series[:markershape], i))),
# :opacity => needs_scatter_fix ? [1, 0] : 1,
:size => 2 * _cycle(series[:markersize], i),
:color => rgba_string(plot_color(get_markercolor(series, clims, i), get_markeralpha(series, i))),
:color => needs_scatter_fix ? [mcolor, "rgba(0, 0, 0, 0.000)"] : mcolor,
:line => KW(
:color => rgba_string(plot_color(get_markerstrokecolor(series, i), get_markerstrokealpha(series, i))),
:color => needs_scatter_fix ? [lcolor, "rgba(0, 0, 0, 0.000)"] : lcolor,
:width => _cycle(series[:markerstrokewidth], i),
),
)
@@ -688,6 +790,8 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
:width => get_linewidth(series, i),
:shape => if st == :steppre
"vh"
elseif st == :stepmid
"hvh"
elseif st == :steppost
"hv"
else
@@ -720,16 +824,15 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
else
# if fillrange is a tuple with upper and lower limit, plotattributes_out_fillrange
# is the series that will do the filling
fillrng = Tuple(series[:fillrange][i][rng] for i in 1:2)
plotattributes_out_fillrange[:x], plotattributes_out_fillrange[:y] = concatenate_fillrange(x[rng], fillrng)
plotattributes_out_fillrange[:x], plotattributes_out_fillrange[:y] = concatenate_fillrange(x[rng], series[:fillrange])
plotattributes_out_fillrange[:line][:width] = 0
delete!(plotattributes_out, :fill)
delete!(plotattributes_out, :fillcolor)
end
plotattributes_outs[(2 * i - 1):(2 * i)] = [plotattributes_out_fillrange, plotattributes_out]
plotattributes_outs[(2k-1):(2k)] = [plotattributes_out_fillrange, plotattributes_out]
else
plotattributes_outs[i] = plotattributes_out
plotattributes_outs[k] = plotattributes_out
end
end
@@ -748,17 +851,17 @@ function plotly_colorbar_hack(series::Series, plotattributes_base::KW, sym::Symb
plotattributes_out = deepcopy(plotattributes_base)
cmin, cmax = get_clims(series[:subplot])
plotattributes_out[:showlegend] = false
plotattributes_out[:type] = is3d(series) ? :scatter3d : :scatter
plotattributes_out[:type] = RecipesPipeline.is3d(series) ? :scatter3d : :scatter
plotattributes_out[:hoverinfo] = :none
plotattributes_out[:mode] = :markers
plotattributes_out[:x], plotattributes_out[:y] = [series[:x][1]], [series[:y][1]]
if is3d(series)
if RecipesPipeline.is3d(series)
plotattributes_out[:z] = [series[:z][1]]
end
# zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line)
plotattributes_out[:marker] = KW(
:size => 0,
:opacity => 0,
:size => 1e-10,
:opacity => 1e-10,
:color => [0.5],
:cmin => cmin,
:cmax => cmax,
@@ -805,25 +908,19 @@ 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 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[]
# using requirejs seems to be key to load a js depency in IJulia!
# https://requirejs.org/docs/start.html
# https://github.com/JuliaLang/IJulia.jl/issues/345
display("text/html", """
<script type="text/javascript">
requirejs([$(repr(plotly))], function(p) {
window.Plotly = p
});
</script>
""")
ijulia_initialized[] = true
plotly =
use_local_dependencies[] ? ("file:///" * plotly_local_file_path[]) : "https://cdn.plot.ly/$(_plotly_min_js_filename)"
include_mathjax = get(plt[:extra_plot_kwargs], :include_mathjax, "")
mathjax_file = include_mathjax != "cdn" ? ("file://" * include_mathjax) : "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"
mathjax_head = include_mathjax == "" ? "" : "<script src=\"$mathjax_file\"></script>\n\t\t"
if isijulia()
mathjax_head
else
"$mathjax_head<script src=$(repr(plotly))></script>"
end
return "<script src=$(repr(plotly))></script>"
end
function plotly_html_body(plt, style = nothing)
@@ -831,12 +928,33 @@ function plotly_html_body(plt, style = nothing)
w, h = plt[:size]
style = "width:$(w)px;height:$(h)px;"
end
requirejs_prefix = ""
requirejs_suffix = ""
if isijulia()
# require.js adds .js automatically
plotly_no_ext =
use_local_dependencies[] ? ("file:///" * plotly_local_file_path[]) : "https://cdn.plot.ly/$(_plotly_min_js_filename)"
plotly_no_ext = plotly_no_ext[1:end-3]
requirejs_prefix = """
requirejs.config({
paths: {
Plotly: '$(plotly_no_ext)'
}
});
require(['Plotly'], function (Plotly) {
"""
requirejs_suffix = "});"
end
uuid = UUIDs.uuid4()
html = """
<div id=\"$(uuid)\" style=\"$(style)\"></div>
<script>
PLOT = document.getElementById('$(uuid)');
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
$(requirejs_prefix)
$(js_body(plt, uuid))
$(requirejs_suffix)
</script>
"""
html
@@ -844,7 +962,7 @@ end
function js_body(plt::Plot, uuid)
js = """
PLOT = document.getElementById('$(uuid)');
var PLOT = document.getElementById('$(uuid)');
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
"""
end
@@ -868,7 +986,7 @@ end
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
write(io, standalone_html(plt))
write(io, embeddable_html(plt))
end
+23
View File
@@ -0,0 +1,23 @@
function plotlybase_syncplot(plt::Plot)
plt.o = PlotlyBase.Plot()
traces = PlotlyBase.GenericTrace[]
for series_dict in plotly_series(plt)
plotly_type = pop!(series_dict, :type)
push!(traces, PlotlyBase.GenericTrace(plotly_type; series_dict...))
end
PlotlyBase.addtraces!(plt.o, traces...)
layout = plotly_layout(plt)
w, h = plt[:size]
PlotlyBase.relayout!(plt.o, layout, width = w, height = h)
return plt.o
end
for (mime, fmt) in (
"application/pdf" => "pdf",
"image/png" => "png",
"image/svg+xml" => "svg",
"image/eps" => "eps",
)
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyBackend}) =
PlotlyBase.savefig(io, plotlybase_syncplot(plt), format = $fmt)
end
+4 -9
View File
@@ -19,14 +19,12 @@ end
# ------------------------------------------------------------------------------
const _plotlyjs_mimeformats = Dict(
for (mime, fmt) in (
"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
@@ -36,15 +34,12 @@ _show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBack
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))
_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, embeddable_html(plt))
_display(plt::Plot{PlotlyJSBackend}) = display(plotlyjs_syncplot(plt))
@require WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" begin
function WebIO.render(plt::Plot{PlotlyJSBackend})
plt_html = sprint(show, MIME("text/html"), plt)
return WebIO.render(WebIO.dom"div"(innerHTML=plt_html))
end
function PlotlyJS.WebIO.render(plt::Plot{PlotlyJSBackend})
return PlotlyJS.WebIO.render(plotlyjs_syncplot(plt))
end
function closeall(::PlotlyJSBackend)
+425 -345
View File
File diff suppressed because it is too large Load Diff
+8 -10
View File
@@ -3,19 +3,17 @@
# don't warn on unsupported... there's just too many warnings!!
warnOnUnsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
# --------------------------------------------------------------------------------------
const _canvas_type = Ref(:auto)
function _canvas_map()
KW(
:braille => UnicodePlots.BrailleCanvas,
:ascii => UnicodePlots.AsciiCanvas,
:block => UnicodePlots.BlockCanvas,
:dot => UnicodePlots.DotCanvas,
:density => UnicodePlots.DensityCanvas,
(
braille = UnicodePlots.BrailleCanvas,
ascii = UnicodePlots.AsciiCanvas,
block = UnicodePlots.BlockCanvas,
dot = UnicodePlots.DotCanvas,
density = UnicodePlots.DensityCanvas,
)
end
@@ -126,7 +124,7 @@ function addUnicodeSeries!(o, plotattributes, addlegend::Bool, xlim, ylim)
color = plotattributes[:linecolor] in UnicodePlots.color_cycle ? plotattributes[:linecolor] : :auto
# add the series
x, y = Plots.unzip(collect(Base.Iterators.filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y))))
x, y = RecipesPipeline.unzip(collect(Base.Iterators.filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y))))
func(o, x, y; color = color, name = label)
end
+5 -1
View File
@@ -19,6 +19,10 @@ function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr
"""
end
function embeddable_html(plt::AbstractPlot)
html_head(plt) * html_body(plt)
end
function open_browser_window(filename::AbstractString)
@static if Sys.isapple()
return run(`open $(filename)`)
@@ -45,7 +49,7 @@ function standalone_html_window(plt::AbstractPlot)
old = use_local_dependencies[] # save state to restore afterwards
# if we open a browser ourself, we can host local files, so
# when we have a local plotly downloaded this is the way to go!
use_local_dependencies[] = isfile(plotly_local_file_path)
use_local_dependencies[] = plotly_local_file_path[] === nothing ? false : isfile(plotly_local_file_path[])
filename = write_temp_html(plt)
open_browser_window(filename)
# restore for other backends
+90
View File
@@ -0,0 +1,90 @@
# These functions return an operator for use in `get_clims(::Seres, op)`
process_clims(lims::Tuple{<:Number,<:Number}) = (zlims -> ifelse.(isfinite.(lims), lims, zlims)) ignorenan_extrema
process_clims(s::Union{Symbol,Nothing,Missing}) = ignorenan_extrema
# don't specialize on ::Function otherwise python functions won't work
process_clims(f) = f
function get_clims(sp::Subplot, op=process_clims(sp[:clims]))
zmin, zmax = Inf, -Inf
for series in series_list(sp)
if series[:colorbar_entry]
zmin, zmax = _update_clims(zmin, zmax, get_clims(series, op)...)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(sp::Subplot, series::Series, op=process_clims(sp[:clims]))
zmin, zmax = if series[:colorbar_entry]
get_clims(sp, op)
else
get_clims(series, op)
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
"""
get_clims(::Series, op=Plots.ignorenan_extrema)
Finds the limits for the colorbar by taking the "z-values" for the series and passing them into `op`,
which must return the tuple `(zmin, zmax)`. The default op is the extrema of the finite
values of the input.
"""
function get_clims(series::Series, op=ignorenan_extrema)
zmin, zmax = Inf, -Inf
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface, :hexbin)
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, op(vals.surf)...)
elseif (vals !== nothing) && (eltype(vals) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, op(vals)...)
end
end
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))
function get_colorbar_ticks(sp::Subplot; update = true)
if update || !haskey(sp.attr, :colorbar_optimized_ticks)
ticks = _transform_ticks(sp[:colorbar_ticks])
cvals = sp[:colorbar_continuous_values]
dvals = sp[:colorbar_discrete_values]
clims = get_clims(sp)
scale = sp[:colorbar_scale]
formatter = sp[:colorbar_formatter]
sp.attr[:colorbar_optimized_ticks] =
get_ticks(ticks, cvals, dvals, clims, scale, formatter)
end
return sp.attr[:colorbar_optimized_ticks]
end
function _update_subplot_colorbars(sp::Subplot)
# Dynamic callback from the pipeline if needed
end
+77 -112
View File
@@ -1,7 +1,5 @@
const P2 = GeometryTypes.Point2{Float64}
const P3 = GeometryTypes.Point3{Float64}
const P2 = GeometryBasics.Point2{Float64}
const P3 = GeometryBasics.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))
@@ -11,9 +9,9 @@ compute_angle(v::P2) = (angle = atan(v[2], v[1]); angle < 0 ? 2π - angle : angl
# -------------------------------------------------------------
struct Shape
x::Vector{Float64}
y::Vector{Float64}
struct Shape{X<:Number, Y<:Number}
x::Vector{X}
y::Vector{Y}
# function Shape(x::AVec, y::AVec)
# # if x[1] != x[end] || y[1] != y[end]
# # new(vcat(x, x[1]), vcat(y, y[1]))
@@ -29,7 +27,7 @@ end
Construct a polygon to be plotted
"""
Shape(verts::AVec) = Shape(unzip(verts)...)
Shape(verts::AVec) = Shape(RecipesPipeline.unzip(verts)...)
Shape(s::Shape) = deepcopy(s)
get_xs(shape::Shape) = shape.x
@@ -44,21 +42,17 @@ function coords(shape::Shape)
shape.x, shape.y
end
function coords(shapes::AVec{Shape})
length(shapes) == 0 && return zeros(0), zeros(0)
xs = map(get_xs, shapes)
ys = map(get_ys, shapes)
x, y = map(copy, coords(shapes[1]))
for shape in shapes[2:end]
nanappend!(x, shape.x)
nanappend!(y, shape.y)
end
#coords(shapes::AVec{Shape}) = unzip(map(coords, shapes))
function coords(shapes::AVec{<:Shape})
c = map(coords, shapes)
x = [q[1] for q in c]
y = [q[2] for q in c]
x, y
end
"get an array of tuples of points on a circle with radius `r`"
function partialcircle(start_θ, end_θ, n = 20, r=1)
Tuple{Float64,Float64}[(r*cos(u),r*sin(u)) for u in range(start_θ, stop=end_θ, length=n)]
[(r*cos(u), r*sin(u)) for u in range(start_θ, stop=end_θ, length=n)]
end
"interleave 2 vectors into each other (like a zipper's teeth)"
@@ -77,7 +71,6 @@ function weave(x,y; ordering = Vector[x,y])
ret
end
"create a star by weaving together points from an outer and inner circle. `n` is the number of arms"
function makestar(n; offset = -0.5, radius = 1.0)
z1 = offset * π
@@ -93,7 +86,6 @@ function makeshape(n; offset = -0.5, radius = 1.0)
Shape(partialcircle(z, z + 2π, n+1, radius))
end
function makecross(; offset = -0.5, radius = 1.0)
z2 = offset * π
z1 = z2 - π/8
@@ -103,7 +95,6 @@ function makecross(; offset = -0.5, radius = 1.0)
ordering=Vector[outercircle,innercircle,outercircle]))
end
from_polar(angle, dist) = P2(dist*cos(angle), dist*sin(angle))
function makearrowhead(angle; h = 2.0, w = 0.4)
@@ -112,31 +103,6 @@ function makearrowhead(angle; h = 2.0, w = 0.4)
from_polar(angle + 0.5π, w) - tip, (0,0)])
end
const _shape_keys = Symbol[
:circle,
:rect,
:star5,
:diamond,
:hexagon,
:cross,
:xcross,
:utriangle,
:dtriangle,
:rtriangle,
:ltriangle,
:pentagon,
:heptagon,
:octagon,
:star4,
:star6,
:star7,
:star8,
:vline,
:hline,
:+,
:x,
]
const _shapes = KW(
:circle => makeshape(20),
:rect => makeshape(4, offset=-0.25),
@@ -239,9 +205,12 @@ function rotate!(shape::Shape, Θ::Real, c = center(shape))
end
"rotate an object in space"
function rotate(shape::Shape, Θ::Real, c = center(shape))
shapecopy = deepcopy(shape)
rotate!(shapecopy, Θ, c)
function rotate(shape::Shape, θ::Real, c = center(shape))
x, y = coords(shape)
cx, cy = c
x_new = rotate_x.(x, y, θ, cx, cy)
y_new = rotate_y.(x, y, θ, cx, cy)
Shape(x_new, y_new)
end
# -----------------------------------------------------------------------
@@ -319,7 +288,7 @@ function font(args...;kw...)
for symbol in keys(kw)
if symbol == :family
family = kw[:family]
family = string(kw[:family])
elseif symbol == :pointsize
pointsize = kw[:pointsize]
elseif symbol == :halign
@@ -358,9 +327,15 @@ end
Scales all **current** font sizes by `factor`. For example `scalefontsizes(1.1)` increases all current font sizes by 10%. To reset to initial sizes, use `scalefontsizes()`
"""
function scalefontsizes(factor::Number)
for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize)
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
scalefontsize(k, factor)
end
for letter in (:x,:y,:z)
for k in (:guidefontsize, :tickfontsize)
scalefontsize(Symbol(letter, k), factor)
end
end
end
"""
@@ -369,15 +344,27 @@ end
Resets font sizes to initial default values.
"""
function scalefontsizes()
for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize)
f = default(k)
if k in keys(_initial_fontsizes)
factor = f / _initial_fontsizes[k]
scalefontsize(k, 1.0/factor)
end
end
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
f = default(k)
if k in keys(_initial_fontsizes)
factor = f / _initial_fontsizes[k]
scalefontsize(k, 1.0/factor)
end
end
for letter in (:x,:y,:z)
for k in (:guidefontsize, :tickfontsize)
if k in keys(_initial_fontsizes)
f = default(Symbol(letter, k))
factor = f / _initial_fontsizes[k]
scalefontsize(Symbol(letter, k), 1.0/factor)
end
end
end
end
resetfontsizes() = scalefontsizes()
"Wrap a string with font info"
struct PlotText
str::AbstractString
@@ -588,27 +575,47 @@ annotations(sa::SeriesAnnotations) = sa
# Expand arrays of coordinates, positions and labels into induvidual annotations
# and make sure labels are of type PlotText
function process_annotation(sp::Subplot, xs, ys, labs, font = font())
function process_annotation(sp::Subplot, xs, ys, labs, font = nothing)
anns = []
labs = makevec(labs)
xlength = length(methods(length, (typeof(xs),))) == 0 ? 1 : length(xs)
ylength = length(methods(length, (typeof(ys),))) == 0 ? 1 : length(ys)
if isnothing(font)
font = Plots.font(;
family=sp[:annotationfontfamily],
pointsize=sp[:annotationfontsize],
halign=sp[:annotationhalign],
valign=sp[:annotationvalign],
rotation=sp[:annotationrotation],
color=sp[:annotationcolor],
)
end
for i in 1:max(xlength, ylength, length(labs))
x, y, lab = _cycle(xs, i), _cycle(ys, i), _cycle(labs, i)
x = typeof(x) <: TimeType ? Dates.value(x) : x
y = typeof(y) <: TimeType ? Dates.value(y) : y
x = typeof(x) <: TimeType ? Dates.value(x) : x
y = typeof(y) <: TimeType ? Dates.value(y) : y
if lab == :auto
alphabet = "abcdefghijklmnopqrstuvwxyz"
push!(anns, (x, y, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
else
push!(anns, (x, y, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab...) : text(lab, font)))
push!(anns, (x, y, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab[1], font, lab[2:end]...) : text(lab, font)))
end
end
anns
end
function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, labs, font = font())
function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, labs, font = nothing)
anns = []
positions, labs = makevec(positions), makevec(labs)
if isnothing(font)
font = Plots.font(;
family=sp[:annotationfontfamily],
pointsize=sp[:annotationfontsize],
halign=sp[:annotationhalign],
valign=sp[:annotationvalign],
rotation=sp[:annotationrotation],
color=sp[:annotationcolor],
)
end
for i in 1:max(length(positions), length(labs))
pos, lab = _cycle(positions, i), _cycle(labs, i)
pos = get(_positionAliases, pos, pos)
@@ -616,12 +623,15 @@ function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol},
alphabet = "abcdefghijklmnopqrstuvwxyz"
push!(anns, (pos, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
else
push!(anns, (pos, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab...) : text(lab, font)))
push!(anns, (pos, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab[1], font, lab[2:end]...) : text(lab, font)))
end
end
anns
end
function process_any_label(lab, font=Font())
lab isa Tuple ? text(lab...) : text( lab, font )
end
# Give each annotation coordinates based on specified position
function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText)
position_multiplier = Dict{Symbol, Tuple{Float64,Float64}}(
@@ -638,6 +648,7 @@ function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText)
(x, y, lab)
end
locate_annotation(sp::Subplot, x, y, label::PlotText) = (x, y, label)
locate_annotation(sp::Subplot, x, y, z, label::PlotText) = (x, y, z, label)
# -----------------------------------------------------------------------
"type which represents z-values for colors and sizes (and anything else that might come up)"
@@ -652,23 +663,6 @@ end
# -----------------------------------------------------------------------
abstract type AbstractSurface end
"represents a contour or surface mesh"
struct Surface{M<:AMat} <: AbstractSurface
surf::M
end
Surface(f::Function, x, y) = Surface(Float64[f(xi,yi) for yi in y, xi in x])
Base.Array(surf::Surface) = surf.surf
for f in (:length, :size, :axes)
@eval Base.$f(surf::Surface, args...) = $f(surf.surf, args...)
end
Base.copy(surf::Surface) = Surface(copy(surf.surf))
Base.eltype(surf::Surface{T}) where {T} = eltype(T)
function expand_extrema!(a::Axis, surf::Surface)
ex = a[:extrema]
for vi in surf.surf
@@ -688,28 +682,7 @@ end
# # I don't want to clash with ValidatedNumerics, but this would be nice:
# ..(a::T, b::T) = (a,b)
struct Volume{T}
v::Array{T,3}
x_extents::Tuple{T,T}
y_extents::Tuple{T,T}
z_extents::Tuple{T,T}
end
default_extents(::Type{T}) where {T} = (zero(T), one(T))
function Volume(v::Array{T,3},
x_extents = default_extents(T),
y_extents = default_extents(T),
z_extents = default_extents(T)) where T
Volume(v, x_extents, y_extents, z_extents)
end
Base.Array(vol::Volume) = vol.v
for f in (:length, :size)
@eval Base.$f(vol::Volume, args...) = $f(vol.v, args...)
end
Base.copy(vol::Volume{T}) where {T} = Volume{T}(copy(vol.v), vol.x_extents, vol.y_extents, vol.z_extents)
Base.eltype(vol::Volume{T}) where {T} = T
# -----------------------------------------------------------------------
@@ -773,17 +746,9 @@ function add_arrows(func::Function, x::AVec, y::AVec)
end
end
# -----------------------------------------------------------------------
"Represents data values with formatting that should apply to the tick labels."
struct Formatted{T}
data::T
formatter::Function
end
# -----------------------------------------------------------------------
"create a BezierCurve for plotting"
mutable struct BezierCurve{T <: GeometryTypes.Point}
mutable struct BezierCurve{T <: GeometryBasics.Point}
control_points::Vector{T}
end
@@ -798,7 +763,7 @@ end
@deprecate curve_points coords
coords(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, Base.range(range..., length=n))
coords(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, Base.range(first(range), stop=last(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]
+267 -85
View File
@@ -7,9 +7,9 @@ mutable struct PlotExample
exprs::Vector{Expr}
end
# the _examples we'll run for each
# the _examples we'll run for each backend
const _examples = PlotExample[
PlotExample(
PlotExample( # 1
"Lines",
"A simple line plot of the columns.",
[:(
@@ -18,7 +18,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 2
"Functions, adding data, and animations",
"""
Plot multiple functions. You can also put the function first, or use the form `plot(f,
@@ -30,16 +30,16 @@ const _examples = PlotExample[
""",
[:(
begin
p = plot([sin, cos], zeros(0), leg = false)
p = plot([sin, cos], zeros(0), leg = false, xlims = (0, 2π), ylims = (-1, 1))
anim = Animation()
for x in range(0, stop = 10π, length = 100)
for x in range(0, stop = 2π, length = 20)
push!(p, x, Float64[sin(x), cos(x)])
frame(anim)
end
end
)],
),
PlotExample(
PlotExample( # 3
"Parametric plots",
"Plot function pair (x(u), y(u)).",
[
@@ -58,7 +58,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 4
"Colors",
"""
Access predefined palettes (or build your own with the `colorscheme` method).
@@ -74,7 +74,7 @@ const _examples = PlotExample[
rand(11, 4),
lab = "lines",
w = 3,
palette = :grays,
palette = cgrad(:grays),
fill = 0,
α = 0.6,
)
@@ -89,7 +89,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 5
"Global",
"""
Change the guides/background/limits/ticks. Convenience args `xaxis` and `yaxis` allow
@@ -121,13 +121,7 @@ const _examples = PlotExample[
],
),
# PlotExample("Two-axis",
# "Use the `axis` arguments.",
# [
# :(plot(Vector[randn(100), randn(100)*100], axis = [:l :r], ylabel="LEFT", yrightlabel="RIGHT", xlabel="X", title="TITLE"))
# ]),
PlotExample(
PlotExample( # 6
"Images",
"Plot an image. y-axis is set to flipped",
[
@@ -142,7 +136,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 7
"Arguments",
"""
Plot multiple series with different numbers of points. Mix arguments that apply to all
@@ -166,7 +160,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 8
"Build plot in pieces",
"Start with a base plot...",
[:(
@@ -175,7 +169,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 9
"",
"and add to it later.",
[:(
@@ -184,7 +178,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 10
"Histogram2D",
"",
[:(
@@ -193,7 +187,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 11
"Line types",
"",
[
@@ -214,7 +208,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 12
"Line styles",
"",
[
@@ -237,7 +231,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 13
"Marker types",
"",
[
@@ -247,14 +241,15 @@ const _examples = PlotExample[
m -> m in Plots.supported_markers(),
Plots._shape_keys,
)
markers = reshape(markers, 1, length(markers))
markers = permutedims(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),
m = markers,
markersize = 8,
lab = map(string, markers),
bg = :linen,
xlim = (0, 10),
@@ -264,7 +259,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 14
"Bar",
"`x` is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)",
[:(
@@ -273,7 +268,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 15
"Histogram",
"",
[
@@ -288,7 +283,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 16
"Subplots",
"""
Use the `layout` keyword, and optionally the convenient `@layout` macro to generate
@@ -310,7 +305,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 17
"Adding to subplots",
"""
Note here the automatic grid layout, as well as the order in which new series are added
@@ -322,21 +317,27 @@ const _examples = PlotExample[
plot(
Plots.fakedata(100, 10),
layout = 4,
palette = [:grays :blues :heat :lightrainbow],
palette = cgrad.([:grays :blues :heat :lightrainbow]),
bg_inside = [:orange :pink :darkblue :black],
)
end
),
],
),
PlotExample("", "", [:(
begin
using Random
Random.seed!(111)
plot!(Plots.fakedata(100, 10))
end
)]),
PlotExample(
PlotExample( # 18
"",
"",
[
:(
begin
using Random
Random.seed!(111)
plot!(Plots.fakedata(100, 10))
end
)
]
),
PlotExample( # 19
"Open/High/Low/Close",
"""
Create an OHLC chart. Pass in a list of (open,high,low,close) tuples as your `y`
@@ -365,7 +366,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 20
"Annotations",
"""
The `annotations` keyword is used for text annotations in data-coordinates. Pass in a
@@ -408,7 +409,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 21
"Custom Markers",
"""A `Plots.Shape` is a light wrapper around vertices of a polygon. For supported
backends, pass arbitrary polygons as the marker shapes. Note: The center is (0,0) and
@@ -454,7 +455,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 22
"Contours",
"""
Any value for fill works here. We first build a filled contour from a function, then an
@@ -474,7 +475,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 23
"Pie",
"",
[:(
@@ -485,7 +486,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 24
"3D",
"",
[
@@ -511,7 +512,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 25
"DataFrames",
"Plot using DataFrame column symbols.",
[
@@ -534,7 +535,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 26
"Groups and Subplots",
"",
[
@@ -552,7 +553,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 27
"Polar Plots",
"",
[:(
@@ -563,7 +564,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 28
"Heatmap, categorical axes, and aspect_ratio",
"",
[:(
@@ -575,7 +576,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample(
PlotExample( # 29
"Layouts, margins, label rotation, title location",
"",
[
@@ -586,7 +587,7 @@ const _examples = PlotExample[
rand(100, 6),
layout = @layout([a b; c]),
title = ["A" "B" "C"],
title_location = :left,
titlelocation = :left,
left_margin = [20mm 0mm],
bottom_margin = 10px,
xrotation = 60,
@@ -595,7 +596,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 30
"Boxplot and Violin series recipes",
"",
[
@@ -620,7 +621,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 31
"Animation with subplots",
"The `layout` macro can be used to create an animation with subplots.",
[
@@ -628,14 +629,15 @@ const _examples = PlotExample[
begin
l = @layout([[a; b] c])
p = plot(
plot([sin, cos], 1, leg = false),
scatter([atan, cos], 1, leg = false),
plot(log, 1, xlims = (1, 10π), ylims = (0, 5), leg = false),
plot([sin, cos], 1, ylims = (-1, 1), leg = false),
scatter([atan, cos], 1, ylims = (-1, 1.5), leg = false),
plot(log, 1, ylims = (0, 2), leg = false),
layout = l,
xlims = (1, 2π),
)
anim = Animation()
for x in range(1, stop = 10π, length = 100)
for x in range(1, stop = 2π, length = 20)
plot(push!(
p,
x,
@@ -647,7 +649,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 32
"Spy",
"""
For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has
@@ -681,7 +683,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 33
"Magic grid argument",
"""
The grid lines can be modified individually for each axis with the magic `grid` argument.
@@ -711,7 +713,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 34
"Framestyle",
"""
The style of the frame/axes of a (sub)plot can be changed with the `framestyle`
@@ -735,7 +737,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 35
"Lines and markers with varying colors",
"""
You can use the `line_z` and `marker_z` properties to associate a color with
@@ -761,7 +763,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 36
"Portfolio Composition maps",
"""
see: http://stackoverflow.com/a/37732384/5075246
@@ -787,7 +789,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 37
"Ribbons",
"""
Ribbons can be added to lines via the `ribbon` keyword;
@@ -810,7 +812,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 38
"Histogram2D (complex values)",
"",
[
@@ -829,7 +831,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 39
"Unconnected lines using `missing` or `NaN`",
"""
Missing values and non-finite values, including `NaN`, are not plotted.
@@ -853,7 +855,7 @@ const _examples = PlotExample[
),
],
),
PlotExample(
PlotExample( # 40
"Lens",
"A lens lets you easily magnify a region of a plot. x and y coordinates refer to the to be magnified region and the via the `inset` keyword the subplot index and the bounding box (in relative coordinates) of the inset plot with the magnified plot can be specified. Additional attributes count for the inset plot.",
[
@@ -875,7 +877,7 @@ const _examples = PlotExample[
end,
],
),
PlotExample(
PlotExample( # 41
"Array Types",
"Plots supports different `Array` types that follow the `AbstractArray` interface, like `StaticArrays` and `OffsetArrays.`",
[
@@ -885,11 +887,12 @@ const _examples = PlotExample[
sv = SVector{10}(rand(10))
ov = OffsetVector(rand(10), -2)
plot([sv, ov], label = ["StaticArray" "OffsetArray"])
plot!(3ov, ribbon=ov, label="OffsetArray ribbon")
end
end,
],
),
PlotExample(
PlotExample( # 42
"Setting defaults and font arguments",
"",
[
@@ -919,7 +922,7 @@ const _examples = PlotExample[
end,
],
),
PlotExample(
PlotExample( # 43
"Heatmap with DateTime axis",
"",
[
@@ -934,7 +937,7 @@ const _examples = PlotExample[
end,
],
),
PlotExample(
PlotExample( # 44
"Linked axes",
"",
[
@@ -946,7 +949,7 @@ const _examples = PlotExample[
end,
],
),
PlotExample(
PlotExample( # 45
"Error bars and array type recipes",
"",
[
@@ -973,8 +976,8 @@ const _examples = PlotExample[
surf = Measurement.((1:10) .* (1:10)', rand(10,10))
plot(
scatter(x, [x y], msw = 0),
scatter(x, y, z, msw = 0),
scatter(x, [x y]),
scatter(x, y, z),
heatmap(x, y, surf),
wireframe(x, y, surf),
legend = :topleft
@@ -983,24 +986,203 @@ const _examples = PlotExample[
end,
],
),
PlotExample( # 46
"Tuples and `Point`s as data",
"",
[quote
using GeometryBasics
using Distributions
d = MvNormal([1.0 0.75; 0.75 2.0])
plot([(1,2),(3,2),(2,1),(2,3)])
scatter!(Point2.(eachcol(rand(d,1000))), alpha=0.25)
end]
),
PlotExample( # 47
"Mesh3d",
"""
Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically.
You can also specify the connections using the connections keyword.
The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle,
such that elements at the same position of these vectors form a triangle.
""",
[
:(
begin
# specify the vertices
x=[0, 1, 2, 0]
y=[0, 0, 1, 2]
z=[0, 2, 0, 1]
# specify the triangles
# every column is one triangle,
# where the values denote the indices of the vertices of the triangle
i=[0, 0, 0, 1]
j=[1, 2, 3, 2]
k=[2, 3, 1, 3]
# the four triangles gives above give a tetrahedron
mesh3d(x,y,z;connections=(i,j,k))
end
),
],
),
PlotExample( # 48
"Vectors of markershapes and segments",
"",
[quote
using Base.Iterators: cycle, take
yv = ones(9)
ys = [1; 1; NaN; ones(6)]
y = 5 .- [yv 2ys 3yv 4ys]
plt_color_rows = plot(
y,
seriestype = [:path :path :scatter :scatter],
markershape = collect(take(cycle((:utriangle, :rect)), 9)),
markersize = 8,
color = collect(take(cycle((:red, :black)), 9))
)
plt_z_cols = plot(
y,
markershape = [:utriangle :x :circle :square],
markersize = [5 10 10 5],
marker_z = [5 4 3 2],
line_z = [1 3 3 1],
linewidth = [1 10 5 1]
)
plot(plt_color_rows, plt_z_cols)
end]
),
PlotExample( # 49
"Polar heatmaps",
"",
[quote
x = range(0, 2π, length=9)
y = 0:4
z = (1:4) .+ (1:8)'
heatmap(x, y, z, projection = :polar)
end]
),
PlotExample( # 50
"3D surface with axis guides",
"",
[quote
f(x,a) = 1/x + a*x^2
xs = collect(0.1:0.05:2.0);
as = collect(0.2:0.1:2.0);
x_grid = [x for x in xs for y in as];
a_grid = [y for x in xs for y in as];
plot(x_grid, a_grid, f.(x_grid,a_grid),
st = :surface,
xlabel = "longer xlabel",
ylabel = "longer ylabel",
zlabel = "longer zlabel",
)
end]
),
PlotExample( # 51
"Images with custom axes",
"",
[quote
using Plots
using TestImages
img = testimage("lighthouse")
# plot the image reversing the first dimension and setting yflip = false
plot([-π, π], [-1, 1], reverse(img, dims=1), yflip=false, aspect_ratio=:none)
# plot other data
plot!(sin, -π, π, lw=3, color=:red)
end]
),
PlotExample(
"3d quiver",
"",
[quote
using Plots
ϕs = range(-π, π, length=50)
θs = range(0, π, length=25)
θqs = range(1, π-1, length=25)
x = vec([sin(θ) * cos(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θs)])
y = vec([sin(θ) * sin(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θs)])
z = vec([cos(θ) for (ϕ, θ) in Iterators.product(ϕs, θs)])
u = 0.1 * vec([sin(θ) * cos(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θqs)])
v = 0.1 * vec([sin(θ) * sin(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θqs)])
w = 0.1 * vec([cos(θ) for (ϕ, θ) in Iterators.product(ϕs, θqs)])
quiver(x,y,z, quiver=(u,v,w))
end]
),
PlotExample( # 53
"Step Types",
"A comparison of the various step-like `seriestype`s",
[
:(
begin
x = 1:5
y = [1, 2, 3, 2, 1]
default(shape=:circle)
plot(
plot(x, y, markershape=:circle, seriestype=:steppre, label="steppre"),
plot(x, y, markershape=:circle, seriestype=:stepmid, label="stepmid"),
plot(x, y, markershape=:circle, seriestype=:steppost, label="steppost"),
layout=(3,1)
)
end
),
],
),
PlotExample( # 54
"Guide positions and alignment",
"",
[
:(
begin
plot(
rand(10, 4),
layout=4,
xguide="x guide",
yguide="y guide",
xguidefonthalign=[:left :right :right :left],
yguidefontvalign=[:top :bottom :bottom :top],
xguideposition=:top,
yguideposition=[:right :left :right :left],
ymirror=[false true true false],
xmirror=[false false true true],
legend=false,
seriestype=[:bar :scatter :path :stepmid]
)
end
),
],
),
]
# Some constants for PlotDocs and PlotReferenceImages
_animation_examples = [2, 30]
_animation_examples = [2, 31]
_backend_skips = Dict(
:gr => [25, 30],
:pyplot => [25, 30],
:plotlyjs => [2, 21, 24, 25, 30, 31],
:plotly => [2, 21, 24, 25, 30, 31],
:pgfplots => [2, 5, 6, 10, 16, 20, 22, 23, 25, 28, 30, 31, 34, 37, 38, 39],
:pgfplotsx => [ 6, # images
10, # histogram2d
16, # pgfplots thinks the upper panel is too small
22, # contourf
23, # pie
32, # spy
38, # histogram2d
] )
:gr => [25, 30, 47],
:pyplot => [2, 25, 30, 31, 47, 49],
:plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51],
:plotly => [2, 21, 24, 25, 30, 31, 49, 50, 51],
:pgfplotsx => [
2, # animation
6, # images
16, # pgfplots thinks the upper panel is too small
30, # @df
31, # animation
32, # spy
49, # polar heatmap
51, # image with custom axes
],
)
+2 -2
View File
@@ -4,7 +4,7 @@ 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)
use_local_plotlyjs[] = plotly_local_file_path[] === nothing ? false : isfile(plotly_local_file_path[])
ENV["MPLBACKEND"] = "Agg"
end
@@ -54,9 +54,9 @@ function _ijulia_display_dict(plt::Plot)
elseif output_type == :html
mime = "text/html"
out[mime] = sprint(show, MIME(mime), plt)
_ijulia__extra_mime_info!(plt, out)
else
error("Unsupported output type $output_type")
end
_ijulia__extra_mime_info!(plt, out)
out
end
+18 -23
View File
@@ -1,9 +1,12 @@
using REPL
using Scratch
const plotly_local_file_path = Ref{Union{Nothing, String}}(nothing)
function _plots_defaults()
if isdefined(Main, :PLOTS_DEFAULTS)
Dict{Symbol,Any}(Main.PLOTS_DEFAULTS)
copy(Dict{Symbol,Any}(Main.PLOTS_DEFAULTS))
else
Dict{Symbol,Any}()
end
@@ -13,10 +16,9 @@ end
function __init__()
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)
theme(pop!(user_defaults, :theme); user_defaults...)
else
default(; user_defaults...)
end
insert!(Base.Multimedia.displays, findlast(x -> x isa Base.TextDisplay || x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, PlotsDisplay())
@@ -31,49 +33,41 @@ function __init__()
@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")
fn = joinpath(@__DIR__, "backends", "deprecated", "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")
@require PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" begin
fn = joinpath(@__DIR__, "backends", "plotlybase.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
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
@@ -84,16 +78,17 @@ function __init__()
end
end
if haskey(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL")
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")
if get(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL", "false") == "true"
global plotly_local_file_path[] = joinpath(@get_scratch!("plotly"), _plotly_min_js_filename)
if !isfile(plotly_local_file_path[])
download("https://cdn.plot.ly/$(_plotly_min_js_filename)", plotly_local_file_path[])
end
else
use_local_dependencies[] = use_local_plotlyjs[]
use_local_plotlyjs[] = true
end
use_local_dependencies[] = use_local_plotlyjs[]
@require FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" begin
_show(io::IO, mime::MIME"image/png", plt::Plot{<:PDFBackends}) = _show_pdfbackends(io, mime, plt)
+5 -35
View File
@@ -4,34 +4,6 @@
to_pixels(m::AbsoluteLength) = m.value / 0.254
const _cbar_width = 5mm
#Base.broadcast(::typeof(Base.:.*), m::Measure, n::Number) = m * n
#Base.broadcast(::typeof(Base.:.*), m::Number, n::Measure) = m * n
Base.:-(m::Measure, a::AbstractArray) = map(ai -> m - ai, a)
Base.:-(a::AbstractArray, m::Measure) = map(ai -> ai - m, a)
Base.zero(::Type{typeof(mm)}) = 0mm
Base.one(::Type{typeof(mm)}) = 1mm
Base.typemin(::typeof(mm)) = -Inf*mm
Base.typemax(::typeof(mm)) = Inf*mm
Base.convert(::Type{F}, l::AbsoluteLength) where {F<:AbstractFloat} = convert(F, l.value)
# TODO: these are unintuitive and may cause tricky bugs
# Base.:+(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 + m2.value))
# Base.:+(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * (1 + m1.value))
# Base.:-(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 - m2.value))
# Base.:-(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * (m1.value - 1))
Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value)
Base.:*(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * m1.value)
Base.:/(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value / m2.value)
Base.:/(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value / m1.value)
Base.zero(::Type{typeof(pct)}) = 0pct
Base.one(::Type{typeof(pct)}) = 1pct
Base.typemin(::typeof(pct)) = 0pct
Base.typemax(::typeof(pct)) = 1pct
const defaultbox = BoundingBox(0mm, 0mm, 0mm, 0mm)
left(bbox::BoundingBox) = bbox.x0[1]
@@ -258,7 +230,7 @@ end
grid(args...; kw...)
Create a grid layout for subplots. `args` specify the dimensions, e.g.
`grid(3,2, widths = (0.6,04))` creates a grid with three rows and two
`grid(3,2, widths = (0.6,0.4))` creates a grid with three rows and two
columns of different width.
"""
grid(args...; kw...) = GridLayout(args...; kw...)
@@ -345,10 +317,8 @@ end
# recursively compute the bounding boxes for the layout and plotarea (relative to canvas!)
function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm,0mm,0mm,0mm])
nr, nc = size(layout)
# # create a matrix for each minimum padding direction
# _update_min_padding!(layout)
minpad_left = map(leftpad, layout.grid)
minpad_top = map(toppad, layout.grid)
minpad_right = map(rightpad, layout.grid)
@@ -407,10 +377,10 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm,0mm,0
# this is the minimum perimeter as decided by this child's parent, so that
# all children on this border have the same value
min_child_perimeter = [
c == 1 ? layout.minpad[1] : 0mm,
r == 1 ? layout.minpad[2] : 0mm,
c == nc ? layout.minpad[3] : 0mm,
r == nr ? layout.minpad[4] : 0mm
c == 1 ? layout.minpad[1] : pad_left[c],
r == 1 ? layout.minpad[2] : pad_top[r],
c == nc ? layout.minpad[3] : pad_right[c],
r == nr ? layout.minpad[4] : pad_bottom[r]
]
# recursively update the child's children
+59
View File
@@ -0,0 +1,59 @@
"""
```julia
legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax, inout)
```
Return `(x,y)` at an angle `theta` degrees from
`(xcenter,ycenter)` on a rectangle defined by (`xmin`,
`xmax`, `ymin`, `ymax`).
"""
function legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax)
(s,c) = sincosd(theta)
x = c < 0 ? (xmin-xcenter)/c : (xmax-xcenter)/c
y = s < 0 ? (ymin-ycenter)/s : (ymax-ycenter)/s
A = min(x,y)
return (xcenter + A*c, ycenter + A*s)
end
"""
Split continuous range `[-1,1]` evenly into an integer `[1,2,3]`
"""
function legend_anchor_index(x)
x<-1//3 && return 1
x<1//3 && return 2
return 3
end
"""
Turn legend argument into a (theta, :inner) or (theta, :outer) tuple.
For backends where legend position is given in normal coordinates (0,0) -- (1,1),
so :topleft exactly corresponds to (45, :inner) etc.
If `leg` is a (::Real,::Real) tuple, keep it as is.
"""
legend_angle(leg::Real) = (leg,:inner)
legend_angle(leg::Tuple{S,T}) where {S<:Real,T<:Real} = leg
legend_angle(leg::Tuple{S,Symbol}) where S<:Real = leg
legend_angle(leg::Symbol) = get(
(
topleft = (135,:inner),
top = (90, :inner),
topright = (45, :inner),
left = (180,:inner),
right = (0, :inner),
bottomleft = (225,:inner),
bottom = (270,:inner),
bottomright = (315,:inner),
outertopleft = (135,:outer),
outertop = (90, :outer),
outertopright = (45, :outer),
outerleft = (180,:outer),
outerright = (0, :outer),
outerbottomleft = (225,:outer),
outerbottom = (270,:outer),
outerbottomright = (315,:outer),
),
leg,
(45, :inner)
)
+88 -99
View File
@@ -1,54 +1,51 @@
defaultOutputFormat(plt::Plot) = "png"
function png(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "png")
io = open(fn, "w")
show(io, MIME("image/png"), plt)
close(io)
fn = addExtension(fn, "png")
io = open(fn, "w")
show(io, MIME("image/png"), plt)
close(io)
end
png(fn::AbstractString) = png(current(), fn)
function svg(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "svg")
io = open(fn, "w")
show(io, MIME("image/svg+xml"), plt)
close(io)
fn = addExtension(fn, "svg")
io = open(fn, "w")
show(io, MIME("image/svg+xml"), plt)
close(io)
end
svg(fn::AbstractString) = svg(current(), fn)
function pdf(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "pdf")
io = open(fn, "w")
show(io, MIME("application/pdf"), plt)
close(io)
fn = addExtension(fn, "pdf")
io = open(fn, "w")
show(io, MIME("application/pdf"), plt)
close(io)
end
pdf(fn::AbstractString) = pdf(current(), fn)
function ps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "ps")
io = open(fn, "w")
show(io, MIME("application/postscript"), plt)
close(io)
fn = addExtension(fn, "ps")
io = open(fn, "w")
show(io, MIME("application/postscript"), plt)
close(io)
end
ps(fn::AbstractString) = ps(current(), fn)
function eps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "eps")
io = open(fn, "w")
show(io, MIME("image/eps"), plt)
close(io)
fn = addExtension(fn, "eps")
io = open(fn, "w")
show(io, MIME("image/eps"), plt)
close(io)
end
eps(fn::AbstractString) = eps(current(), fn)
function tex(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "tex")
io = open(fn, "w")
show(io, MIME("application/x-tex"), plt)
close(io)
fn = addExtension(fn, "tex")
io = open(fn, "w")
show(io, MIME("application/x-tex"), plt)
close(io)
end
tex(fn::AbstractString) = tex(current(), fn)
@@ -69,48 +66,39 @@ end
html(fn::AbstractString) = html(current(), fn)
function txt(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "txt")
io = open(fn, "w")
show(io, MIME("text/plain"), plt)
close(io)
fn = addExtension(fn, "txt")
io = open(fn, "w")
show(io, MIME("text/plain"), plt)
close(io)
end
txt(fn::AbstractString) = txt(current(), fn)
# ----------------------------------------------------------------
# ----------------------------------------------------------------
const _savemap = Dict(
"png" => png,
"svg" => svg,
"pdf" => pdf,
"ps" => ps,
"ps" => ps,
"eps" => eps,
"tex" => tex,
"json" => json,
"html" => html,
"tikz" => tex,
"txt" => txt,
)
)
function getExtension(fn::AbstractString)
pieces = split(fn, ".")
length(pieces) > 1 || error("Can't extract file extension: ", fn)
ext = pieces[end]
haskey(_savemap, ext) || error("Invalid file extension: ", fn)
ext
end
const _extension_map = Dict("tikz" => "tex")
function addExtension(fn::AbstractString, ext::AbstractString)
try
oldext = getExtension(fn)
if oldext == ext
return fn
oldfn, oldext = splitext(fn)
oldext = chop(oldext, head = 1, tail = 0)
if get(_extension_map, oldext, oldext) == ext
return fn
else
return "$fn.$ext"
return string(fn, ".", ext)
end
catch
return "$fn.$ext"
end
end
"""
@@ -121,27 +109,28 @@ 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
ext = getExtension(fn)
catch
# if we couldn't extract the extension, add the default
ext = defaultOutputFormat(plt)
fn = addExtension(fn, ext)
end
fn = abspath(expanduser(fn))
# save it
func = get(_savemap, ext) do
error("Unsupported extension $ext with filename ", fn)
end
func(plt, fn)
# get the extension
_, ext = splitext(fn)
ext = chop(ext, head = 1, tail = 0)
if isempty(ext)
ext = defaultOutputFormat(plt)
end
# save it
if haskey(_savemap, ext)
func = _savemap[ext]
return func(plt, fn)
else
error("Invalid file extension: ", fn)
end
end
savefig(fn::AbstractString) = savefig(current(), fn)
# ---------------------------------------------------------
"""
gui([plot])
@@ -164,17 +153,13 @@ end
_do_plot_show(plt, showval::Bool) = showval && gui(plt)
function _do_plot_show(plt, showval::Symbol)
showval == :gui && gui(plt)
showval in (:inline,:ijulia) && inline(plt)
showval in (:inline, :ijulia) && inline(plt)
end
# ---------------------------------------------------------
const _best_html_output_type = KW(
:pyplot => :png,
:unicodeplots => :txt,
:plotlyjs => :html,
:plotly => :html
)
const _best_html_output_type =
KW(:pyplot => :png, :unicodeplots => :txt, :plotlyjs => :html, :plotly => :html)
# a backup for html... passes to svg or png depending on the html_output_format arg
function _show(io::IO, ::MIME"text/html", plt::Plot)
@@ -184,7 +169,12 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end
if output_type == :png
# @info("writing png to html output")
print(io, "<img src=\"data:image/png;base64,", base64encode(show, MIME("image/png"), plt), "\" />")
print(
io,
"<img src=\"data:image/png;base64,",
base64encode(show, MIME("image/png"), plt),
"\" />",
)
elseif output_type == :svg
# @info("writing svg to html output")
show(io, MIME("image/svg+xml"), plt)
@@ -196,7 +186,7 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end
# delegate showable to _show instead
function Base.showable(m::M, plt::P) where {M<:MIME, P<:Plot}
function Base.showable(m::M, plt::P) where {M <: MIME, P <: Plot}
return hasmethod(_show, Tuple{IO, M, P})
end
@@ -204,25 +194,32 @@ function _display(plt::Plot)
@warn("_display is not defined for this backend.")
end
Base.show(io::IO, m::MIME"text/plain", plt::Plot) = show(io, plt)
# 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/vnd.plotly.v1+json")
for mime in (
"text/html",
"image/png",
"image/eps",
"image/svg+xml",
"application/eps",
"application/pdf",
"application/postscript",
"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)
showjuno(io, m, plt)
else
prepare_output(plt)
_show(io, m, plt)
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)
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) =
showjuno(io, MIME("text/html"), plt)
"Close all open gui windows of the current backend"
closeall() = closeall(backend())
@@ -249,34 +246,26 @@ closeall() = closeall(backend())
# Atom PlotPane
# ---------------------------------------------------------
function showjuno(io::IO, m, plt)
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] = jratio*Plots.DPI
plt[:thickness_scaling] *= scale
plt[:dpi] = jratio * Plots.DPI
prepare_output(plt)
try
_showjuno(io, m, plt)
_showjuno(io, m, plt)
finally
plt[:size] = sz
plt[:dpi] = dpi
plt[:thickness_scaling] = thickness_scaling
plt[:dpi] = dpi
end
end
function _showjuno(io::IO, m::MIME"image/svg+xml", plt)
if Symbol(plt.attr[:html_output_format]) :svg
throw(MethodError(show, (typeof(m), typeof(plt))))
else
_show(io, m, plt)
end
if Symbol(plt.attr[:html_output_format]) :svg
throw(MethodError(show, (typeof(m), typeof(plt))))
else
_show(io, m, plt)
end
end
Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot) = false
+160 -235
View File
@@ -1,127 +1,73 @@
# Error for aliases used in recipes
function warn_on_recipe_aliases!(plotattributes, recipe_type, args...)
# RecipesPipeline API
## Warnings
function RecipesPipeline.warn_on_recipe_aliases!(
plt::Plot,
plotattributes::AKW,
recipe_type::Symbol,
@nospecialize(args)
)
for k in keys(plotattributes)
if !is_default_attribute(k)
dk = get(_keyAliases, k, k)
if k !== dk
@warn "Attribute alias `$k` detected in the $recipe_type recipe defined for the signature $(signature_string(Val{recipe_type}, args...)). To ensure expected behavior it is recommended to use the default attribute `$dk`."
if recipe_type == :user
signature_string = RecipesPipeline.userrecipe_signature_string(args)
elseif recipe_type == :type
signature_string = RecipesPipeline.typerecipe_signature_string(args)
elseif recipe_type == :plot
signature_string = RecipesPipeline.plotrecipe_signature_string(args)
elseif recipe_type == :series
signature_string = RecipesPipeline.seriesrecipe_signature_string(args)
else
throw(ArgumentError("Invalid recipe type `$recipe_type`"))
end
@warn "Attribute alias `$k` detected in the $recipe_type recipe defined for the signature $signature_string. To ensure expected behavior it is recommended to use the default attribute `$dk`."
end
plotattributes[dk] = pop_kw!(plotattributes, k)
plotattributes[dk] = RecipesPipeline.pop_kw!(plotattributes, k)
end
end
end
function warn_on_recipe_aliases!(v::AbstractVector, recipe_type, args...)
foreach(x -> warn_on_recipe_aliases!(x, recipe_type, args...), v)
end
function warn_on_recipe_aliases!(rd::RecipeData, recipe_type, args...)
warn_on_recipe_aliases!(rd.plotattributes, recipe_type, args...)
## Grouping
RecipesPipeline.splittable_attribute(plt::Plot, key, val::SeriesAnnotations, len) =
RecipesPipeline.splittable_attribute(plt, key, val.strs, len)
function RecipesPipeline.split_attribute(plt::Plot, key, val::SeriesAnnotations, indices)
split_strs = RecipesPipeline.split_attribute(plt, key, val.strs, indices)
return SeriesAnnotations(split_strs, val.font, val.baseshape, val.scalefactor)
end
function signature_string(::Type{Val{:user}}, args...)
return string("(::", join(string.(typeof.(args)), ", ::"), ")")
end
signature_string(::Type{Val{:type}}, T) = "(::Type{$T}, ::$T)"
signature_string(::Type{Val{:plot}}, st) = "(::Type{Val{:$st}}, ::AbstractPlot)"
signature_string(::Type{Val{:series}}, st) = "(::Type{Val{:$st}}, x, y, z)"
# ------------------------------------------------------------------
# preprocessing
function series_idx(kw_list::AVec{KW}, kw::AKW)
Int(kw[:series_plotindex]) - Int(kw_list[1][:series_plotindex]) + 1
end
function _expand_seriestype_array(plotattributes::AKW, args)
sts = get(plotattributes, :seriestype, :path)
if typeof(sts) <: AbstractArray
reset_kw!(plotattributes, :seriestype)
rd = Vector{RecipeData}(undef, size(sts, 1))
for r in axes(sts, 1)
dc = copy(plotattributes)
dc[:seriestype] = sts[r:r,:]
rd[r] = RecipeData(dc, args)
end
rd
else
RecipeData[RecipeData(copy(plotattributes), args)]
end
end
function _preprocess_args(plotattributes::AKW, args, still_to_process::Vector{RecipeData})
# the grouping mechanism is a recipe on a GroupBy object
# we simply add the GroupBy object to the front of the args list to allow
# the recipe to be applied
if haskey(plotattributes, :group)
args = (extractGroupArgs(plotattributes[:group], args...), args...)
end
# if we were passed a vector/matrix of seriestypes and there's more than one row,
# we want to duplicate the inputs, once for each seriestype row.
if !isempty(args)
append!(still_to_process, _expand_seriestype_array(plotattributes, args))
end
# remove subplot and axis args from plotattributes... they will be passed through in the kw_list
if !isempty(args)
for (k,v) in plotattributes
if k in _all_subplot_args || k in _all_axis_args
reset_kw!(plotattributes, k)
end
## Preprocessing attributes
function RecipesPipeline.preprocess_axis_args!(plt::Plot, plotattributes, letter)
# Fix letter for seriestypes that are x only but data gets passed as y
if treats_y_as_x(get(plotattributes, :seriestype, :path))
if get(plotattributes, :orientation, :vertical) == :vertical
letter = :x
end
end
args
plotattributes[:letter] = letter
RecipesPipeline.preprocess_axis_args!(plt, plotattributes)
end
# ------------------------------------------------------------------
# user recipes
RecipesPipeline.preprocess_attributes!(plt::Plot, plotattributes) =
RecipesPipeline.preprocess_attributes!(plotattributes) # in src/args.jl
RecipesPipeline.is_axis_attribute(plt::Plot, attr) = is_axis_attr_noletter(attr) # in src/args.jl
RecipesPipeline.is_subplot_attribute(plt::Plot, attr) = is_subplot_attr(attr) # in src/args.jl
function _process_userrecipes(plt::Plot, plotattributes::AKW, args)
still_to_process = RecipeData[]
args = _preprocess_args(plotattributes, args, still_to_process)
## User recipes
# for plotting recipes, swap out the args and update the parameter dictionary
# we are keeping a stack of series that still need to be processed.
# each pass through the loop, we pop one off and apply the recipe.
# the recipe will return a list a Series objects... the ones that are
# finished (no more args) get added to the kw_list, the ones that are not
# are placed on top of the stack and are then processed further.
kw_list = KW[]
while !isempty(still_to_process)
# grab the first in line to be processed and either add it to the kw_list or
# pass it through apply_recipe to generate a list of RecipeData objects (data + attributes)
# for further processing.
next_series = popfirst!(still_to_process)
# recipedata should be of type RecipeData. if it's not then the inputs must not have been fully processed by recipes
if !(typeof(next_series) <: RecipeData)
error("Inputs couldn't be processed... expected RecipeData but got: $next_series")
end
if isempty(next_series.args)
_process_userrecipe(plt, kw_list, next_series)
else
rd_list = RecipesBase.apply_recipe(
next_series.plotattributes,
next_series.args...
)
warn_on_recipe_aliases!(rd_list, :user, next_series.args...)
prepend!(still_to_process,rd_list)
end
end
# don't allow something else to handle it
plotattributes[:smooth] = false
kw_list
end
function _process_userrecipe(plt::Plot, kw_list::Vector{KW}, recipedata::RecipeData)
# when the arg tuple is empty, that means there's nothing left to recursively
# process... finish up and add to the kw_list
kw = recipedata.plotattributes
preprocessArgs!(kw)
function RecipesPipeline.process_userrecipe!(plt::Plot, kw_list, kw)
_preprocess_userrecipe(kw)
warnOnUnsupported_scales(plt.backend, kw)
warn_on_unsupported_scales(plt.backend, kw)
# add the plot index
plt.n += 1
kw[:series_plotindex] = plt.n
@@ -135,18 +81,17 @@ end
function _preprocess_userrecipe(kw::AKW)
_add_markershape(kw)
# if there was a grouping, filter the data here
_filter_input_data!(kw)
# map marker_z if it's a Function
if isa(get(kw, :marker_z, nothing), Function)
# TODO: should this take y and/or z as arguments?
kw[:marker_z] = isa(kw[:z], Nothing) ? map(kw[:marker_z], kw[:x], kw[:y]) : map(kw[:marker_z], kw[:x], kw[:y], kw[:z])
kw[:marker_z] = isa(kw[:z], Nothing) ? map(kw[:marker_z], kw[:x], kw[:y]) :
map(kw[:marker_z], kw[:x], kw[:y], kw[:z])
end
# map line_z if it's a Function
if isa(get(kw, :line_z, nothing), Function)
kw[:line_z] = isa(kw[:z], Nothing) ? map(kw[:line_z], kw[:x], kw[:y]) : map(kw[:line_z], kw[:x], kw[:y], kw[:z])
kw[:line_z] = isa(kw[:z], Nothing) ? map(kw[:line_z], kw[:x], kw[:y]) :
map(kw[:line_z], kw[:x], kw[:y], kw[:z])
end
# convert a ribbon into a fillrange
@@ -178,59 +123,58 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::AKW)
β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y)
sx = [ignorenan_minimum(x), ignorenan_maximum(x)]
sy = β .* sx .+ α
push!(kw_list, merge(copy(kw), KW(
:seriestype => :path,
:x => sx,
:y => sy,
:fillrange => nothing,
:label => "",
:primary => false,
)))
push!(
kw_list,
merge(
copy(kw),
KW(
:seriestype => :path,
:x => sx,
:y => sy,
:fillrange => nothing,
:label => "",
:primary => false,
),
),
)
end
end
# ------------------------------------------------------------------
# plot recipes
# Grab the first in line to be processed and pass it through apply_recipe
# to generate a list of RecipeData objects (data + attributes).
# If we applied a "plot recipe" without error, then add the returned datalist's KWs,
# otherwise we just add the original KW.
function _process_plotrecipe(plt::Plot, kw::AKW, kw_list::Vector{KW}, still_to_process::Vector{KW})
if !isa(get(kw, :seriestype, nothing), Symbol)
# seriestype was never set, or it's not a Symbol, so it can't be a plot recipe
push!(kw_list, kw)
return
end
try
st = kw[:seriestype]
st = kw[:seriestype] = get(_typeAliases, st, st)
datalist = RecipesBase.apply_recipe(kw, Val{st}, plt)
warn_on_recipe_aliases!(datalist, :plot, st)
for data in datalist
preprocessArgs!(data.plotattributes)
if data.plotattributes[:seriestype] == st
error("Plot recipe $st returned the same seriestype: $(data.plotattributes)")
end
push!(still_to_process, data.plotattributes)
end
catch err
if isa(err, MethodError)
push!(kw_list, kw)
else
rethrow()
RecipesPipeline.get_axis_limits(plt::Plot, letter) = axis_limits(plt[1], letter)
## Plot recipes
RecipesPipeline.type_alias(plt::Plot) = get(_typeAliases, st, st)
## Plot setup
function RecipesPipeline.plot_setup!(plt::Plot, plotattributes, kw_list)
_plot_setup(plt, plotattributes, kw_list)
_subplot_setup(plt, plotattributes, kw_list)
return nothing
end
function RecipesPipeline.process_sliced_series_attributes!(plt::Plots.Plot, kw_list)
# swap errors
err_inds = findall(kw -> get(kw, :seriestype, :path) in (:xerror, :yerror, :zerror), kw_list)
for ind in err_inds
if get(kw_list[ind-1],:seriestype,:path) == :scatter
tmp = copy(kw_list[ind])
kw_list[ind] = copy(kw_list[ind-1])
kw_list[ind-1] = tmp
end
end
return
return nothing
end
# ------------------------------------------------------------------
# setup plot and subplot
# TODO: Should some of this logic be moved to RecipesPipeline?
function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
# merge in anything meant for the Plot
for kw in kw_list, (k,v) in kw
for kw in kw_list, (k, v) in kw
haskey(_plot_defaults, k) && (plotattributes[k] = pop!(kw, k))
end
@@ -241,7 +185,7 @@ function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
# create the layout and subplots from the inputs
plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr)
for (idx,sp) in enumerate(plt.subplots)
for (idx, sp) in enumerate(plt.subplots)
sp.plt = plt
sp.attr[:subplot_index] = idx
end
@@ -266,7 +210,7 @@ function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
else
parent = plt.layout
end
sp = Subplot(backend(), parent=parent)
sp = Subplot(backend(), parent = parent)
sp.plt = plt
push!(plt.subplots, sp)
push!(plt.inset_subplots, sp)
@@ -282,28 +226,34 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
# Subplot/Axis attributes set by a user/series recipe apply only to the
# Subplot object which they belong to.
# TODO: allow matrices to still apply to all subplots
sp_attrs = Dict{Subplot,Any}()
sp_attrs = Dict{Subplot, Any}()
for kw in kw_list
# get the Subplot object to which the series belongs.
sps = get(kw, :subplot, :auto)
sp = get_subplot(plt, _cycle(sps == :auto ? plt.subplots : plt.subplots[sps], series_idx(kw_list,kw)))
sp = get_subplot(
plt,
_cycle(
sps == :auto ? plt.subplots : plt.subplots[sps],
series_idx(kw_list, kw),
),
)
kw[:subplot] = sp
# extract subplot/axis attributes from kw and add to sp_attr
attr = KW()
for (k,v) in collect(kw)
for (k, v) in collect(kw)
if is_subplot_attr(k) || is_axis_attr(k)
attr[k] = pop!(kw, k)
end
if is_axis_attr_noletter(k)
v = pop!(kw, k)
for letter in (:x,:y,:z)
attr[Symbol(letter,k)] = v
for letter in (:x, :y, :z)
attr[Symbol(letter, k)] = v
end
end
for k in (:scale,), letter in (:x,:y,:z)
for k in (:scale,), letter in (:x, :y, :z)
# Series recipes may need access to this information
lk = Symbol(letter,k)
lk = Symbol(letter, k)
if haskey(attr, lk)
kw[lk] = attr[lk]
end
@@ -313,7 +263,7 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
end
# override subplot/axis args. `sp_attrs` take precendence
for (idx,sp) in enumerate(plt.subplots)
for (idx, sp) in enumerate(plt.subplots)
attr = if !haskey(plotattributes, :subplot) || plotattributes[:subplot] == idx
merge(plotattributes, get(sp_attrs, sp, KW()))
else
@@ -326,9 +276,35 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
link_axes!(plt.layout, plt[:link])
end
function series_idx(kw_list::AVec{KW}, kw::AKW)
Int(kw[:series_plotindex]) - Int(kw_list[1][:series_plotindex]) + 1
end
## Series recipes
function RecipesPipeline.slice_series_attributes!(plt::Plot, kw_list, kw)
sp::Subplot = kw[:subplot]
# in series attributes given as vector with one element per series,
# select the value for current series
_slice_series_args!(kw, plt, sp, series_idx(kw_list, kw))
return nothing
end
RecipesPipeline.series_defaults(plt::Plot) = _series_defaults # in args.jl
RecipesPipeline.is_seriestype_supported(plt::Plot, st) = is_seriestype_supported(st)
function RecipesPipeline.add_series!(plt::Plot, plotattributes)
sp = _prepare_subplot(plt, plotattributes)
_expand_subplot_extrema(sp, plotattributes, plotattributes[:seriestype])
_update_series_attributes!(plotattributes, plt, sp)
_add_the_series(plt, sp, plotattributes)
end
# getting ready to add the series... last update to subplot from anything
# that might have been added during series recipes
function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where T
function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where {T}
st::Symbol = plotattributes[:seriestype]
sp::Subplot{T} = plotattributes[:subplot]
sp_idx = get_subplot_index(plt, sp)
@@ -337,7 +313,7 @@ function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where T
st = _override_seriestype_check(plotattributes, st)
# change to a 3d projection for this subplot?
if is3d(st)
if RecipesPipeline.needs_3d_axes(st) || (st == :quiver && plotattributes[:z] !== nothing)
sp.attr[:projection] = "3d"
end
@@ -349,14 +325,12 @@ function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where T
sp
end
# ------------------------------------------------------------------
# series types
function _override_seriestype_check(plotattributes::AKW, st::Symbol)
# do we want to override the series type?
if !is3d(st) && !(st in (:contour,:contour3d))
if !RecipesPipeline.is3d(st) && !(st in (:contour, :contour3d, :quiver))
z = plotattributes[:z]
if !isa(z, Nothing) && (size(plotattributes[:x]) == size(plotattributes[:y]) == size(z))
if z !== nothing &&
(size(plotattributes[:x]) == size(plotattributes[:y]) == size(z))
st = (st == :scatter ? :scatter3d : :path3d)
plotattributes[:seriestype] = st
end
@@ -364,30 +338,14 @@ function _override_seriestype_check(plotattributes::AKW, st::Symbol)
st
end
function _prepare_annotations(sp::Subplot, plotattributes::AKW)
# strip out series annotations (those which are based on series x/y coords)
# and add them to the subplot attr
sp_anns = annotations(sp[:annotations])
# series_anns = annotations(pop!(plotattributes, :series_annotations, []))
# if isa(series_anns, SeriesAnnotations)
# series_anns.x = plotattributes[:x]
# series_anns.y = plotattributes[:y]
# elseif length(series_anns) > 0
# x, y = plotattributes[:x], plotattributes[:y]
# nx, ny, na = map(length, (x,y,series_anns))
# n = max(nx, ny, na)
# series_anns = [(x[mod1(i,nx)], y[mod1(i,ny)], text(series_anns[mod1(i,na)])) for i=1:n]
# end
# sp.attr[:annotations] = vcat(sp_anns, series_anns)
end
function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
# adjust extrema and discrete info
if st == :image
xmin, xmax = ignorenan_extrema(plotattributes[:x]); ymin, ymax = ignorenan_extrema(plotattributes[:y])
xmin, xmax = ignorenan_extrema(plotattributes[:x])
ymin, ymax = ignorenan_extrema(plotattributes[:y])
expand_extrema!(sp[:xaxis], (xmin, xmax))
expand_extrema!(sp[:yaxis], (ymin, ymax))
elseif !(st in (:pie, :histogram, :bins2d, :histogram2d))
elseif !(st in (:histogram, :bins2d, :histogram2d))
expand_extrema!(sp, plotattributes)
end
# expand for zerolines (axes through origin)
@@ -398,56 +356,23 @@ function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
end
function _add_the_series(plt, sp, plotattributes)
warnOnUnsupported_args(plt.backend, plotattributes)
warnOnUnsupported(plt.backend, plotattributes)
extra_kwargs = warn_on_unsupported_args(plt.backend, plotattributes)
if (kw = plt[:extra_kwargs]) isa AbstractDict
plt[:extra_plot_kwargs] = get(kw,:plot,KW())
sp[:extra_kwargs] = get(kw,:subplot, KW())
plotattributes[:extra_kwargs] = get(kw,:series,KW())
elseif plt[:extra_kwargs] == :plot
plt[:extra_plot_kwargs] = extra_kwargs
elseif plt[:extra_kwargs] == :subplot
sp[:extra_kwargs] = extra_kwargs
elseif plt[:extra_kwargs] == :series
plotattributes[:extra_kwargs] = extra_kwargs
else
ArgumentError("Unsupported type for extra keyword arguments")
end
warn_on_unsupported(plt.backend, plotattributes)
series = Series(plotattributes)
push!(plt.series_list, series)
push!(sp.series_list, series)
_series_added(plt, series)
end
# -------------------------------------------------------------------------------
# this method recursively applies series recipes when the seriestype is not supported
# natively by the backend
function _process_seriesrecipe(plt::Plot, plotattributes::AKW)
#println("process $(typeof(plotattributes))")
# replace seriestype aliases
st = Symbol(plotattributes[:seriestype])
st = plotattributes[:seriestype] = get(_typeAliases, st, st)
# shapes shouldn't have fillrange set
if plotattributes[:seriestype] == :shape
plotattributes[:fillrange] = nothing
end
# if it's natively supported, finalize processing and pass along to the backend, otherwise recurse
if is_seriestype_supported(st)
sp = _prepare_subplot(plt, plotattributes)
_prepare_annotations(sp, plotattributes)
_expand_subplot_extrema(sp, plotattributes, st)
_update_series_attributes!(plotattributes, plt, sp)
_add_the_series(plt, sp, plotattributes)
else
# get a sub list of series for this seriestype
x, y, z = plotattributes[:x], plotattributes[:y], plotattributes[:z]
datalist = RecipesBase.apply_recipe(plotattributes, Val{st}, x, y, z)
warn_on_recipe_aliases!(datalist, :series, st)
# assuming there was no error, recursively apply the series recipes
for data in datalist
if isa(data, RecipeData)
preprocessArgs!(data.plotattributes)
if data.plotattributes[:seriestype] == st
error("The seriestype didn't change in series recipe $st. This will cause a StackOverflow.")
end
_process_seriesrecipe(plt, data.plotattributes)
else
@warn("Unhandled recipe: $(data)")
break
end
end
end
nothing
end
+16 -87
View File
@@ -43,13 +43,14 @@ The main plot command. Use `plot` to create a new plot object, and `plot!` to ad
There are lots of ways to pass in data, and lots of keyword arguments... just try it and it will likely work as expected.
When you pass in matrices, it splits by columns. To see the list of available attributes, use the `plotattr([attr])`
function, where `attr` is the symbol `:Series:`, `:Subplot:`, `:Plot` or `:Axis`. Pass any attribute to `plotattr`
as a String to look up its docstring; e.g. `plotattr("seriestype")`.
function, where `attr` is the symbol `:Series`, `:Subplot`, `:Plot`, or `:Axis`. Pass any attribute to `plotattr`
as a String to look up its docstring, e.g., `plotattr("seriestype")`.
"""
function plot(args...; kw...)
@nospecialize
# this creates a new plot with args/kw and sets it to be the current plot
plotattributes = KW(kw)
preprocessArgs!(plotattributes)
RecipesPipeline.preprocess_attributes!(plotattributes)
# create an empty Plot then process
plt = Plot()
@@ -60,8 +61,9 @@ end
# build a new plot from existing plots
# note: we split into plt1 and plts_tail so we can dispatch correctly
function plot(plt1::Plot, plts_tail::Plot...; kw...)
@nospecialize
plotattributes = KW(kw)
preprocessArgs!(plotattributes)
RecipesPipeline.preprocess_attributes!(plotattributes)
# build our plot vector from the args
n = length(plts_tail) + 1
@@ -140,7 +142,8 @@ end
# this adds to the current plot, or creates a new plot if none are current
function plot!(args...; kw...)
function plot!(args...; kw...)
@nospecialize
local plt
try
plt = current()
@@ -152,8 +155,9 @@ end
# this adds to a specific plot... most plot commands will flow through here
function plot!(plt::Plot, args...; kw...)
@nospecialize
plotattributes = KW(kw)
preprocessArgs!(plotattributes)
RecipesPipeline.preprocess_attributes!(plotattributes)
# merge!(plt.user_attr, plotattributes)
_plot!(plt, plotattributes, args)
end
@@ -163,87 +167,12 @@ end
# this is the core plotting function. recursively apply recipes to build
# a list of series KW dicts.
# note: at entry, we only have those preprocessed args which were passed in... no default values yet
function _plot!(plt::Plot, plotattributes::AKW, args::Tuple)
plotattributes[:plot_object] = plt
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 StatsPlots")
end
# --------------------------------
# "USER RECIPES"
# --------------------------------
kw_list = _process_userrecipes(plt, plotattributes, args)
# @info(1)
# map(DD, kw_list)
# --------------------------------
# "PLOT RECIPES"
# --------------------------------
# "plot recipe", which acts like a series type, and is processed before
# the plot layout is created, which allows for setting layouts and other plot-wide attributes.
# we get inputs which have been fully processed by "user recipes" and "type recipes",
# so we can expect standard vectors, surfaces, etc. No defaults have been set yet.
still_to_process = kw_list
kw_list = KW[]
while !isempty(still_to_process)
next_kw = popfirst!(still_to_process)
_process_plotrecipe(plt, next_kw, kw_list, still_to_process)
end
# @info(2)
# map(DD, kw_list)
# --------------------------------
# Plot/Subplot/Layout setup
# --------------------------------
_plot_setup(plt, plotattributes, kw_list)
_subplot_setup(plt, plotattributes, kw_list)
# !!! note: At this point, kw_list is fully decomposed into individual series... one KW per series. !!!
# !!! The next step is to recursively apply series recipes until the backend supports that series type !!!
# --------------------------------
# "SERIES RECIPES"
# --------------------------------
# @info(3)
# map(DD, kw_list)
for kw in kw_list
sp::Subplot = kw[:subplot]
# in series attributes given as vector with one element per series,
# select the value for current series
_slice_series_args!(kw, plt, sp, series_idx(kw_list,kw))
series_attr = Attr(kw, _series_defaults)
# now we have a fully specified series, with colors chosen. we must recursively handle
# series recipes, which dispatch on seriestype. If a backend does not natively support a seriestype,
# we check for a recipe that will convert that series type into one made up of lower-level components.
# For example, a histogram is just a bar plot with binned data, a bar plot is really a filled step plot,
# and a step plot is really just a path. So any backend that supports drawing a path will implicitly
# be able to support step, bar, and histogram plots (and any recipes that use those components).
_process_seriesrecipe(plt, series_attr)
end
# --------------------------------
function _plot!(plt::Plot, plotattributes, args)
@nospecialize
RecipesPipeline.recipe_pipeline!(plt, plotattributes, args)
current(plt)
# do we want to force display?
# if plt[:show]
# gui(plt)
# end
_do_plot_show(plt, plt[:show])
plt
return plt
end
@@ -281,12 +210,12 @@ end
# plot to a Subplot
function plot(sp::Subplot, args...; kw...)
@nospecialize
plt = sp.plt
plot(plt, args...; kw..., subplot = findfirst(isequal(sp), plt.subplots))
end
function plot!(sp::Subplot, args...; kw...)
@nospecialize
plt = sp.plt
plot!(plt, args...; kw..., subplot = findfirst(isequal(sp), plt.subplots))
end
# --------------------------------------------------------------------
-1119
View File
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
should_precompile = true
# Don't edit the following! Instead change the script for `snoop_bot`.
ismultios = false
ismultiversion = false
# precompile_enclosure
@static if !should_precompile
# nothing
elseif !ismultios && !ismultiversion
@static if isfile(joinpath(
@__DIR__,
"../deps/SnoopCompile/precompile/precompile_Plots.jl",
))
include("../deps/SnoopCompile/precompile/precompile_Plots.jl")
_precompile_()
end
else
end # precompile_enclosure
+409 -133
View File
@@ -71,12 +71,15 @@ const POTENTIAL_VECTOR_ARGUMENTS = [
:marker_z,
:markerstrokecolor,
:markerstrokealpha,
:xerror,
:yerror,
:yerror,
:zerror,
:series_annotations,
:fillrange,
]
@nospecialize
@recipe function f(::Type{Val{:line}}, x, y, z)
indices = sortperm(x)
x := x[indices]
@@ -111,7 +114,7 @@ end
@recipe function f(::Type{Val{:hline}}, x, y, z)
n = length(y)
newx = repeat(Float64[-1, 1, NaN], n)
newx = repeat(Float64[1, 2, NaN], n)
newy = vec(Float64[yi for i = 1:3, yi in y])
x := newx
y := newy
@@ -123,9 +126,8 @@ end
@recipe function f(::Type{Val{:vline}}, x, y, z)
n = length(y)
newx = vec(Float64[yi for i = 1:3, yi in y])
newy = repeat(Float64[-1, 1, NaN], n)
x := newx
y := newy
y := repeat(Float64[1, 2, NaN], n)
seriestype := :straightline
()
end
@@ -163,45 +165,81 @@ end
x := x
y := y
seriestype := :scatter
@series begin
()
end
@series begin
seriestype := :path
label := ""
primary := false
()
end
primary := false
()
end
@deps scatterpath path scatter
# ---------------------------------------------------------------------------
# regression line and scatter
# plots line corresponding to linear regression of y on a constant and x
@recipe function f(::Type{Val{:linearfit}}, x, y, z)
x := x
y := y
seriestype := :scatter
@series begin
()
end
@series begin
y := mean(y) .+ cov(x, y) / var(x) .* (x .- mean(x))
seriestype := :path
label := ""
primary := false
()
end
primary := false
()
end
@specialize
# ---------------------------------------------------------------------------
# steps
make_steps(x, st) = x
function make_steps(x::AbstractArray, st)
make_steps(x, st, even) = x
function make_steps(x::AbstractArray, st, even)
n = length(x)
n == 0 && return zeros(0)
newx = zeros(2n - 1)
for i = 1:n
newx = zeros(2n - (even ? 0 : 1))
newx[1] = x[1]
for i = 2:n
idx = 2i - 1
newx[idx] = x[i]
if i > 1
if st == :mid
newx[idx] = newx[idx-1] = (x[i] + x[i-1]) / 2
else
newx[idx] = x[i]
newx[idx - 1] = x[st == :pre ? i : i - 1]
end
end
even && (newx[end] = x[end])
return newx
end
make_steps(t::Tuple, st) = Tuple(make_steps(ti, st) for ti in t)
make_steps(t::Tuple, st, even) = Tuple(make_steps(ti, st, even) for ti in t)
@nospecialize
# create a path from steps
@recipe function f(::Type{Val{:steppre}}, x, y, z)
plotattributes[:x] = make_steps(x, :post)
plotattributes[:y] = make_steps(y, :pre)
plotattributes[:x] = make_steps(x, :post, false)
plotattributes[:y] = make_steps(y, :pre, false)
seriestype := :path
# handle fillrange
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :pre)
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :pre, false)
# create a secondary series for the markers
if plotattributes[:markershape] != :none
@@ -220,13 +258,38 @@ end
@deps steppre path scatter
# create a path from steps
@recipe function f(::Type{Val{:steppost}}, x, y, z)
plotattributes[:x] = make_steps(x, :pre)
plotattributes[:y] = make_steps(y, :post)
@recipe function f(::Type{Val{:stepmid}}, x, y, z)
plotattributes[:x] = make_steps(x, :mid, true)
plotattributes[:y] = make_steps(y, :post, true)
seriestype := :path
# handle fillrange
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post)
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post, true)
# create a secondary series for the markers
if plotattributes[:markershape] != :none
@series begin
seriestype := :scatter
x := x
y := y
label := ""
primary := false
()
end
markershape := :none
end
()
end
@deps stepmid path scatter
# create a path from steps
@recipe function f(::Type{Val{:steppost}}, x, y, z)
plotattributes[:x] = make_steps(x, :pre, false)
plotattributes[:y] = make_steps(y, :post, false)
seriestype := :path
# handle fillrange
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post, false)
# create a secondary series for the markers
if plotattributes[:markershape] != :none
@@ -262,24 +325,39 @@ end
end
end
newx, newy = zeros(3n), zeros(3n)
for i = 1:n
newz = z !== nothing ? zeros(3n) : nothing
for (i, (xi, yi, zi)) = enumerate(zip(x, y, z !== nothing ? z : 1:n))
rng = (3i - 2):(3i)
newx[rng] = [x[i], x[i], NaN]
newy[rng] = [_cycle(fr, i), y[i], NaN]
newx[rng] = [xi, xi, NaN]
if z !== nothing
newy[rng] = [yi, yi, NaN]
newz[rng] = [_cycle(fr, i), zi, NaN]
else
newy[rng] = [_cycle(fr, i), yi, NaN]
end
end
x := newx
y := newy
if z !== nothing
z := newz
end
fillrange := nothing
seriestype := :path
if plotattributes[:linecolor] == :auto && plotattributes[:marker_z] !== nothing && plotattributes[:line_z] === nothing
line_z := plotattributes[:marker_z]
end
# create a secondary series for the markers
# create a primary series for the markers
if plotattributes[:markershape] != :none
primary := false
@series begin
seriestype := :scatter
x := x
y := y
label := ""
primary := false
if z !== nothing
z := z
end
primary := true
()
end
markershape := :none
@@ -288,6 +366,8 @@ end
end
@deps sticks path scatter
@specialize
# ---------------------------------------------------------------------------
# bezier curves
@@ -302,6 +382,8 @@ function bezier_value(pts::AVec, t::Real)
val
end
@nospecialize
# 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)
@@ -373,7 +455,7 @@ end
bw = plotattributes[:bar_width]
hw = if bw === nothing
if nx > 1
0.5 * _bar_width * ignorenan_minimum(filter(x -> x > 0, diff(procx)))
0.5 * _bar_width * ignorenan_minimum(filter(x -> x > 0, diff(sort(procx))))
else
0.5 * _bar_width
end
@@ -390,6 +472,15 @@ end
fillto = map(x -> _is_positive(x) ? typeof(baseline)(x) : baseline, fillto)
end
if !isnothing(plotattributes[:series_annotations])
if isvertical(plotattributes)
annotations := (x,y,plotattributes[:series_annotations].strs,:bottom)
else
annotations := (y,x,plotattributes[:series_annotations].strs,:left)
end
series_annotations := nothing
end
# create the bar shapes by adding x/y segments
xseg, yseg = Segments(), Segments()
for i = 1:ny
@@ -458,6 +549,11 @@ end
end
@deps plots_heatmap shape
@specialize
is_3d(::Type{Val{:plots_heatmap}}) = true
RecipesPipeline.is_surface(::Type{Val{:plots_heatmap}}) = true
RecipesPipeline.is_surface(::Type{Val{:hexbin}}) = true
# ---------------------------------------------------------------------------
# Histograms
@@ -518,6 +614,8 @@ function _preprocess_binlike(plotattributes, x, y)
end
@nospecialize
@recipe function f(::Type{Val{:barbins}}, x, y, z)
edge, weights, xscale, yscale, baseline =
_preprocess_binlike(plotattributes, x, y)
@@ -535,14 +633,21 @@ end
@recipe function f(::Type{Val{:scatterbins}}, x, y, z)
edge, weights, xscale, yscale, baseline =
_preprocess_binlike(plotattributes, x, y)
xerror := diff(edge) / 2
@series begin
x := _bin_centers(edge)
xerror := diff(edge) / 2
primary := false
seriestype := :xerror
()
end
x := _bin_centers(edge)
y := weights
seriestype := :scatter
()
end
@deps scatterbins scatter
@deps scatterbins xerror scatter
@specialize
function _stepbins_path(
edge,
@@ -610,8 +715,8 @@ function _stepbins_path(
(x, y)
end
@recipe function f(::Type{Val{:stepbins}}, x, y, z)
@nospecialize
axis =
plotattributes[:subplot][Plots.isvertical(plotattributes) ? :xaxis : :yaxis]
@@ -748,6 +853,7 @@ function _make_hist(
normalize!(h, mode = _hist_norm_mode(normed))
end
@nospecialize
@recipe function f(::Type{Val{:histogram}}, x, y, z)
seriestype := length(y) > 1e6 ? :stephist : :barhist
@@ -757,7 +863,7 @@ end
@recipe function f(::Type{Val{:barhist}}, x, y, z)
h = _make_hist(
(y,),
tuple(y),
plotattributes[:bins],
normed = plotattributes[:normalize],
weights = plotattributes[:weights],
@@ -771,7 +877,7 @@ end
@recipe function f(::Type{Val{:stephist}}, x, y, z)
h = _make_hist(
(y,),
tuple(y),
plotattributes[:bins],
normed = plotattributes[:normalize],
weights = plotattributes[:weights],
@@ -785,7 +891,7 @@ end
@recipe function f(::Type{Val{:scatterhist}}, x, y, z)
h = _make_hist(
(y,),
tuple(y),
plotattributes[:bins],
normed = plotattributes[:normalize],
weights = plotattributes[:weights],
@@ -852,9 +958,7 @@ end
x := Plots._bin_centers(edge_x)
y := Plots._bin_centers(edge_y)
z := Surface(float_weights)
match_dimensions := true
z := Surface(permutedims(float_weights))
seriestype := :heatmap
()
end
@@ -883,6 +987,41 @@ end
end
# ---------------------------------------------------------------------------
# pie
@recipe function f(::Type{Val{:pie}}, x, y, z)
framestyle --> :none
aspect_ratio --> true
s = sum(y)
θ = 0
for i in eachindex(y)
θ_new = θ + 2π * y[i] / s
coords = [(0.0, 0.0); partialcircle(θ, θ_new, 50)]
@series begin
seriestype := :shape
label --> string(x[i])
x := first.(coords)
y := last.(coords)
end
θ = θ_new
end
end
@deps pie shape
# ---------------------------------------------------------------------------
# mesh 3d replacement for non-plotly backends
@recipe function f(::Type{Val{:mesh3d}}, x, y, z)
# As long as no i,j,k are supplied this should work with PyPlot and GR
seriestype := :surface
if plotattributes[:connections] !== nothing
throw(ArgumentError("Giving triangles using the connections argument is only supported on Plotly backend."))
end
()
end
# ---------------------------------------------------------------------------
# scatter 3d
@@ -898,7 +1037,6 @@ end
# note: don't add dependencies because this really isn't a drop-in replacement
# ---------------------------------------------------------------------------
# lens! - magnify a region of a plot
lens!(args...;kwargs...) = plot!(args...; seriestype=:lens, kwargs...)
@@ -920,8 +1058,12 @@ export lens!
lens_index = last(plt.subplots)[:subplot_index] + 1
x1, x2 = plotattributes[:x]
y1, y2 = plotattributes[:y]
backup = copy(plotattributes)
empty!(plotattributes)
series_plotindex := backup[:series_plotindex]
seriestype := :path
label := ""
primary := false
linecolor := :lightgray
bbx_mag = (x1 + x2) / 2
bby_mag = (y1 + y2) / 2
@@ -931,6 +1073,7 @@ export lens!
if xl1 < xi_lens < xl2 &&
yl1 < yi_lens < yl2
@series begin
primary := false
subplot := sp_index
x := [xi_mag, xi_lens]
y := [yi_mag, yi_lens]
@@ -939,6 +1082,7 @@ export lens!
end
# add magnification shape
@series begin
primary := false
subplot := sp_index
x := [x1, x1, x2, x2, x1]
y := [y1, y2, y2, y1, y1]
@@ -947,20 +1091,19 @@ export lens!
# add subplot
for series in sp.series_list
@series begin
plotattributes = merge(plotattributes, copy(series.plotattributes))
plotattributes = merge(backup, copy(series.plotattributes))
subplot := lens_index
label := ""
primary := false
xlims := (x1, x2)
ylims := (y1, y2)
()
end
end
backup = copy(plotattributes)
empty!(plotattributes)
seriestype := :path
series_plotindex := backup[:series_plotindex]
nothing
end
@specialize
function intersection_point(xA, yA, xB, yB, h, w)
s = (yA - yB) / (xA - xB)
hh = h / 2
@@ -988,6 +1131,7 @@ end
# contourf - filled contours
@recipe function f(::Type{Val{:contourf}}, x, y, z)
@nospecialize
fillrange := true
seriestype := :contour
()
@@ -997,8 +1141,24 @@ end
# Error Bars
function error_style!(plotattributes::AKW)
msc = plotattributes[:markerstrokecolor]
msc = if msc === :match
plotattributes[:subplot][:foreground_color_subplot]
elseif msc === :auto
get_series_color(
plotattributes[:linecolor],
plotattributes[:subplot],
plotattributes[:series_plotindex],
plotattributes[:seriestype],
)
else
msc
end
plotattributes[:seriestype] = :path
plotattributes[:linecolor] = plotattributes[:markerstrokecolor]
plotattributes[:markerstrokecolor] = msc
plotattributes[:markercolor] = msc
plotattributes[:linecolor] = msc
plotattributes[:linewidth] = plotattributes[:markerstrokewidth]
plotattributes[:label] = ""
end
@@ -1017,7 +1177,7 @@ error_tuple(x::Tuple) = x
function error_coords(errorbar, errordata, otherdata...)
ed = Vector{float_extended_type(errordata)}(undef, 0)
od = [Float64[] for _ in otherdata]
od = [Vector{float_extended_type(odi)}(undef, 0) for odi in otherdata]
for (i, edi) in enumerate(errordata)
for (j, odj) in enumerate(otherdata)
odi = _cycle(odj, i)
@@ -1029,9 +1189,17 @@ function error_coords(errorbar, errordata, otherdata...)
return (ed, od...)
end
# clamp non-NaN values in an array to Base.eps(Float64) for log-scale plots
function clamp_to_eps!(ary)
replace!(x -> x <= 0.0 ? Base.eps(Float64) : x, ary)
nothing
end
# we will create a series of path segments, where each point represents one
# side of an errorbar
@nospecialize
@recipe function f(::Type{Val{:xerror}}, x, y, z)
error_style!(plotattributes)
markershape := :vline
@@ -1042,6 +1210,9 @@ end
plotattributes[:x], plotattributes[:y], plotattributes[:z] =
error_coords(xerr, x, y, z)
end
if :xscale keys(plotattributes) && plotattributes[:xscale] == :log10
clamp_to_eps!(plotattributes[:x])
end
()
end
@deps xerror path
@@ -1056,6 +1227,9 @@ end
plotattributes[:y], plotattributes[:x], plotattributes[:z] =
error_coords(yerr, y, x, z)
end
if :yscale keys(plotattributes) && plotattributes[:yscale] == :log10
clamp_to_eps!(plotattributes[:y])
end
()
end
@deps yerror path
@@ -1068,10 +1242,14 @@ end
plotattributes[:z], plotattributes[:x], plotattributes[:y] =
error_coords(zerr, z, x, y)
end
if :zscale keys(plotattributes) && plotattributes[:zscale] == :log10
clamp_to_eps!(plotattributes[:z])
end
()
end
@deps xerror path
@deps zerror path
@specialize
# TODO: move quiver to PlotRecipes
@@ -1085,35 +1263,51 @@ function quiver_using_arrows(plotattributes::AKW)
if !isa(plotattributes[:arrow], Arrow)
plotattributes[:arrow] = arrow()
end
is_3d = haskey(plotattributes,:z) && !isnothing(plotattributes[:z])
velocity = error_zipit(plotattributes[:quiver])
xorig, yorig = plotattributes[:x], plotattributes[:y]
zorig = is_3d ? plotattributes[:z] : []
# for each point, we create an arrow of velocity vi, translated to the x/y coordinates
x, y = zeros(0), zeros(0)
for i = 1:max(length(xorig), length(yorig))
is_3d && ( z = zeros(0))
for i = 1:max(length(xorig), length(yorig), is_3d ? 0 : length(zorig))
# get the starting position
xi = _cycle(xorig, i)
yi = _cycle(yorig, i)
zi = is_3d ? _cycle(zorig, i) : 0
# get the velocity
vi = _cycle(velocity, i)
vx, vy = if istuple(vi)
first(vi), last(vi)
elseif isscalar(vi)
vi, vi
elseif isa(vi, Function)
vi(xi, yi)
else
error("unexpected vi type $(typeof(vi)) for quiver: $vi")
if is_3d
vx, vy, vz = if istuple(vi)
vi[1], vi[2], vi[3]
elseif isscalar(vi)
vi, vi, vi
elseif isa(vi, Function)
vi(xi, yi, zi)
else
error("unexpected vi type $(typeof(vi)) for quiver: $vi")
end
else # 2D quiver
vx, vy = if istuple(vi)
first(vi), last(vi)
elseif isscalar(vi)
vi, vi
elseif isa(vi, Function)
vi(xi, yi)
else
error("unexpected vi type $(typeof(vi)) for quiver: $vi")
end
end
# add the points
nanappend!(x, [xi, xi + vx, NaN])
nanappend!(y, [yi, yi + vy, NaN])
is_3d && nanappend!(z, [zi, zi + vz, NaN])
end
plotattributes[:x], plotattributes[:y] = x, y
if is_3d
plotattributes[:z] = z
end
# KW[plotattributes]
end
@@ -1162,12 +1356,13 @@ function quiver_using_hack(plotattributes::AKW)
)
end
plotattributes[:x], plotattributes[:y] = Plots.unzip(pts[2:end])
plotattributes[:x], plotattributes[:y] = RecipesPipeline.unzip(pts[2:end])
# KW[plotattributes]
end
# function apply_series_recipe(plotattributes::AKW, ::Type{Val{:quiver}})
@recipe function f(::Type{Val{:quiver}}, x, y, z)
@nospecialize
if :arrow in supported_attrs()
quiver_using_arrows(plotattributes)
else
@@ -1178,6 +1373,131 @@ end
@deps quiver shape path
# --------------------------------------------------------------------
# 1 argument
# --------------------------------------------------------------------
# images - grays
function clamp_greys!(mat::AMat{<: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{<:Gray})
n, m = axes(mat)
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, m, n, Surface(clamp_greys!(mat))
else
seriestype := :heatmap
yflip --> true
colorbar --> false
fillcolor --> cgrad([:black, :white])
SliceIt, m, n, Surface(clamp!(convert(Matrix{Float64}, mat), 0.0, 1.0))
end
end
@nospecialize
# images - colors
@recipe function f(mat::AMat{T}) where {T <: Colorant}
n, m = axes(mat)
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, m, n, Surface(mat)
else
seriestype := :heatmap
yflip --> true
colorbar --> false
aspect_ratio --> :equal
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, m, n, Surface(z)
end
end
# plotting arbitrary shapes/polygons
@recipe function f(shape::Shape)
seriestype --> :shape
coords(shape)
end
@recipe function f(shapes::AVec{<:Shape})
seriestype --> :shape
# For backwards compatibility, column vectors of segmenting attributes are
# interpreted as having one element per shape
for attr in union(_segmenting_array_attributes, _segmenting_vector_attributes)
v = get(plotattributes, attr, nothing)
if v isa AVec || v isa AMat && size(v,2) == 1
@warn "Column vector attribute `$attr` reinterpreted as row vector (one value per shape).\n" *
"Pass a row vector instead (e.g. using `permutedims`) to suppress this warning."
plotattributes[attr] = permutedims(v)
end
end
coords(shapes)
end
@recipe function f(shapes::AMat{<:Shape})
seriestype --> :shape
for j in axes(shapes, 2)
@series coords(vec(shapes[:, j]))
end
end
# --------------------------------------------------------------------
# 3 arguments
# --------------------------------------------------------------------
# images - grays
@recipe function f(x::AVec, y::AVec, mat::AMat{T}) where {T <: Gray}
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, x, y, Surface(mat)
else
seriestype := :heatmap
yflip --> true
colorbar --> false
fillcolor --> cgrad([:black, :white])
SliceIt, x, y, Surface(convert(Matrix{Float64}, mat))
end
end
# images - colors
@recipe function f(x::AVec, y::AVec, mat::AMat{T}) where {T <: Colorant}
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, x, y, Surface(mat)
else
seriestype := :heatmap
yflip --> true
colorbar --> false
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, x, y, Surface(z)
end
end
# --------------------------------------------------------------------
# Lists of tuples and GeometryBasics.Points
# --------------------------------------------------------------------
@recipe f(v::AVec{<:GeometryBasics.Point}) = RecipesPipeline.unzip(v)
@recipe f(p::GeometryBasics.Point) = [p]
# 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] :
RecipesPipeline.unzip(xyuv)
@specialize
# -------------------------------------------------
# TODO: move OHLC to PlotRecipes finance.jl
@@ -1216,6 +1536,8 @@ end
# TODO: when I allow `@recipe f(::Type{T}, v::T) = ...` definitions to replace convertToAnyVector,
# then I should replace these with one definition to convert to a vector of 4-tuples
@nospecialize
# to squash ambiguity warnings...
@recipe f(x::AVec{Function}, v::AVec{OHLC}) = error()
@recipe f(
@@ -1273,17 +1595,17 @@ end
@recipe function f(::Type{Val{:spy}}, x, y, z)
yflip := true
aspect_ratio := 1
rs, cs, zs = findnz(z.surf)
xlims := ignorenan_extrema(cs)
ylims := ignorenan_extrema(rs)
if plotattributes[:markershape] == :none
markershape := :circle
end
if plotattributes[:markersize] == default(:markersize)
markersize := 1
end
rs, cs, zs = Plots.findnz(z.surf)
xlims := widen(ignorenan_extrema(cs)..., get(plotattributes, :xscale, :identity))
ylims := widen(ignorenan_extrema(rs)..., get(plotattributes, :yscale, :identity))
markershape --> :circle
markersize --> 1
markerstrokewidth := 0
marker_z := zs
if length(unique(zs)) == 1
seriescolor --> :black
else
marker_z := zs
end
label := ""
x := cs
y := rs
@@ -1293,34 +1615,30 @@ end
()
end
@specialize
Plots.findnz(A::AbstractSparseMatrix) = SparseArrays.findnz(A)
# fallback function for finding non-zero elements of non-sparse matrices
function Plots.findnz(A::AbstractMatrix)
keysnz = findall(!iszero, A)
rs = [k[1] for k in keysnz]
cs = [k[2] for k in keysnz]
zs = A[keysnz]
rs, cs, zs
end
# -------------------------------------------------
@nospecialize
"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...)
# -------------------------------------------------
# Dates & Times
dateformatter(dt) = string(Date(Dates.UTD(dt)))
datetimeformatter(dt) = string(DateTime(Dates.UTM(dt)))
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
@@ -1340,50 +1658,6 @@ end
end
# --------------------------------------------------
# Color Gradients
@userplot ShowLibrary
@recipe function f(cl::ShowLibrary)
if !(length(cl.args) == 1 && isa(cl.args[1], Symbol))
error("showlibrary takes the name of a color library as a Symbol")
end
library = PlotUtils.color_libraries[cl.args[1]]
z = sqrt.((1:15) * reshape(1:20, 1, :))
seriestype := :heatmap
ticks := nothing
legend := false
layout --> length(library.lib)
i = 0
for grad in sort(collect(keys(library.lib)))
@series begin
seriescolor := cgrad(grad, cl.args[1])
title := string(grad)
subplot := i += 1
z
end
end
end
@userplot ShowGradient
@recipe function f(grad::ShowGradient)
if !(length(grad.args) == 1 && isa(grad.args[1], Symbol))
error("showgradient takes the name of a color gradient as a Symbol")
end
z = sqrt.((1:15) * reshape(1:20, 1, :))
seriestype := :heatmap
ticks := nothing
legend := false
seriescolor := grad.args[1]
title := string(grad.args[1])
z
end
# Moved in from PlotRecipes - see: http://stackoverflow.com/a/37732384/5075246
@userplot PortfolioComposition
@@ -1428,3 +1702,5 @@ julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], f
end
end
end
@specialize
-659
View File
@@ -1,659 +0,0 @@
# create a new "build_series_args" which converts all inputs into xs = Any[xitems], ys = Any[yitems].
# Special handling for: no args, xmin/xmax, parametric, dataframes
# Then once inputs have been converted, build the series args, map functions, etc.
# This should cut down on boilerplate code and allow more focused dispatch on type
# 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}
prepareSeriesData(x) = error("Cannot convert $(typeof(x)) to series data for plotting")
prepareSeriesData(::Nothing) = nothing
prepareSeriesData(t::Tuple{T, T}) where {T<:Number} = t
prepareSeriesData(f::Function) = f
prepareSeriesData(ar::AbstractRange{<:Number}) = ar
function prepareSeriesData(a::AbstractArray{<:MaybeNumber})
f = isimmutable(a) ? replace : replace!
a = f(x -> ismissing(x) || isinf(x) ? NaN : x, map(float, a))
end
prepareSeriesData(a::AbstractArray{<:Missing}) = fill(NaN, axes(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)
# default: assume x represents a single series
series_vector(x, plotattributes) = [prepareSeriesData(x)]
# fixed number of blank series
series_vector(n::Integer, plotattributes) = [zeros(0) for i in 1:n]
# vector of data points is a single series
series_vector(v::AVec{<:DataPoint}, plotattributes) = [prepareSeriesData(v)]
# list of things (maybe other vectors, functions, or something else)
function series_vector(v::AVec, plotattributes)
if all(x -> x isa MaybeNumber, v)
series_vector(Vector{MaybeNumber}(v), plotattributes)
elseif all(x -> x isa MaybeString, v)
series_vector(Vector{MaybeString}(v), plotattributes)
else
vcat((series_vector(vi, plotattributes) for vi in v)...)
end
end
# Matrix is split into columns
function series_vector(v::AMat{<:DataPoint}, plotattributes)
if all3D(plotattributes)
[prepareSeriesData(Surface(v))]
else
[prepareSeriesData(v[:, i]) for i in axes(v, 2)]
end
end
# --------------------------------------------------------------------
# Fillranges & ribbons
process_fillrange(range::Number, plotattributes) = [range]
process_fillrange(range, plotattributes) = series_vector(range, plotattributes)
process_ribbon(ribbon::Number, plotattributes) = [ribbon]
process_ribbon(ribbon, plotattributes) = series_vector(ribbon, plotattributes)
# ribbon as a tuple: (lower_ribbons, upper_ribbons)
process_ribbon(ribbon::Tuple{S, T}, plotattributes) where {S, T} = collect(zip(
series_vector(ribbon[1], plotattributes),
series_vector(ribbon[2], plotattributes),
))
# --------------------------------------------------------------------
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) = x
compute_y(x::Nothing, y::Nothing, z) = axes(z,2)
compute_y(x, y::Function, z) = map(y, x)
compute_y(x, y, z) = y
compute_z(x, y, z::Function) = map(z, x, y)
compute_z(x, y, z::AbstractMatrix) = Surface(z)
compute_z(x, y, z::Nothing) = nothing
compute_z(x, y, z) = z
nobigs(v::AVec{BigFloat}) = map(Float64, v)
nobigs(v::AVec{BigInt}) = map(Int64, v)
nobigs(v) = v
@noinline function compute_xyz(x, y, z)
x = compute_x(x,y,z)
y = compute_y(x,y,z)
z = compute_z(x,y,z)
nobigs(x), nobigs(y), nobigs(z)
end
# not allowed
compute_xyz(x::Nothing, y::FuncOrFuncs{F}, z) where {F<:Function} = error("If you want to plot the function `$y`, you need to define the x values!")
compute_xyz(x::Nothing, y::Nothing, z::FuncOrFuncs{F}) where {F<:Function} = error("If you want to plot the function `$z`, you need to define x and y values!")
compute_xyz(x::Nothing, y::Nothing, z::Nothing) = error("x/y/z are all nothing!")
# --------------------------------------------------------------------
# we are going to build recipes to do the processing and splitting of the args
# --------------------------------------------------------------------
# The catch-all SliceIt recipe
# --------------------------------------------------------------------
# ensure we dispatch to the slicer
struct SliceIt end
# The `SliceIt` recipe finishes user and type recipe processing.
# It splits processed data into individual series data, stores in copied `plotattributes`
# for each series and returns no arguments.
@recipe function f(::Type{SliceIt}, x, y, z)
# handle data with formatting attached
if typeof(x) <: Formatted
xformatter := x.formatter
x = x.data
end
if typeof(y) <: Formatted
yformatter := y.formatter
y = y.data
end
if typeof(z) <: Formatted
zformatter := z.formatter
z = z.data
end
xs = series_vector(x, plotattributes)
ys = series_vector(y, plotattributes)
zs = series_vector(z, plotattributes)
fr = pop!(plotattributes, :fillrange, nothing)
fillranges = process_fillrange(fr, plotattributes)
mf = length(fillranges)
rib = pop!(plotattributes, :ribbon, nothing)
ribbons = process_ribbon(rib, plotattributes)
mr = length(ribbons)
mx = length(xs)
my = length(ys)
mz = length(zs)
if mx > 0 && my > 0 && mz > 0
for i in 1:max(mx, my, mz)
# add a new series
di = copy(plotattributes)
xi, yi, zi = xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)]
di[:x], di[:y], di[:z] = compute_xyz(xi, yi, zi)
# handle fillrange
fr = fillranges[mod1(i,mf)]
di[:fillrange] = isa(fr, Function) ? map(fr, di[:x]) : fr
# handle ribbons
rib = ribbons[mod1(i,mr)]
di[:ribbon] = isa(rib, Function) ? map(rib, di[:x]) : rib
push!(series_list, RecipeData(di, ()))
end
end
nothing # don't add a series for the main block
end
# --------------------------------------------------------------------
# Apply type recipes
# --------------------------------------------------------------------
# this is the default "type recipe"... just pass the object through
@recipe f(::Type{T}, v::T) where T = v
# this should catch unhandled "series recipes" and error with a nice message
@recipe f(::Type{V}, x, y, z) where {V<:Val} = error("The backend must not support the series type $V, and there isn't a series recipe defined.")
function _apply_type_recipe(plotattributes, v, letter)
_preprocess_axis_args!(plotattributes, letter)
rdvec = RecipesBase.apply_recipe(plotattributes, typeof(v), v)
warn_on_recipe_aliases!(plotattributes, :type, typeof(v))
_postprocess_axis_args!(plotattributes, letter)
return rdvec[1].args[1]
end
# Handle type recipes when the recipe is defined on the elements.
# 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, letter)
_preprocess_axis_args!(plotattributes, letter)
# First we try to apply an array type recipe.
w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1]
warn_on_recipe_aliases!(plotattributes, :type, typeof(v))
# If the type did not change try it element-wise
if typeof(v) == typeof(w)
isempty(skipmissing(v)) && return Float64[]
x = first(skipmissing(v))
args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args
warn_on_recipe_aliases!(plotattributes, :type, typeof(x))
_postprocess_axis_args!(plotattributes, letter)
if length(args) == 2 && all(arg -> arg isa Function, args)
numfunc, formatter = args
return Formatted(map(numfunc, v), formatter)
else
return v
end
end
_postprocess_axis_args!(plotattributes, letter)
return w
end
# special handling for Surface... need to properly unwrap and re-wrap
_apply_type_recipe(
plotattributes,
v::Surface{<:AMat{<:Union{AbstractFloat, Integer, AbstractString, Missing}}},
letter,
) = v
function _apply_type_recipe(plotattributes, v::Surface, letter)
ret = _apply_type_recipe(plotattributes, v.surf, letter)
if typeof(ret) <: Formatted
Formatted(Surface(ret.data), ret.formatter)
else
Surface(ret)
end
end
# don't do anything vectors of datapoints and for nothing
_apply_type_recipe(plotattributes, v::Nothing, letter) = v
_apply_type_recipe(
plotattributes,
v::AbstractArray{<:Union{AbstractFloat, Integer, AbstractString, Missing}},
letter,
) = v
# axis args before type recipes should still be mapped to all axes
function _preprocess_axis_args!(plotattributes)
for (k, v) in plotattributes
if is_axis_attr_noletter(k)
pop!(plotattributes, k)
for l in (:x, :y, :z)
lk = Symbol(l, k)
haskey(plotattributes, lk) || (plotattributes[lk] = v)
end
end
end
end
function _preprocess_axis_args!(plotattributes, letter)
plotattributes[:letter] = letter
_preprocess_axis_args!(plotattributes)
end
# axis args in type recipes should only be applied to the current axis
function _postprocess_axis_args!(plotattributes, letter)
pop!(plotattributes, :letter)
if letter in (:x, :y, :z)
for (k, v) in plotattributes
if is_axis_attr_noletter(k)
pop!(plotattributes, k)
lk = Symbol(letter, k)
haskey(plotattributes, lk) || (plotattributes[lk] = v)
end
end
end
end
# --------------------------------------------------------------------
# Fallback user recipes calling type recipes
# --------------------------------------------------------------------
# handle "type recipes" by converting inputs, and then either re-calling or slicing
@recipe function f(x, y, z)
wrap_surfaces!(plotattributes, x, y, z)
did_replace = false
newx = _apply_type_recipe(plotattributes, x, :x)
x === newx || (did_replace = true)
newy = _apply_type_recipe(plotattributes, y, :y)
y === newy || (did_replace = true)
newz = _apply_type_recipe(plotattributes, z, :z)
z === newz || (did_replace = true)
if did_replace
newx, newy, newz
else
SliceIt, x, y, z
end
end
@recipe function f(x, y)
wrap_surfaces!(plotattributes, x, y)
did_replace = false
newx = _apply_type_recipe(plotattributes, x, :x)
x === newx || (did_replace = true)
newy = _apply_type_recipe(plotattributes, y, :y)
y === newy || (did_replace = true)
if did_replace
newx, newy
else
SliceIt, x, y, nothing
end
end
@recipe function f(y)
wrap_surfaces!(plotattributes, y)
newy = _apply_type_recipe(plotattributes, y, :y)
if y !== newy
newy
else
SliceIt, nothing, y, nothing
end
end
# if there's more than 3 inputs, it can't be passed directly to SliceIt
# so we'll apply_type_recipe to all of them
@recipe function f(v1, v2, v3, v4, vrest...)
did_replace = false
newargs = map(v -> begin
newv = _apply_type_recipe(plotattributes, v, :unknown)
if newv !== v
did_replace = true
end
newv
end, (v1, v2, v3, v4, vrest...))
if !did_replace
error("Couldn't process recipe args: $(map(typeof, (v1, v2, v3, v4, vrest...)))")
end
newargs
end
# helper function to ensure relevant attributes are wrapped by Surface
function wrap_surfaces!(plotattributes, args...) end
wrap_surfaces!(plotattributes, x::AMat, y::AMat, z::AMat) = wrap_surfaces!(plotattributes)
wrap_surfaces!(plotattributes, x::AVec, y::AVec, z::AMat) = wrap_surfaces!(plotattributes)
function wrap_surfaces!(plotattributes, x::AVec, y::AVec, z::Surface)
wrap_surfaces!(plotattributes)
end
function wrap_surfaces!(plotattributes)
if haskey(plotattributes, :fill_z)
v = plotattributes[:fill_z]
if !isa(v, Surface)
plotattributes[:fill_z] = Surface(v)
end
end
end
# --------------------------------------------------------------------
# 1 argument
# --------------------------------------------------------------------
@recipe f(n::Integer) = is3d(get(plotattributes,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing)
all3D(plotattributes) = 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)
if all3D(plotattributes)
n, m = axes(mat)
m, n, Surface(mat)
else
nothing, mat, nothing
end
end
# if a matrix is wrapped by Formatted, do similar logic, but wrap data with Surface
@recipe function f(fmt::Formatted{<:AMat})
if all3D(plotattributes)
mat = fmt.data
n, m = axes(mat)
m, n, Formatted(Surface(mat), fmt.formatter)
else
nothing, fmt, nothing
end
end
# assume this is a Volume, so construct one
@recipe function f(vol::AbstractArray{<:MaybeNumber, 3}, args...)
seriestype := :volume
SliceIt, nothing, Volume(vol, args...), nothing
end
# images - grays
function clamp_greys!(mat::AMat{<: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{<:Gray})
n, m = axes(mat)
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, m, n, Surface(clamp_greys!(mat))
else
seriestype := :heatmap
yflip --> true
cbar --> false
fillcolor --> ColorGradient([:black, :white])
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 = axes(mat)
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, m, n, Surface(mat)
else
seriestype := :heatmap
yflip --> true
cbar --> false
aspect_ratio --> :equal
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, m, n, Surface(z)
end
end
# plotting arbitrary shapes/polygons
@recipe function f(shape::Shape)
seriestype --> :shape
coords(shape)
end
@recipe function f(shapes::AVec{Shape})
seriestype --> :shape
coords(shapes)
end
@recipe function f(shapes::AMat{Shape})
seriestype --> :shape
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 = if haskey(plotattributes, :xlims)
plotattributes[:xlims]
else
try
axis_limits(plt[1], :x)
catch
xinv = invscalefunc(get(plotattributes, :xscale, :identity))
xm = PlotUtils.tryrange(f, xinv.([-5,-1,0,0.01]))
xm, PlotUtils.tryrange(f, filter(x->x>xm, xinv.([5,1,0.99, 0, -0.01])))
end
end
f, xmin, xmax
end
# --------------------------------------------------------------------
# 2 arguments
# --------------------------------------------------------------------
# if functions come first, just swap the order (not to be confused with parametric
# functions... as there would be more than one function passed in)
@recipe function f(f::FuncOrFuncs{F}, x) where F<:Function
F2 = typeof(x)
@assert !(F2 <: Function || (F2 <: AbstractArray && F2.parameters[1] <: Function)) # otherwise we'd hit infinite recursion here
x, f
end
# --------------------------------------------------------------------
# 3 arguments
# --------------------------------------------------------------------
# surface-like... function
@recipe function f(x::AVec, y::AVec, zf::Function)
x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported
end
# surface-like... matrix grid
@recipe function f(x::AVec, y::AVec, z::AMat)
if !like_surface(get(plotattributes, :seriestype, :none))
plotattributes[:seriestype] = :contour
end
x, y, Surface(z)
end
# images - grays
@recipe function f(x::AVec, y::AVec, mat::AMat{T}) where T<:Gray
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, x, y, Surface(mat)
else
seriestype := :heatmap
yflip --> true
cbar --> false
fillcolor --> ColorGradient([:black, :white])
SliceIt, x, y, Surface(convert(Matrix{Float64}, mat))
end
end
# images - colors
@recipe function f(x::AVec, y::AVec, mat::AMat{T}) where T<:Colorant
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, x, y, Surface(mat)
else
seriestype := :heatmap
yflip --> true
cbar --> false
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, x, y, Surface(z)
end
end
# --------------------------------------------------------------------
# Parametric functions
# --------------------------------------------------------------------
# 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)]
_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)]
unzip(_scaled_adapted_grid.(fs, xscale, yscale, xmin, xmax))
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))
xs, ys = adapted_grid(yf∘f∘xinv, xf.((xmin, xmax)))
xinv.(xs), yinv.(ys)
end
# special handling... 3D parametric function(s)
@recipe function f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, u::AVec) where {F<:Function,G<:Function,H<:Function}
mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u)
end
@recipe function f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, umin::Number, umax::Number, numPoints = 200) where {F<:Function,G<:Function,H<:Function}
fx, fy, fz, range(umin, stop = umax, length = numPoints)
end
# --------------------------------------------------------------------
# Lists of tuples and GeometryTypes.Points
# --------------------------------------------------------------------
@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]
# 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)
# --------------------------------------------------------------------
# handle grouping
# --------------------------------------------------------------------
splittable_kw(key, val, lengthGroup) = false
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)
split_kw(key, val::AbstractArray, indices) = val[indices, fill(Colon(), ndims(val)-1)...]
split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in val)
function split_kw(key, val::SeriesAnnotations, indices)
split_strs = split_kw(key, val.strs, indices)
return SeriesAnnotations(split_strs, val.font, val.baseshape, val.scalefactor)
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 eachindex(groupby.groupLabels)
xi = x[groupby.groupIds[i]]
yi = y[groupby.groupIds[i]]
y_mat[getindex.(Ref(x_ind), xi), i] = yi
end
return y_mat
end
groupedvec2mat(x_ind, x, y::Tuple, groupby) = Tuple(groupedvec2mat(x_ind, x, v, groupby) for v in y)
group_as_matrix(t) = false
# split the group into 1 series per group, and set the label and idxfilter for each
@recipe function f(groupby::GroupBy, args...)
lengthGroup = maximum(union(groupby.groupIds...))
if !(group_as_matrix(args[1]))
for (i,glab) in enumerate(groupby.groupLabels)
@series begin
label --> string(glab)
idxfilter --> groupby.groupIds[i]
for (key,val) in plotattributes
if splittable_kw(key, val, lengthGroup)
:($key) := split_kw(key, val, groupby.groupIds[i])
end
end
args
end
end
else
g = args[1]
if length(g.args) == 1
x = zeros(Int, lengthGroup)
for indexes in groupby.groupIds
x[indexes] = eachindex(indexes)
end
last_args = g.args
else
x = g.args[1]
last_args = g.args[2:end]
end
x_u = unique(sort(x))
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)
end
end
label --> reshape(groupby.groupLabels, 1, :)
typeof(g)((x_u, (groupedvec2mat(x_ind, x, arg, groupby, NaN) for arg in last_args)...))
end
end
+38 -12
View File
@@ -1,3 +1,5 @@
@nospecialize
"""
scatter(x,y)
scatter!(x,y)
@@ -55,6 +57,7 @@ Plot a histogram.
# Example
```julia-repl
julia> histogram([1,2,1,1,4,3,8],bins=0:8)
julia> histogram([1,2,1,1,4,3,8],bins=0:8,weights=weights([4,7,3,9,12,2,6]))
```
"""
@shorthands histogram
@@ -69,7 +72,7 @@ Make a histogram bar plot. See `histogram`.
"""
stephist(x)
stephist(x)
stephist!(x)
Make a histogram step plot (bin counts are represented using horizontal lines
instead of bars). See `histogram`.
@@ -251,7 +254,7 @@ Draw contour lines of the `Surface` z.
# Example
```julia-repl
julia> x = y = range(-20, 20, length = 100)
julia> x = y = range(-20, stop = 20, length = 100)
julia> contour(x, y, (x, y) -> x^2 + y^2)
```
"""
@@ -272,7 +275,7 @@ Draw a 3D surface plot.
# Example
```julia-repl
julia> using LinearAlgebra
julia> x = y = range(-3, 3, length = 100)
julia> x = y = range(-3, stop = 3, length = 100)
julia> surface(x, y, (x, y) -> sinc(norm([x, y])))
```
"""
@@ -318,6 +321,27 @@ julia> scatter3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
"""
@shorthands scatter3d
"""
mesh3d(x,y,z)
mesh3d(x,y,z; connections)
Plot a 3d mesh. On Plotly the triangles can be specified using the connections argument.
# Example
```Julia
x=[0, 1, 2, 0]
y=[0, 0, 1, 2]
z=[0, 2, 0, 1]
i=[0, 0, 0, 1]
j=[1, 2, 3, 2]
k=[2, 3, 1, 3]
plot(x,y,z,seriestype=:mesh3d;connections=(i,j,k))
```
"""
@shorthands mesh3d
"""
boxplot(x, y)
boxplot!(x, y)
@@ -381,8 +405,7 @@ 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)
@shorthands pie
"Plot with seriestype :path3d"
plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d)
@@ -398,13 +421,13 @@ xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...)
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...)
xlims!(lims::Tuple; kw...) = 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...)
ylims!(lims::Tuple; kw...) = 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...)
zlims!(lims::Tuple; kw...) = 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...)
@@ -412,10 +435,10 @@ zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmi
"Set xticks for an existing plot"
xticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; xticks = v, kw...)
xticks!(v::TicksArgs; kw...) = plot!(; xticks = v, kw...)
"Set yticks for an existing plot"
yticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; yticks = v, kw...)
yticks!(v::TicksArgs; kw...) = plot!(; yticks = v, kw...)
xticks!(
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...)
@@ -438,8 +461,9 @@ julia> plot(1:10)
julia> annotate!([(7,3,"(7,3)"),(3,7,text("hey", 14, :left, :top, :green))])
```
"""
annotate!(anns...; kw...) = plot!(; annotation = collect(anns), kw...)
annotate!(anns::AVec{T}; kw...) where {T<:Tuple} = plot!(; annotation = anns, kw...)
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
annotate!(anns::Tuple...; kw...) = plot!(; annotation = collect(anns), kw...)
annotate!(anns::AVec{<:Tuple}; kw...) = plot!(; annotation = anns, kw...)
"Flip the current plots' x axis"
xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...)
@@ -454,3 +478,5 @@ xaxis!(args...; kw...) = plot!(; xaxis = args
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
ygrid!(args...; kw...) = plot!(; ygrid = args, kw...)
@specialize
+19 -7
View File
@@ -7,7 +7,7 @@ function Subplot(::T; parent = RootLayout()) where T<:AbstractBackend
(20mm, 5mm, 2mm, 10mm),
defaultbox,
defaultbox,
Attr(KW(), _subplot_defaults),
DefaultsDict(KW(), _subplot_defaults),
nothing,
nothing
)
@@ -42,12 +42,24 @@ get_subplot_index(plt::Plot, sp::Subplot) = findfirst(x -> x === sp, plt.subplot
series_list(sp::Subplot) = sp.series_list # filter(series -> series.plotattributes[:subplot] === sp, sp.plt.series_list)
function should_add_to_legend(series::Series)
series.plotattributes[:primary] && series.plotattributes[:label] != "" &&
!(series.plotattributes[:seriestype] in (
:hexbin,:bins2d,:histogram2d,:hline,:vline,
:contour,:contourf,:contour3d,:surface,:wireframe,
:heatmap, :pie, :image
))
series.plotattributes[:primary] &&
series.plotattributes[:label] != "" &&
!(
series.plotattributes[:seriestype] in (
:hexbin,
:bins2d,
:histogram2d,
:hline,
:vline,
:contour,
:contourf,
:contour3d,
:surface,
:wireframe,
:heatmap,
:image,
)
)
end
# ----------------------------------------------------------------------
+9 -19
View File
@@ -14,25 +14,15 @@ function _theme(s::Symbol, defaults::AKW; kw...)
# Set the theme's gradient as default
if haskey(defaults, :colorgradient)
PlotUtils.clibrary(:misc)
PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s))
pop!(defaults, :colorgradient)
PlotUtils.default_cgrad(pop!(defaults, :colorgradient))
else
PlotUtils.clibrary(:Plots)
PlotUtils.default_cgrad(default = :sequential, sequential = :inferno)
PlotUtils.default_cgrad(:default)
end
# maybe overwrite the theme's gradient
kw = KW(kw)
if haskey(kw, :colorgradient)
kwgrad = pop!(kw, :colorgradient)
for clib in clibraries()
if kwgrad in cgradients(clib)
PlotUtils.clibrary(clib)
PlotUtils.default_cgrad(default = :sequential, sequential = kwgrad)
break
end
end
PlotUtils.default_cgrad(pop!(kw, :colorgradient))
end
# Set the theme's defaults
@@ -57,12 +47,12 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
defaults = PlotThemes._themes[thm].defaults
# get the gradient
gradient_colors = get(defaults, :colorgradient, cgrad(:inferno).colors)
gradient_colors = color_list(cgrad(get(defaults, :colorgradient, :default)))
colorgradient = cgrad(cfunc.(RGB.(gradient_colors)))
# get the palette
palette = get(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17))
palette = cfunc.(RGB.(palette))
cp = color_list(palette(get(defaults, :palette, :default)))
cp = cfunc.(RGB.(cp))
# apply the theme
for k in keys(defaults)
@@ -89,7 +79,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
for j in 1:4
@series begin
subplot := 1
palette := palette
color_palette := cp
seriestype := :path
cumsum(randn(50))
end
@@ -97,7 +87,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
@series begin
subplot := 2
seriestype := :scatter
palette := palette
color_palette := cp
marker := (:circle, :diamond, :star5, :square)[j]
randn(10), randn(10)
end
@@ -106,7 +96,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
@series begin
subplot := 3
seriestype := :histogram
palette := palette
color_palette := cp
randn(1000) .+ (0:2:4)'
end
+5 -60
View File
@@ -18,65 +18,10 @@ end
wrap(obj::T) where {T} = InputWrapper{T}(obj)
Base.isempty(wrapper::InputWrapper) = false
# -----------------------------------------------------------
struct Attr <: AbstractDict{Symbol,Any}
explicit::KW
defaults::KW
end
function Base.getindex(attr::Attr, k)
return haskey(attr.explicit, k) ? attr.explicit[k] : attr.defaults[k]
end
Base.haskey(attr::Attr, k) = haskey(attr.explicit,k) || haskey(attr.defaults,k)
Base.get(attr::Attr, k, default) = haskey(attr, k) ? attr[k] : default
function Base.get!(attr::Attr, k, default)
v = if haskey(attr, k)
attr[k]
else
attr.defaults[k] = default
end
return v
end
function Base.delete!(attr::Attr, k)
haskey(attr.explicit, k) && delete!(attr.explicit, k)
haskey(attr.defaults, k) && delete!(attr.defaults, k)
end
Base.length(attr::Attr) = length(union(keys(attr.explicit), keys(attr.defaults)))
function Base.iterate(attr::Attr)
exp_keys = keys(attr.explicit)
def_keys = setdiff(keys(attr.defaults), exp_keys)
key_list = collect(Iterators.flatten((exp_keys, def_keys)))
iterate(attr, (key_list, 1))
end
function Base.iterate(attr::Attr, (key_list, i))
i > length(key_list) && return nothing
k = key_list[i]
(k=>attr[k], (key_list, i+1))
end
Base.copy(attr::Attr) = Attr(copy(attr.explicit), attr.defaults)
RecipesBase.is_explicit(attr::Attr, k) = haskey(attr.explicit,k)
isdefault(attr::Attr, k) = !is_explicit(attr,k) && haskey(attr.defaults,k)
Base.setindex!(attr::Attr, v, k) = attr.explicit[k] = v
# Reset to default value and return dict
reset_kw!(attr::Attr, k) = is_explicit(attr, k) ? delete!(attr.explicit, k) : attr
# Reset to default value and return old value
pop_kw!(attr::Attr, k) = is_explicit(attr, k) ? pop!(attr.explicit, k) : attr.defaults[k]
pop_kw!(attr::Attr, k, default) = is_explicit(attr, k) ? pop!(attr.explicit, k) : get(attr.defaults, k, default)
# Fallbacks for dicts without defaults
reset_kw!(d::AKW, k) = delete!(d, k)
pop_kw!(d::AKW, k) = pop!(d, k)
pop_kw!(d::AKW, k, default) = pop!(d, k, default)
# -----------------------------------------------------------
mutable struct Series
plotattributes::Attr
plotattributes::DefaultsDict
end
attr(series::Series, k::Symbol) = series.plotattributes[k]
@@ -91,7 +36,7 @@ mutable struct Subplot{T<:AbstractBackend} <: AbstractLayout
minpad::Tuple # leftpad, toppad, rightpad, bottompad
bbox::BoundingBox # the canvas area which is available to this subplot
plotarea::BoundingBox # the part where the data goes
attr::Attr # args specific to this subplot
attr::DefaultsDict # args specific to this subplot
o # can store backend-specific data... like a pyplot ax
plt # the enclosing Plot object (can't give it a type because of no forward declarations)
end
@@ -103,7 +48,7 @@ Base.show(io::IO, sp::Subplot) = print(io, "Subplot{$(sp[:subplot_index])}")
# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
mutable struct Axis
sps::Vector{Subplot}
plotattributes::Attr
plotattributes::DefaultsDict
end
mutable struct Extrema
@@ -122,7 +67,7 @@ const SubplotMap = Dict{Any, Subplot}
mutable struct Plot{T<:AbstractBackend} <: AbstractPlot{T}
backend::T # the backend type
n::Int # number of series
attr::Attr # arguments for the whole plot
attr::DefaultsDict # arguments for the whole plot
series_list::Vector{Series} # arguments for each series
o # the backend's plot object
subplots::Vector{Subplot}
@@ -133,7 +78,7 @@ mutable struct Plot{T<:AbstractBackend} <: AbstractPlot{T}
end
function Plot()
Plot(backend(), 0, Attr(KW(), _plot_defaults), Series[], nothing,
Plot(backend(), 0, DefaultsDict(KW(), _plot_defaults), Series[], nothing,
Subplot[], SubplotMap(), EmptyLayout(),
Subplot[], false)
end
+235 -207
View File
@@ -1,8 +1,10 @@
function treats_y_as_x(seriestype)
return seriestype in (:vline, :vspan, :histogram, :barhist, :stephist, :scatterhist)
end
function replace_image_with_heatmap(z::Array{T}) where T<:Colorant
n, m = size(z)
colors = ColorGradient(vec(z))
newz = reshape(range(0, stop=1, length=n*m), n, m)
colors = palette(vec(z))
newz = reshape(1:n*m, n, m)
newz, colors
end
@@ -51,10 +53,16 @@ function Base.push!(segments::Segments{T}, vs::AVec) where T
end
struct SeriesSegment
# indexes of this segement in series data vectors
range::UnitRange
# index into vector-valued attributes corresponding to this segment
attr_index::Int
end
# -----------------------------------------------------
# helper to manage NaN-separated segments
mutable struct SegmentsIterator
struct NaNSegmentsIterator
args::Tuple
n1::Int
n2::Int
@@ -64,26 +72,50 @@ function iter_segments(args...)
tup = Plots.wraptuple(args)
n1 = minimum(map(firstindex, tup))
n2 = maximum(map(lastindex, tup))
SegmentsIterator(tup, n1, n2)
NaNSegmentsIterator(tup, n1, n2)
end
function iter_segments(series::Series)
function series_segments(series::Series, seriestype::Symbol = :path)
x, y, z = series[:x], series[:y], series[:z]
if x === nothing
return UnitRange{Int}[]
elseif has_attribute_segments(series)
if series[:seriestype] in (:scatter, :scatter3d)
return [[i] for i in eachindex(y)]
else
return [i:(i + 1) for i in firstindex(y):lastindex(y)-1]
end
(x === nothing || isempty(x)) && return UnitRange{Int}[]
args = RecipesPipeline.is3d(series) ? (x, y, z) : (x, y)
nan_segments = collect(iter_segments(args...))
segments = if has_attribute_segments(series)
Iterators.flatten(map(nan_segments) do r
if seriestype in (:scatter, :scatter3d)
(SeriesSegment(i:i, i) for i in r)
else
(SeriesSegment(i:i+1, i) for i in first(r):last(r)-1)
end
end)
else
segs = UnitRange{Int}[]
args = is3d(series) ? (x, y, z) : (x, y)
for seg in iter_segments(args...)
push!(segs, seg)
(SeriesSegment(r, 1) for r in nan_segments)
end
warn_on_attr_dim_mismatch(series, x, y, z, segments)
return segments
end
function warn_on_attr_dim_mismatch(series, x, y, z, segments)
isempty(segments) && return
seg_range = UnitRange(minimum(first(seg.range) for seg in segments),
maximum(last(seg.range) for seg in segments))
for attr in _segmenting_vector_attributes
v = get(series, attr, nothing)
if v isa AVec && eachindex(v) != seg_range
@warn "Indices $(eachindex(v)) of attribute `$attr` does not match data indices $seg_range."
if any(v -> !isnothing(v) && any(isnan, v), (x,y,z))
@info """Data contains NaNs or missing values, and indices of `$attr` vector do not match data indices.
If you intend elements of `$attr` to apply to individual NaN-separated segements in the data,
pass each segment in a separate vector instead, and use a row vector for `$attr`. Legend entries
may be suppressed by passing an empty label.
For example,
plot([1:2,1:3], [[4,5],[3,4,5]], label=["y" ""], $attr=[1 2])
"""
end
end
return segs
end
end
@@ -93,7 +125,7 @@ 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 = itr.n1)
function Base.iterate(itr::NaNSegmentsIterator, nextidx::Int = itr.n1)
i = findfirst(!anynan(itr.args), nextidx:itr.n2)
i === nothing && return nothing
nextval = nextidx + i - 1
@@ -103,6 +135,7 @@ function Base.iterate(itr::SegmentsIterator, nextidx::Int = itr.n1)
nextval:nextnan-1, nextnan
end
Base.IteratorSize(::NaNSegmentsIterator) = Base.SizeUnknown()
# Find minimal type that can contain NaN and x
# To allow use of NaN separated segments with categorical x axis
@@ -122,19 +155,21 @@ isnothing(x) = false
_cycle(wrapper::InputWrapper, idx::Int) = wrapper.obj
_cycle(wrapper::InputWrapper, idx::AVec{Int}) = wrapper.obj
_cycle(v::AVec, idx::Int) = v[mod1(idx, length(v))]
_cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))]
_cycle(v::AVec, idx::Int) = v[mod(idx, axes(v,1))]
_cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[end, mod(idx, axes(v,2))] : v[:, mod(idx, axes(v,2))]
_cycle(v, idx::Int) = v
_cycle(v::AVec, indices::AVec{Int}) = map(i -> _cycle(v,i), indices)
_cycle(v::AMat, indices::AVec{Int}) = map(i -> _cycle(v,i), indices)
_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)
_cycle(cl::PlotUtils.AbstractColorList, idx::Int) = cl[mod1(idx, end)]
_cycle(cl::PlotUtils.AbstractColorList, idx::AVec{Int}) = cl[mod1.(idx, end)]
_as_gradient(grad::ColorGradient) = grad
_as_gradient(c::Colorant) = ColorGradient([c,c])
_as_gradient(grad) = grad
_as_gradient(v::AbstractVector{<:Colorant}) = cgrad(v)
_as_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
_as_gradient(c::Colorant) = cgrad([c, c])
makevec(v::AVec) = v
makevec(v::T) where {T} = T[v]
@@ -143,20 +178,20 @@ makevec(v::T) where {T} = T[v]
maketuple(x::Real) = (x,x)
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]
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)...))
RecipesPipeline.unzip(
v::Union{AVec{<:Tuple{Vararg{T,$i} where T}}, AVec{<:GeometryBasics.Point{$i}}},
) = $(Expr(:tuple, (:([t[$j] for t in v]) for j=1:i)...))
end
end
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.")
RecipesPipeline.unzip(
::Union{AVec{<:GeometryBasics.Point{N}}, AVec{<:Tuple{Vararg{T,N} where T}}}
) where N = error("$N-dimensional unzip not implemented.")
RecipesPipeline.unzip(::Union{AVec{<:GeometryBasics.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)
@@ -190,7 +225,7 @@ end
function replaceAlias!(plotattributes::AKW, k::Symbol, aliases::Dict{Symbol,Symbol})
if haskey(aliases, k)
plotattributes[aliases[k]] = pop_kw!(plotattributes, k)
plotattributes[aliases[k]] = RecipesPipeline.pop_kw!(plotattributes, k)
end
end
@@ -203,37 +238,27 @@ end
createSegments(z) = collect(repeat(reshape(z,1,:),2,1))[2:end]
Base.first(c::Colorant) = c
Base.first(x::Symbol) = x
sortedkeys(plotattributes::Dict) = sort(collect(keys(plotattributes)))
const _scale_base = Dict{Symbol, Real}(
:log10 => 10,
:log2 => 2,
:ln => ,
)
function _heatmap_edges(v::AVec, isedges::Bool = false)
length(v) == 1 && return v[1] .+ [-0.5, 0.5]
function _heatmap_edges(v::AVec, isedges::Bool = false, ispolar::Bool = false)
length(v) == 1 && return v[1] .+ [ispolar ? max(-v[1], -0.5) : -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_min = ispolar ? min(v[1], (v[2] - v[1]) / 2) : (v[2] - v[1]) / 2
extra_max = (v[end] - v[end - 1]) / 2
vcat(vmin-extra_min, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra_max)
end
"create an (n+1) list of the outsides of heatmap rectangles"
function heatmap_edges(v::AVec, scale::Symbol = :identity, isedges::Bool = false)
f, invf = scalefunc(scale), invscalefunc(scale)
map(invf, _heatmap_edges(map(f,v), isedges))
function heatmap_edges(v::AVec, scale::Symbol = :identity, isedges::Bool = false, ispolar::Bool = false)
f, invf = RecipesPipeline.scale_func(scale), RecipesPipeline.inverse_scale_func(scale)
map(invf, _heatmap_edges(map(f,v), isedges, ispolar))
end
function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size::Tuple{Int, Int})
function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size::Tuple{Int, Int}, ispolar::Bool = false)
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.
@@ -245,7 +270,7 @@ function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size:
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)
heatmap_edges(y, yscale, isedges, ispolar) # special handle for `r` in polar plots
return x, y
end
@@ -298,13 +323,11 @@ limsType(lims::Tuple{T,S}) where {T<:Real,S<:Real} = :limits
limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
limsType(lims) = :invalid
# axis_Symbol(letter, postfix) = Symbol(letter * postfix)
# axis_symbols(letter, postfix...) = map(s -> axis_Symbol(letter, s), postfix)
Base.convert(::Type{Vector{T}}, rng::AbstractRange{T}) where {T<:Real} = T[x for x in rng]
Base.convert(::Type{Vector{T}}, rng::AbstractRange{S}) where {T<:Real,S<:Real} = T[x for x in rng]
Base.merge(a::AbstractVector, b::AbstractVector) = sort(unique(vcat(a,b)))
# recursively merge kw-dicts, e.g. for merging extra_kwargs / extra_plot_kwargs in plotly)
recursive_merge(x::AbstractDict...) = merge(recursive_merge, x...)
# if values are not AbstractDicts, take the last definition (as does merge)
recursive_merge(x...) = x[end]
nanpush!(a::AbstractVector, b) = (push!(a, NaN); push!(a, b))
nanappend!(a::AbstractVector, b) = (push!(a, NaN); append!(a, b))
@@ -342,17 +365,8 @@ function indices_and_unique_values(z::AbstractArray)
newz, vals
end
# this is a helper function to determine whether we need to transpose a surface matrix.
# it depends on whether the backend matches rows to x (transpose_on_match == true) or vice versa
# for example: PyPlot sends rows to y, so transpose_on_match should be true
function transpose_z(plotattributes, z, transpose_on_match::Bool = true)
if plotattributes[:match_dimensions] == transpose_on_match
# z'
permutedims(z, [2,1])
else
z
end
end
handle_surface(z) = z
handle_surface(z::Surface) = permutedims(z.surf)
function ok(x::Number, y::Number, z::Number = 0)
isfinite(x) && isfinite(y) && isfinite(z)
@@ -360,10 +374,10 @@ end
ok(tup::Tuple) = ok(tup...)
# compute one side of a fill range from a ribbon
function make_fillrange_side(y, rib)
frs = zeros(length(y))
for (i, (yi, ri)) in enumerate(zip(y, Base.Iterators.cycle(rib)))
frs[i] = yi + ri
function make_fillrange_side(y::AVec, rib)
frs = zeros(axes(y))
for (i, yi) in pairs(y)
frs[i] = yi + _cycle(rib,i)
end
frs
end
@@ -418,78 +432,7 @@ xlims(sp_idx::Int = 1) = xlims(current(), sp_idx)
ylims(sp_idx::Int = 1) = ylims(current(), sp_idx)
zlims(sp_idx::Int = 1) = zlims(current(), sp_idx)
function get_clims(sp::Subplot)
zmin, zmax = Inf, -Inf
for series in series_list(sp)
if series[:colorbar_entry]
zmin, zmax = _update_clims(zmin, zmax, get_clims(series)...)
end
end
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(sp::Subplot, series::Series)
zmin, zmax = if series[:colorbar_entry]
get_clims(sp)
else
get_clims(series)
end
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
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
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
iscontour(series::Series) = series[:seriestype] in (:contour, :contour3d)
isfilledcontour(series::Series) = iscontour(series) && series[:fillrange] !== nothing
function contour_levels(series::Series, clims)
@@ -524,8 +467,7 @@ for comp in (:line, :fill, :marker)
if z === nothing
isa(c, ColorGradient) ? c : plot_color(_cycle(c, i))
else
grad = isa(c, ColorGradient) ? c : cgrad()
grad[clamp((_cycle(z, i) - cmin) / (cmax - cmin), 0, 1)]
get(get_gradient(c), z[i], (cmin, cmax))
end
end
@@ -543,9 +485,28 @@ for comp in (:line, :fill, :marker)
end
end
function get_colorgradient(series::Series)
st = series[:seriestype]
if st in (:surface, :heatmap) || isfilledcontour(series)
series[:fillcolor]
elseif st in (:contour, :wireframe)
series[:linecolor]
elseif series[:marker_z] !== nothing
series[:markercolor]
elseif series[:line_z] !== nothing
series[:linecolor]
elseif series[:fill_z] !== nothing
series[:fillcolor]
end
end
single_color(c, v = 0.5) = c
single_color(grad::ColorGradient, v = 0.5) = grad[v]
get_gradient(c) = cgrad()
get_gradient(cg::ColorGradient) = cg
get_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
function get_linewidth(series, i::Int = 1)
_cycle(series[:linewidth], i)
end
@@ -567,17 +528,34 @@ function get_markerstrokewidth(series, i::Int = 1)
_cycle(series[:markerstrokewidth], i)
end
const _segmenting_vector_attributes = (
:seriescolor,
:seriesalpha,
:linecolor,
:linealpha,
:linewidth,
:linestyle,
:fillcolor,
:fillalpha,
:markercolor,
:markeralpha,
:markersize,
:markerstrokecolor,
:markerstrokealpha,
:markerstrokewidth,
:markershape,
)
const _segmenting_array_attributes = (:line_z, :fill_z, :marker_z)
function has_attribute_segments(series::Series)
# we want to check if a series needs to be split into segments just because
# of its attributes
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
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, :linestyle, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray for attr in (:line_z, :fill_z, :marker_z))
# check relevant attributes if they have multiple inputs
return any(series[attr] isa AbstractVector && length(series[attr]) > 1
for attr in _segmenting_vector_attributes
) || any(series[attr] isa AbstractArray for attr in _segmenting_array_attributes)
end
function get_aspect_ratio(sp)
@@ -593,6 +571,17 @@ function get_aspect_ratio(sp)
return aspect_ratio
end
get_size(kw) = get(kw, :size, default(:size))
get_size(plt::Plot) = get_size(plt.attr)
get_size(sp::Subplot) = get_size(sp.plt)
get_size(series::Series) = get_size(series.plotattributes[:subplot])
get_thickness_scaling(kw) = get(kw, :thickness_scaling, default(:thickness_scaling))
get_thickness_scaling(plt::Plot) = get_thickness_scaling(plt.attr)
get_thickness_scaling(sp::Subplot) = get_thickness_scaling(sp.plt)
get_thickness_scaling(series::Series) =
get_thickness_scaling(series.plotattributes[:subplot])
# ---------------------------------------------------------------
makekw(; kw...) = KW(kw)
@@ -838,7 +827,7 @@ end
function attr!(series::Series; kw...)
plotattributes = KW(kw)
preprocessArgs!(plotattributes)
RecipesPipeline.preprocess_attributes!(plotattributes)
for (k,v) in plotattributes
if haskey(_series_defaults, k)
series[k] = v
@@ -852,7 +841,7 @@ end
function attr!(sp::Subplot; kw...)
plotattributes = KW(kw)
preprocessArgs!(plotattributes)
RecipesPipeline.preprocess_attributes!(plotattributes)
for (k,v) in plotattributes
if haskey(_subplot_defaults, k)
sp[k] = v
@@ -935,7 +924,7 @@ px2inch(px::Real) = float(px / PX_PER_INCH)
inch2mm(inches::Real) = float(inches * MM_PER_INCH)
mm2inch(mm::Real) = float(mm / MM_PER_INCH)
px2mm(px::Real) = float(px * MM_PER_PX)
mm2px(mm::Real) = float(px / MM_PER_PX)
mm2px(mm::Real) = float(mm / MM_PER_PX)
"Smallest x in plot"
@@ -950,54 +939,72 @@ ignorenan_extrema(plt::Plot) = (xmin(plt), xmax(plt))
# ---------------------------------------------------------------
# get fonts from objects:
titlefont(sp::Subplot) = font(
sp[:titlefontfamily],
sp[:titlefontsize],
sp[:titlefontvalign],
sp[:titlefonthalign],
sp[:titlefontrotation],
sp[:titlefontcolor],
plottitlefont(p::Plot) = font(;
family = p[:plot_titlefontfamily],
pointsize = p[:plot_titlefontsize],
valign = p[:plot_titlefontvalign],
halign = p[:plot_titlefonthalign],
rotation = p[:plot_titlefontrotation],
color = p[:plot_titlefontcolor],
)
legendfont(sp::Subplot) = font(
sp[:legendfontfamily],
sp[:legendfontsize],
sp[:legendfontvalign],
sp[:legendfonthalign],
sp[:legendfontrotation],
sp[:legendfontcolor],
colorbartitlefont(sp::Subplot) = font(;
family = sp[:colorbar_titlefontfamily],
pointsize = sp[:colorbar_titlefontsize],
valign = sp[:colorbar_titlefontvalign],
halign = sp[:colorbar_titlefonthalign],
rotation = sp[:colorbar_titlefontrotation],
color = sp[:colorbar_titlefontcolor],
)
legendtitlefont(sp::Subplot) = font(
sp[:legendtitlefontfamily],
sp[:legendtitlefontsize],
sp[:legendtitlefontvalign],
sp[:legendtitlefonthalign],
sp[:legendtitlefontrotation],
sp[:legendtitlefontcolor],
titlefont(sp::Subplot) = font(;
family = sp[:titlefontfamily],
pointsize = sp[:titlefontsize],
valign = sp[:titlefontvalign],
halign = sp[:titlefonthalign],
rotation = sp[:titlefontrotation],
color = sp[:titlefontcolor],
)
tickfont(ax::Axis) = font(
ax[:tickfontfamily],
ax[:tickfontsize],
ax[:tickfontvalign],
ax[:tickfonthalign],
ax[:tickfontrotation],
ax[:tickfontcolor],
legendfont(sp::Subplot) = font(;
family = sp[:legendfontfamily],
pointsize = sp[:legendfontsize],
valign = sp[:legendfontvalign],
halign = sp[:legendfonthalign],
rotation = sp[:legendfontrotation],
color = sp[:legendfontcolor],
)
guidefont(ax::Axis) = font(
ax[:guidefontfamily],
ax[:guidefontsize],
ax[:guidefontvalign],
ax[:guidefonthalign],
ax[:guidefontrotation],
ax[:guidefontcolor],
legendtitlefont(sp::Subplot) = font(;
family = sp[:legendtitlefontfamily],
pointsize = sp[:legendtitlefontsize],
valign = sp[:legendtitlefontvalign],
halign = sp[:legendtitlefonthalign],
rotation = sp[:legendtitlefontrotation],
color = sp[:legendtitlefontcolor],
)
tickfont(ax::Axis) = font(;
family = ax[:tickfontfamily],
pointsize = ax[:tickfontsize],
valign = ax[:tickfontvalign],
halign = ax[:tickfonthalign],
rotation = ax[:tickfontrotation],
color = ax[:tickfontcolor],
)
guidefont(ax::Axis) = font(;
family = ax[:guidefontfamily],
pointsize = ax[:guidefontsize],
valign = ax[:guidefontvalign],
halign = ax[:guidefonthalign],
rotation = ax[:guidefontrotation],
color = ax[:guidefontcolor],
)
# ---------------------------------------------------------------
# converts unicode scientific notation unsupported by pgfplots and gr
# into a format that works
# converts unicode scientific notation, as returned by Showoff,
# to a tex-like format (supported by gr, pyplot, and pgfplots).
function convert_sci_unicode(label::AbstractString)
unicode_dict = Dict(
@@ -1026,10 +1033,21 @@ end
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]
# handle axes scales
xscale = sp[:xaxis][:scale]
xf = RecipesPipeline.scale_func(xscale)
xinvf = RecipesPipeline.inverse_scale_func(xscale)
yscale = sp[:yaxis][:scale]
yf = RecipesPipeline.scale_func(yscale)
yinvf = RecipesPipeline.inverse_scale_func(yscale)
xl, yl = xf.(xl), yf.(yl)
x, y = xf.(series[:x]), yf.(series[:y])
n = length(x)
if n == 2
return straightline_data(xl, yl, x, y, expansion_factor)
xdata, ydata = if n == 2
straightline_data(xl, yl, x, y, expansion_factor)
else
k, r = divrem(n, 3)
if r == 0
@@ -1038,11 +1056,13 @@ function straightline_data(series, expansion_factor = 1)
inds = (3 * i - 2):(3 * i - 1)
xdata[inds], ydata[inds] = straightline_data(xl, yl, x[inds], y[inds], expansion_factor)
end
return xdata, ydata
xdata, ydata
else
error("Misformed data. `straightline_data` either accepts vectors of length 2 or 3k. The provided series has length $n")
end
end
return xinvf.(xdata), yinvf.(ydata)
end
function straightline_data(xl, yl, x, y, expansion_factor = 1)
@@ -1074,20 +1094,28 @@ end
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
# handle axes scales
xscale = sp[:xaxis][:scale]
xf = RecipesPipeline.scale_func(xscale)
xinvf = RecipesPipeline.inverse_scale_func(xscale)
yscale = sp[:yaxis][:scale]
yf = RecipesPipeline.scale_func(yscale)
yinvf = RecipesPipeline.inverse_scale_func(yscale)
x, y = copy(series[:x]), copy(series[:y])
for i in eachindex(x)
if x[i] == -Inf
x[i] = xl[1] - expansion_factor * (xl[2] - xl[1])
x[i] = xinvf(xf(xl[1]) - expansion_factor * (xf(xl[2]) - xf(xl[1])))
elseif x[i] == Inf
x[i] = xl[2] + expansion_factor * (xl[2] - xl[1])
x[i] = xinvf(xf(xl[2]) + expansion_factor * (xf(xl[2]) - xf(xl[1])))
end
end
for i in eachindex(y)
if y[i] == -Inf
y[i] = yl[1] - expansion_factor * (yl[2] - yl[1])
y[i] = yinvf(yf(yl[1]) - expansion_factor * (yf(yl[2]) - yf(yl[1])))
elseif y[i] == Inf
y[i] = yl[2] + expansion_factor * (yl[2] - yl[1])
y[i] = yinvf(yf(yl[2]) + expansion_factor * (yf(yl[2]) - yf(yl[1])))
end
end
return x, y
+41 -16
View File
@@ -1,15 +1,36 @@
import Plots._current_plots_version
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = !is_ci(), sigma = [1,1], tol = 1e-2)
# replace `f(args...)` with `f(rng, args...)` for `f ∈ (rand, randn)`
function replace_rand!(ex) end
function replace_rand!(ex::Expr)
for arg in ex.args
replace_rand!(arg)
end
if ex.head === :call && ex.args[1] (:rand, :randn)
pushfirst!(ex.args, ex.args[1])
ex.args[2] = :rng
end
end
function fix_rand!(ex)
replace_rand!(ex)
pushfirst!(ex.args[1].args, :(rng = StableRNG(1234)))
end
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)
default(size = (500, 300))
fn = "ref$idx.png"
reffn = reference_file(pkg, idx, _current_plots_version)
@@ -19,25 +40,29 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = !i
func = (fn, idx) -> begin
expr = Expr(:block)
append!(expr.args, example.exprs)
fix_rand!(expr)
eval(expr)
png(fn)
end
# the test
vtest = VisualTest(func, reffn, idx)
test_images(vtest, popup=popup, sigma=sigma, tol=tol, newfn = newfn)
test_images(vtest, popup = popup, sigma = sigma, tol = tol, newfn = newfn)
end
function image_comparison_facts(pkg::Symbol;
skip = [], # skip these examples (int index)
only = nothing, # limit to these examples (int index)
debug = false, # print debug information?
sigma = [1,1], # number of pixels to "blur"
tol = 1e-2) # acceptable error (percent)
for i in 1:length(Plots._examples)
i in skip && continue
if only === nothing || i in only
@test image_comparison_tests(pkg, i, debug=debug, sigma=sigma, tol=tol) |> success == true
function image_comparison_facts(
pkg::Symbol;
skip = [], # skip these examples (int index)
only = nothing, # limit to these examples (int index)
debug = false, # print debug information?
sigma = [1, 1], # number of pixels to "blur"
tol = 1e-2,
) # acceptable error (percent)
for i = 1:length(Plots._examples)
i in skip && continue
if only === nothing || i in only
@test image_comparison_tests(pkg, i, debug = debug, sigma = sigma, tol = tol) |>
success == true
end
end
end
end
+60
View File
@@ -0,0 +1,60 @@
using Plots, Test, Dates
@testset "Limits" begin
y=[1.0*i*i for i in 1:10]
x=[Date(2019,11,i) for i in 1:10]
rx=[x[3],x[5]]
p = plot(x,y, widen = false)
vspan!(p, rx, label="", alpha=0.2)
ref_ylims = (y[1], y[end])
ref_xlims = (x[1].instant.periods.value, x[end].instant.periods.value)
@test Plots.ylims(p) == ref_ylims
@test Plots.xlims(p) == ref_xlims
#@static if (haskey(ENV, "APPVEYOR") || haskey(ENV, "CI"))
@static if haskey(ENV, "APPVEYOR")
@info "Skipping display tests on AppVeyor"
else
@test isa(display(p), Nothing) == true
closeall()
end
end # testset
@testset "Date xlims" begin
y=[1.0*i*i for i in 1:10]
x=[Date(2019,11,i) for i in 1:10]
span = (Date(2019,10,31), Date(2019,11,11))
ref_xlims = map(date->date.instant.periods.value, span)
p = plot(x,y, xlims=span, widen = false)
@test Plots.xlims(p) == ref_xlims
#@static if (haskey(ENV, "APPVEYOR") || haskey(ENV, "CI"))
@static if haskey(ENV, "APPVEYOR")
@info "Skipping display tests on AppVeyor"
else
@test isa(display(p), Nothing) == true
closeall()
end
end # testset
@testset "DateTime xlims" begin
y=[1.0*i*i for i in 1:10]
x=[DateTime(2019,11,i,11) for i in 1:10]
span = (DateTime(2019,10,31,11,59,59), DateTime(2019,11,11,12,01,15))
ref_xlims = map(date->date.instant.periods.value, span)
p = plot(x,y, xlims=span, widen = false)
@test Plots.xlims(p) == ref_xlims
#@static if (haskey(ENV, "APPVEYOR") || haskey(ENV, "CI"))
@static if haskey(ENV, "APPVEYOR")
@info "Skipping display tests on AppVeyor"
else
@test isa(display(p), Nothing) == true
closeall()
end
end # testset
+100 -49
View File
@@ -1,14 +1,41 @@
using Plots: guidefont
import ImageMagick
using VisualRegressionTests
using Plots
using Random
using StableRNGs
using Test
using TestImages
using FileIO
using Gtk
using LibGit2
using GeometryTypes
import GeometryBasics
using Dates
using RecipesBase
@testset "Plotly standalone" begin
@test_nowarn Plots._init_ijulia_plotting()
@test Plots.plotly_local_file_path[] === nothing
temp = Plots.use_local_dependencies[]
withenv("PLOTS_HOST_DEPENDENCY_LOCAL" => true) do
Plots.__init__()
@test Plots.plotly_local_file_path[] isa String
@test isfile(Plots.plotly_local_file_path[])
@test Plots.use_local_dependencies[] = true
@test_nowarn Plots._init_ijulia_plotting()
end
Plots.plotly_local_file_path[] = nothing
Plots.use_local_dependencies[] = temp
end # testset
include("test_defaults.jl")
include("test_axes.jl")
include("test_axis_letter.jl")
include("test_components.jl")
include("test_shorthands.jl")
include("integration_dates.jl")
include("test_recipes.jl")
include("test_hdf5plots.jl")
include("test_pgfplotsx.jl")
@@ -17,7 +44,7 @@ reference_dir(args...) = joinpath(homedir(), ".julia", "dev", "PlotReferenceImag
function reference_file(backend, i, version)
refdir = reference_dir("Plots", string(backend))
fn = "ref$i.png"
versions = sort(VersionNumber.(readdir(refdir)), rev = true)
versions = sort(VersionNumber.(readdir(refdir)), rev=true)
reffn = joinpath(refdir, string(version), fn)
for v in versions
@@ -43,30 +70,31 @@ include("imgcomp.jl")
Random.seed!(1234)
default(show=false, reuse=true)
is_ci() = get(ENV, "CI", "false") == "true"
img_tol = is_ci() ? 1e-2 : Sys.islinux() ? 1e-3 : 0.1
const IMG_TOL = VERSION < v"1.4" && Sys.iswindows() ? 1e-1 : is_ci() ? 1e-2 : 1e-3
## Uncomment the following lines to update reference images for different backends
#=
@testset "GR" begin
image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
end
# @testset "GR" begin
# image_comparison_facts(:gr, tol=IMG_TOL, skip = Plots._backend_skips[:gr])
# end
#
# plotly()
# @testset "Plotly" begin
# image_comparison_facts(:plotly, tol=IMG_TOL, skip = Plots._backend_skips[:plotlyjs])
# end
#
# pyplot()
# @testset "PyPlot" begin
# image_comparison_facts(:pyplot, tol=IMG_TOL, skip = Plots._backend_skips[:pyplot])
# end
#
# pgfplotsx()
# @testset "PGFPlotsX" begin
# image_comparison_facts(:pgfplotsx, tol=IMG_TOL, skip = Plots._backend_skips[:pgfplotsx])
# end
plotly()
@testset "Plotly" begin
image_comparison_facts(:plotly, tol=img_tol, skip = Plots._backend_skips[:plotlyjs])
end
# 10 Histogram2D
pyplot()
@testset "PyPlot" begin
image_comparison_facts(:pyplot, tol=img_tol, skip = Plots._backend_skips[:pyplot])
end
pgfplots()
@testset "PGFPlots" begin
image_comparison_facts(:pgfplots, tol=img_tol, skip = Plots._backend_skips[:pgfplots])
end
=#
##
@testset "Backends" begin
@@ -80,7 +108,7 @@ end
@static if haskey(ENV, "APPVEYOR")
@info "Skipping GR image comparison tests on AppVeyor"
else
image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
image_comparison_facts(:gr, tol=IMG_TOL, skip=Plots._backend_skips[:gr])
end
end
@@ -106,12 +134,21 @@ end
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, :auto)])
hline!(p, [3.1])
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
end
@testset "PlotlyJS" begin
@test plotlyjs() == Plots.PlotlyJSBackend()
@test backend() == Plots.PlotlyJSBackend()
p = plot(rand(10))
@test isa(p, Plots.Plot) == true
@test_broken isa(display(p), Nothing) == true
end
end
@testset "Axes" begin
@@ -120,27 +157,42 @@ end
@test typeof(axis) == Plots.Axis
@test Plots.discrete_value!(axis, "HI") == (0.5, 1)
@test Plots.discrete_value!(axis, :yo) == (1.5, 2)
@test Plots.ignorenan_extrema(axis) == (0.5,1.5)
@test Plots.ignorenan_extrema(axis) == (0.5, 1.5)
@test axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1)
Plots.discrete_value!(axis, ["x$i" for i=1:5])
Plots.discrete_value!(axis, ["x$i" for i=0:2])
Plots.discrete_value!(axis, ["x$i" for i = 1:5])
Plots.discrete_value!(axis, ["x$i" for i = 0:2])
@test Plots.ignorenan_extrema(axis) == (0.5, 7.5)
end
@testset "NoFail" begin
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)
#ensure backend with tested display
@test unicodeplots() == Plots.UnicodePlotsBackend()
@test backend() == Plots.UnicodePlotsBackend()
@testset "Plot" begin
plots = [histogram([1, 0, 0, 0, 0, 0]),
plot([missing]),
plot([missing, missing]),
plot(fill(missing, 10)),
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
@testset "Bar" begin
p = bar([3,2,1], [1,2,3]);
@test isa(p, Plots.Plot)
@test isa(display(p), Nothing) == true
end
@test_nowarn plot(x->x^2,0,2)
end
@testset "EmptyAnim" begin
anim = @animate for i in []
end
@@ -148,16 +200,10 @@ end
@test_throws ArgumentError gif(anim)
end
@testset "Segments" begin
function segments(args...)
segs = UnitRange{Int}[]
for seg in iter_segments(args...)
push!(segs,seg)
end
segs
end
@testset "NaN-separated Segments" begin
segments(args...) = collect(iter_segments(args...))
nan10 = fill(NaN,10)
nan10 = fill(NaN, 10)
@test segments(11:20) == [1:10]
@test segments([NaN]) == []
@test segments(nan10) == []
@@ -169,12 +215,17 @@ end
end
@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")])
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)
@test isequal(collect(zip(Plots.unzip(GeometryBasics.Point.(z))...)), z)
end
op1 = Plots.process_clims((1.0, 2.0))
op2 = Plots.process_clims((1, 2.0))
data = randn(100, 100)
@test op1(data) == op2(data)
@test Plots.process_clims(nothing) == Plots.process_clims(missing) == Plots.process_clims(:auto)
end
+55
View File
@@ -0,0 +1,55 @@
using Plots, Test
@testset "Showaxis" begin
for value in Plots._allShowaxisArgs
@test plot(1:5, showaxis = value)[1][:yaxis][:showaxis] isa Bool
end
@test plot(1:5, showaxis = :y)[1][:yaxis][:showaxis] == true
@test plot(1:5, showaxis = :y)[1][:xaxis][:showaxis] == false
end
@testset "Magic axis" begin
@test plot(1, axis=nothing)[1][:xaxis][:ticks] == []
@test plot(1, axis=nothing)[1][:yaxis][:ticks] == []
end # testset
@testset "Categorical ticks" begin
p1 = plot('A':'M', 1:13)
p2 = plot('A':'Z', 1:26)
p3 = plot('A':'Z', 1:26, ticks = :all)
@test Plots.get_ticks(p1[1], p1[1][:xaxis])[2] == string.('A':'M')
@test Plots.get_ticks(p2[1], p2[1][:xaxis])[2] == string.('C':3:'Z')
@test Plots.get_ticks(p3[1], p3[1][:xaxis])[2] == string.('A':'Z')
end
@testset "Ticks getter functions" begin
ticks1 = ([1,2,3], ("a","b","c"))
ticks2 = ([4,5], ("e","f"))
p1 = plot(1:5, 1:5, 1:5, xticks=ticks1, yticks=ticks1, zticks=ticks1)
p2 = plot(1:5, 1:5, 1:5, xticks=ticks2, yticks=ticks2, zticks=ticks2)
p = plot(p1, p2)
@test xticks(p) == yticks(p) == zticks(p) == [ticks1, ticks2]
@test xticks(p[1]) == yticks(p[1]) == zticks(p[1]) == ticks1
end
@testset "Axis limits" begin
pl = plot(1:5, xlims=:symmetric, widen = false)
@test Plots.xlims(pl) == (-5, 5)
pl = plot(1:3)
@test Plots.xlims(pl) == Plots.widen(1,3)
pl = plot([1.05,2.0,2.95], ylims=:round)
@test Plots.ylims(pl) == (1, 3)
pl = plot(1:3, xlims=(1,5))
@test Plots.xlims(pl) == (1, 5)
pl = plot(1:3, xlims=(1,5), widen=true)
@test Plots.xlims(pl) == Plots.widen(1, 5)
end
@testset "3D Axis" begin
ql = quiver([1, 2], [2, 1], [3, 4], quiver = ([1, -1], [0, 0], [1, -0.5]), arrow=true)
@test ql[1][:projection] == "3d"
end
+25
View File
@@ -0,0 +1,25 @@
using Plots, Test
@testset "axis letter" begin
using Plots, RecipesBase
# a custom type for dispacthing the axis-letter-testing recipe
struct MyType <: Number
val::Float64
end
value(m::MyType) = m.val
data = MyType.(sort(randn(20)))
# A recipe that puts the axis letter in the title
@recipe function f(::Type{T}, m::T) where T <: AbstractArray{<:MyType}
title --> string(plotattributes[:letter])
value.(m)
end
@testset "$f (orientation = $o)" for f in [histogram, barhist, stephist, scatterhist], o in [:vertical, :horizontal]
@test f(data, orientation=o).subplots[1].attr[:title] == (o == :vertical ? "x" : "y")
end
@testset "$f" for f in [hline, hspan]
@test f(data).subplots[1].attr[:title] == "y"
end
@testset "$f" for f in [vline, vspan]
@test f(data).subplots[1].attr[:title] == "x"
end
end
+127
View File
@@ -0,0 +1,127 @@
using Plots, Test
@testset "Shapes" begin
@testset "Type" begin
square = Shape([(0,0.0),(1,0.0),(1,1.0),(0,1.0)])
@test isa(square, Shape{Int64, Float64})
@test coords(square) isa Tuple{Vector{S}, Vector{T}} where {T,S}
end
@testset "Copy" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
square2 = Shape(square)
@test square2.x == square.x
@test square2.y == square.y
end
@testset "Center" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
@test Plots.center(square) == (0.5,0.5)
end
@testset "Translate" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
squareUp = Shape([(0,1),(1,1),(1,2),(0,2)])
squareUpRight = Shape([(1,1),(2,1),(2,2),(1,2)])
@test Plots.translate(square,0,1).x == squareUp.x
@test Plots.translate(square,0,1).y == squareUp.y
@test Plots.center(translate!(square,1)) == (1.5,1.5)
end
@testset "Rotate" begin
# 2 radians rotation matrix
R2 = [cos(2) sin(2); -sin(2) cos(2)]
coords = [0 0; 1 0; 1 1; 0 1]'
coordsRotated2 = R2*(coords.-0.5).+0.5
square = Shape([(0,0),(1,0),(1,1),(0,1)])
# make a new, rotated square
square2 = Plots.rotate(square, -2)
@test square2.x coordsRotated2[1,:]
@test square2.y coordsRotated2[2,:]
# unrotate the new square in place
rotate!(square2, 2)
@test square2.x coords[1,:]
@test square2.y coords[2,:]
end
@testset "Plot" begin
ang = range(0, 2π, length = 60)
ellipse(x, y, w, h) = Shape(w*sin.(ang).+x, h*cos.(ang).+y)
myshapes = [ellipse(x,rand(),rand(),rand()) for x = 1:4]
@test coords(myshapes) isa Tuple{Vector{Vector{S}}, Vector{Vector{T}}} where {T,S}
local p
@test_nowarn p = plot(myshapes)
@test p[1][1][:seriestype] == :shape
end
end
@testset "Brush" begin
@testset "Colors" begin
baseline = brush(1, RGB(0,0,0))
@test brush(:black) == baseline
@test brush("black") == baseline
end
@testset "Weight" begin
@test brush(10).size == 10
@test brush(0.1).size == 1
end
@testset "Alpha" begin
@test brush(0.4).alpha == 0.4
@test brush(20).alpha == nothing
end
@testset "Bad Argument" begin
# using test_logs because test_warn seems to not work anymore
@test_logs (:warn,"Unused brush arg: nothing (Nothing)") begin
brush(nothing)
end
end
end
@testset "Fonts" begin
@testset "Scaling" begin
sizesToCheck = [:titlefontsize, :legendfontsize, :legendtitlefontsize,
:xtickfontsize, :ytickfontsize, :ztickfontsize,
:xguidefontsize, :yguidefontsize, :zguidefontsize,]
# get inital font sizes
initialSizes = [Plots.default(s) for s in sizesToCheck ]
#scale up font sizes
scalefontsizes(2)
# get inital font sizes
doubledSizes = [Plots.default(s) for s in sizesToCheck ]
@test doubledSizes == initialSizes*2
# reset font sizes
resetfontsizes()
finalSizes = [Plots.default(s) for s in sizesToCheck ]
@test finalSizes == initialSizes
end
end
@testset "Series Annotations" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
@test_logs (:warn,"Unused SeriesAnnotations arg: triangle (Symbol)") begin
p = plot([1,2,3],
series_annotations=(["a"],
2, # pass a scale factor
(1,4), # pass two scale factors (overwrites first one)
square, # pass a shape
font(:courier), # pass an annotation font
:triangle # pass an incorrect argument
))
sa = p.series_list[1].plotattributes[:series_annotations]
@test sa.strs == ["a"]
@test sa.font.family == "courier"
@test sa.baseshape == square
@test sa.scalefactor == (1,4)
end
end
+13
View File
@@ -0,0 +1,13 @@
using Plots, Test
const PLOTS_DEFAULTS = Dict(:theme => :wong2, :fontfamily => :palantino)
Plots.__init__()
@testset "Loading theme" begin
pl = plot(1:5)
@test pl[1][1][:seriescolor] == RGBA(colorant"black")
@test guidefont(pl[1][:xaxis]).family == "palantino"
end
empty!(PLOTS_DEFAULTS)
Plots.__init__()
+115 -22
View File
@@ -21,12 +21,12 @@ end
@test !haskey(axis.contents[1].options.dict, "fill")
@testset "Legends" begin
legends_plot = plot( rand(5,2), lab = ["1" ""] )
scatter!(legends_plot, rand(5) )
legends_plot = plot(rand(5, 2), lab = ["1" ""])
scatter!(legends_plot, rand(5))
Plots._update_plot_object(legends_plot)
axis_contents = Plots.pgfx_axes(legends_plot.o)[1].contents
leg_entries = filter( x -> x isa PGFPlotsX.LegendEntry, axis_contents )
series = filter( x -> x isa PGFPlotsX.Plot, axis_contents )
leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents)
series = filter(x -> x isa PGFPlotsX.Plot, axis_contents)
@test length(leg_entries) == 2
@test !haskey(series[1].options.dict, "forget plot")
@test haskey(series[2].options.dict, "forget plot")
@@ -71,7 +71,7 @@ end
pl = scatter!(
y,
zcolor = abs.(y .- 0.5),
m = (:heat, 0.8, Plots.stroke(1, :green)),
m = (:hot, 0.8, Plots.stroke(1, :green)),
ms = 10 * abs.(y .- 0.5) .+ 4,
lab = ["grad", "", "ient"],
)
@@ -84,15 +84,15 @@ end
@test marker.options["mark"] == "*"
@test marker.options["mark options"]["color"] ==
RGBA{Float64}(colorant"green", 0.8)
@test marker.options["mark options"]["line width"] == 1
@test marker.options["mark options"]["line width"] == 0.75 # 1px is 0.75pt
end # testset
@testset "Plot in pieces" begin
pic = plot(rand(100) / 3, reg = true, fill = (0, :green))
scatter!(pic, rand(100), markersize = 6, c = :orange)
Plots._update_plot_object(pic)
axis_contents = Plots.pgfx_axes(pic.o)[1].contents
leg_entries = filter( x -> x isa PGFPlotsX.LegendEntry, axis_contents )
series = filter( x -> x isa PGFPlotsX.Plot, axis_contents )
leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents)
series = filter(x -> x isa PGFPlotsX.Plot, axis_contents)
@test length(leg_entries) == 2
@test length(series) == 4
@test haskey(series[1].options.dict, "forget plot")
@@ -106,7 +106,7 @@ end
end), Plots._shape_keys)
markers = reshape(markers, 1, length(markers))
n = length(markers)
x = (range(0, stop = 10, length = n + 2))[2:(end - 1)]
x = (range(0, stop = 10, length = n + 2))[2:(end-1)]
y = repeat(reshape(reverse(x), 1, :), n, 1)
scatter(
x,
@@ -122,7 +122,7 @@ end
plot(
Plots.fakedata(100, 10),
layout = 4,
palette = [:grays :blues :heat :lightrainbow],
palette = [:grays :blues :hot :rainbow],
bg_inside = [:orange :pink :darkblue :black],
)
end # testset
@@ -211,7 +211,7 @@ end
marker_z = ((x, y) -> begin
x + y
end),
color = :bluesreds,
color = :bwr,
legend = false,
)
plot(p1, p2)
@@ -231,7 +231,7 @@ end
# TODO: support :semi
end # testset
@testset "Quiver" begin
x = (-2pi):0.2:(2 * pi)
x = (-2pi):0.2:(2*pi)
y = sin.(x)
u = ones(length(x))
@@ -255,7 +255,7 @@ end
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 1
mktempdir() do path
file_path =joinpath(path,"annotations.tex")
file_path = joinpath(path, "annotations.tex")
@test_nowarn savefig(pgfx_plot, file_path)
open(file_path) do io
lines = readlines(io)
@@ -271,7 +271,7 @@ end
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 3
mktempdir() do path
file_path =joinpath(path,"annotations.tex")
file_path = joinpath(path, "annotations.tex")
@test_nowarn savefig(pgfx_plot, file_path)
open(file_path) do io
lines = readlines(io)
@@ -296,12 +296,17 @@ end
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 9
mktempdir() do path
file_path =joinpath(path,"annotations.tex")
file_path = joinpath(path, "annotations.tex")
@test_nowarn savefig(annotation_plot, file_path)
open(file_path) do io
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 9
end
# test .tikz extension
file_path = joinpath(path, "annotations.tikz")
@test_nowarn savefig(annotation_plot, file_path)
@test_nowarn open(file_path) do io
end
end
end # testset
@testset "Ribbon" begin
@@ -314,15 +319,103 @@ end
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 length(plots) == 3
@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
@testset "Markers and Paths" begin
pl = plot(
5 .- ones(9),
markershape = [:utriangle, :rect],
markersize = 8,
color = [:red, :black],
)
Plots._update_plot_object(pl)
axis = Plots.pgfx_axes(pl.o)[1]
plots = filter(x -> x isa PGFPlotsX.Plot, axis.contents)
@test length(plots) == 9
end # testset
@testset "Groups and Subplots" begin
group = rand(map((i->begin
"group $(i)"
end), 1:4), 100)
pl = plot(rand(100), layout = @layout([a b; c]), group = group, linetype = [:bar :scatter :steppre], linecolor = :match)
Plots._update_plot_object(pl)
axis = Plots.pgfx_axes(pl.o)[1]
legend_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis.contents)
@test length(legend_entries) == 2
end
end # testset
@testset "Extra kwargs" begin
pl = plot(1:5, test = "me")
@test pl[1][1].plotattributes[:extra_kwargs][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :subplot)
@test pl[1].attr[:extra_kwargs][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :plot)
@test pl.attr[:extra_plot_kwargs][:test] == "me"
pl = plot(
1:5,
extra_kwargs = Dict(
:plot => Dict(:test => "me"),
:series => Dict(:and => "me too"),
),
)
@test pl.attr[:extra_plot_kwargs][:test] == "me"
@test pl[1][1].plotattributes[:extra_kwargs][:and] == "me too"
pl = plot(
plot(1:5, title = "Line"),
scatter(
1:5,
title = "Scatter",
extra_kwargs = Dict(:subplot => Dict("axis line shift" => "10pt")),
),
)
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test !haskey(axes[1].options.dict, "axis line shift")
@test haskey(axes[2].options.dict, "axis line shift")
pl = plot(
x -> x,
-1:1;
add = raw"\node at (0,0.5) {\huge hi};",
extra_kwargs = :subplot,
)
@test pl[1][:extra_kwargs] == Dict(:add => raw"\node at (0,0.5) {\huge hi};")
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test filter(x -> x isa String, axes[1].contents)[1] ==
raw"\node at (0,0.5) {\huge hi};"
plot!(pl)
@test pl[1][:extra_kwargs] == Dict(:add => raw"\node at (0,0.5) {\huge hi};")
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test filter(x -> x isa String, axes[1].contents)[1] ==
raw"\node at (0,0.5) {\huge hi};"
end # testset
@testset "Titlefonts" begin
pl = plot(1:5, title = "Test me", titlefont = (2, :left))
@test pl[1][:title] == "Test me"
@test pl[1][:titlefontsize] == 2
@test pl[1][:titlefonthalign] == :left
Plots._update_plot_object(pl)
ax_opt = Plots.pgfx_axes(pl.o)[1].options
@test ax_opt["title"] == "Test me"
@test(haskey(ax_opt.dict, "title style")) isa Test.Pass
pl = plot(1:5, plot_title = "Test me", plot_titlefont = (2, :left))
@test pl[:plot_title] == "Test me"
@test pl[:plot_titlefontsize] == 2
@test pl[:plot_titlefonthalign] == :left
pl = heatmap(
rand(3, 3),
colorbar_title = "Test me",
colorbar_titlefont = (12, :right),
)
@test pl[1][:colorbar_title] == "Test me"
@test pl[1][:colorbar_titlefontsize] == 12
@test pl[1][:colorbar_titlefonthalign] == :right
end # testset
+49
View File
@@ -0,0 +1,49 @@
using Plots, Test
using OffsetArrays
@testset "lens!" begin
pl = plot(1:5)
lens!(pl, [1,2], [1,2], inset = (1, bbox(0.0,0.0,0.2,0.2)), colorbar = false)
@test length(pl.series_list) == 4
@test pl[2][:colorbar] == :none
end # testset
@testset "vline, vspan" begin
vl = vline([1], widen = false)
@test Plots.xlims(vl) == (1,2)
@test Plots.ylims(vl) == (1,2)
vl = vline([1], xlims=(0,2), widen = false)
@test Plots.xlims(vl) == (0,2)
vl = vline([1], ylims=(-3,5), widen = false)
@test Plots.ylims(vl) == (-3,5)
vsp = vspan([1,3], widen = false)
@test Plots.xlims(vsp) == (1,3)
@test Plots.ylims(vsp) == (0,1) # TODO: might be problematic on log-scales
vsp = vspan([1,3], xlims=(-2,5), widen = false)
@test Plots.xlims(vsp) == (-2,5)
vsp = vspan([1,3], ylims=(-2,5), widen = false)
@test Plots.ylims(vsp) == (-2,5)
end # testset
@testset "offset axes" begin
tri = OffsetVector(vcat(1:5, 4:-1:1), 11:19)
sticks = plot(tri, seriestype = :sticks)
@test length(sticks) == 1
end
@testset "framestyle axes" begin
pl = plot(-1:1, -1:1, -1:1)
sp = pl.subplots[1]
defaultret = Plots.axis_drawing_info_3d(sp, :x)
for letter in [:x, :y, :z]
for fr in [:box :semi :origin :zerolines :grid :none]
prevha = UInt64(0)
push!(sp.attr, :framestyle => fr)
ret = Plots.axis_drawing_info_3d(sp, letter)
ha = hash(string(ret))
@test ha != prevha
prevha = ha
end
end
end
+48
View File
@@ -0,0 +1,48 @@
using Plots, Test
@testset "Shorthands" begin
@testset "Set Lims" begin
p = plot(rand(10))
xlims!((1,20))
@test xlims(p) == (1,20)
ylims!((-1,1))
@test ylims(p) == (-1,1)
zlims!((-1,1))
@test zlims(p) == (-1,1)
xlims!(-1,11)
@test xlims(p) == (-1,11)
ylims!((-10,10))
@test ylims(p) == (-10,10)
zlims!((-10,10))
@test zlims(p) == (-10,10)
end
@testset "Set Ticks" begin
p = plot([0,2,3,4,5,6,7,8,9,10])
xticks = 2:6
xticks!(xticks)
@test Plots.get_subplot(current(),1).attr[:xaxis][:ticks] == xticks
yticks = 0.2:0.1:0.7
yticks!(yticks)
@test Plots.get_subplot(current(),1).attr[:yaxis][:ticks] == yticks
xticks = [5,6,7.5]
xlabels = ["a","b","c"]
xticks!(xticks, xlabels)
@test Plots.get_subplot(current(),1).attr[:xaxis][:ticks] == (xticks, xlabels)
yticks = [.5,.6,.75]
ylabels = ["z","y","x"]
yticks!(yticks, ylabels)
@test Plots.get_subplot(current(),1).attr[:yaxis][:ticks] == (yticks, ylabels)
end
end