Compare commits

...

321 Commits

Author SHA1 Message Date
mantaohuang
2a7a1f2e2a remove math font from tick font dict 2022-05-14 02:05:58 -04:00
github-actions[bot]
18b11a71e3
Update precompile_*.jl file [skip ci] (#4197)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-05-06 08:51:03 +02:00
Simon Christ
9e34ed0383
add permute, deprecate orientation (#4164)
* add series_permutation

* works for dates and categorical input, not vector of strings

* Update src/pipeline.jl

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update src/pipeline.jl

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* add test

* correct test

* make bar workign

* add deprecation

* rename series_permutation -> permute

* add Documentation

* fix uneccessary deprecation

* permute h/vlines

* Auto-format

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* 1.29.0

* Update Project.toml [skip ci]

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-05-05 15:15:56 +02:00
Simon Christ
561839a029
1.28.2 2022-05-05 11:40:46 +02:00
github-actions[bot]
88f2541288
Update precompile_*.jl file [skip ci] (#4194)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-05-04 21:37:19 +02:00
Simon Christ
92611ea3b4
reset marker_z for errorbars (#4193)
* reset marker_z for errorbars

* also reset line_z
2022-05-04 16:58:23 +02:00
Simon Christ
3e1bad0971
Update SnoopCompile.yml 2022-05-04 14:14:48 +02:00
Simon Christ
a13d4d8554
1.28.1 2022-05-02 17:11:46 +02:00
Jeremiah
b76dc2d7a3
quarto pdf fix? (#4188) 2022-05-02 14:25:17 +02:00
zhiyuanzhai
137d339e0b
Fixing the colorbar title for colorbars on the top. (#4191)
* To fix #4183.

* Providing my information according to #3503.
2022-05-02 11:00:50 +02:00
Simon Christ
e06143ce33
fix #4190 2022-05-02 09:28:55 +02:00
Simon Christ
06220420a3
1.28.0 2022-04-29 12:57:16 +02:00
Simon Christ
d8da3c60d9
update anshul's data 2022-04-28 09:05:49 +02:00
t-bltg
9e92ada61a
Update examples.jl 2022-04-26 16:29:08 +02:00
t-bltg
cebca5174b
UnicodePlots: support polarplot (#4185) 2022-04-26 15:36:23 +02:00
Stephan Antholzer
e3e86aa6cd
merge series extra_kwargs for plotly_series (#4172) 2022-04-22 11:12:55 +02:00
Simon Christ
add8364bbd
1.27.6 2022-04-20 17:39:10 +02:00
github-actions[bot]
09abf2e40f
Update precompile_*.jl file [skip ci] (#4174)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-04-20 09:12:50 +02:00
Benoit Pasquier
182d4683e6
Add areaplot example to gallery (#4178)
* Add areaplot example to gallery

Not sure this is the right way to add example to the gallery but hopefully this is helpful :)

* format files

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2022-04-19 16:03:50 +02:00
t-bltg
a681f3e307
Update SnoopCompile.yml 2022-04-16 15:17:41 +02:00
t-bltg
1c59b19343
Update SnoopCompile.yml 2022-04-16 15:13:29 +02:00
t-bltg
6773666549
Update SnoopCompile.yml 2022-04-16 14:59:00 +02:00
t-bltg
42bf100ad3
Update precompile_Plots.jl 2022-04-16 14:53:10 +02:00
t-bltg
e826c87114
Update SnoopCompile.yml 2022-04-16 14:27:59 +02:00
Jeff Bezanson
616d72476a
Add version check for 1.8 precompiles (#4179)
Co-authored-by: t-bltg <tf.bltg@gmail.com>
2022-04-14 13:32:59 +02:00
Simon Christ
4f9a708f66
fix empty segments in plotly (#4177)
* fix empty segment case

* fix failure on 1.6
2022-04-08 16:39:37 +02:00
t-bltg
4b73b8b5d5
Update docs build (#4175) 2022-04-05 20:08:31 +02:00
t-bltg
99ad317590
1.27.5 2022-04-05 16:27:46 +02:00
github-actions[bot]
90975d95f8
Update precompile_*.jl file [skip ci] (#4173)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-04-05 16:27:15 +02:00
t-bltg
f0a1ef8a0c
Update gaston.jl 2022-04-05 15:26:17 +02:00
t-bltg
49aee2d204
Update unicodeplots.jl 2022-04-05 15:02:56 +02:00
t-bltg
02351a45b4
UnicodePlots: rework png output (#4171) 2022-04-05 14:56:47 +02:00
Simon Christ
e691a42b90 add docs to scale, rotate 2022-04-05 14:52:51 +02:00
Simon Christ
8a584ceab4 add/ rearrange docstrings 2022-04-05 13:43:19 +02:00
t-bltg
cc1bd28ccd
Disable warnings on experimental backends (#4169) 2022-04-05 00:52:49 +02:00
t-bltg
4446a63135
Update docs CI (font) 2022-04-05 00:15:39 +02:00
github-actions[bot]
412a8993ad
Update precompile_*.jl file [skip ci] (#4167)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-04-05 00:03:07 +02:00
Fons van der Plas
d9fb8b8ef3
Remove Main.Plots dependency (#4168) 2022-04-04 23:36:52 +02:00
github-actions[bot]
37eb1db8d2
Update precompile_*.jl file [skip ci] (#4165)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-04-04 18:14:58 +02:00
t-bltg
dc3e3176f2
UnicodePlots: fix internal change 2022-04-04 18:10:58 +02:00
github-actions[bot]
2cd3331f30
Update precompile_*.jl file [skip ci] (#4163)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-04-01 11:22:07 +02:00
github-actions[bot]
db932d62f6
CompatHelper: bump compat for PlotThemes to 3, (keep existing compat) (#4162)
Co-authored-by: CompatHelper Julia <compathelper_noreply@julialang.org>
2022-04-01 11:17:47 +02:00
Simon Christ
caf4d1857c
1.27.4 2022-03-30 16:35:47 +02:00
github-actions[bot]
bbde8ad1b1
Update precompile_*.jl file [skip ci] (#4154)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-03-30 15:43:45 +02:00
Simon Christ
d3449331c9 remove Shape from _pgfplotsx_marker 2022-03-30 15:38:11 +02:00
Ian Butterworth
eb746d1641
Sort supported args (#4156)
* sort supported args

* Update src/args.jl

* sort all supported* functions

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2022-03-29 17:42:23 +02:00
Steve Leung
a33c0205b2
Restored plotly hover functionality for plots with multidimensional data (#4159)
* Restored hover functionality for plots with multidimensional data

* Renamed plotly_hover!() to plotly_adjust_hover_label!()

* Updated contributors list

* Update src/backends/plotly.jl [skip ci]

Co-authored-by: t-bltg <tf.bltg@gmail.com>

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
Co-authored-by: t-bltg <tf.bltg@gmail.com>
2022-03-29 17:42:01 +02:00
Simon Christ
65ab68c3b5
fix legends for arrows (#4161)
* fix legends for arrows

* Apply suggestions from code review [skip ci]

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* raise tolerance on windows

* Update test/runtests.jl [skip ci]

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-03-29 17:41:25 +02:00
t-bltg
0f4a0c7154
fix examples 2022-03-27 12:09:54 +02:00
t-bltg
02d08beb1e
improve coverage (#4155) 2022-03-27 01:42:05 +01:00
Simon Christ
d3817796a4
1.27.3 2022-03-25 17:41:01 +01:00
Simon Christ
dbe81dabd5
fix #4151 (#4153)
* letter and Set the consts

* use julia-code-style-suggesters

* remove superfluous name

* edit by copy of code-style-suggesters

* delete stuff

* remove using

* Apply suggestions from code review

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-03-25 17:39:54 +01:00
t-bltg
5c2cc926a6
docs: more verbosity 2022-03-24 13:13:38 +01:00
t-bltg
bcc66caf7d
1.27.2 [skip ci] 2022-03-23 20:07:36 +01:00
t-bltg
0686461686
UnicodePlots: png output (#4149) 2022-03-23 20:06:57 +01:00
github-actions[bot]
5c4fbc5e1a
Update precompile_*.jl file [skip ci] (#4143)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-03-22 10:35:19 +01:00
Simon Christ
5872bdefc4
1.27.1 2022-03-17 14:02:50 +01:00
Simon Christ
a4849da775 format [skip ci] 2022-03-17 12:07:54 +01:00
Simon Christ
afe24f46bc fix example 25 2022-03-17 12:04:47 +01:00
Simon Christ
79638b7789
Update examples.jl 2022-03-17 09:12:02 +01:00
github-actions[bot]
e82e95c8e3
Update precompile_*.jl file [skip ci] (#4140)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-03-17 09:05:56 +01:00
Simon Christ
843226bfe1
Revert "annotations over marksers in pgfplotsx backend (#3957)" (#4142)
This reverts commit 06bc99ef68dca50fd3f91cadff0b5d210ad3fdbf.
2022-03-17 09:05:29 +01:00
Simon Christ
317bfc918a
1.27.0 2022-03-11 20:52:22 +01:00
Simon Christ
4665f5caab
fix compat check 2022-03-11 20:51:43 +01:00
Simon Christ
1520705fa7
add z_order (#4139)
* add z_order

* format

* add missing ,

* fix testss

* this time for real

* format [skip ci]
2022-03-11 15:57:06 +01:00
Simon Christ
b60cf3cc53
1.26.1 [skip ci] 2022-03-11 11:35:22 +01:00
Simon Christ
092fb67017
Actually check if the loaded backend version mets the compat entries (#4137)
* implement checking backend compat

* format

* handle backends without compat entry

* get version for julia 1.6
2022-03-11 10:49:40 +01:00
github-actions[bot]
4ebadb7612
Update precompile_*.jl file [skip ci] (#4132)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-03-07 11:23:57 +01:00
Simon Christ
fcd3246e4a
Update .zenodo.json 2022-03-04 13:36:14 +01:00
Simon Christ
5f858fe6f6
1.26.0 2022-03-02 09:45:32 +01:00
github-actions[bot]
8a4aea1fc7
Update precompile_*.jl file [skip ci] (#4126)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-03-02 09:44:48 +01:00
Simon Christ
3483799cfc
add compat entries (#4122) 2022-03-01 16:36:41 +01:00
Simon Christ
a5f52be5c2
1.25.12 2022-03-01 15:38:29 +01:00
t-bltg
2b7e304c7e
revert constant legend box (#4117) 2022-03-01 14:53:45 +01:00
github-actions[bot]
6c77801835
Update precompile_*.jl file [skip ci] (#4124)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-03-01 14:28:27 +01:00
Simon Christ
b34f8b87c1
check loaded_modules instead of Main for warnings about StatsPlots recipes (#4123)
* check loaded_modules instead of Main

* format
2022-03-01 09:23:10 +01:00
github-actions[bot]
5130da5a40
Update precompile_*.jl file [skip ci] (#4121)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-02-26 18:26:28 +01:00
Simon Christ
95fd48ed9b
Bbs/legendfontx (#4119)
* revert legendfont being determant

* format

* fix precompiles
2022-02-26 17:26:14 +01:00
Simon Christ
e31d056820
1.25.11 2022-02-20 14:43:34 +01:00
github-actions[bot]
afe85207e1
Update precompile_*.jl file [skip ci] (#4110)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-02-20 14:42:57 +01:00
Simon Christ
204b2178d0
better line (#4085) 2022-02-18 21:13:16 +01:00
Simon Christ
51358717ee
add slicing of tuples of matrices for plotattributes (#4109)
* add slicing of tuples of matrices

* remove dot

* format files
2022-02-18 21:12:44 +01:00
github-actions[bot]
ed9f0bcab3
Update precompile_*.jl file [skip ci] (#4101)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-02-18 13:55:22 +01:00
t-bltg
d342672dd2
Allow color on txt io (#4102) 2022-02-17 22:33:09 +01:00
github-actions[bot]
64d275e7cb
CompatHelper: bump compat for NaNMath to 1 (#4104)
Co-authored-by: CompatHelper Julia <compathelper_noreply@julialang.org>
2022-02-17 15:27:00 +01:00
t-bltg
a919fe59d3
Center :image axes ticks (#4088) 2022-02-16 22:05:50 +01:00
Josef Heinen
88cd04b46a
Bump Plots version
Bump Plots version to 1.25.10
2022-02-15 16:45:19 +01:00
Josef Heinen
325d60e8b8
Bump GR version
Bump GR version to 0.64
2022-02-15 15:24:04 +01:00
Simon Christ
20f576211c
1.25.9 2022-02-11 17:45:18 +01:00
github-actions[bot]
bb99e7a5ce
Update precompile_*.jl file [skip ci] (#4096)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-02-11 17:44:40 +01:00
Simon Christ
0813b18d69
Fix regression in legend font size setting (#4100)
* take legend font attributes from existing font

* "format" file

* format remaining files

* better in the error box
2022-02-11 15:26:01 +01:00
t-bltg
6c67908a3a
UnicodePlots: allow setting width / height 2022-02-09 16:04:22 +01:00
t-bltg
a361ba60b8
UnicodePlots: support zoom (#4099) 2022-02-09 14:30:51 +01:00
t-bltg
34c22970f2
UnicodePlots: update hack for png 2022-02-08 23:41:12 +01:00
t-bltg
5d8acf5189
UnicodePlots: add more extra_kwargs (#4097) 2022-02-08 20:56:54 +01:00
t-bltg
59cd5c180e
temporarily disable nightly precomp (#4095) 2022-02-08 13:20:11 +01:00
t-bltg
77e465a453
1.25.8 [skip ci] 2022-02-07 21:52:56 +01:00
github-actions[bot]
eb3e10ffa6
Update precompile_*.jl file [skip ci] (#4074)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-02-07 21:51:24 +01:00
t-bltg
bf5d1aa060
Fix plotattributes in _add_plot_title! (#4090)
Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2022-02-07 21:21:22 +01:00
t-bltg
ce70ec26a6
UnicodePlots: 3d support (#4089) 2022-02-07 20:22:39 +01:00
t-bltg
6e4cb5fedc
Fix example 41 (#4093) 2022-02-06 22:32:40 +01:00
Michael Krabbe Borregaard
2a7d2d710e
Merge pull request #4076 from JuliaPlots/mkb/fix_wand
fix the wand binning
2022-01-30 08:24:58 +01:00
t-bltg
e3ea97199f
Precompilation statements for nightly (#4082)
* enable precompilation on nightly

* update CompileBot, add precompile statements for nightly
2022-01-28 22:00:26 +01:00
t-bltg
2896c5a25a
Rework warn_on_unsupported (#4081) 2022-01-28 15:32:15 +01:00
t-bltg
824dbe9948
UnicodePlots: use more extra_kwargs (#4080) 2022-01-28 11:30:42 +01:00
t-bltg
3e8db4532b
UnicodePlots: toggle canvas blend with extra_kwargs 2022-01-28 10:30:27 +01:00
Michael Krabbe Borregaard
0ba580bcaa fix the wand binning 2022-01-26 17:28:56 +01:00
t-bltg
46e19d9ad5
Update docs.yml 2022-01-26 15:35:06 +01:00
t-bltg
b204918b23
Update docs.yml 2022-01-26 15:03:25 +01:00
Tom Gillam
5d5239834c
Example for vspan and hspan (#4062)
* Example for vspan and hspan

* Format

* First time contributor
2022-01-26 13:21:46 +01:00
github-actions[bot]
2ddedf97bf
Update precompile_*.jl file [skip ci] (#4071)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-01-26 11:12:38 +01:00
Simon Christ
5facd2bf55
1.25.7 2022-01-25 22:45:39 +01:00
Simon Christ
915df5d3ee
Fix ribbon slicing (#4068)
* move ribbon handling after slicing

* format file
2022-01-25 21:20:18 +01:00
Simon Christ
2eaf9f3b15
fix plotting empty plot for plotly (#4067) 2022-01-25 17:14:07 +01:00
github-actions[bot]
91bb983c08
Update precompile_*.jl file [skip ci] (#4056)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-01-25 11:06:47 +01:00
t-bltg
311831ca4e
UnicodePlots: do not show blank plots (on layouts) (#4058) 2022-01-22 18:26:13 +01:00
t-bltg
ab698da5a4
Add format check, reduce format PR frequency (#4053) 2022-01-22 16:10:28 +01:00
Tianyi Pu
34e581ff3f
Fix default docstring (#4057) 2022-01-22 15:58:30 +01:00
Zhanibek
acb5d5ac4b
gr-constant-legendbox (#4055) 2022-01-22 02:52:46 +09:00
Zhanibek
e8ac74a390
Revert "gr-constant-legendbox (#4043)" (#4054)
This reverts commit 806e7691851101b1586af2bc23f58b6415405631.
2022-01-22 01:27:28 +09:00
Zhanibek
806e769185
gr-constant-legendbox (#4043) 2022-01-22 01:27:01 +09:00
github-actions[bot]
bcd98737bb
Update precompile_*.jl file [skip ci] (#4050)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-01-19 21:13:01 +01:00
t-bltg
f333cb284a
UnicodePlots: basic quiver and contour support (#4031)
* basic quiver support

* toggle grid

* add contour

* add colorbar

* toggle contour example

* rework keywords
2022-01-19 18:58:11 +01:00
github-actions[bot]
1f49839529
Format .jl files [skip ci] (#4042)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-01-17 12:50:54 +01:00
Simon Christ
536712359c
Update README.md 2022-01-15 10:48:21 +01:00
Simon Christ
b13f3d5021
direct docs link to stable [skip ci] 2022-01-13 10:51:09 +01:00
Simon Christ
2e4344b9b5
Update Project.toml 2022-01-13 09:42:41 +01:00
Josef Heinen
16e5a49800
Bump GR version 2022-01-13 06:29:50 +01:00
Simon Christ
67bd08614a
1.25.6 2022-01-12 16:31:04 +01:00
Simon Christ
a24fb93ab1
Move fillrange and ribbon logic from RecipesPipeline and add tests for default function (#4030)
* add tests for default function

* remove fillrange and ribbon handling from RecipesPipeline

* adjust compat
2022-01-12 15:30:52 +01:00
github-actions[bot]
b1c11cca33
Update precompile_*.jl file [skip ci] (#4032)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-01-12 15:30:26 +01:00
Pearl Li
cffeba7609
Check if plot title already exists before adding again (#4027)
* Check if plot title already exists before adding again

* Add plot title tests
2022-01-12 14:52:43 +01:00
github-actions[bot]
2872c7a345
Update precompile_*.jl file [skip ci] (#4029)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2022-01-12 13:57:25 +01:00
Simon Christ
3313780b4e
add Downloads badge 2022-01-11 20:37:10 +01:00
t-bltg
47ca50d037
1.25.5 [skip ci] 2022-01-11 11:18:42 +01:00
github-actions[bot]
1014b8f494
Update precompile_*.jl file [skip ci] (#4022)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-01-05 14:17:55 +01:00
github-actions[bot]
ece53c5fd1
Format .jl files [skip ci] (#4023)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2022-01-05 14:17:40 +01:00
t-bltg
c34d4e950e
UnicodePlots: fix ansi regex 2022-01-01 10:35:55 +01:00
t-bltg
b6d7bd82e6
UnicodePlots: enhance display / show (#4021) 2021-12-31 16:04:02 +01:00
t-bltg
e5883a3447
1.25.4 [skip ci] 2021-12-29 16:17:50 +01:00
github-actions[bot]
ead9d87942
Update precompile_*.jl file [skip ci] (#4018)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-12-29 15:24:32 +01:00
t-bltg
0beba9d1c8
Update and rename SnoopCompile.yml to CompileBot.yml 2021-12-29 14:16:23 +01:00
t-bltg
6e79cf4a3e
Run SnoopCompile on master only 2021-12-29 14:04:38 +01:00
github-actions[bot]
693391e135
Update precompile_*.jl file [skip ci] (#4015)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-12-29 14:03:04 +01:00
Chris Elrod
95d1fa0001
Set max_methods=1 (#4010) 2021-12-29 13:31:29 +01:00
Diego Javier Zea
30d2f01d9d
Update boxplot doc (#4014)
Update and improve whisker_width documentation (boxplots).
2021-12-29 13:30:00 +01:00
Zhanibek
834a1523af add extrakw for colorbar positioning control in 3d 2021-12-27 23:44:37 +09:00
Josef Heinen
e0bc4b1406
[GR] bump version
bump GR version
2021-12-22 12:59:42 +01:00
Simon Christ
492f94bf10
Fix fillranges with OffsetVectors for plotly (#4006)
* don't mutate the Plot object

* remove show

* collect vectors to workaround vcat issue
2021-12-20 21:24:58 +01:00
Simon Christ
cb359c0d4e
1.25.3 [skip ci] 2021-12-20 21:01:25 +01:00
Yuval
3af92908ee
Merge pull request #3988 from yha/yha/boxplot-whisker-range
boxplots docs update: rename range->whisker_range
2021-12-20 18:48:36 +02:00
github-actions[bot]
5d97de1345
Format .jl files [skip ci] (#4012)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-12-19 23:21:41 +01:00
Simon Christ
f784010c29 add text/latex mimetype 2021-12-17 17:50:07 +01:00
Yuval
d618f2e2ca
Merge pull request #3998 from yha/yha/Unzip2
Use Unzip.unzip
2021-12-16 17:13:21 +02:00
github-actions[bot]
d970a6568e
Format .jl files [skip ci] (#3997)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-12-12 13:04:15 +01:00
yha
7de50f91de Undo unrelated change 2021-12-12 11:26:05 +02:00
yha
15ce6ebfeb Use Unzip.unzip 2021-12-12 11:16:42 +02:00
Simon Christ
75938bf747
give TagBot its own key [skip ci] 2021-12-10 14:59:14 +01:00
github-actions[bot]
b3e6e92698
Update precompile_*.jl file [skip ci] (#3995)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-12-09 16:23:45 +01:00
Simon Christ
b3002c5457
add manual trigger 2021-12-09 15:56:20 +01:00
Simon Christ
6b44955bc4
1.25.2 [skip ci] 2021-12-09 13:55:48 +01:00
Simon Christ
c28bf96c4a Merge branch 'master' of github.com:JuliaPlots/Plots.jl 2021-12-09 11:54:21 +01:00
Simon Christ
096d293550 fix gr fontcolor setting 2021-12-09 11:54:15 +01:00
Simon Christ
cab76f67e2
fix scale warnings for layouts (#3992)
* fix scale warnings for layouts

* don't run ci twice on PR

* use broadcasting for scalar case
2021-12-09 10:32:06 +01:00
github-actions[bot]
461476f4ed
Update precompile_*.jl file [skip ci] (#3990)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-12-08 16:53:39 +01:00
Simon Christ
11eea2453f
check ref in docs action 2021-12-08 16:08:58 +01:00
Simon Christ
b51cddceb5
add DOCUMENTER_KEY to TagBot action 2021-12-08 15:53:32 +01:00
yha
60222095b6 boxplots: rename range->whisker_range 2021-12-07 19:13:32 +02:00
Simon Christ
5dd0ca27a5
1.25.1 [skip ci] 2021-12-07 17:37:39 +01:00
github-actions[bot]
249ce48cb4
Update precompile_*.jl file [skip ci] (#3987)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-12-07 17:24:53 +01:00
Simon Christ
5f7c2a5eae Fix #3984 2021-12-07 17:05:40 +01:00
github-actions[bot]
9e23082a7d
Format .jl files [skip ci] (#3981)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-12-05 10:36:34 +01:00
github-actions[bot]
ef3038314d
Update precompile_*.jl file [skip ci] (#3979)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-12-02 20:58:24 +01:00
Jks Liu
c4752b786b
Fix #3967 (#3978)
Pluto do not use require.js, so Plotly is not renamed to Plotly2
2021-12-02 16:33:52 +01:00
t-bltg
a75b17e42f
Bump version to 1.25.0 (#3977) [skip ci]
* bump version
* deprecate NEWS.md
2021-12-02 13:40:25 +01:00
github-actions[bot]
c7e3049dac
Update precompile_*.jl file [skip ci] (#3976)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-12-02 12:03:05 +01:00
t-bltg
3405d2991a
Versioned precompile script - drop 1.5 - support 1.6 and 1.7 (#3972)
* versioned precompile script

* add explicit minor version in CI

* revert to supporting 1.5 - 1.7

* update precompile_includer

* drop support for 1.5, bump to 1.6

* Update ci.yml

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2021-12-02 11:38:45 +01:00
Simon Christ
ca0e52b622
test on 1.6 also (#3966)
* test on 1.6 also

* Update ci.yml

* Update ci.yml

* Update ci.yml

* Update ci.yml

live up to the claimed `[compat]`

* change matrix

* remove ifs

* update include

* split include array

Co-authored-by: Jerry Ling <proton@jling.dev>
2021-12-01 22:24:57 +01:00
t-bltg
b1c56126fb
Fix missing examples backend 2021-12-01 17:43:52 +01:00
t-bltg
e1f507b77f
Update doc examples 2021-12-01 17:30:24 +01:00
t-bltg
0b1ca841cd
1.24.4 [skip ci] 2021-12-01 14:31:41 +01:00
github-actions[bot]
b341df1cb8
Update precompile_*.jl file [skip ci] (#3963)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-12-01 14:30:42 +01:00
Jks Liu
79cf62cf91
Upgrade plotly.js to v2.6.3 (#3958)
* Upgrade plotly.js to version 2.6.3

* plotly polar support, api changed in plotly.js v2.x.x

https://plotly.com/javascript/polar-chart/
https://community.plotly.com/t/announcing-plotly-js-2-0/53675
2021-12-01 13:45:23 +01:00
Simon Christ
c32dbeef8a
1.24.3[skip ci] 2021-11-29 09:46:26 +01:00
chwons
06bc99ef68
annotations over marksers in pgfplotsx backend (#3957) 2021-11-29 09:36:08 +01:00
t-bltg
9305cd41ab
PGFPlotsX: fix log scale power with custom ticks (#3961) 2021-11-29 09:31:47 +01:00
github-actions[bot]
7427a85661
Update precompile_*.jl file [skip ci] (#3956)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-11-29 09:23:18 +01:00
t-bltg
8abae0c575
Formatter: use latest CSTParser tagged version 2021-11-28 13:40:49 +01:00
github-actions[bot]
3963957e70
Format .jl files [skip ci] (#3960)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-11-28 10:27:13 +01:00
Simon Christ
58381822d9
1.24.2 [skip ci] 2021-11-26 14:23:03 +01:00
github-actions[bot]
2472ce164b
Update precompile_*.jl file [skip ci] (#3955)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-11-26 13:34:09 +01:00
Simon Christ
c94cf1855d fix plotly 2021-11-26 13:32:29 +01:00
Simon Christ
6baa120245
fix transposing in plotlyjs (#3953)
* fix transposing

* fix plotly_series
2021-11-26 09:59:44 +01:00
Simon Christ
7e5ba301fd
add documentation for legend_column 2021-11-26 09:47:59 +01:00
Simon Christ
138589bb61
1.24.1 [skip ci] 2021-11-25 14:38:34 +01:00
Simon Christ
c2af71756e
add missing get_clims in GR (#3950) 2021-11-25 14:34:15 +01:00
Simon Christ
c1e88d0360
1.24.0 [skip ci] 2021-11-25 12:17:23 +01:00
github-actions[bot]
e0ea601239
Update precompile_*.jl file [skip ci] (#3949)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-11-25 12:15:50 +01:00
Simon Christ
e471ce8d28
rework layout macro to use Base types (#3943)
* @layout -> Base types except for `grid` call

* add layout conversion of namedtuples, vectors and matrices

* add missing method

* rip it out

* fix slicing

* adjust compat

* add Measure conversion
2021-11-25 11:40:25 +01:00
Simon Christ
1bdec476c3 add missing docstrings 2021-11-25 10:23:44 +01:00
github-actions[bot]
b23c620d77
Format .jl files [skip ci] (#3941)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-11-15 09:56:31 +01:00
Simon Christ
21c3ac4c45
1.23.6 [skip ci] 2021-11-11 10:30:39 +01:00
github-actions[bot]
861f537736
Update precompile_*.jl file [skip ci] (#3939)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-11-11 10:27:14 +01:00
Simon Christ
e9ae75dfa4
Fix setting of legend font via legend_font (#3934)
* find pipeline spot

* better spot

* construct font

* set font and matching

* respect defaults
2021-11-11 09:48:29 +01:00
github-actions[bot]
07bcecd47c
Update precompile_*.jl file [skip ci] (#3937)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-11-10 21:18:39 +01:00
Simon Christ
af3ebe9936
split looops (#3931) 2021-11-10 20:34:49 +01:00
github-actions[bot]
9d3ce54c37
Format .jl files [skip ci] (#3927)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-11-09 16:13:21 +01:00
Josef Heinen
6df1f38492 gr: fix text problems 2021-11-03 14:43:06 +01:00
Simon Christ
c4b7757e22
1.23.4 [skip ci] 2021-11-03 10:53:01 +01:00
t-bltg
d1309c6c7b
Fix LaTeXStrings support for UnicodePlots and InspectDR (#3879)
* fix LaTeXStrings support for UnicodePlots and InspectDR

* rename & fix
2021-11-03 09:22:37 +01:00
github-actions[bot]
58ed4a60de
Update precompile_*.jl file [skip ci] (#3919)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-11-02 20:39:32 +01:00
Lukas Hauertmann
70dec42308
Add :log10-colorbar_scale support in GR (#3915)
* Add `:log10`-`colorbar_scale` support in GR

* Change `clims` behaviour (gr heatmap)
2021-11-02 19:08:10 +01:00
Simon Christ
fdbd2c397c
GR compat and 1.23.3 [skip ci] 2021-11-02 13:46:23 +01:00
github-actions[bot]
c337f15e18
Update precompile_*.jl file [skip ci] (#3916)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-11-01 14:16:28 +01:00
Simon Christ
1fe9a9f536 update gaston backend 2021-11-01 13:52:03 +01:00
github-actions[bot]
41cf64b400
Format .jl files [skip ci] (#3914)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-11-01 12:46:08 +01:00
Josef Heinen
19b70c06ff
Update gr.jl
Use new text functionality. GR v0.62+ can handle multiline strings and inline math expressions.
2021-10-29 15:22:37 +02:00
Josef Heinen
40fe8eed9a
Update Project.toml
add GR v0.62.0
2021-10-29 13:33:04 +02:00
Simon Christ
4b94384c7d
support axis flip (#3908) 2021-10-29 12:01:07 +02:00
Simon Christ
35e96a5302
1.23.2 [skip ci] 2021-10-28 16:13:37 +02:00
Simon Christ
e84905c2a0
detect aliases in recipes (#3904)
* detect aliases in recipes

* remove doubled tests
2021-10-28 16:12:59 +02:00
Simon Christ
1c621feacc
1.23.1 [skip ci] 2021-10-26 09:17:12 +02:00
Simon Christ
e8356965e9 fix pyplot backend 2021-10-26 09:15:46 +02:00
Nicholas Bauer
72428000cc
Moved clims into plot/series attributes (#3897)
* Moved limits into plot/series attributes

* Moved const to args
2021-10-26 09:09:23 +02:00
Simon Christ
d9116d577f
1.23.0 [skip ci] 2021-10-25 15:02:58 +02:00
github-actions[bot]
96dbd07627
Update precompile_*.jl file [skip ci] (#3889)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-10-25 09:00:09 +02:00
github-actions[bot]
804fab45ad
Format .jl files [skip ci] (#3896)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-10-25 08:57:08 +02:00
Simon Christ
2e67e84361
Legend overhaul including horizontal legends (#2854)
* prototype

* use add_attributes macro with modification

* add Colors back

* fix convertLegendValue

* fix legendtitlefontsize

* fix gr legend position

* fix aliases

* symbolic color is okay

* remove redundant legend_forground_color aliases

* legend -> legend_postion

* fix inspectdr

* add legendtitlefont pointsize and color

* fix symbol cache

* fix rebase woes

* Update precompile_*.jl file [skip ci] (#3885)

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

* fix gr

* more fixes

* add match_table to `@add_attributes`

* fix match_map

* Update src/backends/pgfplotsx.jl

Co-authored-by: t-bltg <tf.bltg@gmail.com>

* fix font calls

* apply formatter

* readd descriptions

* more missing descriptions

* adjust pyplot to master

* fix pgfplotsx

* Revert "Merge branch 'bbs/horizontal-legends' of https://github.com/JuliaPlots/Plots.jl into bbs/horizontal-legends"

This reverts commit d880d89ef66eb18731bc67d32d627dd690c6d9e5.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
Co-authored-by: t-bltg <tf.bltg@gmail.com>
2021-10-22 15:09:14 +02:00
Simon Christ
b298711379
1.22.7 [skip ci] 2021-10-22 15:04:30 +02:00
t-bltg
bacf2d2f06
Update SnoopCompile.yml 2021-10-20 13:47:07 +02:00
t-bltg
bb9cd718a5
Fix formatting src/precompile_includer.jl 2021-10-20 13:08:56 +02:00
Simon Christ
0af22a8fe6
fix name [skip ci] 2021-10-20 10:59:59 +02:00
Yuval
3b0950f915
Fix vector attributes to bar plots (#3751) 2021-10-19 21:21:20 +02:00
github-actions[bot]
31d3bf3e06
Format .jl files [skip ci] (#3882)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-10-18 09:39:08 +02:00
Simon Christ
c487a10f79
use codecov-action v2 2021-10-13 17:23:39 +02:00
github-actions[bot]
ef3417617c
Update precompile_*.jl file [skip ci] (#3876)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-10-13 13:06:08 +02:00
Simon Christ
0d2d516ca6
1.22.6 [skip ci] 2021-10-13 11:37:48 +02:00
Lukas Hauertmann
12a1d83595
Use GR.polygonmesh3d for :mesh3d seriestype (#3868)
* Use `GR.polygonmesh3d` for `:mesh3d` seriestype

* Remove unecessary code

* Update GR version dependency

* Add drawing of edges in `:mesh3d` with GR
2021-10-13 11:35:06 +02:00
Simon Christ
9eba5964d9
1.22.5 [skip ci] 2021-10-12 20:18:58 +02:00
Nicholas Bauer
d74ee63710
Fix for regression with colorbar limits (#3874)
* Fix for regression

* Remove call

* Refactored to dispatching

* Fixes

* Unrolling loop

* Change to IdDict in case objects mutated
2021-10-12 20:18:12 +02:00
github-actions[bot]
9941563b0b
Update precompile_*.jl file [skip ci] (#3849)
Co-authored-by: isentropic <isentropic@users.noreply.github.com>
2021-10-11 17:18:56 +02:00
github-actions[bot]
fb82722dd3
Format .jl files [skip ci] (#3872)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-10-11 17:18:02 +02:00
Jack Dunn
86a9b8bf6d
Fix PyCall deprecations (#3864)
Fixes #3818
2021-10-11 18:55:52 +09:00
Josef Heinen
5a19673eaf
Update Project.toml 2021-10-09 09:04:26 +02:00
Josef Heinen
c26561eab3
Update Project.toml
Bump GR version
2021-10-06 20:51:21 +02:00
Simon Christ
f0ad66da36
1.22.4 [skip ci] 2021-10-05 19:25:45 +02:00
Nicholas Bauer
aca2aa49b8
Generalize GR tick label rotations (#3782)
* gr tick rotations

* consistency

* start of angle offset work

* Working!

* simplify logic

* gr tick rotations

* consistency

* start of angle offset work

* Working!

* simplify logic

* all offsets

* Rebase

* tick factor reversion

* Fix for 3d plots

* simplification

* offset update

* bump offset

* Remove conflict error

* Resolve merge conflict error.

* Resolve merge conflict error

* 3d done

* remove excess

* adjust offset

* restore offset

* fix sign check

Co-authored-by: t-bltg <tf.bltg@gmail.com>
Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2021-10-05 13:44:12 +02:00
t-bltg
9d56e72f6a
Update .zenodo.json
Fix broken .json
2021-10-05 09:43:40 +02:00
Lee Phillips
f06225655d
Allow styling of magnification shape in lens!() (#3860)
* Allow styling of magnification shape in lens!()

The guide lines that indicate the region of the plot magnified in the
inset lens plot, called the magnification shape, are hard-coded with
the :lightgray color and are drawn with the default other line
attributes. This is often too light to be seen clearly and could be a
problem for publication. This commit allows the user to set the
linecolor, linewidth, and linestyle in the call to lens!().

* Update src/recipes.jl

Co-authored-by: t-bltg <tf.bltg@gmail.com>

* Update .zenodo.json

Co-authored-by: t-bltg <tf.bltg@gmail.com>
Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2021-10-04 17:38:59 +02:00
github-actions[bot]
4f0f84f400
Format .jl files [skip ci] (#3861)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-10-04 13:23:01 +02:00
Jan Schneider
a65cda8b7e
change docs link to httpS (#3852)
always bugs me to get a warning from my browser about the not secure connection.
Could someone also update the About section at the right of the Github page to a https URL?
2021-09-28 16:15:26 +02:00
Simon Christ
37744d7b6a
1.22.3 [skip ci] 2021-09-27 19:24:47 +02:00
Jan Schneider
09a66224ce
Update Plots.jl's colorbar_titel maps to PGFPlotsX's color bar style={ylabel} (#3848)
* Update PGFPlotsX colorbar_titel map to ylabel

For most of the backends supported by Polts.jl the `colorbar_title` attribute maps to the attribute in the backend that ultimately is displayed on the vertical axis of the colorbar, which is vertically aligned. Not for PGFPlotsX as in this backend the `title` attribute is displayed on top of the colorbar while the `ylabel` is shown on the vertical bar.

* Update .zenodo.json

added my name to the contributors list
2021-09-27 16:16:16 +02:00
Nicholas Bauer
405bc0820b
Speed up get_clims (#3839)
* For Shape type, cut off process

* Remove fillcolor for now

* Address type inference failure instead

* Store value instead of re-evaluating

* Works, but not ideal

* Unnecessary to update here, I think

* return type

* Remove unnecessary default arg

* Typo

* Change to clims

* missed one

* reconfigured to free up clims property

* fix

* Remove debug println, add hook for updating clims after series added

* restore docstring

* typo

* Change to _update_subplot_colorbars
2021-09-27 14:01:18 +02:00
github-actions[bot]
1c89bd8727
Update precompile_*.jl file [skip ci] (#3841)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-26 15:44:10 +02:00
github-actions[bot]
8e17a182f9
Format .jl files [skip ci] (#3846)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-26 15:42:31 +02:00
t-bltg
032c5d1638
UnicodePlots: support markers (#3845) 2021-09-25 12:18:41 +02:00
BerndR
8d95333d1e
Legend positioning for 3d plots in plotly (#3840)
* Remove hardoced numbers, shift for 3d plots

* Revert changes

* Fixed some missed reverts
2021-09-23 19:14:55 +02:00
github-actions[bot]
7bfc97285c
Update precompile_*.jl file [skip ci] (#3828)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-09-23 10:26:58 +02:00
Simon Christ
acca707f34
1.22.2 [skip ci] 2021-09-22 21:21:13 +02:00
Nicholas Bauer
6fa3dae166
Fix type inference failure in get_clims (#3838)
* For Shape type, cut off process

* Remove fillcolor for now

* NaN

* Address type inference failure instead
2021-09-22 19:18:57 +02:00
Lukas Hauertmann
866cb0c335
Add :mesh3d seriesstyle for PyPlot backend (#3835)
* Add `:mesh3d` seriesstyle for PyPlot backend

via `Poly3DCollection`.

* Add `:connections` to lists of supported keywords

for the backends which support `:mesh3d` as series type.

* Remove #47 from list of skipping examples for PyPlot

* Add support for only-triangle syntax for `:connections` kw

for PyPlot

* Add 1-based indexing syntax for `connections` kw in `:mesh3d`

* Update description for example `#47` (`:mesh3d`)

* Hotfix 1-based indexing for mesh3d in pgfplotsx
2021-09-22 17:12:11 +02:00
t-bltg
4d40bae9cc
Update bug.md
update supported backends
2021-09-21 00:28:51 +02:00
github-actions[bot]
5a48002d31
Format .jl files [skip ci] (#3829)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-20 16:10:29 +02:00
t-bltg
0cd81243ad
UnicodePlots: compact plots 2021-09-18 14:13:37 +02:00
t-bltg
ed3bab0e6f
1.22.1 [skip ci] 2021-09-17 22:11:50 +02:00
github-actions[bot]
4621c18b23
Update precompile_*.jl file [skip ci] (#3822)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-17 22:10:48 +02:00
BerndR
4f8a265c6a
Fix generic aliases (#3824) 2021-09-17 21:43:26 +02:00
t-bltg
e2539a3d19
UnicodePlots: adjust layout width per column (#3825) 2021-09-17 21:42:50 +02:00
t-bltg
85739932f0
Negate condition on :warn_on_unsupported (#3816) 2021-09-17 14:55:43 +02:00
t-bltg
9d84e53bcb
Test cleanup (#3821) 2021-09-17 12:00:40 +02:00
zhanibek
82f31c48b7 pyplot fixing ticks=:native 2021-09-17 16:30:22 +09:00
zhanibek
81571fe534 fix typos 2021-09-17 14:44:16 +09:00
zhanibek
293b8b112e instructions for matplotlib update 2021-09-17 14:38:24 +09:00
t-bltg
d988d4c9d1
1.22.0 [skip ci] 2021-09-15 12:54:42 +02:00
github-actions[bot]
85bd3ea53f
Update precompile_*.jl file [skip ci] (#3810)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-15 12:53:58 +02:00
t-bltg
cd6a8c87b6
GR: fix NaN tick size (#3813) 2021-09-15 12:28:53 +02:00
t-bltg
175c87cec6
Avoid Vararg usage (#3809) 2021-09-15 12:28:24 +02:00
t-bltg
c3f45dd712
UnicodePlots: minor fixes (#3812) 2021-09-15 11:21:41 +02:00
t-bltg
198a59b621
UnicodePlots: propagate xyscale (#3811) 2021-09-15 01:29:23 +02:00
t-bltg
c5d7283473
Update examples.jl
UnicodePlots: annotations are supported
2021-09-14 21:02:30 +02:00
t-bltg
7a1bc88f66
Use hyphens to specify version ranges 2021-09-14 20:27:44 +02:00
github-actions[bot]
ad5cd2f1da
Update precompile_*.jl file [skip ci] (#3807)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-14 19:01:40 +02:00
t-bltg
6cf01229bb
UnicodePlots: support :annotations (#3804) 2021-09-14 18:46:46 +02:00
t-bltg
0a9d30f7ac
Fix invalid axes aliases (#3803)
* Fix invalid axes aliases

* Add test

* Enhance testing
2021-09-14 18:00:23 +02:00
github-actions[bot]
7da990b23f
Format .jl files [skip ci] (#3801)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-13 09:18:59 +02:00
github-actions[bot]
942fb38dcd
Update precompile_*.jl file [skip ci] (#3797)
Co-authored-by: isentropic <isentropic@users.noreply.github.com>
2021-09-13 09:18:18 +02:00
Zhanibek
7ba99d1b06
handling fonts better, moving to stable 3.4 (#3793)
* handling fonts better, moving to stable 3.4

* better math parent font matching
2021-09-11 13:43:42 +09:00
t-bltg
6b82a82d04
Update examples.jl 2021-09-06 13:18:22 +02:00
t-bltg
7c882a7288
Update Project.toml 2021-09-06 12:48:26 +02:00
github-actions[bot]
5343873f72
Update precompile_*.jl file [skip ci] (#3752)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-06 12:47:06 +02:00
t-bltg
e3a5f2b11e
UnicodePlots: support log scales (#3796) 2021-09-06 12:45:29 +02:00
github-actions[bot]
34758c82a3
Format .jl files [skip ci] (#3795)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-06 11:52:32 +02:00
t-bltg
748104c807
UnicodePlots: fix NaN segments plot (#3794) 2021-09-04 12:46:34 +02:00
t-bltg
0d2bc3f227
UnicodePlots: Update URL 2021-09-02 22:20:54 +02:00
t-bltg
c45352d153
fix UnicodePlots.jl/issues/125 (#3791) 2021-09-02 17:59:02 +02:00
Josef Heinen
b833b6582a
Update Project.toml
Bump GR version
2021-09-01 16:55:16 +02:00
t-bltg
b28a261b39
1.21.3 [skip ci] 2021-09-01 14:06:42 +02:00
t-bltg
1a1cc08992
UnicodePlots: fixes 2021-09-01 13:10:09 +02:00
t-bltg
31d33e6be4
UnicodePlots: Allow simple nesting 2021-09-01 12:48:31 +02:00
t-bltg
2dc812aa15
UnicodePlots: support layout (#3787) 2021-09-01 11:26:29 +02:00
t-bltg
bdbe300412
Pyplot: fix building docs (#3775) 2021-09-01 11:24:16 +02:00
Nicholas Bauer
70b635dbe1
Cache axis args in a dictionary (#3775)
Co-authored-by: t-bltg <tf.bltg@gmail.com>
Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2021-08-31 21:36:58 +02:00
t-bltg
1e44dd7035
Unicodeplots: "join" subplots 2021-08-31 00:21:11 +02:00
t-bltg
4744152f86
Add newline between subplots 2021-08-30 23:25:19 +02:00
t-bltg
dc51f2c159
v1.21.2 [skip ci] 2021-08-30 22:22:05 +02:00
t-bltg
cc1f662b3a
UnicodePlots: rm forced width/height (arbitrary) 2021-08-30 17:50:41 +02:00
t-bltg
7b77527f80
UnicodePlots: display fix, simplify axis labels 2021-08-30 14:04:00 +02:00
github-actions[bot]
8b6073c088
Format .jl files [skip ci] (#3780)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-08-29 10:53:46 +02:00
t-bltg
09d35d7b9f
UnicodePlots: heatmap support (#3774)
* UnicodePlots: heatmap support

* Fix type check
2021-08-28 21:29:04 +02:00
Simon Christ
0a9da21443
sanitize axis strings (#3772) 2021-08-28 21:08:21 +02:00
Simon Christ
ea686c331b
improve axis decorations (#3756)
* improve handling of LaTeXStrings in tick labels

* respect guidefonthalign
2021-08-28 21:08:03 +02:00
t-bltg
25a36bab85
merge root codecov.yml [skip ci] 2021-08-28 17:05:13 +02:00
t-bltg
b227fb8943
move codecov.yml 2021-08-28 00:12:43 +02:00
t-bltg
22651e8728
UnicodePlots: disable some unsupported examples 2021-08-26 19:54:58 +02:00
Nicholas Bauer
5acf967a9e
v1.21.1 | No exception thrown in apply_recipe fallback (#3765)
* No exception thrown in `apply_recipe` fallback

Throwing an exception here can vastly slow down plotting, as it happens frequently. Returning an error value instead, which the calling function can check, can speed up plotting 2x. An accompanying change is necessary in RecipesPipeline.jl, assuming this value is suitable.

* Bumped compat for RecipesPipeline, tentative

* Bump patch version

* Fix wrong versioning

Co-authored-by: t-bltg <tf.bltg@gmail.com>
2021-08-26 17:46:28 +02:00
Simon Christ
5afeba656b check if .zenodo.json is valid 2021-08-26 17:17:26 +02:00
LukasKrumwiede
7b8bd5b253
Implementation of filling the space between and under curves for gaston (#3755) 2021-08-26 16:58:05 +02:00
Pearl Li
ded808477d
Add hatched fill for GR and PyPlot (#3107) 2021-08-26 16:55:56 +02:00
Simon Christ
854d5ba5c9
1.21.0 [skip ci] 2021-08-26 16:21:47 +02:00
t-bltg
07a619e5ae
Replace deprecated Base.download with Downloads.download (#3766)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-08-26 00:12:33 +02:00
63 changed files with 4243 additions and 1616 deletions

View File

@ -20,10 +20,11 @@ Backend | yes | no | untested
-------------|-----|-----|--------- -------------|-----|-----|---------
gr (default) | | | gr (default) | | |
pyplot | | | pyplot | | |
plotly | | |
plotlyjs | | | plotlyjs | | |
pgfplotsx | | | pgfplotsx | | |
unicodeplots | | |
inspectdr | | | inspectdr | | |
gaston | | |
### Versions ### Versions

View File

@ -1,9 +1,11 @@
# NOTE: this file should be named 'SnoopCompile.yml', cf github.com/aminya/CompileBot.jl/blob/master/src/CompileBot.jl#L57
name: SnoopCompile name: SnoopCompile
on: on:
push: push:
branches: branches:
# - 'master' # NOTE: to run the bot only on pushes to master - master # NOTE: to run the bot only on pushes to master
defaults: defaults:
run: run:
@ -14,14 +16,19 @@ jobs:
if: "!contains(github.event.head_commit.message, '[skip ci]')" if: "!contains(github.event.head_commit.message, '[skip ci]')"
env: env:
GKS_ENCODING: "utf8" GKS_ENCODING: "utf8"
GKSwstype: "100" GKSwstype: "nul"
PLOTS_TEST: "true" PLOTS_TEST: "true"
runs-on: ${{matrix.os}} runs-on: ${{matrix.os}}
continue-on-error: ${{ matrix.version == '~1.8.0-0' }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
version: # NOTE: the versions below should match those in your botconfig version: # NOTE: the versions below should match those in your botconfig
- '1' - '1.6' # ⎤
- '1.7' # |
- '~1.8.0-0' # |
# - 'nightly' # ⎦ <<< keep these versions in sync with deps/SnoopCompile/snoop_bot_config.jl
# ^^^^^^^^^ for 'nightly', see github.com/JuliaPlots/Plots.jl/issues/4079
os: # NOTE: should match the os setting of your botconfig os: # NOTE: should match the os setting of your botconfig
- ubuntu-latest - ubuntu-latest
arch: arch:
@ -33,11 +40,20 @@ jobs:
with: with:
version: ${{matrix.version}} version: ${{matrix.version}}
- name: Set Swap Space
uses: pierotofy/set-swap-space@master
with:
swap-size-gb: 10 # required (not enough memory on github actions virtual machine)
- name: Install dependencies - name: Install dependencies
run: | run: |
julia --project -e 'using Pkg; Pkg.instantiate();' cat /proc/cpuinfo
julia -e 'using Pkg; Pkg.add( PackageSpec(name = "CompileBot", version = "1") ); Pkg.develop(PackageSpec(; path=pwd())); using CompileBot; CompileBot.addtestdep();' cat /proc/meminfo
cat /proc/swaps
free
df -h
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 # TESTCMD
- name: Default TESTCMD - name: Default TESTCMD
@ -69,7 +85,9 @@ jobs:
uses: actions/download-artifact@v2 uses: actions/download-artifact@v2
- name: CompileBot postprocess - name: CompileBot postprocess
run: julia -e 'using Pkg; Pkg.add( PackageSpec(name = "CompileBot", version = "1") ); using CompileBot; CompileBot.postprocess();' run: |
if ! grep -m1 -q 'format: off' artifact/src/precompile_includer.jl; then sed -i '1 i\#! format: off' artifact/src/precompile_includer.jl; fi
julia -e 'using Pkg; Pkg.add(PackageSpec(name="CompileBot", version="1")); using CompileBot; CompileBot.postprocess()'
- name: Create Pull Request - name: Create Pull Request
uses: peter-evans/create-pull-request@v3 uses: peter-evans/create-pull-request@v3
@ -82,7 +100,6 @@ jobs:
no changelog no changelog
branch: "Test_SnoopCompile_AutoPR_${{ github.ref }}" branch: "Test_SnoopCompile_AutoPR_${{ github.ref }}"
Skip: Skip:
if: "contains(github.event.head_commit.message, '[skip ci]')" if: "contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -12,3 +12,4 @@ jobs:
- uses: JuliaRegistries/TagBot@v1 - uses: JuliaRegistries/TagBot@v1
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
ssh: ${{ secrets.TAGBOT_KEY }}

View File

@ -11,7 +11,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest - uses: julia-actions/setup-julia@latest
with: with:
version: 1 version: '1.7'
# Setup # Setup
- name: Ubuntu TESTCMD - name: Ubuntu TESTCMD

View File

@ -2,6 +2,8 @@ name: ci
on: on:
push: push:
branches:
- master
pull_request: pull_request:
defaults: defaults:
@ -13,7 +15,7 @@ jobs:
if: "!contains(github.event.head_commit.message, '[skip ci]')" if: "!contains(github.event.head_commit.message, '[skip ci]')"
env: env:
GKS_ENCODING: "utf8" GKS_ENCODING: "utf8"
GKSwstype: "100" GKSwstype: "nul"
name: Julia ${{ matrix.version }} - ${{ matrix.os }} name: Julia ${{ matrix.version }} - ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@ -22,8 +24,8 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
version: version:
- '1' - '1.6' # LTS
- 'nightly' - '1.7' # latest stable
os: os:
- ubuntu-latest - ubuntu-latest
- windows-latest - windows-latest
@ -31,9 +33,11 @@ jobs:
arch: arch:
- x64 - x64
# - x86 # - x86
include:
- version: 'nightly'
os: ubuntu-latest
steps: steps:
# Setup environment # Setup environment
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest - uses: julia-actions/setup-julia@latest
@ -51,19 +55,16 @@ jobs:
${{ runner.os }}-test- ${{ runner.os }}-test-
${{ runner.os }}- ${{ 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 # TESTCMD
- name: Default TESTCMD - name: Default TESTCMD
run: echo "TESTCMD=julia" >> $GITHUB_ENV run: echo "TESTCMD=julia" >> $GITHUB_ENV
- name: Ubuntu TESTCMD - name: Ubuntu TESTCMD
if: startsWith(matrix.os,'ubuntu') if: startsWith(matrix.os,'ubuntu')
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV run: |
echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
sudo apt-get -y update
sudo apt-get -y install gnuplot poppler-utils texlive-{latex-base,latex-extra,luatex}
sudo fc-cache -vr
# Julia Dependencies # Julia Dependencies
- name: Install Julia dependencies - name: Install Julia dependencies
@ -78,7 +79,9 @@ jobs:
# Codecov # Codecov
- uses: julia-actions/julia-processcoverage@v1 - uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1 if: startsWith(matrix.os,'ubuntu')
- uses: codecov/codecov-action@v2
if: startsWith(matrix.os,'ubuntu')
with: with:
file: lcov.info file: lcov.info

View File

@ -1,2 +0,0 @@
github_checks:
annotations: false

View File

@ -1,6 +1,7 @@
name: docs name: docs
on: on:
workflow_dispatch:
push: push:
branches: branches:
- master - master
@ -8,7 +9,7 @@ on:
jobs: jobs:
Build_docs: Build_docs:
runs-on: ubuntu-18.04 runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
@ -25,32 +26,9 @@ jobs:
${{runner.os}}-test-${{env.cache-name}}- ${{runner.os}}-test-${{env.cache-name}}-
${{runner.os}}-test- ${{runner.os}}-test-
${{runner.os}}- ${{runner.os}}-
- name: Install dependencies - name: Build documentation
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 \
gnuplot
sudo fc-cache -vr
- name: build documentation
env: env:
PYTHON: "" PYTHON: ""
DOCUMENTER_KEY: ${{secrets.DOCUMENTER_KEY}} DOCUMENTER_KEY: ${{secrets.DOCUMENTER_KEY}}
run: | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
export JULIA_DEBUG=Documenter run: bash docs/ci_build.sh
export PLOTDOCS_ANSICOLOR=true
export GKSwstype=nul # Plots.jl/issues/3664
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 'using Pkg; pkg"add Documenter#master"'
xvfb-run julia --color=yes --project=docs/ -e 'using Pkg; pkg"st -m"'
xvfb-run julia --color=yes --project=docs/ -e 'withenv("GITHUB_REPOSITORY" => "JuliaPlots/PlotDocs.jl") do; include("docs/make.jl"); end'

View File

@ -1,22 +0,0 @@
name: format
on:
pull_request:
jobs:
JuliaFormatter:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: 1
# Check format
- name: Install JuliaFormatter and format
run: |
git diff --name-only --exit-code
julia -e 'using Pkg; pkg"add JuliaFormatter CSTParser#master"'
julia -e 'using JuliaFormatter; [format(["src", "test"]) for _ in 1:2]'
git diff --exit-code

54
.github/workflows/format_check.yml vendored Normal file
View File

@ -0,0 +1,54 @@
name: format
on:
pull_request:
push:
branches:
- 'master'
jobs:
code-style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
- name: Install dependencies
run: |
using Pkg
Pkg.add([
PackageSpec("JuliaFormatter"),
PackageSpec(url = "https://github.com/tkf/JuliaProjectFormatter.jl.git"),
])
shell: julia --color=yes {0}
- name: Format Julia files
run: |
using JuliaFormatter
format(["src", "test"])
shell: julia --color=yes --compile=min -O0 {0}
- name: suggester / JuliaFormatter
uses: reviewdog/action-suggester@v1
with:
tool_name: JuliaFormatter
fail_on_error: true
# reviewdog/action-suggester not using `cleanup` flag?
- name: Cleanup
if: success() || failure()
run: |
git checkout -- .
git clean --force
shell: bash
- name: Format Julia project files
if: success() || failure()
run: |
using JuliaProjectFormatter
format_projects()
shell: julia --color=yes --compile=min -O0 {0}
- name: suggester / JuliaProjectFormatter
if: success() || failure()
uses: reviewdog/action-suggester@v1
with:
tool_name: JuliaProjectFormatter
fail_on_error: true

View File

@ -1,18 +1,18 @@
name: format-pr name: format
on: on:
schedule: schedule:
- cron: '0 0 * * SUN' - cron: '0 0 1 * *'
jobs: jobs:
build: pr:
if: "!contains(github.event.head_commit.message, '[skip ci]')" if: "!contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Install JuliaFormatter and format - name: Install JuliaFormatter and format
run: | run: |
julia -e 'using Pkg; pkg"add JuliaFormatter CSTParser#master"' julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter"))'
julia -e 'using JuliaFormatter; [format(["src", "test"]) for _ in 1:2]' julia -e 'using JuliaFormatter; [format(["src", "test"]) for _ in 1:2]'
git diff --exit-code git diff --exit-code

View File

@ -3,7 +3,7 @@
"license": "MIT", "license": "MIT",
"creators": [ "creators": [
{ {
"affiliation": "Elemental Cognition", "affiliation": "Headlands Technologies",
"name": "Tom Breloff" "name": "Tom Breloff"
} }
], ],
@ -142,6 +142,8 @@
}, },
{ {
"name": "Anshul Singhvi", "name": "Anshul Singhvi",
"affiliation": "Columbia University",
"orcid": "0000-0001-6055-1291",
"type": "Other" "type": "Other"
}, },
{ {
@ -401,7 +403,7 @@
"type": "Other" "type": "Other"
}, },
{ {
"name": "Moesè Giodano", "name": "Mosè Giodano",
"type": "Other" "type": "Other"
}, },
{ {
@ -692,6 +694,28 @@
{ {
"name": "Fred Callaway", "name": "Fred Callaway",
"type": "Other" "type": "Other"
},
{
"name": "Jan Thorben Schneider",
"type": "Other"
},
{
"orcid": "0000-0003-4102-2460",
"affiliation": "Alogus Research Corporation",
"name": "Lee Phillips",
"type": "Other"
},
{
"name": "Tom Gillam",
"type": "Other"
},
{
"name": "Steve Leung",
"type": "Other"
},
{
"name": "Xu Zhi-Yuan",
"type": "Other"
} }
], ],
"upload_type": "software" "upload_type": "software"

View File

@ -3,7 +3,7 @@
#### notes on release changes, ongoing development, and future planned work #### notes on release changes, ongoing development, and future planned work
## (current master) ## NOTE: this file is deprecated, see the [TagBot](https://github.com/marketplace/actions/julia-tagbot) auto-generated changelogs instead
## 0.28.3 ## 0.28.3
- support generalized array interface - support generalized array interface

View File

@ -1,12 +1,13 @@
name = "Plots" name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"] author = ["Tom Breloff (@tbreloff)"]
version = "1.20.1" version = "1.29.0"
[deps] [deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" Contour = "d38c429a-6771-53c6-b99e-75d170b6e991"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
@ -16,6 +17,7 @@ Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Measures = "442fdcdd-2543-5da2-b0f3-8c86c306513e" Measures = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
@ -31,40 +33,53 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1"
Unzip = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d"
[compat] [compat]
Contour = "0.5" Contour = "0.5"
FFMPEG = "0.2, 0.3, 0.4" FFMPEG = "0.2 - 0.4"
FixedPointNumbers = "0.6, 0.7, 0.8" FixedPointNumbers = "0.6 - 0.8"
GR = "0.53, 0.54, 0.55, 0.57, 0.58" GR = "0.64"
GeometryBasics = "0.2, 0.3.1, 0.4" GeometryBasics = "0.2, 0.3.1, 0.4"
JSON = "0.21, 1" JSON = "0.21, 1"
Latexify = "0.14, 0.15" Latexify = "0.14 - 0.15"
Measures = "0.3" Measures = "0.3"
NaNMath = "0.3" NaNMath = "0.3, 1"
PlotThemes = "2" PGFPlotsX = "1"
PlotThemes = "2, 3"
PlotUtils = "1" PlotUtils = "1"
RecipesBase = "1" PlotlyBase = "0.7"
RecipesPipeline = "0.3" PlotlyJS = "0.18"
PyPlot = "2"
RecipesBase = "1.2"
RecipesPipeline = "0.5"
Reexport = "0.2, 1.0" Reexport = "0.2, 1.0"
Requires = "1" Requires = "1"
Scratch = "1" Scratch = "1"
Showoff = "0.3.1, 1.0" Showoff = "0.3.1, 1.0"
StatsBase = "0.32, 0.33" StatsBase = "0.32 - 0.33"
UnicodePlots = "2" UnicodeFun = "0.4"
julia = "1.5" UnicodePlots = "2.10"
Unzip = "0.1"
julia = "1.6"
[extras] [extras]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
Gaston = "4b11ee91-296f-5714-9832-002c20994614"
Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44" Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44"
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d"
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433" LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925" PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a"
PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b" RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
@ -75,4 +90,4 @@ UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92" VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"
[targets] [targets]
test = ["Distributions", "FileIO", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"] test = ["Colors", "Distributions", "FileIO", "Gaston", "Gtk", "ImageMagick", "Images", "InspectDR", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "PlotlyBase", "PyPlot", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"]

View File

@ -10,18 +10,18 @@
[gitter-url]: https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge [gitter-url]: https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[docs-img]: https://img.shields.io/badge/docs-stable-blue.svg [docs-img]: https://img.shields.io/badge/docs-stable-blue.svg
[docs-url]: http://docs.juliaplots.org/latest/ [docs-url]: https://docs.juliaplots.org/stable/
[![][gh-ci-img]][gh-ci-url] [![][gh-ci-img]][gh-ci-url]
[![][pkgeval-img]][pkgeval-url] [![][pkgeval-img]][pkgeval-url]
[![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://julialang.zulipchat.com/#narrow/stream/236493-plots) [![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://julialang.zulipchat.com/#narrow/stream/236493-plots)
[![][docs-img]][docs-url] [![][docs-img]][docs-url]
[![Codecov](https://codecov.io/gh/JuliaPlots/Plots.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaPlots/Plots.jl) [![Codecov](https://codecov.io/gh/JuliaPlots/Plots.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaPlots/Plots.jl)
[![Plots Downloads](https://shields.io/endpoint?url=https://pkgs.genieframework.com/api/v1/badge/Plots)](https://pkgs.genieframework.com?packages=Plots)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4725317.svg)](https://doi.org/10.5281/zenodo.4725317) [![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. This is the DOI for all Versions, please follow the link to get the DOI for a specific version.
#### Created by Tom Breloff (@tbreloff) #### Created by Tom Breloff (@tbreloff)
#### Maintained by the [JuliaPlots members](https://github.com/orgs/JuliaPlots/people) #### Maintained by the [JuliaPlots members](https://github.com/orgs/JuliaPlots/people)

View File

@ -1,3 +1,6 @@
github_checks:
annotations: false
ignore: ignore:
- "src/backends/inspectdr.jl" - "src/backends/inspectdr.jl"
- "src/backends/orca.jl" - "src/backends/orca.jl"

View File

@ -66,24 +66,19 @@ end
function _precompile_() function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing 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{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}},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}, 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, 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(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Vector{Int64}}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(areaplot)),Any,typeof(areaplot),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:foreground_color_grid, :grid, :gridalpha, :gridstyle, :gridlinewidth), Tuple{RGBA{Float64}, Bool, Float64, Symbol, Int64}},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{(:formatter,), Tuple{typeof(datetimeformatter)}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :flip, :minorgrid, :guide), Tuple{Bool, Bool, Bool, String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :flip, :minorgrid, :guide), Tuple{Bool, Bool, Bool, String}},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), 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, :lims, :flip), Tuple{Bool, Tuple{Float64, Float64}, Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :guide), Tuple{Bool, Bool, String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :guide), Tuple{Bool, Bool, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :mirror, :guide), Tuple{Bool, Bool, Bool, String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :mirror, :guide), Tuple{Bool, Bool, Bool, String}},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,), 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{(: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{(:guidefonthalign, :guide_position, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis})
@ -92,7 +87,6 @@ function _precompile_()
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, 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{(:lims,), Tuple{Tuple{Int64, Int64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:minorgrid, :scale, :guide), Tuple{Bool, Symbol, String}},typeof(attr!),Axis}) Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:minorgrid, :scale, :guide), Tuple{Bool, Symbol, String}},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{(:ticks,), Tuple{Nothing}},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(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{(:shape,), Tuple{Symbol}},typeof(default)})
@ -104,12 +98,18 @@ function _precompile_()
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},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),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_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),Vector{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(hline!)),Any,typeof(hline!),Any}) Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:rotation, :color), Tuple{Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Vector{Int64}})
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{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!),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{(: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, Tuple{String, Any, Any, Any}}}}},typeof(plot!)}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:annotation,), Tuple{Vector{Tuple{Int64, Float64, Tuple{String, Any, Any, Any}}}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:layout, :margin), Tuple{GridLayout, AbsoluteLength}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:layout, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{GRBackend},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},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{PlotlyBackend},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},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
@ -135,33 +135,36 @@ function _precompile_()
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!)}) 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},Vector{Float64},Vararg{Any, N} where N}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},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{(:xgrid,), Tuple{Tuple{Symbol, Symbol, Int64, Symbol, Float64}}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!),Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!)}) Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},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{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!),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{(: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{(: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},Matrix{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bar_width, :alpha, :color, :fillto, :label, :seriestype), Tuple{Float64, Float64, Vector{Symbol}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, String, Symbol}},typeof(plot),Vector{Float64}})
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{(: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{(: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, :title, :xlabel, :ylabel, :zlabel, :legend, :margin, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, String, String, String, String, Symbol, AbsoluteLength, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vector{Int64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:connections, :title, :xlabel, :ylabel, :zlabel, :legend, :margin, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, String, String, String, String, Symbol, AbsoluteLength, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vector{Int64}})
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}},Function}) 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}},Function})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill_z, :alpha, :label, :bar_width, :seriestype), Tuple{StepRange{Int64, Int64}, Vector{Float64}, String, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Int64},Vector{Int64}})
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{(: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{(: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{(: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, :legend, :seriestype), Tuple{String, Symbol, Symbol}},typeof(plot),Vector{Int64}})
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,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,Float64})
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{(: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, :group, :linetype, :linecolor), Tuple{Matrix{Any}, 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},Plot{GRBackend}}) 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},Plot{GRBackend}})
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},Plot{PlotlyBackend}}) 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},Plot{PlotlyBackend}})
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{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, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :margin), Tuple{GridLayout, AbsoluteLength}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
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, :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, :t, :leg, :ticks, :border), Tuple{Matrix{Any}, 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, :title, :titlelocation, :left_margin, :bottom_margin, :xrotation), Tuple{Matrix{Any}, 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, :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},Plot{GRBackend}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xlims), Tuple{Matrix{Any}, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
@ -189,10 +192,10 @@ function _precompile_()
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{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{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{(:ribbon,), Tuple{typeof(sqrt)}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriescolor, :fillalpha), Tuple{Matrix{Symbol}, Matrix{Float64}}},typeof(plot),AreaPlot})
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, :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),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{OHLC}}) 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},Vector{Float64}}) Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}})
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, :l, :seriestype), Tuple{String, Float64, Symbol}},typeof(plot),Vector{String},Vector{Float64}})
@ -217,12 +220,14 @@ function _precompile_()
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{: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{: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{:hline}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hspan}},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{: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{: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{:quiver}},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{: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{: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{:vline}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vspan}},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},Type{Val{:xerror}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Vector{ComplexF64}}) 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{GRBackend},DefaultsDict})
@ -230,27 +235,29 @@ function _precompile_()
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{GRBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}}) 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.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.preprocess_attributes!),Plot{GRBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_axis_args!),Plot{GRBackend},Dict{Symbol, Any},Symbol}) Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{GRBackend},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}}) 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.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.unzip),Vector{GeometryBasics.Point2{Float64}}})
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(_bin_centers),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
Base.precompile(Tuple{typeof(_bin_centers),Vector{Float64}})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Float64},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Int64},String}) 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{Nothing},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{PlotUtils.ContinuousColorGradient},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{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Symbol},String}) Base.precompile(Tuple{typeof(_cbar_unique),Vector{Symbol},String})
Base.precompile(Tuple{typeof(_cycle),StepRange{Int64, Int64},Vector{Int64}}) Base.precompile(Tuple{typeof(_cycle),UnitRange{Int64},Vector{Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},StepRange{Int64, Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Int64},StepRange{Int64, Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Int64},UnitRange{Int64}})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool}) Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},Bool}) Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},Bool})
Base.precompile(Tuple{typeof(_heatmap_edges),Vector{Float64},Bool,Bool}) Base.precompile(Tuple{typeof(_heatmap_edges),Vector{Float64},Bool,Bool})
Base.precompile(Tuple{typeof(_plot!),Plot,Any,Any}) 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_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(_preprocess_binlike),DefaultsDict,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(_slice_series_args!),DefaultsDict,Plot{GRBackend},Subplot{GRBackend},Int64})
Base.precompile(Tuple{typeof(_update_min_padding!),GridLayout}) 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{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_args),Plot{PlotlyBackend},Subplot{PlotlyBackend},Dict{Symbol, Any},Int64,Bool})
@ -263,14 +270,17 @@ function _precompile_()
Base.precompile(Tuple{typeof(bbox),Float64,Float64,Float64,Float64}) Base.precompile(Tuple{typeof(bbox),Float64,Float64,Float64,Float64})
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64,Vector{Plot}}) Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64,Vector{Plot}})
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Int64, Float64}}) 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(default),Symbol,Bool})
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},Vararg{Vector{Float64}, N} where N})
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64}}) 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(error_zipit),Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}})
Base.precompile(Tuple{typeof(fakedata),Int64,Int64}) Base.precompile(Tuple{typeof(fakedata),Int64,Int64})
Base.precompile(Tuple{typeof(fakedata),MersenneTwister,Int64,Vararg{Int64, N} where N})
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{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}}) Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}})
Base.precompile(Tuple{typeof(get_series_color),SubArray{Symbol, 1, Vector{Symbol}, Tuple{UnitRange{Int64}}, true},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol}) Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{PlotlyBackend},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),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{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, Float64},Vararg{Any, N} where N})
@ -280,40 +290,44 @@ function _precompile_()
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), 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, Int64, Int64, Float64, Int64, Float64, Float64, Float64, 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, Int64, Int64, 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_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_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_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,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,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Shape{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
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,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Int64,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_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,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Vector{Int64},Vector{Int64},Tuple{Float64, Float64},Int64,Int64}) 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},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,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,StepRange{Int64, Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,UnitRange{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,UnitRange{Int64},Vector{Float64},Vector{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_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},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_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_fill_viewport),Vector{Float64},RGBA{Float64}})
Base.precompile(Tuple{typeof(gr_get_3d_axis_angle),Vector{Float64},Float64,Float64,Symbol})
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Float64}, Vector{String}},Int64}) 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),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Int64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_label_ticks_3d),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_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_set_gradient),PlotUtils.ContinuousColorGradient})
Base.precompile(Tuple{typeof(gr_text),Float64,Float64,String})
Base.precompile(Tuple{typeof(gr_text_size),String})
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), 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, Int64, Int64, Float64, Int64, Float64, Float64, Float64, 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, Int64, Int64, 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(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),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),UnitRange{Int64},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(heatmap_edges),Vector{Float64},Symbol})
Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}}) Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}})
Base.precompile(Tuple{typeof(layout_args),NamedTuple{(:label, :blank), Tuple{Symbol, Bool}}})
Base.precompile(Tuple{typeof(layout_args),NamedTuple{(:label, :width, :height), Tuple{Symbol, Symbol, Float64}}})
Base.precompile(Tuple{typeof(make_fillrange_side),UnitRange{Int64},LinRange{Float64}}) 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,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{Float64, Float64},Symbol,Symbol})
@ -322,10 +336,12 @@ function _precompile_()
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),StepRange{Int64, Int64},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(optimal_ticks_and_labels),UnitRange{Int64},Tuple{Float64, Float64},Symbol,Symbol})
Base.precompile(Tuple{typeof(partialcircle),Int64,Float64,Int64}) Base.precompile(Tuple{typeof(partialcircle),Int64,Float64,Int64})
Base.precompile(Tuple{typeof(plot!),Any})
Base.precompile(Tuple{typeof(plot!),Plot,Plot,Plot,Vararg{Plot, N} where N})
Base.precompile(Tuple{typeof(plot),Any,Any}) Base.precompile(Tuple{typeof(plot),Any,Any})
Base.precompile(Tuple{typeof(plot),Any})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N}) Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}}) Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend}})
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N}) Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}}) Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Symbol,Symbol}) Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Symbol,Symbol})
@ -335,7 +351,6 @@ function _precompile_()
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},RGBA{Float64}}) 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},Shape{Float64, Float64}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Symbol}) Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(processMinorGridArg!),Dict{Symbol, Any},Bool,Symbol})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText}) Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}}) Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}}) Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
@ -345,24 +360,43 @@ function _precompile_()
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol}) 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(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}}) Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}})
Base.precompile(Tuple{typeof(push!),Segments{Tuple{Float64, Float64, Float64}},Tuple{Int64, Int64, Float64},Tuple{Int64, Int64, Float64}})
Base.precompile(Tuple{typeof(resetfontsizes)}) Base.precompile(Tuple{typeof(resetfontsizes)})
Base.precompile(Tuple{typeof(scalefontsizes),Float64}) Base.precompile(Tuple{typeof(scalefontsizes),Float64})
Base.precompile(Tuple{typeof(series_annotations),Vector{Any}}) Base.precompile(Tuple{typeof(series_annotations),Vector{Any}})
Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}},Int64}) Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{AbsoluteLength},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{RGBA{Float64}},Int64})
Base.precompile(Tuple{typeof(spy),Any}) 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(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(stroke),Int64,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(title!),AbstractString}) 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(vline!),Any})
Base.precompile(Tuple{typeof(warn_on_attr_dim_mismatch),Series,Vector{Float64},Vector{Float64},Nothing,Base.Iterators.Flatten{Vector{Tuple{SeriesSegment}}}})
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any, N} where N}) Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}}) Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
isdefined(Plots, Symbol("#add_major_or_minor_segments#126")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#126")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64}},Float64,Bool}) isdefined(Plots, Symbol("#166#167")) && Base.precompile(Tuple{getfield(Plots, Symbol("#166#167")),Any})
isdefined(Plots, Symbol("#add_major_or_minor_segments#127")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#127")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64, Float64}},Float64,Bool}) isdefined(Plots, Symbol("#2#6")) && Base.precompile(Tuple{getfield(Plots, Symbol("#2#6")),UnitRange{Int64}})
isdefined(Plots, Symbol("#295#331")) && Base.precompile(Tuple{getfield(Plots, Symbol("#295#331"))})
isdefined(Plots, Symbol("#316#352")) && Base.precompile(Tuple{getfield(Plots, Symbol("#316#352"))})
isdefined(Plots, Symbol("#add_major_or_minor_segments#100")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#100")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64}},Float64,Bool})
isdefined(Plots, Symbol("#add_major_or_minor_segments#101")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#101")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64, Float64}},Float64,Bool})
let fbody = try __lookup_kwbody__(which(font, (Font,Vararg{Any, N} where N,))) catch missing end let fbody = try __lookup_kwbody__(which(font, (Font,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody) if !ismissing(fbody)
precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(font),Font,Vararg{Any, N} where N,)) precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(font),Font,Vararg{Any, N} where N,))
end end
end
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(gr_set_font, (Font,Subplot{GRBackend},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Symbol,Symbol,RGBA{Float64},Float64,typeof(gr_set_font),Font,Subplot{GRBackend},))
end
end end
let fbody = try __lookup_kwbody__(which(plot!, (Any,))) catch missing end let fbody = try __lookup_kwbody__(which(plot!, (Any,))) catch missing end
if !ismissing(fbody) if !ismissing(fbody)
@ -373,6 +407,26 @@ function _precompile_()
if !ismissing(fbody) if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Any,Vararg{Any, N} where N,)) precompile(fbody, (Any,typeof(plot!),Any,Vararg{Any, N} where N,))
end end
end
let fbody = try __lookup_kwbody__(which(plot!, (Plot,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Plot,))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Plot,Plot,))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,Plot,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Plot,Plot,Plot,))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,Plot,Vararg{Plot, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Plot,Plot,Plot,Vararg{Plot, N} where N,))
end
end end
let fbody = try __lookup_kwbody__(which(plot, (Any,))) catch missing end let fbody = try __lookup_kwbody__(which(plot, (Any,))) catch missing end
if !ismissing(fbody) if !ismissing(fbody)
@ -383,6 +437,11 @@ function _precompile_()
if !ismissing(fbody) if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Any,Vararg{Any, N} where N,)) precompile(fbody, (Any,typeof(plot),Any,Vararg{Any, N} where N,))
end end
end
let fbody = try __lookup_kwbody__(which(scatter, (Any,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(scatter),Any,Vararg{Any, N} where N,))
end
end end
let fbody = try __lookup_kwbody__(which(title!, (AbstractString,))) catch missing end let fbody = try __lookup_kwbody__(which(title!, (AbstractString,))) catch missing end
if !ismissing(fbody) if !ismissing(fbody)

View File

@ -0,0 +1,487 @@
# 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{(: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(areaplot)),Any,typeof(areaplot),Any,Vararg{Any}})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:flip,), Tuple{Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:foreground_color_grid, :grid, :gridalpha, :gridstyle, :gridlinewidth), Tuple{RGBA{Float64}, Bool, Float64, Symbol, Int64}},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, :flip, :minorgrid, :guide), Tuple{Bool, Bool, Bool, String}},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, :minorgrid, :guide), Tuple{Bool, Bool, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :mirror, :guide), Tuple{Bool, Bool, Bool, String}},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{(: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{(:minorgrid, :scale, :guide), Tuple{Bool, Symbol, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:minorgrid,), Tuple{Bool}},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{(: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}, Int64},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), Tuple{Symbol, Symbol, Int64}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:rotation, :color), Tuple{Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(lens!)),Any,typeof(lens!),Any,Vararg{Any}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Vector{Int64}})
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, Tuple{String, Any, Any, Any}}}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:layout, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
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,Irrational{}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Plot{GRBackend},Function,Float64,Vararg{Any}})
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}, Int64},Vector{Float64}})
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}, Int64},Vector{Float64}})
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}, Int64},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!),Plot{PlotlyBackend},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},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{PlotlyBackend},Vector{Int64},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!),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},Vector{Float64},Vararg{Any}})
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, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},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},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bar_width, :alpha, :color, :fillto, :label, :seriestype), Tuple{Float64, Float64, Vector{Symbol}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, String, Symbol}},typeof(plot),Vector{Float64}})
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}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:connections, :title, :xlabel, :ylabel, :zlabel, :legend, :margin, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, String, String, String, String, Symbol, AbsoluteLength, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill, :seriestype), Tuple{Bool, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Function})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill_z, :alpha, :label, :bar_width, :seriestype), Tuple{StepRange{Int64, Int64}, Vector{Float64}, String, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Int64},Vector{Int64}})
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, :legend, :seriestype), Tuple{String, Symbol, Symbol}},typeof(plot),Vector{Int64}})
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,Float64})
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{(:labels,), Tuple{Matrix{String}}},typeof(plot),PortfolioComposition})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :group, :linetype, :linecolor), Tuple{Matrix{Any}, 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},Plot{GRBackend}})
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},Plot{PlotlyBackend}})
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, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
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{Matrix{Any}, 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{Matrix{Any}, 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{Matrix{Any}, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
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},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,Int64,Vararg{Any}})
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}, Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line_z, :linewidth, :legend), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, 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}, Int64},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}, Int64},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}, Int64},UnitRange{Int64},Matrix{Int64}})
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},Vector{Float64}})
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}, Int64}}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Tuple{LinRange{Float64, Int64}, LinRange{Float64, Int64}}}},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{(:seriescolor, :fillalpha), Tuple{Matrix{Symbol}, Matrix{Float64}}},typeof(plot),AreaPlot})
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),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}})
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},Vector{Float64}})
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, :xflip, :yflip, :zflip, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :xmirror, :ymirror, :zmirror, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
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{(: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{(:zcolor, :m, :leg, :cbar, :w), Tuple{StepRange{Int64, Int64}, Tuple{Int64, Float64, Symbol, Stroke}, Bool, Bool, Int64}},typeof(plot),Vector{Float64},Vector{Float64},UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(portfoliocomposition)),Any,typeof(portfoliocomposition),Any,Vararg{Any}})
Base.precompile(Tuple{Core.kwftype(typeof(scatter!)),Any,typeof(scatter!),Any})
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip, :disp), Tuple{Vector{Int64}, Bool}},typeof(test_examples),Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip,), Tuple{Vector{Int64}}},typeof(test_examples),Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(yaxis!)),Any,typeof(yaxis!),Any,Any})
Base.precompile(Tuple{Type{GridLayout},Int64,Vararg{Int64}})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},AbstractVector{<:GeometryBasics.Point}})
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{:hspan}},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{:vspan}},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.preprocess_axis_args!),Plot{GRBackend},Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_axis_args!),Plot{PlotlyBackend},Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{GRBackend},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}}})
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.unzip),Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{typeof(_bin_centers),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Float64},String})
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}, Int64}},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),UnitRange{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(_cycle),Vector{Float64},Vector{Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Int64},StepRange{Int64, Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Int64},UnitRange{Int64}})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},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}, Int64},Vector{Float64}})
Base.precompile(Tuple{typeof(_replace_markershape),Vector{Symbol}})
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(annotate!),AbstractVector{<:Tuple}})
Base.precompile(Tuple{typeof(axis_limits),Subplot{GRBackend},Symbol,Bool,Bool})
Base.precompile(Tuple{typeof(axis_limits),Subplot{PlotlyBackend},Symbol,Bool,Bool})
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,Vector{Plot}})
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64},Tuple{Int64, Float64}})
Base.precompile(Tuple{typeof(discrete_value!),Axis,Vector{Union{Missing, Float64}}})
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64},Vararg{Vector{Float64}}})
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(fakedata),Int64,Int64})
Base.precompile(Tuple{typeof(fakedata),TaskLocalRNG,Int64,Vararg{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),SubArray{Symbol, 1, Vector{Symbol}, Tuple{UnitRange{Int64}}, true},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{PlotlyBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_ticks),StepRange{Int64, Int64},Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any}})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any}})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Float64},Vararg{Any}})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any}})
Base.precompile(Tuple{typeof(get_ticks),UnitRange{Int64},Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any}})
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, Int64, Int64, 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_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},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,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
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,Float64,Tuple{Float64, Float64},Int64,Int64,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},Int64,Int64})
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}, Int64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,UnitRange{Int64},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,Base.OneTo{Int64},Vector{Float64},Nothing,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64},Nothing,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,UnitRange{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,UnitRange{Int64},Vector{Float64},Nothing,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,UnitRange{Int64},Vector{Float64},Vector{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_segments),Series,Vector{Float64},Vector{Float64},Nothing,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Int64},Vector{Int64},Nothing,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_3d_axis_angle),Vector{Float64},Float64,Float64,Symbol})
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),Subplot{GRBackend},Symbol,Tuple{Vector{Int64}, 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_text),Float64,Float64,String})
Base.precompile(Tuple{typeof(gr_text_size),String})
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, Int64, Int64, 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),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),UnitRange{Int64},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol})
Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}})
Base.precompile(Tuple{typeof(layout_args),Matrix{Any}})
Base.precompile(Tuple{typeof(layout_args),NamedTuple{(:label, :blank), Tuple{Symbol, Bool}}})
Base.precompile(Tuple{typeof(layout_args),NamedTuple{(:label, :width, :height), Tuple{Symbol, Symbol, Float64}}})
Base.precompile(Tuple{typeof(make_fillrange_side),UnitRange{Int64},LinRange{Float64, Int64}})
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),Float64,Float64,Int64})
Base.precompile(Tuple{typeof(partialcircle),Int64,Float64,Int64})
Base.precompile(Tuple{typeof(plot!),Any})
Base.precompile(Tuple{typeof(plot!),Plot,Plot,Plot,Vararg{Plot}})
Base.precompile(Tuple{typeof(plot),Any,Any})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend}})
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
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},Bool})
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{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
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(quiver_using_arrows),DefaultsDict})
Base.precompile(Tuple{typeof(resetfontsizes)})
Base.precompile(Tuple{typeof(scalefontsizes),Float64})
Base.precompile(Tuple{typeof(series_annotations),Vector{Any}})
Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{AbsoluteLength},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(slice_arg),Matrix{Symbol},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}})
Base.precompile(Tuple{typeof(text),String,Symbol})
Base.precompile(Tuple{typeof(title!),AbstractString})
Base.precompile(Tuple{typeof(vline!),Any})
Base.precompile(Tuple{typeof(warn_on_attr_dim_mismatch),Series,Vector{Float64},Vector{Float64},Nothing,Base.Iterators.Flatten{Vector{Tuple{SeriesSegment}}}})
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any}})
Base.precompile(Tuple{typeof(xgrid!),Plot{PlotlyBackend},Symbol,Vararg{Any}})
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
isdefined(Plots, Symbol("#168#169")) && Base.precompile(Tuple{getfield(Plots, Symbol("#168#169")),Any})
isdefined(Plots, Symbol("#170#171")) && Base.precompile(Tuple{getfield(Plots, Symbol("#170#171")),Any})
isdefined(Plots, Symbol("#2#6")) && Base.precompile(Tuple{getfield(Plots, Symbol("#2#6")),UnitRange{Int64}})
isdefined(Plots, Symbol("#301#337")) && Base.precompile(Tuple{getfield(Plots, Symbol("#301#337"))})
isdefined(Plots, Symbol("#322#358")) && Base.precompile(Tuple{getfield(Plots, Symbol("#322#358"))})
isdefined(Plots, Symbol("#add_major_or_minor_segments#102")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#102")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64}},Float64,Bool})
isdefined(Plots, Symbol("#add_major_or_minor_segments#103")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#103")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64, Float64}},Float64,Bool})
let fbody = try __lookup_kwbody__(which(annotate!, (AbstractVector{<:Tuple},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(annotate!),AbstractVector{<:Tuple},))
end
end
let fbody = try __lookup_kwbody__(which(font, (Font,Vararg{Any},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(font),Font,Vararg{Any},))
end
end
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(gr_set_font, (Font,Subplot{GRBackend},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Symbol,Symbol,RGBA{Float64},Float64,typeof(gr_set_font),Font,Subplot{GRBackend},))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Any,Vararg{Any},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot!),Any,Vararg{Any},))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot!),Plot,Plot,))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,Plot,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot!),Plot,Plot,Plot,))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,Plot,Vararg{Plot},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot!),Plot,Plot,Plot,Vararg{Plot},))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Any,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot),Any,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Any,Vararg{Any},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot),Any,Vararg{Any},))
end
end
let fbody = try __lookup_kwbody__(which(title!, (AbstractString,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(title!),AbstractString,))
end
end
let fbody = try __lookup_kwbody__(which(yaxis!, (Any,Vararg{Any},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(yaxis!),Any,Vararg{Any},))
end
end
end

View File

@ -0,0 +1,282 @@
# 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
function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
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}},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{(:formatter,), Tuple{typeof(datetimeformatter)}},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{(:lims,), Tuple{Tuple{Int64, Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{Nothing}},typeof(attr!),Axis})
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(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},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), Tuple{Symbol, Symbol, Int64}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:rotation, :color), Tuple{Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Vector{Int64}})
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, Tuple{String, Any, Any, Any}}}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:layout, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
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,Irrational{}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Plot{GRBackend},Function,Float64,Vararg{Any}})
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}, Int64},Vector{Float64}})
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}, Int64},Vector{Float64}})
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}, Int64},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},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{PlotlyBackend},Vector{Int64},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!),Vector{Int64},Vector{Float64}})
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},Vector{Float64},Vararg{Any}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},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{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bar_width, :alpha, :color, :fillto, :label, :seriestype), Tuple{Float64, Float64, Vector{Symbol}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, String, Symbol}},typeof(plot),Vector{Float64}})
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}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:connections, :title, :xlabel, :ylabel, :zlabel, :legend, :margin, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, String, String, String, String, Symbol, AbsoluteLength, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill, :seriestype), Tuple{Bool, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Function})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill_z, :alpha, :label, :bar_width, :seriestype), Tuple{StepRange{Int64, Int64}, Vector{Float64}, String, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Int64},Vector{Int64}})
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, :legend, :seriestype), Tuple{String, Symbol, Symbol}},typeof(plot),Vector{Int64}})
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,Float64})
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{Matrix{Any}, 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},Plot{GRBackend}})
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},Plot{PlotlyBackend}})
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{Matrix{Any}, 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{Matrix{Any}, 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{Matrix{Any}, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
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},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,Int64,Vararg{Any}})
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}, Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line_z, :linewidth, :legend), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, 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}, Int64},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}, Int64},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}, Int64},UnitRange{Int64},Matrix{Int64}})
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},Vector{Float64}})
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{Tuple{LinRange{Float64, Int64}, LinRange{Float64, Int64}}}},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),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}})
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},Vector{Float64}})
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, :xflip, :yflip, :zflip, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :xmirror, :ymirror, :zmirror, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
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{(: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{(:zcolor, :m, :leg, :cbar, :w), Tuple{StepRange{Int64, Int64}, Tuple{Int64, Float64, Symbol, Stroke}, Bool, Bool, Int64}},typeof(plot),Vector{Float64},Vector{Float64},UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(portfoliocomposition)),Any,typeof(portfoliocomposition),Any,Vararg{Any}})
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip, :disp), Tuple{Vector{Int64}, Bool}},typeof(test_examples),Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip,), Tuple{Vector{Int64}}},typeof(test_examples),Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(yaxis!)),Any,typeof(yaxis!),Any,Any})
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{: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{:hspan}},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{: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{:vspan}},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_sliced_series_attributes!),Plot{GRBackend},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.unzip),Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{typeof(_bin_centers),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{PlotUtils.ContinuousColorGradient},String})
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},Vector{Int64}})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},Bool})
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}, Int64},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(annotate!),AbstractVector{<:Tuple}})
Base.precompile(Tuple{typeof(axis_limits),Subplot{GRBackend},Symbol,Bool,Bool})
Base.precompile(Tuple{typeof(axis_limits),Subplot{PlotlyBackend},Symbol,Bool,Bool})
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,Vector{Plot}})
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64},Tuple{Int64, Float64}})
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64},Vararg{Vector{Float64}}})
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(fakedata),Int64,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),SubArray{Symbol, 1, Vector{Symbol}, Tuple{UnitRange{Int64}}, true},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{PlotlyBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_ticks),StepRange{Int64, Int64},Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any}})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any}})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Float64},Vararg{Any}})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any}})
Base.precompile(Tuple{typeof(get_ticks),UnitRange{Int64},Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any}})
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, Int64, Int64, 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_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},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,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
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,Float64,Tuple{Float64, Float64},Int64,Int64,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_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_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_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Int64}, 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_set_gradient),PlotUtils.ContinuousColorGradient})
Base.precompile(Tuple{typeof(gr_text),Float64,Float64,String})
Base.precompile(Tuple{typeof(gr_text_size),String})
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, Int64, Int64, 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),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),UnitRange{Int64},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol})
Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}})
Base.precompile(Tuple{typeof(is_marker_supported),GRBackend,Vector{Symbol}})
Base.precompile(Tuple{typeof(layout_args),Matrix{Any}})
Base.precompile(Tuple{typeof(link_axes!),GridLayout,Symbol})
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!),Plot,Plot,Plot,Vararg{Plot}})
Base.precompile(Tuple{typeof(plot),Any,Any})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{typeof(plot),Plot{GRBackend}})
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Matrix{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(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText,Font})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol},Font})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String},Font})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText,Font})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol},Font})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Symbol, Int64, String},Font})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
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(push!),Segments{Tuple{Float64, Float64, Float64}},Tuple{Float64, Int64, Int64},Tuple{Float64, Int64, Int64}})
Base.precompile(Tuple{typeof(resetfontsizes)})
Base.precompile(Tuple{typeof(scalefontsizes),Float64})
Base.precompile(Tuple{typeof(series_annotations),Vector{Any}})
Base.precompile(Tuple{typeof(slice_arg),Matrix{AbsoluteLength},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{Bool},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{Int64},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(title!),AbstractString})
Base.precompile(Tuple{typeof(update_child_bboxes!),GridLayout})
Base.precompile(Tuple{typeof(update_clims),Float64,Float64,SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true},typeof(ignorenan_extrema)})
Base.precompile(Tuple{typeof(warn_on_attr_dim_mismatch),Series,Vector{Float64},Vector{Float64},Nothing,Base.Iterators.Flatten{Vector{Tuple{SeriesSegment}}}})
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any}})
Base.precompile(Tuple{typeof(xgrid!),Plot{PlotlyBackend},Symbol,Vararg{Any}})
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
isdefined(Plots, Symbol("#2#6")) && Base.precompile(Tuple{getfield(Plots, Symbol("#2#6")),UnitRange{Int64}})
isdefined(Plots, Symbol("#322#358")) && Base.precompile(Tuple{getfield(Plots, Symbol("#322#358"))})
isdefined(Plots, Symbol("#add_major_or_minor_segments#102")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#102")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64}},Float64,Bool})
isdefined(Plots, Symbol("#add_major_or_minor_segments#103")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#103")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64, Float64}},Float64,Bool})
end

View File

@ -1,8 +1,6 @@
using CompileBot include("snoop_bot_config.jl")
snoop_bench( snoop_bench(
BotConfig( botconfig,
"Plots",
),
joinpath(@__DIR__, "precompile_script.jl"), joinpath(@__DIR__, "precompile_script.jl"),
) )

View File

@ -1,8 +1,6 @@
using CompileBot include("snoop_bot_config.jl")
snoop_bot( snoop_bot(
BotConfig( botconfig,
"Plots",
),
joinpath(@__DIR__, "precompile_script.jl"), joinpath(@__DIR__, "precompile_script.jl"),
) )

7
deps/SnoopCompile/snoop_bot_config.jl vendored Normal file
View File

@ -0,0 +1,7 @@
using CompileBot
botconfig = BotConfig(
"Plots",
version = ["1.6", "1.7", "1.8", "nightly"], # <<< keep these versions in sync with .github/workflows/SnoopCompile.yml
# else_version = "nightly",
)

View File

@ -1,36 +1,52 @@
module Plots module Plots
using Pkg
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optlevel")) if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optlevel"))
@eval Base.Experimental.@optlevel 1 @eval Base.Experimental.@optlevel 1
end end
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@max_methods"))
@eval Base.Experimental.@max_methods 1
end
const _current_plots_version = VersionNumber( const _plots_project = Pkg.Types.read_project(normpath(@__DIR__, "..", "Project.toml"))
split( const _current_plots_version = _plots_project.version
first( const _plots_compats = _plots_project.compat
filter( function _check_compat(sim::Module)
line -> occursin("version", line), sim_str = string(sim)
readlines(normpath(@__DIR__, "..", "Project.toml")), if !haskey(_plots_compats, sim_str)
), return nothing
), end
"\"", be_v = Pkg.Types.read_project(joinpath(Base.pkgdir(sim), "Project.toml")).version
)[2], be_c = _plots_compats[sim_str]
) if be_c isa String # julia 1.6
if !(be_v in Pkg.Types.semver_spec(be_c))
@warn "$sim $be_v is not compatible with this version of Plots. The declared compatibility is $(be_c)."
end
else
if isempty(intersect(be_v, be_c.val))
@warn "$sim $be_v is not compatible with this version of Plots. The declared compatibility is $(be_c.str)."
end
end
end
using Reexport using Reexport
import GeometryBasics import GeometryBasics
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random using Dates, Printf, Statistics, Base64, LinearAlgebra, Random, Unzip
using SparseArrays using SparseArrays
using FFMPEG using FFMPEG
@reexport using RecipesBase @reexport using RecipesBase
import RecipesBase: plot, plot!, animate, is_explicit import RecipesBase: plot, plot!, animate, is_explicit, grid
using Base.Meta using Base.Meta
@reexport using PlotUtils @reexport using PlotUtils
@reexport using PlotThemes @reexport using PlotThemes
import Showoff import UnicodeFun
import StatsBase import StatsBase
import Downloads
import Showoff
import JSON import JSON
using Requires using Requires
@ -40,7 +56,6 @@ export
grid, grid,
bbox, bbox,
plotarea, plotarea,
@layout,
KW, KW,
wrap, wrap,
@ -165,6 +180,8 @@ const BBox = Measures.Absolute2DBox
const px = AbsoluteLength(0.254) const px = AbsoluteLength(0.254)
const pct = Length{:pct,Float64}(1.0) const pct = Length{:pct,Float64}(1.0)
Base.convert(::Type{<:Measure}, x::Float64) = x * pct
Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value) Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value)
Base.:*(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * m1.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::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value / m2.value)
@ -193,14 +210,13 @@ import RecipesPipeline:
pop_kw!, pop_kw!,
scale_func, scale_func,
inverse_scale_func, inverse_scale_func,
unzip,
dateformatter, dateformatter,
datetimeformatter, datetimeformatter,
timeformatter timeformatter
# Use fixed version of Plotly instead of the latest one for stable dependency # Use fixed version of Plotly instead of the latest one for stable dependency
# Ref: https://github.com/JuliaPlots/Plots.jl/pull/2779 # Ref: https://github.com/JuliaPlots/Plots.jl/pull/2779
const _plotly_min_js_filename = "plotly-1.57.1.min.js" const _plotly_min_js_filename = "plotly-2.6.3.min.js"
include("types.jl") include("types.jl")
include("utils.jl") include("utils.jl")
@ -208,6 +224,7 @@ include("colorbars.jl")
include("axes.jl") include("axes.jl")
include("args.jl") include("args.jl")
include("components.jl") include("components.jl")
include("consts.jl")
include("themes.jl") include("themes.jl")
include("plot.jl") include("plot.jl")
include("pipeline.jl") include("pipeline.jl")

View File

@ -14,6 +14,7 @@ const _arg_desc = KW(
:fillcolor => "Color Type. Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`.", :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.", :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).", :markershape => "Symbol, Shape, or AbstractVector. Choose from $(_allMarkers).",
:fillstyle => "Symbol. Style of the fill area. `nothing` (the default) means solid fill. Choose from :/, :\\, :|, :-, :+, :x",
:markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.", :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.", :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", :markersize => "Number or AbstractVector. Size (radius pixels) of the markers",
@ -31,7 +32,8 @@ const _arg_desc = KW(
: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).", :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`.", :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 (number of contours) or AbstractVector (contour values). Determines contour levels for a contour type.", :levels => "Integer (number of contours) or AbstractVector (contour values). Determines contour 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).", :permute => "Tuple{Symbol,Symbol}. Permutes data and axis properties of the axes given in the tuple. E.g. (:x, :y).",
:orientation => "Symbol. (deprecated) 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_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_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)?", :bar_edges => "Bool. Align bars to edges (true), or centers (the default)?",
@ -51,6 +53,7 @@ const _arg_desc = KW(
: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.", :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.", :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.", :colorbar_entry => "Bool. Include this series in the color bar? Set to `false` to exclude.",
:z_order => "Symbol or Integer. :front (default), :back or index of position where 1 is farest in the background.",
# plot args # plot args
:plot_title => "String. Title for the whole plot (not the subplots)", :plot_title => "String. Title for the whole plot (not the subplots)",
@ -85,26 +88,28 @@ const _arg_desc = KW(
:titlefontrotation => "Real. Font rotation of subplot title", :titlefontrotation => "Real. Font rotation of subplot title",
:titlefontcolor => "Color Type. Font color 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_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.", :legend_background_color => "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).", :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_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.", :legend_foreground_color => "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.", :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.", :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.", :legend_position => "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)",
:legendfontfamily => "String or Symbol. Font family of legend entries.", :legend_column => "Integer. Number of columns in the legend. `-1` stands for maximum number of colums (horizontal legend).",
:legendfontsize => "Integer. Font pointsize of legend entries.", :legend_title_font => "Font. Font of the legend title.",
:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center", :legend_font_family => "String or Symbol. Font family of legend entries.",
:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center", :legend_font_pointsize => "Integer. Font pointsize of legend entries.",
:legendfontrotation => "Real. Font rotation of legend entries", :legend_font_halign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center",
:legendfontcolor => "Color Type. Font color of legend entries", :legend_font_valign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center",
:legendtitle => "String. Legend title.", :legend_font_rotation => "Real. Font rotation of legend entries",
:legendtitlefontfamily => "String or Symbol. Font family of the legend title.", :legend_font_color => "Color Type. Font color of legend entries",
:legendtitlefontsize => "Integer. Font pointsize the legend title.", :legend_title => "String. Legend title.",
:legendtitlefonthalign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center", :legend_title_font_family => "String or Symbol. Font family of the legend title.",
:legendtitlefontvalign => "Symbol. Font vertical alignment of the legend title: :vcenter, :top, :bottom or :center", :legend_title_font_pointsize => "Integer. Font pointsize the legend title.",
:legendtitlefontrotation => "Real. Font rotation of the legend title", :legend_title_font_halign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center",
:legendtitlefontcolor => "Color Type. Font color of the legend title", :legend_title_font_valign => "Symbol. Font vertical alignment of the legend title: :vcenter, :top, :bottom or :center",
:legend_title_font_rotation => "Real. Font rotation of the legend title",
:legend_title_font_color => "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)", :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.", :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_fontfamily => "String or Symbol. Font family of colobar entries.",
@ -114,8 +119,8 @@ const _arg_desc = KW(
:colorbar_tickfontcolor => "Color Type. Font color 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_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.", :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.", :legend_font => "Font. Font of legend items.",
:legendtitlefont => "Font. Font of the legend title.", :legend_titlefont => "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, PlotText (created with `text(args...)`), or a tuple of arguments to `text` (e.g., `(\"Label\", 8, :red, :top)`). Add one-off text annotations at the x,y coordinates.", :annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String, PlotText (created with `text(args...)`), or a tuple of arguments to `text` (e.g., `(\"Label\", 8, :red, :top)`). Add one-off text annotations at the x,y coordinates.",
:annotationfontfamily => "String or Symbol. Font family of annotations.", :annotationfontfamily => "String or Symbol. Font family of annotations.",
:annotationfontsize => "Integer. Font pointsize of annotations.", :annotationfontsize => "Integer. Font pointsize of annotations.",

View File

@ -24,6 +24,14 @@ function add_aliases(sym::Symbol, aliases::Symbol...)
return nothing return nothing
end end
function add_axes_aliases(sym::Symbol, aliases::Symbol...; generic::Bool = true)
sym in keys(_axis_defaults) || throw(ArgumentError("Invalid `$sym`"))
generic && add_aliases(sym, aliases...)
for letter in (:x, :y, :z)
add_aliases(Symbol(letter, sym), (Symbol(letter, a) for a in aliases)...)
end
end
function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol}) function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol})
for (k, v) in aliases for (k, v) in aliases
s = string(k) s = string(k)
@ -81,6 +89,8 @@ const _allTypes = vcat(
_3dTypes, _3dTypes,
) )
const _z_colored_series = [:contour, :contour3d, :heatmap, :histogram2d, :surface, :hexbin]
const _typeAliases = Dict{Symbol,Symbol}( const _typeAliases = Dict{Symbol,Symbol}(
:n => :none, :n => :none,
:no => :none, :no => :none,
@ -276,7 +286,7 @@ function hasgrid(arg::Symbol, letter)
arg in (:all, :both, :on) || occursin(string(letter), string(arg)) arg in (:all, :both, :on) || occursin(string(letter), string(arg))
else else
@warn( @warn(
"Unknown grid argument $arg; $(Symbol(letter, :grid)) was set to `true` instead." "Unknown grid argument $arg; $(get_attr_symbol(letter, :grid)) was set to `true` instead."
) )
true true
end end
@ -316,7 +326,7 @@ function showaxis(arg::Symbol, letter)
arg in (:all, :both, :on, :yes) || occursin(string(letter), string(arg)) arg in (:all, :both, :on, :yes) || occursin(string(letter), string(arg))
else else
@warn( @warn(
"Unknown showaxis argument $arg; $(Symbol(letter, :showaxis)) was set to `true` instead." "Unknown showaxis argument $arg; $(get_attr_symbol(letter, :showaxis)) was set to `true` instead."
) )
true true
end end
@ -348,6 +358,7 @@ const _series_defaults = KW(
:fillrange => nothing, # ribbons, areas, etc :fillrange => nothing, # ribbons, areas, etc
:fillcolor => :match, :fillcolor => :match,
:fillalpha => nothing, :fillalpha => nothing,
:fillstyle => nothing,
:markershape => :none, :markershape => :none,
:markercolor => :match, :markercolor => :match,
:markeralpha => nothing, :markeralpha => nothing,
@ -388,6 +399,8 @@ const _series_defaults = KW(
:hover => nothing, # text to display when hovering over the data points :hover => nothing, # text to display when hovering over the data points
:stride => (1, 1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride. :stride => (1, 1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride.
:connections => nothing, # tuple of arrays to specifiy connectivity of a 3d mesh :connections => nothing, # tuple of arrays to specifiy connectivity of a 3d mesh
:z_order => :front, # one of :front, :back or integer in 1:length(sp.series_list)
:permute => :none, # tuple of two symbols to be permuted
:extra_kwargs => Dict(), :extra_kwargs => Dict(),
) )
@ -436,14 +449,10 @@ const _subplot_defaults = KW(
:titlefontrotation => 0.0, :titlefontrotation => 0.0,
:titlefontcolor => :match, :titlefontcolor => :match,
:background_color_subplot => :match, # default for other bg colors... match takes plot default :background_color_subplot => :match, # default for other bg colors... match takes plot default
:background_color_legend => :match, # background of legend
:background_color_inside => :match, # background inside grid :background_color_inside => :match, # background inside grid
:foreground_color_subplot => :match, # default for other fg colors... match takes plot default :foreground_color_subplot => :match, # default for other fg colors... match takes plot default
:foreground_color_legend => :match, # foreground of legend
:foreground_color_title => :match, # title color :foreground_color_title => :match, # title color
:color_palette => :auto, :color_palette => :auto,
:legend => :best,
:legendtitle => nothing,
:colorbar => :legend, :colorbar => :legend,
:clims => :auto, :clims => :auto,
:colorbar_fontfamily => :match, :colorbar_fontfamily => :match,
@ -458,18 +467,6 @@ const _subplot_defaults = KW(
:colorbar_formatter => :auto, :colorbar_formatter => :auto,
:colorbar_discrete_values => [], :colorbar_discrete_values => [],
:colorbar_continuous_values => zeros(0), :colorbar_continuous_values => zeros(0),
:legendfontfamily => :match,
:legendfontsize => 8,
:legendfonthalign => :hcenter,
:legendfontvalign => :vcenter,
:legendfontrotation => 0.0,
:legendfontcolor => :match,
:legendtitlefontfamily => :match,
:legendtitlefontsize => 11,
:legendtitlefonthalign => :hcenter,
:legendtitlefontvalign => :vcenter,
:legendtitlefontrotation => 0.0,
:legendtitlefontcolor => :match,
:annotations => [], # annotation tuples... list of (x,y,annotation) :annotations => [], # annotation tuples... list of (x,y,annotation)
:annotationfontfamily => :match, :annotationfontfamily => :match,
:annotationfontsize => 14, :annotationfontsize => 14,
@ -488,6 +485,7 @@ const _subplot_defaults = KW(
:colorbar_title => "", :colorbar_title => "",
:colorbar_titlefontsize => 10, :colorbar_titlefontsize => 10,
:colorbar_title_location => :center, # also :left or :right :colorbar_title_location => :center, # also :left or :right
:colorbar_fontfamily => :match,
:colorbar_titlefontfamily => :match, :colorbar_titlefontfamily => :match,
:colorbar_titlefonthalign => :hcenter, :colorbar_titlefonthalign => :hcenter,
:colorbar_titlefontvalign => :vcenter, :colorbar_titlefontvalign => :vcenter,
@ -557,71 +555,6 @@ const _suppress_warnings = Set{Symbol}([
:relative_bbox, :relative_bbox,
]) ])
# add defaults for the letter versions
const _axis_defaults_byletter = KW()
function reset_axis_defaults_byletter!()
for letter in (:x, :y, :z)
_axis_defaults_byletter[letter] = KW()
for (k, v) in _axis_defaults
_axis_defaults_byletter[letter][k] = v
end
end
end
reset_axis_defaults_byletter!()
for letter in (:x, :y, :z), k in keys(_axis_defaults)
# allow the underscore version too: xguide or x_guide
add_aliases(Symbol(letter, k), Symbol(letter, "_", k))
end
const _all_defaults = KW[_series_defaults, _plot_defaults, _subplot_defaults]
const _initial_defaults = deepcopy(_all_defaults)
const _initial_axis_defaults = deepcopy(_axis_defaults)
# to be able to reset font sizes to initial values
const _initial_plt_fontsizes =
Dict(:plot_titlefontsize => _plot_defaults[:plot_titlefontsize])
const _initial_sp_fontsizes = Dict(
:titlefontsize => _subplot_defaults[:titlefontsize],
:legendfontsize => _subplot_defaults[:legendfontsize],
:legendtitlefontsize => _subplot_defaults[:legendtitlefontsize],
:annotationfontsize => _subplot_defaults[:annotationfontsize],
:colorbar_tickfontsize => _subplot_defaults[:colorbar_tickfontsize],
:colorbar_titlefontsize => _subplot_defaults[:colorbar_titlefontsize],
)
const _initial_ax_fontsizes = Dict(
:tickfontsize => _axis_defaults[:tickfontsize],
:guidefontsize => _axis_defaults[:guidefontsize],
)
const _initial_fontsizes =
merge(_initial_plt_fontsizes, _initial_sp_fontsizes, _initial_ax_fontsizes)
const _internal_args =
[:plot_object, :series_plotindex, :markershape_to_add, :letter, :idxfilter]
const _axis_args = sort(union(collect(keys(_axis_defaults))))
const _series_args = sort(union(collect(keys(_series_defaults))))
const _subplot_args = sort(union(collect(keys(_subplot_defaults))))
const _plot_args = sort(union(collect(keys(_plot_defaults))))
const _magic_axis_args = [:axis, :tickfont, :guidefont, :grid, :minorgrid]
const _magic_subplot_args =
[:titlefont, :legendfont, :legendtitlefont, :plot_titlefont, :colorbar_titlefont]
const _magic_series_args = [:line, :marker, :fill]
const _all_axis_args = sort(union([_axis_args; _magic_axis_args]))
const _all_subplot_args = sort(union([_subplot_args; _magic_subplot_args]))
const _all_series_args = sort(union([_series_args; _magic_series_args]))
const _all_plot_args = _plot_args
const _all_args =
sort(union([_all_axis_args; _all_subplot_args; _all_series_args; _all_plot_args]))
is_subplot_attr(k) = k in _all_subplot_args is_subplot_attr(k) = k in _all_subplot_args
is_series_attr(k) = k in _all_series_args is_series_attr(k) = k in _all_series_args
is_axis_attr(k) = Symbol(chop(string(k); head = 1, tail = 0)) in _all_axis_args is_axis_attr(k) = Symbol(chop(string(k); head = 1, tail = 0)) in _all_axis_args
@ -653,9 +586,46 @@ aliases(aliasMap::Dict{Symbol,Symbol}, val) =
sortedkeys(filter((k, v) -> v == val, aliasMap)) sortedkeys(filter((k, v) -> v == val, aliasMap))
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# legend
add_aliases(:legend_position, :legend, :leg, :key, :legends)
add_aliases(
:legend_background_color,
:bg_legend,
:bglegend,
:bgcolor_legend,
:bg_color_legend,
:background_legend,
:background_colour_legend,
:bgcolour_legend,
:bg_colour_legend,
:background_color_legend,
)
add_aliases(
:legend_foreground_color,
:fg_legend,
:fglegend,
:fgcolor_legend,
:fg_color_legend,
:foreground_legend,
:foreground_colour_legend,
:fgcolour_legend,
:fg_colour_legend,
:foreground_color_legend,
)
add_aliases(:legend_font_pointsize, :legendfontsize)
add_aliases(
:legend_title,
:key_title,
:keytitle,
:label_title,
:labeltitle,
:leg_title,
:legtitle,
)
add_aliases(:legend_title_font_pointsize, :legendtitlefontsize)
# margin # margin
add_aliases(:left_margin, :leftmargin) add_aliases(:left_margin, :leftmargin)
add_aliases(:top_margin, :topmargin) add_aliases(:top_margin, :topmargin)
add_aliases(:bottom_margin, :bottommargin) add_aliases(:bottom_margin, :bottommargin)
add_aliases(:right_margin, :rightmargin) add_aliases(:right_margin, :rightmargin)
@ -678,17 +648,6 @@ add_aliases(
:bgcolour, :bgcolour,
:bg_colour, :bg_colour,
) )
add_aliases(
:background_color_legend,
:bg_legend,
:bglegend,
:bgcolor_legend,
:bg_color_legend,
:background_legend,
:background_colour_legend,
:bgcolour_legend,
:bg_colour_legend,
)
add_aliases( add_aliases(
:background_color_subplot, :background_color_subplot,
:bg_subplot, :bg_subplot,
@ -732,17 +691,7 @@ add_aliases(
:fgcolour, :fgcolour,
:fg_colour, :fg_colour,
) )
add_aliases(
:foreground_color_legend,
:fg_legend,
:fglegend,
:fgcolor_legend,
:fg_color_legend,
:foreground_legend,
:foreground_colour_legend,
:fgcolour_legend,
:fg_colour_legend,
)
add_aliases( add_aliases(
:foreground_color_subplot, :foreground_color_subplot,
:fg_subplot, :fg_subplot,
@ -839,13 +788,147 @@ add_aliases(
:guidecolor, :guidecolor,
) )
add_aliases(
:foreground_color_title,
:fg_title,
:fgtitle,
:fgcolor_title,
:fg_color_title,
:foreground_title,
:foreground_colour_title,
:fgcolour_title,
:fg_colour_title,
:titlecolor,
)
add_aliases(
:foreground_color_axis,
:fg_axis,
:fgaxis,
:fgcolor_axis,
:fg_color_axis,
:foreground_axis,
:foreground_colour_axis,
:fgcolour_axis,
:fg_colour_axis,
:axiscolor,
)
add_aliases(
:foreground_color_border,
:fg_border,
:fgborder,
:fgcolor_border,
:fg_color_border,
:foreground_border,
:foreground_colour_border,
:fgcolour_border,
:fg_colour_border,
:bordercolor,
)
add_aliases(
:foreground_color_text,
:fg_text,
:fgtext,
:fgcolor_text,
:fg_color_text,
:foreground_text,
:foreground_colour_text,
:fgcolour_text,
:fg_colour_text,
:textcolor,
)
add_aliases(
:foreground_color_guide,
:fg_guide,
:fgguide,
:fgcolor_guide,
:fg_color_guide,
:foreground_guide,
:foreground_colour_guide,
:fgcolour_guide,
:fg_colour_guide,
:guidecolor,
)
# alphas # alphas
add_aliases(:seriesalpha, :alpha, :α, :opacity) add_aliases(:seriesalpha, :alpha, :α, :opacity)
add_aliases(:linealpha, :la, :lalpha, :lα, :lineopacity, :lopacity) add_aliases(:linealpha, :la, :lalpha, :lα, :lineopacity, :lopacity)
add_aliases(:markeralpha, :ma, :malpha, :mα, :markeropacity, :mopacity) add_aliases(:markeralpha, :ma, :malpha, :mα, :markeropacity, :mopacity)
add_aliases(:markerstrokealpha, :msa, :msalpha, :msα, :markerstrokeopacity, :msopacity) add_aliases(:markerstrokealpha, :msa, :msalpha, :msα, :markerstrokeopacity, :msopacity)
add_aliases(:fillalpha, :fa, :falpha, :fα, :fillopacity, :fopacity) add_aliases(:fillalpha, :fa, :falpha, :fα, :fillopacity, :fopacity)
add_aliases(:gridalpha, :ga, :galpha, :gα, :gridopacity, :gopacity)
# axes attributes
add_axes_aliases(:guide, :label, :lab, :l; generic = false)
add_axes_aliases(:lims, :lim, :limit, :limits, :range)
add_axes_aliases(:ticks, :tick)
add_axes_aliases(:rotation, :rot, :r)
add_axes_aliases(:guidefontsize, :labelfontsize)
add_axes_aliases(:gridalpha, :ga, :galpha, :gα, :gridopacity, :gopacity)
add_axes_aliases(
:gridstyle,
:grid_style,
:gridlinestyle,
:grid_linestyle,
:grid_ls,
:gridls,
)
add_axes_aliases(
:foreground_color_grid,
:fg_grid,
:fggrid,
:fgcolor_grid,
:fg_color_grid,
:foreground_grid,
:foreground_colour_grid,
:fgcolour_grid,
:fg_colour_grid,
:gridcolor,
)
add_axes_aliases(
:foreground_color_minor_grid,
:fg_minor_grid,
:fgminorgrid,
:fgcolor_minorgrid,
:fg_color_minorgrid,
:foreground_minorgrid,
:foreground_colour_minor_grid,
:fgcolour_minorgrid,
:fg_colour_minor_grid,
:minorgridcolor,
)
add_axes_aliases(
:gridlinewidth,
:gridwidth,
:grid_linewidth,
:grid_width,
:gridlw,
:grid_lw,
)
add_axes_aliases(
:minorgridstyle,
:minorgrid_style,
:minorgridlinestyle,
:minorgrid_linestyle,
:minorgrid_ls,
:minorgridls,
)
add_axes_aliases(
:minorgridlinewidth,
:minorgridwidth,
:minorgrid_linewidth,
:minorgrid_width,
:minorgridlw,
:minorgrid_lw,
)
add_axes_aliases(
:tick_direction,
:tickdirection,
:tick_dir,
:tickdir,
:tick_orientation,
:tickorientation,
:tick_or,
:tickor,
)
# series attributes # series attributes
add_aliases(:seriestype, :st, :t, :typ, :linetype, :lt) add_aliases(:seriestype, :st, :t, :typ, :linetype, :lt)
@ -887,8 +970,6 @@ add_aliases(
:surfcolor, :surfcolor,
:surfcolour, :surfcolour,
) )
add_aliases(:legend, :leg, :key)
add_aliases(:legendtitle, :legend_title, :labeltitle, :label_title, :leg_title, :key_title)
add_aliases(:colorbar, :cb, :cbar, :colorkey) add_aliases(:colorbar, :cb, :cbar, :colorkey)
add_aliases( add_aliases(
:colorbar_title, :colorbar_title,
@ -945,24 +1026,7 @@ add_aliases(:html_output_format, :format, :fmt, :html_format)
add_aliases(:orientation, :direction, :dir) add_aliases(:orientation, :direction, :dir)
add_aliases(:inset_subplots, :inset, :floating) add_aliases(:inset_subplots, :inset, :floating)
add_aliases(:stride, :wirefame_stride, :surface_stride, :surf_str, :str) add_aliases(:stride, :wirefame_stride, :surface_stride, :surf_str, :str)
add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw)
add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls)
add_aliases(
:minorgridlinewidth,
:minorgridwidth,
:minorgrid_linewidth,
:minorgrid_width,
:minorgridlw,
:minorgrid_lw,
)
add_aliases(
:minorgridstyle,
:minorgrid_style,
:minorgridlinestyle,
:minorgrid_linestyle,
:minorgrid_ls,
:minorgridls,
)
add_aliases( add_aliases(
:framestyle, :framestyle,
:frame_style, :frame_style,
@ -976,27 +1040,11 @@ add_aliases(
:border_style, :border_style,
:border, :border,
) )
add_aliases(
:tick_direction,
:tickdirection,
:tick_dir,
:tickdir,
:tick_orientation,
:tickorientation,
:tick_or,
:tickor,
)
add_aliases(:camera, :cam, :viewangle, :view_angle) add_aliases(:camera, :cam, :viewangle, :view_angle)
add_aliases(:contour_labels, :contourlabels, :clabels, :clabs) add_aliases(:contour_labels, :contourlabels, :clabels, :clabs)
add_aliases(:warn_on_unsupported, :warn) add_aliases(:warn_on_unsupported, :warn)
# add all pluralized forms to the _keyAliases dict
for arg in _all_args
add_aliases(arg, makeplural(arg))
end
# add all non_underscored forms to the _keyAliases
add_non_underscore_aliases!(_keyAliases)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
function parse_axis_kw(s::Symbol) function parse_axis_kw(s::Symbol)
@ -1012,10 +1060,14 @@ end
# update the defaults globally # update the defaults globally
""" """
`default(key)` returns the current default value for that key `default(key)` returns the current default value for that key.
`default(key, value)` sets the current default value for that key
`default(; kw...)` will set the current default value for each key/value pair `default(key, value)` sets the current default value for that key.
`default(plotattributes, key)` returns the key from plotattributes if it exists, otherwise `default(key)`
`default(; kw...)` will set the current default value for each key/value pair.
`default(plotattributes, key)` returns the key from plotattributes if it exists, otherwise `default(key)`.
""" """
function default(k::Symbol) function default(k::Symbol)
k = get(_keyAliases, k, k) k = get(_keyAliases, k, k)
@ -1117,6 +1169,7 @@ function processLineArg(plotattributes::AKW, arg)
arg.color == :auto ? :auto : plot_color(arg.color) arg.color == :auto ? :auto : plot_color(arg.color)
) )
arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha) arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha)
arg.style === nothing || (plotattributes[:fillstyle] = arg.style)
elseif typeof(arg) <: Arrow || arg in (:arrow, :arrows) elseif typeof(arg) <: Arrow || arg in (:arrow, :arrows)
plotattributes[:arrow] = arg plotattributes[:arrow] = arg
@ -1188,6 +1241,7 @@ function processFillArg(plotattributes::AKW, arg)
arg.color == :auto ? :auto : plot_color(arg.color) arg.color == :auto ? :auto : plot_color(arg.color)
) )
arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha) arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha)
arg.style === nothing || (plotattributes[:fillstyle] = arg.style)
elseif typeof(arg) <: Bool elseif typeof(arg) <: Bool
plotattributes[:fillrange] = arg ? 0 : nothing plotattributes[:fillrange] = arg ? 0 : nothing
@ -1213,69 +1267,79 @@ end
function processGridArg!(plotattributes::AKW, arg, letter) function processGridArg!(plotattributes::AKW, arg, letter)
if arg in _allGridArgs || isa(arg, Bool) if arg in _allGridArgs || isa(arg, Bool)
plotattributes[Symbol(letter, :grid)] = hasgrid(arg, letter) plotattributes[get_attr_symbol(letter, :grid)] = hasgrid(arg, letter)
elseif allStyles(arg) elseif allStyles(arg)
plotattributes[Symbol(letter, :gridstyle)] = arg plotattributes[get_attr_symbol(letter, :gridstyle)] = arg
elseif typeof(arg) <: Stroke elseif typeof(arg) <: Stroke
arg.width === nothing || arg.width === nothing ||
(plotattributes[Symbol(letter, :gridlinewidth)] = arg.width) (plotattributes[get_attr_symbol(letter, :gridlinewidth)] = arg.width)
arg.color === nothing || ( arg.color === nothing || (
plotattributes[Symbol(letter, :foreground_color_grid)] = plotattributes[get_attr_symbol(letter, :foreground_color_grid)] =
arg.color in (:auto, :match) ? :match : plot_color(arg.color) arg.color in (:auto, :match) ? :match : plot_color(arg.color)
) )
arg.alpha === nothing || (plotattributes[Symbol(letter, :gridalpha)] = arg.alpha) arg.alpha === nothing ||
arg.style === nothing || (plotattributes[Symbol(letter, :gridstyle)] = arg.style) (plotattributes[get_attr_symbol(letter, :gridalpha)] = arg.alpha)
arg.style === nothing ||
(plotattributes[get_attr_symbol(letter, :gridstyle)] = arg.style)
# linealpha # linealpha
elseif allAlphas(arg) elseif allAlphas(arg)
plotattributes[Symbol(letter, :gridalpha)] = arg plotattributes[get_attr_symbol(letter, :gridalpha)] = arg
# linewidth # linewidth
elseif allReals(arg) elseif allReals(arg)
plotattributes[Symbol(letter, :gridlinewidth)] = arg plotattributes[get_attr_symbol(letter, :gridlinewidth)] = arg
# color # color
elseif !handleColors!(plotattributes, arg, Symbol(letter, :foreground_color_grid)) elseif !handleColors!(
plotattributes,
arg,
get_attr_symbol(letter, :foreground_color_grid),
)
@warn("Skipped grid arg $arg.") @warn("Skipped grid arg $arg.")
end end
end end
function processMinorGridArg!(plotattributes::AKW, arg, letter) function processMinorGridArg!(plotattributes::AKW, arg, letter)
if arg in _allGridArgs || isa(arg, Bool) if arg in _allGridArgs || isa(arg, Bool)
plotattributes[Symbol(letter, :minorgrid)] = hasgrid(arg, letter) plotattributes[get_attr_symbol(letter, :minorgrid)] = hasgrid(arg, letter)
elseif allStyles(arg) elseif allStyles(arg)
plotattributes[Symbol(letter, :minorgridstyle)] = arg plotattributes[get_attr_symbol(letter, :minorgridstyle)] = arg
plotattributes[Symbol(letter, :minorgrid)] = true plotattributes[get_attr_symbol(letter, :minorgrid)] = true
elseif typeof(arg) <: Stroke elseif typeof(arg) <: Stroke
arg.width === nothing || arg.width === nothing ||
(plotattributes[Symbol(letter, :minorgridlinewidth)] = arg.width) (plotattributes[get_attr_symbol(letter, :minorgridlinewidth)] = arg.width)
arg.color === nothing || ( arg.color === nothing || (
plotattributes[Symbol(letter, :foreground_color_minor_grid)] = plotattributes[get_attr_symbol(letter, :foreground_color_minor_grid)] =
arg.color in (:auto, :match) ? :match : plot_color(arg.color) arg.color in (:auto, :match) ? :match : plot_color(arg.color)
) )
arg.alpha === nothing || arg.alpha === nothing ||
(plotattributes[Symbol(letter, :minorgridalpha)] = arg.alpha) (plotattributes[get_attr_symbol(letter, :minorgridalpha)] = arg.alpha)
arg.style === nothing || arg.style === nothing ||
(plotattributes[Symbol(letter, :minorgridstyle)] = arg.style) (plotattributes[get_attr_symbol(letter, :minorgridstyle)] = arg.style)
plotattributes[Symbol(letter, :minorgrid)] = true plotattributes[get_attr_symbol(letter, :minorgrid)] = true
# linealpha # linealpha
elseif allAlphas(arg) elseif allAlphas(arg)
plotattributes[Symbol(letter, :minorgridalpha)] = arg plotattributes[get_attr_symbol(letter, :minorgridalpha)] = arg
plotattributes[Symbol(letter, :minorgrid)] = true plotattributes[get_attr_symbol(letter, :minorgrid)] = true
# linewidth # linewidth
elseif allReals(arg) elseif allReals(arg)
plotattributes[Symbol(letter, :minorgridlinewidth)] = arg plotattributes[get_attr_symbol(letter, :minorgridlinewidth)] = arg
plotattributes[Symbol(letter, :minorgrid)] = true plotattributes[get_attr_symbol(letter, :minorgrid)] = true
# color # color
elseif handleColors!(plotattributes, arg, Symbol(letter, :foreground_color_minor_grid)) elseif handleColors!(
plotattributes[Symbol(letter, :minorgrid)] = true plotattributes,
arg,
get_attr_symbol(letter, :foreground_color_minor_grid),
)
plotattributes[get_attr_symbol(letter, :minorgrid)] = true
else else
@warn("Skipped grid arg $arg.") @warn("Skipped grid arg $arg.")
end end
@ -1285,7 +1349,12 @@ function processFontArg!(plotattributes::AKW, fontname::Symbol, arg)
T = typeof(arg) T = typeof(arg)
if T <: Font if T <: Font
plotattributes[Symbol(fontname, :family)] = arg.family plotattributes[Symbol(fontname, :family)] = arg.family
# TODO: this is neccessary in the transition from old fontsize to new font_pointsize and should be removed when it is completed
if in(Symbol(fontname, :size), _all_args)
plotattributes[Symbol(fontname, :size)] = arg.pointsize plotattributes[Symbol(fontname, :size)] = arg.pointsize
else
plotattributes[Symbol(fontname, :_pointsize)] = arg.pointsize
end
plotattributes[Symbol(fontname, :halign)] = arg.halign plotattributes[Symbol(fontname, :halign)] = arg.halign
plotattributes[Symbol(fontname, :valign)] = arg.valign plotattributes[Symbol(fontname, :valign)] = arg.valign
plotattributes[Symbol(fontname, :rotation)] = arg.rotation plotattributes[Symbol(fontname, :rotation)] = arg.rotation
@ -1306,7 +1375,11 @@ function processFontArg!(plotattributes::AKW, fontname::Symbol, arg)
plotattributes[Symbol(fontname, :family)] = string(arg) plotattributes[Symbol(fontname, :family)] = string(arg)
end end
elseif typeof(arg) <: Integer elseif typeof(arg) <: Integer
if in(Symbol(fontname, :size), _all_args)
plotattributes[Symbol(fontname, :size)] = arg plotattributes[Symbol(fontname, :size)] = arg
else
plotattributes[Symbol(fontname, :_pointsize)] = arg
end
elseif typeof(arg) <: Real elseif typeof(arg) <: Real
plotattributes[Symbol(fontname, :rotation)] = convert(Float64, arg) plotattributes[Symbol(fontname, :rotation)] = convert(Float64, arg)
else else
@ -1341,7 +1414,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end end
# handle axis args # handle axis args
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
asym = Symbol(letter, :axis) asym = get_attr_symbol(letter, :axis)
args = RecipesPipeline.pop_kw!(plotattributes, asym, ()) args = RecipesPipeline.pop_kw!(plotattributes, asym, ())
if !(typeof(args) <: Axis) if !(typeof(args) <: Axis)
for arg in wraptuple(args) for arg in wraptuple(args)
@ -1368,7 +1441,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end end
# handle individual axes grid args # handle individual axes grid args
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
gridsym = Symbol(letter, :grid) gridsym = get_attr_symbol(letter, :grid)
args = RecipesPipeline.pop_kw!(plotattributes, gridsym, ()) args = RecipesPipeline.pop_kw!(plotattributes, gridsym, ())
for arg in wraptuple(args) for arg in wraptuple(args)
processGridArg!(plotattributes, arg, letter) processGridArg!(plotattributes, arg, letter)
@ -1383,7 +1456,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end end
# handle individual axes grid args # handle individual axes grid args
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
gridsym = Symbol(letter, :minorgrid) gridsym = get_attr_symbol(letter, :minorgrid)
args = RecipesPipeline.pop_kw!(plotattributes, gridsym, ()) args = RecipesPipeline.pop_kw!(plotattributes, gridsym, ())
for arg in wraptuple(args) for arg in wraptuple(args)
processMinorGridArg!(plotattributes, arg, letter) processMinorGridArg!(plotattributes, arg, letter)
@ -1394,16 +1467,20 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
args = RecipesPipeline.pop_kw!(plotattributes, fontname, ()) args = RecipesPipeline.pop_kw!(plotattributes, fontname, ())
for arg in wraptuple(args) for arg in wraptuple(args)
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
processFontArg!(plotattributes, Symbol(letter, fontname), arg) processFontArg!(plotattributes, get_attr_symbol(letter, fontname), arg)
end end
end end
end end
# handle individual axes font args # handle individual axes font args
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
for fontname in (:tickfont, :guidefont) for fontname in (:tickfont, :guidefont)
args = RecipesPipeline.pop_kw!(plotattributes, Symbol(letter, fontname), ()) args = RecipesPipeline.pop_kw!(
plotattributes,
get_attr_symbol(letter, fontname),
(),
)
for arg in wraptuple(args) for arg in wraptuple(args)
processFontArg!(plotattributes, Symbol(letter, fontname), arg) processFontArg!(plotattributes, get_attr_symbol(letter, fontname), arg)
end end
end end
end end
@ -1412,7 +1489,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
if haskey(plotattributes, k) && k !== :link if haskey(plotattributes, k) && k !== :link
v = plotattributes[k] v = plotattributes[k]
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
lk = Symbol(letter, k) lk = get_attr_symbol(letter, k)
if !is_explicit(plotattributes, lk) if !is_explicit(plotattributes, lk)
plotattributes[lk] = v plotattributes[lk] = v
end end
@ -1422,7 +1499,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
# fonts # fonts
for fontname in for fontname in
(:titlefont, :legendfont, :legendtitlefont, :plot_titlefont, :colorbar_titlefont) (:titlefont, :legend_title_font, :plot_titlefont, :colorbar_titlefont, :legend_font)
args = RecipesPipeline.pop_kw!(plotattributes, fontname, ()) args = RecipesPipeline.pop_kw!(plotattributes, fontname, ())
for arg in wraptuple(args) for arg in wraptuple(args)
processFontArg!(plotattributes, fontname, arg) processFontArg!(plotattributes, fontname, arg)
@ -1489,8 +1566,9 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
# end # end
# legends # legends
if haskey(plotattributes, :legend) if haskey(plotattributes, :legend_position)
plotattributes[:legend] = convertLegendValue(plotattributes[:legend]) plotattributes[:legend_position] =
convertLegendValue(plotattributes[:legend_position])
end end
if haskey(plotattributes, :colorbar) if haskey(plotattributes, :colorbar)
plotattributes[:colorbar] = convertLegendValue(plotattributes[:colorbar]) plotattributes[:colorbar] = convertLegendValue(plotattributes[:colorbar])
@ -1509,7 +1587,11 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
# warnings for moved recipes # warnings for moved recipes
st = get(plotattributes, :seriestype, :path) st = get(plotattributes, :seriestype, :path)
if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatsPlots) if st in (:boxplot, :violin, :density) &&
!haskey(
Base.loaded_modules,
Base.PkgId(Base.UUID("f3b207a7-027a-5e70-b257-86293d7955fd"), "StatsPlots"),
)
@warn( @warn(
"seriestype $st has been moved to StatsPlots. To use: \`Pkg.add(\"StatsPlots\"); using StatsPlots\`" "seriestype $st has been moved to StatsPlots. To use: \`Pkg.add(\"StatsPlots\"); using StatsPlots\`"
) )
@ -1522,13 +1604,15 @@ end
const _already_warned = Dict{Symbol,Set{Symbol}}() const _already_warned = Dict{Symbol,Set{Symbol}}()
const _to_warn = Set{Symbol}() const _to_warn = Set{Symbol}()
should_warn_on_unsupported(::AbstractBackend) = _plot_defaults[:warn_on_unsupported]
function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes) function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes)
empty!(_to_warn) empty!(_to_warn)
bend = backend_name(pkg) bend = backend_name(pkg)
already_warned = get!(_already_warned, bend, Set{Symbol}()) already_warned = get!(_already_warned, bend, Set{Symbol}())
extra_kwargs = Dict{Symbol,Any}() extra_kwargs = Dict{Symbol,Any}()
for k in keys(plotattributes) for k in keys(plotattributes)
is_attr_supported(pkg, k) && continue is_attr_supported(pkg, k) && !(k in keys(_deprecated_attributes)) && continue
k in _suppress_warnings && continue k in _suppress_warnings && continue
default_value = default(k) default_value = default(k)
if ismissing(default_value) if ismissing(default_value)
@ -1539,14 +1623,21 @@ function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes)
end end
if !isempty(_to_warn) && if !isempty(_to_warn) &&
!get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported]) get(plotattributes, :warn_on_unsupported, should_warn_on_unsupported(pkg))
for k in sort(collect(_to_warn)) for k in sort(collect(_to_warn))
push!(already_warned, k) push!(already_warned, k)
if k in keys(_deprecated_attributes)
@warn("""
Keyword argument `$k` is deprecated.
Please use `$(_deprecated_attributes[k])` instead.
""")
else
@warn( @warn(
"Keyword argument $k not supported with $pkg. Choose from: $(supported_attrs(pkg))" "Keyword argument $k not supported with $pkg. Choose from: $(join(supported_attrs(pkg), ", "))"
) )
end end
end end
end
return extra_kwargs return extra_kwargs
end end
@ -1555,7 +1646,7 @@ end
# _markershape_supported(pkg::AbstractBackend, shapes::AVec) = all([_markershape_supported(pkg, shape) for shape in shapes]) # _markershape_supported(pkg::AbstractBackend, shapes::AVec) = all([_markershape_supported(pkg, shape) for shape in shapes])
function warn_on_unsupported(pkg::AbstractBackend, plotattributes) function warn_on_unsupported(pkg::AbstractBackend, plotattributes)
if !get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported]) if !get(plotattributes, :warn_on_unsupported, should_warn_on_unsupported(pkg))
return return
end end
if !is_seriestype_supported(pkg, plotattributes[:seriestype]) if !is_seriestype_supported(pkg, plotattributes[:seriestype])
@ -1576,13 +1667,13 @@ function warn_on_unsupported(pkg::AbstractBackend, plotattributes)
end end
function warn_on_unsupported_scales(pkg::AbstractBackend, plotattributes::AKW) function warn_on_unsupported_scales(pkg::AbstractBackend, plotattributes::AKW)
if !get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported]) if !get(plotattributes, :warn_on_unsupported, should_warn_on_unsupported(pkg))
return return
end end
for k in (:xscale, :yscale, :zscale, :scale) for k in (:xscale, :yscale, :zscale, :scale)
if haskey(plotattributes, k) if haskey(plotattributes, k)
v = plotattributes[k] v = plotattributes[k]
if !is_scale_supported(pkg, v) if !all(is_scale_supported.(Ref(pkg), v))
@warn( @warn(
"scale $v is unsupported with $pkg. Choose from: $(supported_scales(pkg))" "scale $v is unsupported with $pkg. Choose from: $(supported_scales(pkg))"
) )
@ -1621,15 +1712,18 @@ function convertLegendValue(val::Symbol)
:inline, :inline,
) )
val val
elseif val == :horizontal
-1
else else
error("Invalid symbol for legend: $val") error("Invalid symbol for legend: $val")
end end
end end
convertLegendValue(val::Real) = val
convertLegendValue(val::Bool) = val ? :best : :none convertLegendValue(val::Bool) = val ? :best : :none
convertLegendValue(val::Nothing) = :none convertLegendValue(val::Nothing) = :none
convertLegendValue(v::Union{Tuple,NamedTuple}) = convertLegendValue.(v)
convertLegendValue(v::Tuple{S,T}) where {S<:Real,T<:Real} = v convertLegendValue(v::Tuple{S,T}) where {S<:Real,T<:Real} = v
convertLegendValue(v::Tuple{<:Real,Symbol}) = v convertLegendValue(v::Tuple{<:Real,Symbol}) = v
convertLegendValue(v::Real) = v
convertLegendValue(v::AbstractArray) = map(convertLegendValue, v) convertLegendValue(v::AbstractArray) = map(convertLegendValue, v)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@ -1677,9 +1771,14 @@ function slice_arg!(
remove_pair::Bool, remove_pair::Bool,
) )
v = get(plotattributes_in, k, plotattributes_out[k]) v = get(plotattributes_in, k, plotattributes_out[k])
plotattributes_out[k] = plotattributes_out[k] = if haskey(plotattributes_in, k) && !(k in _plot_args)
if haskey(plotattributes_in, k) && typeof(v) <: AMat && !isempty(v) if typeof(v) <: AMat && !isempty(v)
slice_arg(v, idx) slice_arg(v, idx)
elseif typeof(v) <: NTuple{2,AMat}
(slice_arg(v[1], idx), slice_arg(v[2], idx))
else
v
end
else else
v v
end end
@ -1715,9 +1814,9 @@ end
# when a value can be `:match`, this is the key that should be used instead for value retrieval # when a value can be `:match`, this is the key that should be used instead for value retrieval
const _match_map = KW( const _match_map = KW(
:background_color_outside => :background_color, :background_color_outside => :background_color,
:background_color_legend => :background_color_subplot, :legend_background_color => :background_color_subplot,
:background_color_inside => :background_color_subplot, :background_color_inside => :background_color_subplot,
:foreground_color_legend => :foreground_color_subplot, :legend_foreground_color => :foreground_color_subplot,
:foreground_color_title => :foreground_color_subplot, :foreground_color_title => :foreground_color_subplot,
:left_margin => :margin, :left_margin => :margin,
:top_margin => :margin, :top_margin => :margin,
@ -1725,10 +1824,10 @@ const _match_map = KW(
:bottom_margin => :margin, :bottom_margin => :margin,
:titlefontfamily => :fontfamily_subplot, :titlefontfamily => :fontfamily_subplot,
:titlefontcolor => :foreground_color_subplot, :titlefontcolor => :foreground_color_subplot,
:legendfontfamily => :fontfamily_subplot, :legend_font_family => :fontfamily_subplot,
:legendfontcolor => :foreground_color_subplot, :legend_font_color => :foreground_color_subplot,
:legendtitlefontfamily => :fontfamily_subplot, :legend_title_font_family => :fontfamily_subplot,
:legendtitlefontcolor => :foreground_color_subplot, :legend_title_font_color => :foreground_color_subplot,
:colorbar_fontfamily => :fontfamily_subplot, :colorbar_fontfamily => :fontfamily_subplot,
:colorbar_titlefontfamily => :fontfamily_subplot, :colorbar_titlefontfamily => :fontfamily_subplot,
:colorbar_titlefontcolor => :foreground_color_subplot, :colorbar_titlefontcolor => :foreground_color_subplot,
@ -1859,10 +1958,10 @@ function _update_subplot_periphery(sp::Subplot, anns::AVec)
sp.attr[:annotations] = newanns sp.attr[:annotations] = newanns
# handle legend/colorbar # handle legend/colorbar
sp.attr[:legend] = convertLegendValue(sp.attr[:legend]) sp.attr[:legend_position] = convertLegendValue(sp.attr[:legend_position])
sp.attr[:colorbar] = convertLegendValue(sp.attr[:colorbar]) sp.attr[:colorbar] = convertLegendValue(sp.attr[:colorbar])
if sp.attr[:colorbar] == :legend if sp.attr[:colorbar] == :legend
sp.attr[:colorbar] = sp.attr[:legend] sp.attr[:colorbar] = sp.attr[:legend_position]
end end
return return
end end
@ -1871,12 +1970,12 @@ function _update_subplot_colors(sp::Subplot)
# background colors # background colors
color_or_nothing!(sp.attr, :background_color_subplot) color_or_nothing!(sp.attr, :background_color_subplot)
sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], 30) sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], 30)
color_or_nothing!(sp.attr, :background_color_legend) color_or_nothing!(sp.attr, :legend_background_color)
color_or_nothing!(sp.attr, :background_color_inside) color_or_nothing!(sp.attr, :background_color_inside)
# foreground colors # foreground colors
color_or_nothing!(sp.attr, :foreground_color_subplot) color_or_nothing!(sp.attr, :foreground_color_subplot)
color_or_nothing!(sp.attr, :foreground_color_legend) color_or_nothing!(sp.attr, :legend_foreground_color)
color_or_nothing!(sp.attr, :foreground_color_title) color_or_nothing!(sp.attr, :foreground_color_title)
return return
end end
@ -1919,7 +2018,8 @@ function _update_axis(
end end
# then get those args that were passed with a leading letter: `xlabel = "X"` # then get those args that were passed with a leading letter: `xlabel = "X"`
lk = Symbol(letter, k) lk = get_attr_symbol(letter, k)
if haskey(plotattributes_in, lk) if haskey(plotattributes_in, lk)
kw[k] = slice_arg(plotattributes_in[lk], subplot_index) kw[k] = slice_arg(plotattributes_in[lk], subplot_index)
end end
@ -1965,7 +2065,7 @@ function _update_subplot_args(
) )
anns = RecipesPipeline.pop_kw!(sp.attr, :annotations) anns = RecipesPipeline.pop_kw!(sp.attr, :annotations)
# # grab those args which apply to this subplot # grab those args which apply to this subplot
for k in keys(_subplot_defaults) for k in keys(_subplot_defaults)
slice_arg!(plotattributes_in, sp.attr, k, subplot_index, remove_pair) slice_arg!(plotattributes_in, sp.attr, k, subplot_index, remove_pair)
end end
@ -1976,7 +2076,7 @@ function _update_subplot_args(
lims_warned = false lims_warned = false
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
_update_axis(plt, sp, plotattributes_in, letter, subplot_index) _update_axis(plt, sp, plotattributes_in, letter, subplot_index)
lk = Symbol(letter, :lims) lk = get_attr_symbol(letter, :lims)
# warn against using `Range` in x,y,z lims # warn against using `Range` in x,y,z lims
if !lims_warned && if !lims_warned &&
@ -1986,7 +2086,6 @@ function _update_subplot_args(
lims_warned = true lims_warned = true
end end
end end
_update_subplot_colorbars(sp)
end end
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@ -2163,7 +2262,16 @@ end
#-------------------------------------------------- #--------------------------------------------------
## inspired by Base.@kwdef ## inspired by Base.@kwdef
macro add_attributes(level, expr) """
add_attributes(level, expr, match_table)
Takes a `struct` definition and recurses into its fields to create keywords by chaining the field names with the structs' name with underscore.
Also creates pluralized and non-underscore aliases for these keywords.
- `level` indicates which group of `plot`, `subplot`, `series`, etc. the keywords belong to.
- `expr` is the struct definition with default values like `Base.@kwdef`
- `match_table` is an expression of the form `:match = (symbols)`, with symbols whose default value should be `:match`
"""
macro add_attributes(level, expr, match_table)
expr = macroexpand(__module__, expr) # to expand @static expr = macroexpand(__module__, expr) # to expand @static
expr isa Expr && expr.head === :struct || error("Invalid usage of @add_attributes") expr isa Expr && expr.head === :struct || error("Invalid usage of @add_attributes")
T = expr.args[2] T = expr.args[2]
@ -2171,16 +2279,18 @@ macro add_attributes(level, expr)
T = T.args[1] T = T.args[1]
end end
key_args = Any[] key_dict = KW()
value_args = Any[]
_splitdef!(expr.args[3], value_args, key_args) _splitdef!(expr.args[3], key_dict)
insert_block = Expr(:block) insert_block = Expr(:block)
for (key, value) in zip(key_args, value_args) for (key, value) in key_dict
# e.g. _series_defualts[key] = value # e.g. _series_defualts[key] = value
exp_key = Symbol(lowercase(string(T)), "_", key) exp_key = Symbol(lowercase(string(T)), "_", key)
pl_key = makeplural(exp_key) pl_key = makeplural(exp_key)
if QuoteNode(exp_key) in match_table.args[2].args
value = QuoteNode(:match)
end
push!( push!(
insert_block.args, insert_block.args,
Expr( Expr(
@ -2214,7 +2324,7 @@ macro add_attributes(level, expr)
end |> esc end |> esc
end end
function _splitdef!(blk, value_args, key_args) function _splitdef!(blk, key_dict)
for i in eachindex(blk.args) for i in eachindex(blk.args)
ei = blk.args[i] ei = blk.args[i]
if ei isa Symbol if ei isa Symbol
@ -2229,20 +2339,25 @@ function _splitdef!(blk, value_args, key_args)
elseif lhs isa Expr && lhs.head === :(::) && lhs.args[1] isa Symbol elseif lhs isa Expr && lhs.head === :(::) && lhs.args[1] isa Symbol
# var::T = defexpr # var::T = defexpr
var = lhs.args[1] var = lhs.args[1]
type = lhs.args[2]
if @isdefined type
for field in fieldnames(getproperty(Plots, type))
key_dict[Symbol(var, "_", field)] =
:(getfield($(ei.args[2]), $(QuoteNode(field))))
end
end
else else
# something else, e.g. inline inner constructor # something else, e.g. inline inner constructor
# F(...) = ... # F(...) = ...
continue continue
end end
defexpr = ei.args[2] # defexpr defexpr = ei.args[2] # defexpr
push!(value_args, defexpr) key_dict[var] = defexpr
push!(key_args, var)
blk.args[i] = lhs blk.args[i] = lhs
elseif ei.head === :(::) && ei.args[1] isa Symbol elseif ei.head === :(::) && ei.args[1] isa Symbol
# var::Typ # var::Typ
var = ei.args[1] var = ei.args[1]
push!(value_args, var) key_dict[var] = defexpr
push!(key_args, var)
elseif ei.head === :block elseif ei.head === :block
# can arise with use of @static inside type decl # can arise with use of @static inside type decl
_kwdef!(ei, value_args, key_args) _kwdef!(ei, value_args, key_args)

View File

@ -23,7 +23,7 @@ function Axis(sp::Subplot, letter::Symbol, args...; kw...)
end end
function get_axis(sp::Subplot, letter::Symbol) function get_axis(sp::Subplot, letter::Symbol)
axissym = Symbol(letter, :axis) axissym = get_attr_symbol(letter, :axis)
if haskey(sp.attr, axissym) if haskey(sp.attr, axissym)
sp.attr[axissym] sp.attr[axissym]
else else
@ -35,40 +35,44 @@ function process_axis_arg!(plotattributes::AKW, arg, letter = "")
T = typeof(arg) T = typeof(arg)
arg = get(_scaleAliases, arg, arg) arg = get(_scaleAliases, arg, arg)
if typeof(arg) <: Font if typeof(arg) <: Font
plotattributes[Symbol(letter, :tickfont)] = arg plotattributes[get_attr_symbol(letter, :tickfont)] = arg
plotattributes[Symbol(letter, :guidefont)] = arg plotattributes[get_attr_symbol(letter, :guidefont)] = arg
elseif arg in _allScales elseif arg in _allScales
plotattributes[Symbol(letter, :scale)] = arg plotattributes[get_attr_symbol(letter, :scale)] = arg
elseif arg in (:flip, :invert, :inverted) elseif arg in (:flip, :invert, :inverted)
plotattributes[Symbol(letter, :flip)] = true plotattributes[get_attr_symbol(letter, :flip)] = true
elseif T <: AbstractString elseif T <: AbstractString
plotattributes[Symbol(letter, :guide)] = arg plotattributes[get_attr_symbol(letter, :guide)] = arg
# xlims/ylims # xlims/ylims
elseif (T <: Tuple || T <: AVec) && length(arg) == 2 elseif (T <: Tuple || T <: AVec) && length(arg) == 2
sym = typeof(arg[1]) <: Number ? :lims : :ticks sym = typeof(arg[1]) <: Number ? :lims : :ticks
plotattributes[Symbol(letter, sym)] = arg plotattributes[get_attr_symbol(letter, sym)] = arg
# xticks/yticks # xticks/yticks
elseif T <: AVec elseif T <: AVec
plotattributes[Symbol(letter, :ticks)] = arg plotattributes[get_attr_symbol(letter, :ticks)] = arg
elseif arg === nothing elseif arg === nothing
plotattributes[Symbol(letter, :ticks)] = [] plotattributes[get_attr_symbol(letter, :ticks)] = []
elseif T <: Bool || arg in _allShowaxisArgs elseif T <: Bool || arg in _allShowaxisArgs
plotattributes[Symbol(letter, :showaxis)] = showaxis(arg, letter) plotattributes[get_attr_symbol(letter, :showaxis)] = showaxis(arg, letter)
elseif typeof(arg) <: Number elseif typeof(arg) <: Number
plotattributes[Symbol(letter, :rotation)] = arg plotattributes[get_attr_symbol(letter, :rotation)] = arg
elseif typeof(arg) <: Function elseif typeof(arg) <: Function
plotattributes[Symbol(letter, :formatter)] = arg plotattributes[get_attr_symbol(letter, :formatter)] = arg
elseif !handleColors!(plotattributes, arg, Symbol(letter, :foreground_color_axis)) elseif !handleColors!(
plotattributes,
arg,
get_attr_symbol(letter, :foreground_color_axis),
)
@warn("Skipped $(letter)axis arg $arg") @warn("Skipped $(letter)axis arg $arg")
end end
end end
@ -297,7 +301,7 @@ for l in (:x, :y, :z)
end end
end end
# get_ticks from axis symbol :x, :y, or :z # get_ticks from axis symbol :x, :y, or :z
get_ticks(sp::Subplot, s::Symbol) = get_ticks(sp, sp[Symbol(s, :axis)]) get_ticks(sp::Subplot, s::Symbol) = get_ticks(sp, sp[get_attr_symbol(s, :axis)])
get_ticks(p::Plot, s::Symbol) = [get_ticks(sp, s) for sp in p.subplots] get_ticks(p::Plot, s::Symbol) = [get_ticks(sp, s) for sp in p.subplots]
function get_ticks(ticks::Symbol, cvals::T, dvals, args...) where {T} function get_ticks(ticks::Symbol, cvals::T, dvals, args...) where {T}
@ -393,7 +397,7 @@ end
function reset_extrema!(sp::Subplot) function reset_extrema!(sp::Subplot)
for asym in (:x, :y, :z) for asym in (:x, :y, :z)
sp[Symbol(asym, :axis)][:extrema] = Extrema() sp[get_attr_symbol(asym, :axis)][:extrema] = Extrema()
end end
for series in sp.series_list for series in sp.series_list
expand_extrema!(sp, series.plotattributes) expand_extrema!(sp, series.plotattributes)
@ -446,7 +450,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
) )
data = [NaN] data = [NaN]
end end
axis = sp[Symbol(letter, "axis")] axis = sp[get_attr_symbol(letter, :axis)]
if isa(data, Volume) if isa(data, Volume)
expand_extrema!(sp[:xaxis], data.x_extents) expand_extrema!(sp[:xaxis], data.x_extents)
@ -463,7 +467,8 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
# TODO: need more here... gotta track the discrete reference value # TODO: need more here... gotta track the discrete reference value
# as well as any coord offset (think of boxplot shape coords... they all # as well as any coord offset (think of boxplot shape coords... they all
# correspond to the same x-value) # correspond to the same x-value)
plotattributes[letter], plotattributes[Symbol(letter, "_discrete_indices")] = plotattributes[letter],
plotattributes[get_attr_symbol(letter, :(_discrete_indices))] =
discrete_value!(axis, data) discrete_value!(axis, data)
expand_extrema!(axis, plotattributes[letter]) expand_extrema!(axis, plotattributes[letter])
end end
@ -502,7 +507,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
plotattributes[:bar_width] = plotattributes[:bar_width] =
_bar_width * ignorenan_minimum(filter(x -> x > 0, diff(sort(data)))) _bar_width * ignorenan_minimum(filter(x -> x > 0, diff(sort(data))))
end end
axis = sp.attr[Symbol(dsym, :axis)] axis = sp.attr[get_attr_symbol(dsym, :axis)]
expand_extrema!(axis, ignorenan_maximum(data) + 0.5maximum(bw)) expand_extrema!(axis, ignorenan_maximum(data) + 0.5maximum(bw))
expand_extrema!(axis, ignorenan_minimum(data) - 0.5minimum(bw)) expand_extrema!(axis, ignorenan_minimum(data) - 0.5minimum(bw))
end end
@ -511,8 +516,8 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
if plotattributes[:seriestype] == :heatmap if plotattributes[:seriestype] == :heatmap
for letter in (:x, :y) for letter in (:x, :y)
data = plotattributes[letter] data = plotattributes[letter]
axis = sp[Symbol(letter, "axis")] axis = sp[get_attr_symbol(letter, :axis)]
scale = get(plotattributes, Symbol(letter, "scale"), :identity) scale = get(plotattributes, get_attr_symbol(letter, :scale), :identity)
expand_extrema!(axis, heatmap_edges(data, scale)) expand_extrema!(axis, heatmap_edges(data, scale))
end end
end end
@ -586,10 +591,10 @@ end
function axis_limits( function axis_limits(
sp, sp,
letter, letter,
should_widen = default_should_widen(sp[Symbol(letter, :axis)]), should_widen = default_should_widen(sp[get_attr_symbol(letter, :axis)]),
consider_aspect = true, consider_aspect = true,
) )
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
ex = axis[:extrema] ex = axis[:extrema]
amin, amax = ex.emin, ex.emax amin, amax = ex.emin, ex.emax
lims = axis[:lims] lims = axis[:lims]
@ -670,9 +675,17 @@ end
# these methods track the discrete (categorical) values which correspond to axis continuous values (cv) # these methods track the discrete (categorical) values which correspond to axis continuous values (cv)
# whenever we have discrete values, we automatically set the ticks to match. # whenever we have discrete values, we automatically set the ticks to match.
# we return (continuous_value, discrete_index) # we return (continuous_value, discrete_index)
function discrete_value!(plotattributes, letter::Symbol, dv)
l = if plotattributes[:permute] !== :none
only(filter(!=(letter), plotattributes[:permute]))
else
letter
end
discrete_value!(plotattributes[:subplot][get_attr_symbol(l, :axis)], dv)
end
function discrete_value!(axis::Axis, dv) function discrete_value!(axis::Axis, dv)
cv_idx = get(axis[:discrete_map], dv, -1) cv_idx = get(axis[:discrete_map], dv, -1)
# @show axis[:discrete_map], axis[:discrete_values], dv
if cv_idx == -1 if cv_idx == -1
ex = axis[:extrema] ex = axis[:extrema]
cv = NaNMath.max(0.5, ex.emax + 1.0) cv = NaNMath.max(0.5, ex.emax + 1.0)
@ -724,10 +737,10 @@ end
# compute the line segments which should be drawn for this axis # compute the line segments which should be drawn for this axis
function axis_drawing_info(sp, letter) function axis_drawing_info(sp, letter)
# find out which axis we are dealing with # find out which axis we are dealing with
asym = Symbol(letter, :axis) asym = get_attr_symbol(letter, :axis)
isy = letter === :y isy = letter === :y
oletter = isy ? :x : :y oletter = isy ? :x : :y
oasym = Symbol(oletter, :axis) oasym = get_attr_symbol(oletter, :axis)
# get axis objects, ticks and minor ticks # get axis objects, ticks and minor ticks
ax, oax = sp[asym], sp[oasym] ax, oax = sp[asym], sp[oasym]
@ -856,9 +869,9 @@ function axis_drawing_info_3d(sp, letter)
near_letter = letter in (:x, :z) ? :y : :x near_letter = letter in (:x, :z) ? :y : :x
far_letter = letter in (:x, :y) ? :z : :x far_letter = letter in (:x, :y) ? :z : :x
ax = sp[Symbol(letter, :axis)] ax = sp[get_attr_symbol(letter, :axis)]
nax = sp[Symbol(near_letter, :axis)] nax = sp[get_attr_symbol(near_letter, :axis)]
fax = sp[Symbol(far_letter, :axis)] fax = sp[get_attr_symbol(far_letter, :axis)]
amin, amax = axis_limits(sp, letter) amin, amax = axis_limits(sp, letter)
namin, namax = axis_limits(sp, near_letter) namin, namax = axis_limits(sp, near_letter)

View File

@ -240,6 +240,8 @@ const _base_supported_args = [
:discrete_values, :discrete_values,
:projection, :projection,
:show_empty_bins, :show_empty_bins,
:z_order,
:permute,
] ]
function merge_with_base_supported(v::AVec) function merge_with_base_supported(v::AVec)
@ -247,7 +249,7 @@ function merge_with_base_supported(v::AVec)
for vi in v for vi in v
if haskey(_axis_defaults, vi) if haskey(_axis_defaults, vi)
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
push!(v, Symbol(letter, vi)) push!(v, get_attr_symbol(letter, vi))
end end
end end
end end
@ -284,7 +286,7 @@ for s in (:attr, :seriestype, :marker, :style, :scale)
v = Symbol("_", bend, "_", s) v = Symbol("_", bend, "_", s)
@eval begin @eval begin
$f(::$bend_type, $s::Symbol) = $s in $v $f(::$bend_type, $s::Symbol) = $s in $v
$f2(::$bend_type) = $v $f2(::$bend_type) = sort(collect($v))
end end
end end
end end
@ -300,20 +302,32 @@ function _initialize_backend(pkg::AbstractBackend)
@eval Main begin @eval Main begin
import $sym import $sym
export $sym export $sym
$(_check_compat)($sym)
end end
end end
_initialize_backend(pkg::GRBackend) = nothing _initialize_backend(pkg::GRBackend) = nothing
function _initialize_backend(pkg::PlotlyBackend)
try
@eval Main begin
import PlotlyBase
end
_check_compat(PlotlyBase)
catch
@info "For saving to png with the Plotly backend PlotlyBase has to be installed."
end
end
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# gr # gr
const _gr_attr = merge_with_base_supported([ const _gr_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :legend_background_color,
:background_color_inside, :background_color_inside,
:background_color_outside, :background_color_outside,
:foreground_color_legend, :legend_foreground_color,
:foreground_color_grid, :foreground_color_grid,
:foreground_color_axis, :foreground_color_axis,
:foreground_color_text, :foreground_color_text,
@ -335,6 +349,7 @@ const _gr_attr = merge_with_base_supported([
:fillrange, :fillrange,
:fillcolor, :fillcolor,
:fillalpha, :fillalpha,
:fillstyle,
:bins, :bins,
:layout, :layout,
:title, :title,
@ -350,12 +365,12 @@ const _gr_attr = merge_with_base_supported([
:titlefontvalign, :titlefontvalign,
:titlefontrotation, :titlefontrotation,
:titlefontcolor, :titlefontcolor,
:legendfontfamily, :legend_font_family,
:legendfontsize, :legend_font_pointsize,
:legendfonthalign, :legend_font_halign,
:legendfontvalign, :legend_font_valign,
:legendfontrotation, :legend_font_rotation,
:legendfontcolor, :legend_font_color,
:tickfontfamily, :tickfontfamily,
:tickfontsize, :tickfontsize,
:tickfonthalign, :tickfonthalign,
@ -372,17 +387,13 @@ const _gr_attr = merge_with_base_supported([
:gridalpha, :gridalpha,
:gridstyle, :gridstyle,
:gridlinewidth, :gridlinewidth,
:legend, :legend_position,
:legendtitle, :legend_title,
:colorbar, :colorbar,
:colorbar_title, :colorbar_title,
:colorbar_entry, :colorbar_entry,
:colorbar_titlefontfamily, :colorbar_scale,
:colorbar_titlefontsize, :clims,
:colorbar_titlefontvalign,
:colorbar_titlefonthalign,
:colorbar_titlefontrotation,
:colorbar_titlefontcolor,
:fill_z, :fill_z,
:line_z, :line_z,
:marker_z, :marker_z,
@ -402,6 +413,7 @@ const _gr_attr = merge_with_base_supported([
:tick_direction, :tick_direction,
:camera, :camera,
:contour_labels, :contour_labels,
:connections,
]) ])
const _gr_seriestype = [ const _gr_seriestype = [
:path, :path,
@ -426,22 +438,12 @@ is_marker_supported(::GRBackend, shape::Shape) = true
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# plotly # plotly
function _initialize_backend(pkg::PlotlyBackend)
try
@eval Main begin
import PlotlyBase
end
catch
@info "For saving to png with the Plotly backend PlotlyBase has to be installed."
end
end
const _plotly_attr = merge_with_base_supported([ const _plotly_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :legend_background_color,
:background_color_inside, :background_color_inside,
:background_color_outside, :background_color_outside,
:foreground_color_legend, :legend_foreground_color,
:foreground_color_guide, :foreground_color_guide,
:foreground_color_grid, :foreground_color_grid,
:foreground_color_axis, :foreground_color_axis,
@ -474,9 +476,9 @@ const _plotly_attr = merge_with_base_supported([
:titlefonthalign, :titlefonthalign,
:titlefontvalign, :titlefontvalign,
:titlefontcolor, :titlefontcolor,
:legendfontfamily, :legend_font_family,
:legendfontsize, :legend_font_pointsize,
:legendfontcolor, :legend_font_color,
:tickfontfamily, :tickfontfamily,
:tickfontsize, :tickfontsize,
:tickfontcolor, :tickfontcolor,
@ -521,6 +523,7 @@ const _plotly_attr = merge_with_base_supported([
:tick_direction, :tick_direction,
:camera, :camera,
:contour_labels, :contour_labels,
:connections,
]) ])
const _plotly_seriestype = [ const _plotly_seriestype = [
@ -563,10 +566,10 @@ defaultOutputFormat(plt::Plot{Plots.PlotlyBackend}) = "html"
const _pgfplots_attr = merge_with_base_supported([ const _pgfplots_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :legend_background_color,
:background_color_inside, :background_color_inside,
# :background_color_outside, # :background_color_outside,
# :foreground_color_legend, # :legend_foreground_color,
:foreground_color_grid, :foreground_color_grid,
:foreground_color_axis, :foreground_color_axis,
:foreground_color_text, :foreground_color_text,
@ -686,11 +689,11 @@ end
const _pyplot_attr = merge_with_base_supported([ const _pyplot_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :legend_background_color,
:background_color_inside, :background_color_inside,
:background_color_outside, :background_color_outside,
:foreground_color_grid, :foreground_color_grid,
:foreground_color_legend, :legend_foreground_color,
:foreground_color_title, :foreground_color_title,
:foreground_color_axis, :foreground_color_axis,
:foreground_color_border, :foreground_color_border,
@ -729,9 +732,9 @@ const _pyplot_attr = merge_with_base_supported([
:titlefontfamily, :titlefontfamily,
:titlefontsize, :titlefontsize,
:titlefontcolor, :titlefontcolor,
:legendfontfamily, :legend_font_family,
:legendfontsize, :legend_font_pointsize,
:legendfontcolor, :legend_font_color,
:tickfontfamily, :tickfontfamily,
:tickfontsize, :tickfontsize,
:tickfontcolor, :tickfontcolor,
@ -742,8 +745,8 @@ const _pyplot_attr = merge_with_base_supported([
:gridalpha, :gridalpha,
:gridstyle, :gridstyle,
:gridlinewidth, :gridlinewidth,
:legend, :legend_position,
:legendtitle, :legend_title,
:colorbar, :colorbar,
:colorbar_title, :colorbar_title,
:colorbar_entry, :colorbar_entry,
@ -777,6 +780,7 @@ const _pyplot_attr = merge_with_base_supported([
:tick_direction, :tick_direction,
:camera, :camera,
:contour_labels, :contour_labels,
:connections,
]) ])
const _pyplot_seriestype = [ const _pyplot_seriestype = [
:path, :path,
@ -793,6 +797,7 @@ const _pyplot_seriestype = [
:contour3d, :contour3d,
:path3d, :path3d,
:scatter3d, :scatter3d,
:mesh3d,
:surface, :surface,
:wireframe, :wireframe,
] ]
@ -860,6 +865,7 @@ const _gaston_attr = merge_with_base_supported([
# :framestyle, # :framestyle,
# :camera, # :camera,
# :contour_labels, # :contour_labels,
:connections,
]) ])
const _gaston_seriestype = [ const _gaston_seriestype = [
@ -910,43 +916,87 @@ const _gaston_scale = [:identity, :ln, :log2, :log10]
# unicodeplots # unicodeplots
const _unicodeplots_attr = merge_with_base_supported([ const _unicodeplots_attr = merge_with_base_supported([
:annotations,
:bins,
:guide,
:grid,
:label, :label,
:layout,
:legend, :legend,
:seriescolor, :lims,
:seriesalpha, :linealpha,
:linecolor,
:linestyle, :linestyle,
:markershape, :markershape,
:bins, :quiver,
:arrow,
:seriesalpha,
:seriescolor,
:scale,
:flip,
:title, :title,
:guide, # :marker_z,
:lims, :line_z,
]) ])
const _unicodeplots_seriestype = [ const _unicodeplots_seriestype = [
:path, :path,
:path3d,
:scatter, :scatter,
:scatter3d,
:straightline, :straightline,
# :bar, # :bar,
:shape, :shape,
:histogram2d, :histogram2d,
:heatmap,
:contour,
# :contour3d,
:permute,
:spy, :spy,
:surface,
:wireframe,
:mesh3d,
] ]
const _unicodeplots_style = [:auto, :solid] const _unicodeplots_style = [:auto, :solid]
const _unicodeplots_marker = [:none, :auto, :circle] const _unicodeplots_marker = [
const _unicodeplots_scale = [:identity] :none,
:auto,
# Additional constants :pixel,
const _canvas_type = Ref(:auto) # vvvvvvvvvv shapes
:circle,
:rect,
:star5,
:diamond,
:hexagon,
:cross,
:xcross,
:utriangle,
:dtriangle,
:rtriangle,
:ltriangle,
:pentagon,
# :heptagon,
# :octagon,
:star4,
:star6,
# :star7,
:star8,
:vline,
:hline,
:+,
:x,
]
const _unicodeplots_scale = [:identity, :ln, :log2, :log10]
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# hdf5 # hdf5
const _hdf5_attr = merge_with_base_supported([ const _hdf5_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :legend_background_color,
:background_color_inside, :background_color_inside,
:background_color_outside, :background_color_outside,
:foreground_color_grid, :foreground_color_grid,
:foreground_color_legend, :legend_foreground_color,
:foreground_color_title, :foreground_color_title,
:foreground_color_axis, :foreground_color_axis,
:foreground_color_border, :foreground_color_border,
@ -1044,11 +1094,11 @@ const HDF5PLOT_PLOTREF = HDF5Plot_PlotRef(nothing)
const _inspectdr_attr = merge_with_base_supported([ const _inspectdr_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :legend_background_color,
:background_color_inside, :background_color_inside,
:background_color_outside, :background_color_outside,
# :foreground_color_grid, # :foreground_color_grid,
:foreground_color_legend, :legend_foreground_color,
:foreground_color_title, :foreground_color_title,
:foreground_color_axis, :foreground_color_axis,
:foreground_color_border, :foreground_color_border,
@ -1081,9 +1131,9 @@ const _inspectdr_attr = merge_with_base_supported([
:titlefontfamily, :titlefontfamily,
:titlefontsize, :titlefontsize,
:titlefontcolor, :titlefontcolor,
:legendfontfamily, :legend_font_family,
:legendfontsize, :legend_font_pointsize,
:legendfontcolor, :legend_font_color,
:tickfontfamily, :tickfontfamily,
:tickfontsize, :tickfontsize,
:tickfontcolor, :tickfontcolor,
@ -1091,7 +1141,7 @@ const _inspectdr_attr = merge_with_base_supported([
:guidefontsize, :guidefontsize,
:guidefontcolor, :guidefontcolor,
:grid, :grid,
:legend, #:colorbar, :legend_position, #:colorbar,
# :marker_z, # :marker_z,
# :line_z, # :line_z,
# :levels, # :levels,
@ -1147,10 +1197,10 @@ const _inspectdr_scale = [:identity, :ln, :log2, :log10]
const _pgfplotsx_attr = merge_with_base_supported([ const _pgfplotsx_attr = merge_with_base_supported([
:annotations, :annotations,
:background_color_legend, :legend_background_color,
:background_color_inside, :background_color_inside,
:background_color_outside, :background_color_outside,
:foreground_color_legend, :legend_foreground_color,
:foreground_color_grid, :foreground_color_grid,
:foreground_color_axis, :foreground_color_axis,
:foreground_color_text, :foreground_color_text,
@ -1187,12 +1237,12 @@ const _pgfplotsx_attr = merge_with_base_supported([
:titlefontvalign, :titlefontvalign,
:titlefontrotation, :titlefontrotation,
:titlefontcolor, :titlefontcolor,
:legendfontfamily, :legend_font_family,
:legendfontsize, :legend_font_pointsize,
:legendfonthalign, :legend_font_halign,
:legendfontvalign, :legend_font_valign,
:legendfontrotation, :legend_font_rotation,
:legendfontcolor, :legend_font_color,
:tickfontfamily, :tickfontfamily,
:tickfontsize, :tickfontsize,
:tickfonthalign, :tickfonthalign,
@ -1209,8 +1259,8 @@ const _pgfplotsx_attr = merge_with_base_supported([
:gridalpha, :gridalpha,
:gridstyle, :gridstyle,
:gridlinewidth, :gridlinewidth,
:legend, :legend_position,
:legendtitle, :legend_title,
:colorbar, :colorbar,
:colorbar_title, :colorbar_title,
:colorbar_entry, :colorbar_entry,
@ -1233,6 +1283,7 @@ const _pgfplotsx_attr = merge_with_base_supported([
:tick_direction, :tick_direction,
:camera, :camera,
:contour_labels, :contour_labels,
:connections,
]) ])
const _pgfplotsx_seriestype = [ const _pgfplotsx_seriestype = [
:path, :path,
@ -1272,7 +1323,6 @@ const _pgfplotsx_marker = [
:pentagon, :pentagon,
:hline, :hline,
:vline, :vline,
Shape,
] ]
const _pgfplotsx_scale = [:identity, :ln, :log2, :log10] const _pgfplotsx_scale = [:identity, :ln, :log2, :log10]
is_marker_supported(::PGFPlotsXBackend, shape::Shape) = true is_marker_supported(::PGFPlotsXBackend, shape::Shape) = true

View File

@ -3,7 +3,7 @@
# significant contributions by: @pkofod # significant contributions by: @pkofod
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
# COV_EXCL_START
const _pgfplots_linestyles = KW( const _pgfplots_linestyles = KW(
:solid => "solid", :solid => "solid",
:dash => "dashed", :dash => "dashed",
@ -227,7 +227,7 @@ function pgf_series(sp::Subplot, series::Series)
end end
# add to legend? # add to legend?
if i == 1 && sp[:legend] != :none && should_add_to_legend(series) if i == 1 && sp[:legend_position] != :none && should_add_to_legend(series)
if plotattributes[:fillrange] !== nothing if plotattributes[:fillrange] !== nothing
push!(style, "forget plot") push!(style, "forget plot")
push!(series_collection, pgf_fill_legend_hack(plotattributes, args)) push!(series_collection, pgf_fill_legend_hack(plotattributes, args))
@ -331,7 +331,7 @@ end
# ---------------------------------------------------------------- # ----------------------------------------------------------------
function pgf_axis(sp::Subplot, letter) function pgf_axis(sp::Subplot, letter)
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
style = [] style = []
kw = KW() kw = KW()
@ -342,7 +342,7 @@ function pgf_axis(sp::Subplot, letter)
framestyle = pgf_framestyle(sp[:framestyle]) framestyle = pgf_framestyle(sp[:framestyle])
# axis guide # axis guide
kw[Symbol(letter, :label)] = axis[:guide] kw[get_attr_symbol(letter, :label)] = axis[:guide]
# axis label position # axis label position
labelpos = "" labelpos = ""
@ -378,7 +378,7 @@ function pgf_axis(sp::Subplot, letter)
# scale # scale
scale = axis[:scale] scale = axis[:scale]
if scale in (:log2, :ln, :log10) if scale in (:log2, :ln, :log10)
kw[Symbol(letter, :mode)] = "log" kw[get_attr_symbol(letter, :mode)] = "log"
scale == :ln || push!(style, "log basis $letter=$(scale == :log2 ? 2 : 10)") scale == :ln || push!(style, "log basis $letter=$(scale == :log2 ? 2 : 10)")
end end
@ -400,8 +400,8 @@ function pgf_axis(sp::Subplot, letter)
lims = lims =
ispolar(sp) && letter == :x ? rad2deg.(axis_limits(sp, :x)) : ispolar(sp) && letter == :x ? rad2deg.(axis_limits(sp, :x)) :
axis_limits(sp, letter) axis_limits(sp, letter)
kw[Symbol(letter, :min)] = lims[1] kw[get_attr_symbol(letter, :min)] = lims[1]
kw[Symbol(letter, :max)] = lims[2] kw[get_attr_symbol(letter, :max)] = lims[2]
end end
if !(axis[:ticks] in (nothing, false, :none, :native)) && framestyle != :none if !(axis[:ticks] in (nothing, false, :none, :native)) && framestyle != :none
@ -590,12 +590,12 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
kw[:axisEqual] = "true" kw[:axisEqual] = "true"
end end
legpos = sp[:legend] legpos = sp[:legend_position]
if haskey(_pgfplots_legend_pos, legpos) if haskey(_pgfplots_legend_pos, legpos)
kw[:legendPos] = _pgfplots_legend_pos[legpos] kw[:legendPos] = _pgfplots_legend_pos[legpos]
end end
cstr, bg_alpha = pgf_color(plot_color(sp[:background_color_legend])) cstr, bg_alpha = pgf_color(plot_color(sp[:legend_background_color]))
fg_alpha = alpha(plot_color(sp[:foreground_color_legend])) fg_alpha = alpha(plot_color(sp[:legend_foreground_color]))
push!( push!(
style, style,
@ -603,16 +603,16 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
"legend style = {", "legend style = {",
pgf_linestyle( pgf_linestyle(
pgf_thickness_scaling(sp), pgf_thickness_scaling(sp),
sp[:foreground_color_legend], sp[:legend_foreground_color],
fg_alpha, fg_alpha,
"solid", "solid",
), ),
",", ",",
"fill = $cstr,", "fill = $cstr,",
"fill opacity = $bg_alpha,", "fill opacity = $bg_alpha,",
"text opacity = $(alpha(plot_color(sp[:legendfontcolor]))),", "text opacity = $(alpha(plot_color(sp[:legend_font_color]))),",
"font = ", "font = ",
pgf_font(sp[:legendfontsize], pgf_thickness_scaling(sp)), pgf_font(sp[:legend_font_pointsize], pgf_thickness_scaling(sp)),
"}", "}",
), ),
) )
@ -740,3 +740,5 @@ function _display(plt::Plot{PGFPlotsBackend})
# cleanup # cleanup
PGFPlots.cleanup(plt.o) PGFPlots.cleanup(plt.o)
end end
# COV_EXCL_STOP

View File

@ -1,8 +1,6 @@
# https://github.com/mbaz/Gaston. # https://github.com/mbaz/Gaston.
# -------------------------------------------- should_warn_on_unsupported(::GastonBackend) = false
# These functions are called by Plots
# --------------------------------------------
# Create the window/figure for this backend. # Create the window/figure for this backend.
function _create_backend_figure(plt::Plot{GastonBackend}) function _create_backend_figure(plt::Plot{GastonBackend})
@ -112,7 +110,7 @@ function gaston_saveopts(plt::Plot{GastonBackend})
# Scale all plot elements to match Plots.jl DPI standard # Scale all plot elements to match Plots.jl DPI standard
scaling = plt.attr[:dpi] / Plots.DPI scaling = plt.attr[:dpi] / Plots.DPI
push!(saveopts, "fontscale $scaling lw $scaling dl $scaling ps $scaling") push!(saveopts, "fontscale $scaling lw $scaling dl $scaling") # ps $scaling
return join(saveopts, " ") return join(saveopts, " ")
end end
@ -225,13 +223,13 @@ function gaston_add_series(plt::Plot{GastonBackend}, series::Series)
gsp = sp.o gsp = sp.o
x, y, z = series[:x], series[:y], series[:z] x, y, z = series[:x], series[:y], series[:z]
st = series[:seriestype] st = series[:seriestype]
curves = [] curves = []
if gsp.dims == 2 && z === nothing if gsp.dims == 2 && z === nothing
for (n, seg) in enumerate(series_segments(series, st; check = true)) for (n, seg) in enumerate(series_segments(series, st; check = true))
i, rng = seg.attr_index, seg.range i, rng = seg.attr_index, seg.range
fr = _cycle(series[:fillrange], 1:length(x[rng]))
for sc in gaston_seriesconf!(sp, series, i, n == 1) for sc in gaston_seriesconf!(sp, series, i, n == 1)
push!(curves, Gaston.Curve(x[rng], y[rng], nothing, nothing, sc)) push!(curves, Gaston.Curve(x[rng], y[rng], nothing, fr, sc))
end end
end end
else else
@ -246,10 +244,9 @@ function gaston_add_series(plt::Plot{GastonBackend}, series::Series)
if (lx = length(x)) == 2 && lx != nc if (lx = length(x)) == 2 && lx != nc
x = collect(range(x[1], x[2], length = nc)) x = collect(range(x[1], x[2], length = nc))
end end
elseif st == :heatmap
length(x) == size(z, 2) + 1 && (x = @view x[1:(end - 1)])
length(y) == size(z, 1) + 1 && (y = @view y[1:(end - 1)])
end end
length(x) == size(z, 2) + 1 && (x = (x[1:(end - 1)] + x[2:end]) / 2)
length(y) == size(z, 1) + 1 && (y = (y[1:(end - 1)] + y[2:end]) / 2)
end end
if st == :mesh3d if st == :mesh3d
x, y, z = mesh3d_triangles(x, y, z, series[:connections]) x, y, z = mesh3d_triangles(x, y, z, series[:connections])
@ -304,8 +301,15 @@ function gaston_seriesconf!(
pt, ps, mc = gaston_mk_ms_mc(series, clims, i) pt, ps, mc = gaston_mk_ms_mc(series, clims, i)
push!(curveconf, "w points pt $pt ps $ps lc $mc") push!(curveconf, "w points pt $pt ps $ps lc $mc")
elseif st (:path, :straightline, :path3d) elseif st (:path, :straightline, :path3d)
fr = series[:fillrange]
fc = gaston_color(get_fillcolor(series, i), get_fillalpha(series, i))
lc, dt, lw = gaston_lc_ls_lw(series, clims, i) lc, dt, lw = gaston_lc_ls_lw(series, clims, i)
if series[:markershape] == :none # simplepath if fr !== nothing # filled curves, but not filled curves with markers
push!(
curveconf,
"w filledcurves fc $fc fs solid border lc $lc lw $lw dt $dt,'' w lines lc $lc lw $lw dt $dt",
)
elseif series[:markershape] == :none # simplepath
push!(curveconf, "w lines lc $lc dt $dt lw $lw") push!(curveconf, "w lines lc $lc dt $dt lw $lw")
else else
pt, ps, mc = gaston_mk_ms_mc(series, clims, i) pt, ps, mc = gaston_mk_ms_mc(series, clims, i)
@ -365,7 +369,7 @@ function gaston_parse_axes_args(
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
(letter == :z && dims == 2) && continue (letter == :z && dims == 2) && continue
axis = sp.attr[Symbol(letter, :axis)] axis = sp.attr[get_attr_symbol(letter, :axis)]
# label names # label names
push!( push!(
axesconf, axesconf,
@ -498,8 +502,8 @@ function gaston_set_ticks!(axesconf, ticks, letter, maj_min, add)
end end
function gaston_set_legend!(axesconf, sp, any_label) function gaston_set_legend!(axesconf, sp, any_label)
leg = sp[:legend] leg = sp[:legend_position]
if sp[:legend] (:none, :inline) && any_label if sp[:legend_position] (:none, :inline) && any_label
leg == :best && (leg = :topright) leg == :best && (leg = :topright)
push!( push!(
@ -510,9 +514,9 @@ function gaston_set_legend!(axesconf, sp, any_label)
occursin(position, string(leg)) && push!(axesconf, "set key $position") occursin(position, string(leg)) && push!(axesconf, "set key $position")
end end
push!(axesconf, "set key $(gaston_font(legendfont(sp), rot=false, align=false))") push!(axesconf, "set key $(gaston_font(legendfont(sp), rot=false, align=false))")
if sp[:legendtitle] !== nothing if sp[:legend_title] !== nothing
# NOTE: cannot use legendtitlefont(sp) as it will override legendfont # NOTE: cannot use legendtitlefont(sp) as it will override legendfont
push!(axesconf, "set key title '$(sp[:legendtitle])'") push!(axesconf, "set key title '$(sp[:legend_title])'")
end end
push!(axesconf, "set key box lw 1 opaque") push!(axesconf, "set key box lw 1 opaque")
push!(axesconf, "set border back") push!(axesconf, "set border back")

View File

@ -104,6 +104,9 @@ function gr_color(c, ::Type{<:AbstractGray})
end end
gr_color(c, ::Type) = gr_color(RGBA(c), RGB) gr_color(c, ::Type) = gr_color(RGBA(c), RGB)
set_RGBA_alpha(alpha, c::RGBA) = RGBA(red(c), green(c), blue(c), alpha)
set_RGBA_alpha(alpha::Nothing, c::RGBA) = c
function gr_getcolorind(c) function gr_getcolorind(c)
gr_set_transparency(float(alpha(c))) gr_set_transparency(float(alpha(c)))
convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c))) convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c)))
@ -136,6 +139,12 @@ gr_set_arrowstyle(s::Symbol) = GR.setarrowstyle(
), ),
) )
gr_set_fillstyle(::Nothing) = GR.setfillintstyle(GR.INTSTYLE_SOLID)
function gr_set_fillstyle(s::Symbol)
GR.setfillintstyle(GR.INTSTYLE_HATCH)
GR.setfillstyle(get(((/) = 9, (\) = 10, (|) = 7, (-) = 8, (+) = 11, (x) = 6), s, 9))
end
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
# draw line segments, splitting x/y into contiguous/finite segments # draw line segments, splitting x/y into contiguous/finite segments
@ -219,9 +228,8 @@ end
gr_inqtext(x, y, s) = gr_inqtext(x, y, string(s)) gr_inqtext(x, y, s) = gr_inqtext(x, y, string(s))
function gr_inqtext(x, y, s::AbstractString) function gr_inqtext(x, y, s::AbstractString)
if length(s) >= 2 && s[1] == '$' && s[end] == '$' if (occursin('\\', s) || occursin("10^{", s)) &&
GR.inqmathtex(x, y, s[2:(end - 1)]) match(r".*\$[^\$]+?\$.*", String(s)) == nothing
elseif occursin('\\', s) || occursin("10^{", s)
GR.inqtextext(x, y, s) GR.inqtextext(x, y, s)
else else
GR.inqtext(x, y, s) GR.inqtext(x, y, s)
@ -231,9 +239,8 @@ end
gr_text(x, y, s) = gr_text(x, y, string(s)) gr_text(x, y, s) = gr_text(x, y, string(s))
function gr_text(x, y, s::AbstractString) function gr_text(x, y, s::AbstractString)
if length(s) >= 2 && s[1] == '$' && s[end] == '$' if (occursin('\\', s) || occursin("10^{", s)) &&
GR.mathtex(x, y, s[2:(end - 1)]) match(r".*\$[^\$]+?\$.*", String(s)) == nothing
elseif occursin('\\', s) || occursin("10^{", s)
GR.textext(x, y, s) GR.textext(x, y, s)
else else
GR.text(x, y, s) GR.text(x, y, s)
@ -406,7 +413,7 @@ function gr_set_font(
gr_font_family[family] >= 200 ? 3 : GR.TEXT_PRECISION_STRING, gr_font_family[family] >= 200 ? 3 : GR.TEXT_PRECISION_STRING,
) )
end end
gr_set_textcolor(color) gr_set_textcolor(plot_color(color))
GR.settextalign(gr_halign(halign), gr_valign(valign)) GR.settextalign(gr_halign(halign), gr_valign(valign))
end end
@ -564,6 +571,9 @@ function gr_draw_colorbar(cbar::GRColorbar, sp::Subplot, clims, viewport_plotare
ztick = 0.5 * GR.tick(zmin, zmax) ztick = 0.5 * GR.tick(zmin, zmax)
gr_set_line(1, :solid, plot_color(:black), sp) gr_set_line(1, :solid, plot_color(:black), sp)
if sp[:colorbar_scale] == :log10
GR.setscale(2)
end
GR.axes(0, ztick, xmax, zmin, 0, 1, 0.005) GR.axes(0, ztick, xmax, zmin, 0, 1, 0.005)
title = if isa(sp[:colorbar_title], PlotText) title = if isa(sp[:colorbar_title], PlotText)
@ -664,32 +674,20 @@ function gr_display(plt::Plot, fmt = "")
end end
function gr_set_tickfont(sp, letter) function gr_set_tickfont(sp, letter)
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
# invalidate alignment changes for small rotations (|θ| < 45°)
trigger(rot) = abs(sind(rot)) < abs(cosd(rot)) ? 0 : sign(rot)
rot = axis[:rotation]
if letter === :x || (RecipesPipeline.is3d(sp) && letter === :y)
halign = (:left, :hcenter, :right)[trigger(rot) + 2]
valign = (axis[:mirror] ? :bottom : :top, :vcenter)[trigger(abs(rot)) + 1]
else
halign = (axis[:mirror] ? :left : :right, :hcenter)[trigger(abs(rot)) + 1]
valign = (:top, :vcenter, :bottom)[trigger(rot) + 2]
end
gr_set_font( gr_set_font(
tickfont(axis), tickfont(axis),
sp, sp,
halign = halign,
valign = valign,
rotation = axis[:rotation], rotation = axis[:rotation],
color = axis[:tickfontcolor], color = axis[:tickfontcolor],
) )
end end
# size of the text with no rotation
function gr_text_size(str) function gr_text_size(str)
GR.savestate() GR.savestate()
GR.selntran(0) GR.selntran(0)
GR.setcharup(0, 1)
xs, ys = gr_inqtext(0, 0, string(str)) xs, ys = gr_inqtext(0, 0, string(str))
l, r = extrema(xs) l, r = extrema(xs)
b, t = extrema(ys) b, t = extrema(ys)
@ -699,9 +697,11 @@ function gr_text_size(str)
return w, h return w, h
end end
# size of the text with rotation applied
function gr_text_size(str, rot) function gr_text_size(str, rot)
GR.savestate() GR.savestate()
GR.selntran(0) GR.selntran(0)
GR.setcharup(0, 1)
xs, ys = gr_inqtext(0, 0, string(str)) xs, ys = gr_inqtext(0, 0, string(str))
l, r = extrema(xs) l, r = extrema(xs)
b, t = extrema(ys) b, t = extrema(ys)
@ -714,12 +714,21 @@ end
text_box_width(w, h, rot) = abs(cosd(rot)) * w + abs(cosd(rot + 90)) * h text_box_width(w, h, rot) = abs(cosd(rot)) * w + abs(cosd(rot + 90)) * h
text_box_height(w, h, rot) = abs(sind(rot)) * w + abs(sind(rot + 90)) * h text_box_height(w, h, rot) = abs(sind(rot)) * w + abs(sind(rot + 90)) * h
function gr_get_3d_axis_angle(cvs, nt, ft, letter)
length(cvs) < 2 && return 0
tickpoints = [gr_w3tondc(sort_3d_axes(cv, nt, ft, letter)...) for cv in cvs]
dx = tickpoints[2][1] - tickpoints[1][1]
dy = tickpoints[2][2] - tickpoints[1][2]
return atand(dy, dx)
end
function gr_get_ticks_size(ticks, rot) function gr_get_ticks_size(ticks, rot)
w, h = 0.0, 0.0 w, h = 0.0, 0.0
for (cv, dv) in zip(ticks...) for (cv, dv) in zip(ticks...)
wi, hi = gr_text_size(dv, rot) wi, hi = gr_text_size(dv, rot)
w = max(w, wi) w = NaNMath.max(w, wi)
h = max(h, hi) h = NaNMath.max(h, hi)
end end
return w, h return w, h
end end
@ -945,6 +954,9 @@ function get_z_normalized(z, clims...)
end end
function gr_clims(args...) function gr_clims(args...)
if args[1][:clims] != :auto
return get_clims(args[1])
end
lo, hi = get_clims(args...) lo, hi = get_clims(args...)
if lo == hi if lo == hi
if lo == 0 if lo == 0
@ -1016,7 +1028,7 @@ end
## Legend ## Legend
function gr_add_legend(sp, leg, viewport_plotarea) function gr_add_legend(sp, leg, viewport_plotarea)
if sp[:legend] (:none, :inline) if !(sp[:legend_position] in (:none, :inline))
GR.savestate() GR.savestate()
GR.selntran(0) GR.selntran(0)
GR.setscale(0) GR.setscale(0)
@ -1024,14 +1036,14 @@ function gr_add_legend(sp, leg, viewport_plotarea)
if leg.w > 0 if leg.w > 0
xpos, ypos = gr_legend_pos(sp, leg, viewport_plotarea) xpos, ypos = gr_legend_pos(sp, leg, viewport_plotarea)
GR.setfillintstyle(GR.INTSTYLE_SOLID) GR.setfillintstyle(GR.INTSTYLE_SOLID)
gr_set_fillcolor(sp[:background_color_legend]) gr_set_fillcolor(sp[:legend_background_color])
GR.fillrect( GR.fillrect(
xpos - leg.leftw, xpos - leg.leftw,
xpos + leg.textw + leg.rightw, xpos + leg.textw + leg.rightw,
ypos + leg.dy, ypos + leg.dy,
ypos - leg.h, ypos - leg.h,
) # Allocating white space for actual legend width here ) # Allocating white space for actual legend width here
gr_set_line(1, :solid, sp[:foreground_color_legend], sp) gr_set_line(1, :solid, sp[:legend_foreground_color], sp)
GR.drawrect( GR.drawrect(
xpos - leg.leftw, xpos - leg.leftw,
xpos + leg.textw + leg.rightw, xpos + leg.textw + leg.rightw,
@ -1039,10 +1051,10 @@ function gr_add_legend(sp, leg, viewport_plotarea)
ypos - leg.h, ypos - leg.h,
) # Drawing actual legend width here ) # Drawing actual legend width here
i = 0 i = 0
if sp[:legendtitle] !== nothing if sp[:legend_title] !== nothing
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF)
gr_set_font(legendtitlefont(sp), sp) gr_set_font(legendtitlefont(sp), sp)
gr_text(xpos - 0.03 + 0.5 * leg.w, ypos, string(sp[:legendtitle])) gr_text(xpos - 0.03 + 0.5 * leg.w, ypos, string(sp[:legend_title]))
ypos -= leg.dy ypos -= leg.dy
gr_set_font(legendfont(sp), sp) gr_set_font(legendfont(sp), sp)
end end
@ -1051,14 +1063,16 @@ function gr_add_legend(sp, leg, viewport_plotarea)
should_add_to_legend(series) || continue should_add_to_legend(series) || continue
st = series[:seriestype] st = series[:seriestype]
lc = get_linecolor(series, clims) lc = get_linecolor(series, clims)
gr_set_line(sp[:legendfontsize] / 8, get_linestyle(series), lc, sp) gr_set_line(sp[:legend_font_pointsize] / 8, get_linestyle(series), lc, sp)
if ( if (
(st == :shape || series[:fillrange] !== nothing) && (st == :shape || series[:fillrange] !== nothing) &&
series[:ribbon] === nothing series[:ribbon] === nothing
) )
fc = get_fillcolor(series, clims) fc = get_fillcolor(series, clims)
gr_set_fill(fc) #, series[:fillalpha]) gr_set_fill(fc)
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
l, r = xpos - leg.width_factor * 3.5, xpos - leg.width_factor / 2 l, r = xpos - leg.width_factor * 3.5, xpos - leg.width_factor / 2
b, t = ypos - 0.4 * leg.dy, ypos + 0.4 * leg.dy b, t = ypos - 0.4 * leg.dy, ypos + 0.4 * leg.dy
x = [l, r, r, l, l] x = [l, r, r, l, l]
@ -1090,16 +1104,17 @@ function gr_add_legend(sp, leg, viewport_plotarea)
ms = first(series[:markersize]) ms = first(series[:markersize])
msw = first(series[:markerstrokewidth]) msw = first(series[:markerstrokewidth])
s, sw = if ms > 0 s, sw = if ms > 0
0.8 * sp[:legendfontsize], 0.8 * sp[:legendfontsize] * msw / ms 0.8 * sp[:legend_font_pointsize],
0.8 * sp[:legend_font_pointsize] * msw / ms
else else
0, 0.8 * sp[:legendfontsize] * msw / 8 0, 0.8 * sp[:legend_font_pointsize] * msw / 8
end end
gr_draw_markers(series, xpos - leg.width_factor * 2, ypos, clims, s, sw) gr_draw_markers(series, xpos - leg.width_factor * 2, ypos, clims, s, sw)
end end
lab = series[:label] lab = series[:label]
GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF) GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF)
gr_set_textcolor(plot_color(sp[:legendfontcolor])) gr_set_textcolor(plot_color(sp[:legend_font_color]))
gr_text(xpos, ypos, string(lab)) gr_text(xpos, ypos, string(lab))
ypos -= leg.dy ypos -= leg.dy
end end
@ -1110,7 +1125,7 @@ function gr_add_legend(sp, leg, viewport_plotarea)
end end
function gr_legend_pos(sp::Subplot, leg, viewport_plotarea) function gr_legend_pos(sp::Subplot, leg, viewport_plotarea)
s = sp[:legend] s = sp[:legend_position]
s isa Real && return gr_legend_pos(s, leg, viewport_plotarea) s isa Real && return gr_legend_pos(s, leg, viewport_plotarea)
if s isa Tuple{<:Real,Symbol} if s isa Tuple{<:Real,Symbol}
if s[2] !== :outer if s[2] !== :outer
@ -1227,24 +1242,29 @@ end
function gr_get_legend_geometry(viewport_plotarea, sp) function gr_get_legend_geometry(viewport_plotarea, sp)
legendn = legendw = dy = 0 legendn = legendw = dy = 0
if sp[:legend] != :none if sp[:legend_position] != :none
GR.savestate() GR.savestate()
GR.selntran(0) GR.selntran(0)
GR.setcharup(0, 1)
GR.setscale(0) GR.setscale(0)
if sp[:legendtitle] !== nothing if sp[:legend_title] !== nothing
gr_set_font(legendtitlefont(sp), sp) gr_set_font(legendtitlefont(sp), sp)
legendn += 1 legendn += 1
tbx, tby = gr_inqtext(0, 0, string(sp[:legendtitle])) tbx, tby = gr_inqtext(0, 0, string(sp[:legend_title]))
legendw = tbx[3] - tbx[1] l, r = extrema(tbx)
dy = tby[3] - tby[1] b, t = extrema(tby)
legendw = r - l
dy = t - b
end end
gr_set_font(legendfont(sp), sp) gr_set_font(legendfont(sp), sp)
for series in series_list(sp) for series in series_list(sp)
should_add_to_legend(series) || continue should_add_to_legend(series) || continue
legendn += 1 legendn += 1
tbx, tby = gr_inqtext(0, 0, string(series[:label])) tbx, tby = gr_inqtext(0, 0, string(series[:label]))
legendw = max(legendw, tbx[3] - tbx[1]) # Holds text width right now l, r = extrema(tbx)
dy = max(dy, tby[3] - tby[1]) b, t = extrema(tby)
legendw = max(legendw, r - l) # Holds text width right now
dy = max(dy, t - b)
end end
GR.setscale(1) GR.setscale(1)
@ -1262,7 +1282,6 @@ function gr_get_legend_geometry(viewport_plotarea, sp)
y_legend_offset = (viewport_plotarea[4] - viewport_plotarea[3]) / 30 y_legend_offset = (viewport_plotarea[4] - viewport_plotarea[3]) / 30
dy *= get(sp[:extra_kwargs], :legend_hfactor, 1) dy *= get(sp[:extra_kwargs], :legend_hfactor, 1)
legendh = dy * legendn legendh = dy * legendn
return ( return (
@ -1281,7 +1300,7 @@ end
## Viewport, window and scale ## Viewport, window and scale
function gr_update_viewport_legend!(viewport_plotarea, sp, leg) function gr_update_viewport_legend!(viewport_plotarea, sp, leg)
s = sp[:legend] s = sp[:legend_position]
xaxis, yaxis = sp[:xaxis], sp[:yaxis] xaxis, yaxis = sp[:xaxis], sp[:yaxis]
xmirror = xmirror =
@ -1330,7 +1349,7 @@ function gr_update_viewport_legend!(viewport_plotarea, sp, leg)
leg.h + leg.dy + leg.yoffset + !xmirror * gr_axis_height(sp, sp[:xaxis]) leg.h + leg.dy + leg.yoffset + !xmirror * gr_axis_height(sp, sp[:xaxis])
end end
end end
if s === :inline if s == :inline
if sp[:yaxis][:mirror] if sp[:yaxis][:mirror]
viewport_plotarea[1] += leg.w viewport_plotarea[1] += leg.w
else else
@ -1448,7 +1467,7 @@ end
function gr_draw_axis(sp, letter, viewport_plotarea) function gr_draw_axis(sp, letter, viewport_plotarea)
ax = axis_drawing_info(sp, letter) ax = axis_drawing_info(sp, letter)
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
# draw segments # draw segments
gr_draw_grid(sp, axis, ax.grid_segments) gr_draw_grid(sp, axis, ax.grid_segments)
@ -1464,7 +1483,7 @@ end
function gr_draw_axis_3d(sp, letter, viewport_plotarea) function gr_draw_axis_3d(sp, letter, viewport_plotarea)
ax = axis_drawing_info_3d(sp, letter) ax = axis_drawing_info_3d(sp, letter)
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
# draw segments # draw segments
gr_draw_grid(sp, axis, ax.grid_segments, gr_polyline3d) gr_draw_grid(sp, axis, ax.grid_segments, gr_polyline3d)
@ -1545,20 +1564,42 @@ function gr_draw_ticks(sp, axis, segments, func = gr_polyline)
end end
function gr_label_ticks(sp, letter, ticks) function gr_label_ticks(sp, letter, ticks)
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
isy = letter === :y isy = letter === :y
oletter = isy ? :x : :y oletter = isy ? :x : :y
oaxis = sp[Symbol(oletter, :axis)] oaxis = sp[get_attr_symbol(oletter, :axis)]
oamin, oamax = axis_limits(sp, oletter) oamin, oamax = axis_limits(sp, oletter)
gr_set_tickfont(sp, letter) gr_set_tickfont(sp, letter)
out_factor = ifelse(axis[:tick_direction] === :out, 1.5, 1) out_factor = ifelse(axis[:tick_direction] === :out, 1.5, 1)
x_offset = isy ? -1.5e-2 * out_factor : 0 x_base_offset = isy ? -1.5e-2 * out_factor : 0
y_offset = isy ? 0 : -8e-3 * out_factor y_base_offset = isy ? 0 : -8e-3 * out_factor
rot = axis[:rotation] % 360
ov = sp[:framestyle] == :origin ? 0 : xor(oaxis[:flip], axis[:mirror]) ? oamax : oamin ov = sp[:framestyle] == :origin ? 0 : xor(oaxis[:flip], axis[:mirror]) ? oamax : oamin
sgn = axis[:mirror] ? -1 : 1 sgn = axis[:mirror] ? -1 : 1
sgn2 = iseven(Int(floor(rot / 90))) ? -1 : 1
sgn3 = if isy
-360 < rot < -180 || 0 < rot < 180 ? 1 : -1
else
rot < -270 || -90 < rot < 90 || rot > 270 ? 1 : -1
end
for (cv, dv) in zip(ticks...) for (cv, dv) in zip(ticks...)
x, y = GR.wctondc(reverse_if((cv, ov), isy)...) x, y = GR.wctondc(reverse_if((cv, ov), isy)...)
sz_rot = gr_text_size(dv, rot)
sz = gr_text_size(dv)
x_offset = x_base_offset
y_offset = y_base_offset
if isy
x_offset += -first(sz_rot) / 2
if rot % 90 != 0
y_offset += sgn2 * last(sz_rot) / 2 + sgn3 * last(sz) * cosd(rot) / 2
end
else
if rot % 90 != 0
x_offset += sgn2 * first(sz_rot) / 2 + sgn3 * last(sz) * sind(rot) / 2
end
y_offset += -last(sz_rot) / 2
end
gr_text(x + sgn * x_offset, y + sgn * y_offset, dv) gr_text(x + sgn * x_offset, y + sgn * y_offset, dv)
end end
end end
@ -1569,19 +1610,22 @@ function gr_label_ticks_3d(sp, letter, ticks)
near_letter = letter in (:x, :z) ? :y : :x near_letter = letter in (:x, :z) ? :y : :x
far_letter = letter in (:x, :y) ? :z : :x far_letter = letter in (:x, :y) ? :z : :x
ax = sp[Symbol(letter, :axis)] isy = letter === :y
nax = sp[Symbol(near_letter, :axis)] isz = letter === :z
fax = sp[Symbol(far_letter, :axis)]
ax = sp[get_attr_symbol(letter, :axis)]
nax = sp[get_attr_symbol(near_letter, :axis)]
fax = sp[get_attr_symbol(far_letter, :axis)]
amin, amax = axis_limits(sp, letter) amin, amax = axis_limits(sp, letter)
namin, namax = axis_limits(sp, near_letter) namin, namax = axis_limits(sp, near_letter)
famin, famax = axis_limits(sp, far_letter) famin, famax = axis_limits(sp, far_letter)
n0, n1 = letter === :y ? (namax, namin) : (namin, namax) n0, n1 = isy ? (namax, namin) : (namin, namax)
# find out which axes we are dealing with # find out which axes we are dealing with
i = findfirst(==(letter), (:x, :y, :z)) i = findfirst(==(letter), (:x, :y, :z))
letters = axes_shift((:x, :y, :z), 1 - i) letters = axes_shift((:x, :y, :z), 1 - i)
asyms = Symbol.(letters, :axis) asyms = get_attr_symbol.(letters, :axis)
# get axis objects, ticks and minor ticks # get axis objects, ticks and minor ticks
# regardless of the `letter` we now use the convention that `x` in variable names refer to # regardless of the `letter` we now use the convention that `x` in variable names refer to
@ -1593,32 +1637,62 @@ function gr_label_ticks_3d(sp, letter, ticks)
nt = sp[:framestyle] == :origin ? 0 : ax[:mirror] ? n1 : n0 nt = sp[:framestyle] == :origin ? 0 : ax[:mirror] ? n1 : n0
ft = sp[:framestyle] == :origin ? 0 : ax[:mirror] ? famax : famin ft = sp[:framestyle] == :origin ? 0 : ax[:mirror] ? famax : famin
xoffset = if letter === :x rot = mod(ax[:rotation], 360)
(sp[:yaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:xaxis][:tick_direction] == :out ? 1.5 : 1) sgn = ax[:mirror] ? -1 : 1
elseif letter === :y
(sp[:yaxis][:mirror] ? -1 : 1) * 1e-2 * (sp[:yaxis][:tick_direction] == :out ? 1.5 : 1)
else
(sp[:zaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:zaxis][:tick_direction] == :out ? 1.5 : 1)
end
yoffset = if letter === :x
(sp[:xaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:xaxis][:tick_direction] == :out ? 1.5 : 1)
elseif letter === :y
(sp[:yaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:yaxis][:tick_direction] == :out ? 1.5 : 1)
else
0
end
cvs, dvs = ticks cvs, dvs = ticks
ax[:flip] && reverse!(cvs) ax[:flip] && reverse!(cvs)
axisθ = isz ? 270 : mod(gr_get_3d_axis_angle(cvs, nt, ft, letter), 360) # issue: doesn't work with 1 tick
axisϕ = mod(axisθ - 90, 360)
out_factor = ifelse(ax[:tick_direction] === :out, 1.5, 1)
axisoffset = out_factor * 1.2e-2
x_base_offset = axisoffset * cosd(axisϕ)
y_base_offset = axisoffset * sind(axisϕ)
sgn2a = sgn2b = sgn3 = 0
if axisθ != 0 || rot % 90 != 0
sgn2a =
(axisθ != 90) && (axisθ == 0 && (rot < 90 || 180 rot < 270)) ||
(axisθ == 270) ||
(axisθ < 90 && (axisθ < rot < 90 || axisθ + 180 < rot < 270)) ||
(axisθ > 270 && (rot < 90 || axisθ - 180 < rot < 270 || rot > axisθ)) ? -1 : 1
end
if (axisθ - 90) % 180 != 0 || (rot - 90) % 180 != 0
sgn2b =
axisθ == 0 ||
(axisθ == 90 && (90 rot < 180 || 270 rot < 360)) ||
(axisθ == 270 && (rot < 90 || 180 rot < 270)) ||
(axisθ < 90 && (axisθ < rot < 180 || axisθ + 180 < rot)) ||
(axisθ > 270 && (rot < axisθ - 180 || 180 rot < axisθ)) ? -1 : 1
end
if !(axisθ == 0 && rot % 180 == 0) && ((rot - 90) % 180 != 0)
sgn3 =
(axisθ == 0 && 90 < rot < 270) ||
(axisθ == 90 && rot < 180) ||
(axisθ == 270 && rot > 180) ||
(axisθ < 90 && (rot < axisθ || 90 rot < 180 || axisθ + 180 < rot < 270)) ||
(axisθ > 270 && (90 rot < axisθ - 180 || 180 rot < 270 || rot > axisθ)) ?
-1 : 1
end
for (cv, dv) in zip((cvs, dvs)...) for (cv, dv) in zip((cvs, dvs)...)
xi, yi = gr_w3tondc(sort_3d_axes(cv, nt, ft, letter)...) xi, yi = gr_w3tondc(sort_3d_axes(cv, nt, ft, letter)...)
gr_text(xi + xoffset, yi + yoffset, dv) sz_rot = gr_text_size(dv, rot)
sz = gr_text_size(dv)
x_offset =
x_base_offset + sgn2a * first(sz_rot) / 2 + sgn3 * last(sz) * sind(rot) / 2
y_offset =
y_base_offset + sgn2b * last(sz_rot) / 2 + sgn3 * last(sz) * cosd(rot) / 2
gr_text(xi + sgn * x_offset, yi + sgn * y_offset, dv)
end end
end end
function gr_label_axis(sp, letter, viewport_plotarea) function gr_label_axis(sp, letter, viewport_plotarea)
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
mirror = axis[:mirror] mirror = axis[:mirror]
# guide # guide
if axis[:guide] != "" if axis[:guide] != ""
@ -1662,13 +1736,13 @@ function gr_label_axis(sp, letter, viewport_plotarea)
end end
function gr_label_axis_3d(sp, letter) function gr_label_axis_3d(sp, letter)
ax = sp[Symbol(letter, :axis)] ax = sp[get_attr_symbol(letter, :axis)]
if ax[:guide] != "" if ax[:guide] != ""
near_letter = letter in (:x, :z) ? :y : :x near_letter = letter in (:x, :z) ? :y : :x
far_letter = letter in (:x, :y) ? :z : :x far_letter = letter in (:x, :y) ? :z : :x
nax = sp[Symbol(near_letter, :axis)] nax = sp[get_attr_symbol(near_letter, :axis)]
fax = sp[Symbol(far_letter, :axis)] fax = sp[get_attr_symbol(far_letter, :axis)]
amin, amax = axis_limits(sp, letter) amin, amax = axis_limits(sp, letter)
namin, namax = axis_limits(sp, near_letter) namin, namax = axis_limits(sp, near_letter)
@ -1776,7 +1850,7 @@ function gr_add_series(sp, series)
elseif st in (:surface, :wireframe, :mesh3d) elseif st in (:surface, :wireframe, :mesh3d)
gr_draw_surface(series, x, y, z, clims) gr_draw_surface(series, x, y, z, clims)
elseif st === :volume elseif st === :volume
sp[:legend] = :none sp[:legend_position] = :none
GR.gr3.clear() GR.gr3.clear()
dmin, dmax = GR.gr3.volume(y.v, 0) dmin, dmax = GR.gr3.volume(y.v, 0)
elseif st === :heatmap elseif st === :heatmap
@ -1794,9 +1868,9 @@ function gr_add_series(sp, series)
gr_text(GR.wctondc(xi, yi)..., str) gr_text(GR.wctondc(xi, yi)..., str)
end end
if sp[:legend] == :inline && should_add_to_legend(series) if sp[:legend_position] == :inline && should_add_to_legend(series)
gr_set_font(legendfont(sp), sp) gr_set_font(legendfont(sp), sp)
gr_set_textcolor(plot_color(sp[:legendfontcolor])) gr_set_textcolor(plot_color(sp[:legend_font_color]))
if sp[:yaxis][:mirror] if sp[:yaxis][:mirror]
(_, i) = sp[:xaxis][:flip] ? findmax(x) : findmin(x) (_, i) = sp[:xaxis][:flip] ? findmax(x) : findmin(x)
GR.settextalign(GR.TEXT_HALIGN_RIGHT, GR.TEXT_VALIGN_HALF) GR.settextalign(GR.TEXT_HALIGN_RIGHT, GR.TEXT_VALIGN_HALF)
@ -1824,6 +1898,8 @@ function gr_draw_segments(series, x, y, fillrange, clims)
i, rng = segment.attr_index, segment.range i, rng = segment.attr_index, segment.range
fc = get_fillcolor(series, clims, i) fc = get_fillcolor(series, clims, i)
gr_set_fillcolor(fc) gr_set_fillcolor(fc)
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
fx = _cycle(x, vcat(rng, reverse(rng))) fx = _cycle(x, vcat(rng, reverse(rng)))
fy = vcat(_cycle(fr_from, rng), _cycle(fr_to, reverse(rng))) fy = vcat(_cycle(fr_from, rng), _cycle(fr_to, reverse(rng)))
gr_set_transparency(fc, get_fillalpha(series, i)) gr_set_transparency(fc, get_fillalpha(series, i))
@ -1912,6 +1988,8 @@ function gr_draw_shapes(series, clims)
# draw the interior # draw the interior
fc = get_fillcolor(series, clims, i) fc = get_fillcolor(series, clims, i)
gr_set_fill(fc) gr_set_fill(fc)
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
gr_set_transparency(fc, get_fillalpha(series, i)) gr_set_transparency(fc, get_fillalpha(series, i))
GR.fillarea(xseg, yseg) GR.fillarea(xseg, yseg)
@ -1969,14 +2047,42 @@ function gr_draw_surface(series, x, y, z, clims)
GR.setfillcolorind(0) GR.setfillcolorind(0)
GR.surface(x, y, z, get(e_kwargs, :display_option, GR.OPTION_FILLED_MESH)) GR.surface(x, y, z, get(e_kwargs, :display_option, GR.OPTION_FILLED_MESH))
elseif st === :mesh3d elseif st === :mesh3d
@warn "GR: mesh3d is experimental (no face colors)" if series[:connections] isa AbstractVector{<:AbstractVector{Int}}
gr_set_line( # Combination of any polygon types
get_linewidth(series), cns = [[length(polyinds), polyinds...] for polyinds in series[:connections]]
get_linestyle(series), elseif series[:connections] isa AbstractVector{NTuple{N,Int}} where {N}
get_linecolor(series), # Only N-gons - connections have to be 1-based (indexing)
series, N = length(series[:connections][1])
cns = [[N, polyinds...] for polyinds in series[:connections]]
elseif series[:connections] isa NTuple{3,<:AbstractVector{Int}}
# Only triangles - connections have to be 0-based (indexing)
ci, cj, ck = series[:connections]
if !(length(ci) == length(cj) == length(ck))
throw(
ArgumentError(
"Argument connections must consist of equally sized arrays.",
),
) )
GR.polyline3d(mesh3d_triangles(x, y, z, series[:connections])...) end
cns = [([3, ci[i] + 1, cj[i] + 1, ck[i] + 1]) for i in eachindex(ci)]
else
throw(
ArgumentError(
"Unsupported `:connections` type $(typeof(series[:connections])) for seriestype=$st",
),
)
end
fillalpha = get_fillalpha(series)
n_polygons = length(cns)
facecolor = if series[:fillcolor] isa AbstractArray
series[:fillcolor]
else
fill(series[:fillcolor], n_polygons)
end
facecolor = map(fc -> set_RGBA_alpha(fillalpha, fc), facecolor)
GR.setborderwidth(get_linewidth(series))
GR.setbordercolorind(gr_getcolorind(get_linecolor(series)))
GR.polygonmesh3d(x, y, z, vcat(cns...), signed.(gr_color.(facecolor)))
else else
throw(ArgumentError("Not handled !")) throw(ArgumentError("Not handled !"))
end end
@ -1992,15 +2098,38 @@ function gr_draw_heatmap(series, x, y, z, clims)
# pdf output, and also supports alpha values. # pdf output, and also supports alpha values.
# Note that drawimage draws uniformly spaced data correctly # Note that drawimage draws uniformly spaced data correctly
# even on log scales, where it is visually non-uniform. # even on log scales, where it is visually non-uniform.
colors = plot_color.(get(fillgrad, z, clims), series[:fillalpha]) colors, _z = if series[:subplot][:colorbar_scale] == :identity
plot_color.(get(fillgrad, z, clims), series[:fillalpha]), z
elseif series[:subplot][:colorbar_scale] == :log10
z_log = replace(x -> isinf(x) ? NaN : x, log10.(z))
z_normalized = get_z_normalized.(z_log, log10.(clims)...)
plot_color.(map(z -> get(fillgrad, z), z_normalized), series[:fillalpha]), z_log
end
for i in eachindex(colors)
if isnan(_z[i])
colors[i] = set_RGBA_alpha(0, colors[i])
end
end
rgba = gr_color.(colors) rgba = gr_color.(colors)
GR.drawimage(first(x), last(x), last(y), first(y), w, h, rgba) GR.drawimage(first(x), last(x), last(y), first(y), w, h, rgba)
else else
if something(series[:fillalpha], 1) < 1 if something(series[:fillalpha], 1) < 1
@warn "GR: transparency not supported in non-uniform heatmaps. Alpha values ignored." @warn "GR: transparency not supported in non-uniform heatmaps. Alpha values ignored."
end end
z_normalized = get_z_normalized.(z, clims...) z_normalized, _z = if series[:subplot][:colorbar_scale] == :identity
get_z_normalized.(z, clims...), z
elseif series[:subplot][:colorbar_scale] == :log10
z_log = replace(x -> isinf(x) ? NaN : x, log10.(z))
get_z_normalized.(z_log, log10.(clims)...), z_log
end
rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized] rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized]
background_color_ind =
gr_getcolorind(plot_color(series[:subplot][:background_color_inside]))
for i in eachindex(rgba)
if isnan(_z[i])
rgba[i] = background_color_ind
end
end
if !ispolar(series) if !ispolar(series)
GR.nonuniformcellarray(x, y, w, h, rgba) GR.nonuniformcellarray(x, y, w, h, rgba)
else else

View File

@ -13,7 +13,7 @@ Add in functionality to Plots.jl:
:aspect_ratio, :aspect_ratio,
=# =#
# --------------------------------------------------------------------------- should_warn_on_unsupported(::InspectDRBackend) = false
is_marker_supported(::InspectDRBackend, shape::Shape) = true is_marker_supported(::InspectDRBackend, shape::Shape) = true
@ -70,7 +70,7 @@ function _inspectdr_add_annotations(plot, x, y, val::PlotText)
color = _inspectdr_mapcolor(val.font.color), color = _inspectdr_mapcolor(val.font.color),
) )
ann = InspectDR.atext( ann = InspectDR.atext(
val.str, texmath2unicode(val.str),
x = x, x = x,
y = y, y = y,
font = fnt, font = fnt,
@ -384,9 +384,9 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
_inspectdr_setticks(sp, plot, strip, xaxis, yaxis) _inspectdr_setticks(sp, plot, strip, xaxis, yaxis)
a = plot.annotation a = plot.annotation
a.title = sp[:title] a.title = texmath2unicode(sp[:title])
a.xlabel = xaxis[:guide] a.xlabel = texmath2unicode(xaxis[:guide])
a.ylabels = [yaxis[:guide]] a.ylabels = [texmath2unicode(yaxis[:guide])]
#Modify base layout of new object: #Modify base layout of new object:
l = plot.layout.defaults = deepcopy(InspectDR.defaults.plotlayout) l = plot.layout.defaults = deepcopy(InspectDR.defaults.plotlayout)
@ -411,15 +411,14 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
_inspectdr_mapptsize(xaxis[:tickfontsize]), _inspectdr_mapptsize(xaxis[:tickfontsize]),
color = _inspectdr_mapcolor(xaxis[:tickfontcolor]), color = _inspectdr_mapcolor(xaxis[:tickfontcolor]),
) )
l.enable_legend = (sp[:legend] != :none) l.enable_legend = (sp[:legend_position] != :none)
#l.halloc_legend = 150 #TODO: compute??? #l.halloc_legend = 150 #TODO: compute???
l.font_legend = InspectDR.Font( l.font_legend = InspectDR.Font(
sp[:legendfontfamily], sp[:legend_font_family],
_inspectdr_mapptsize(sp[:legendfontsize]), _inspectdr_mapptsize(sp[:legend_font_pointsize]),
color = _inspectdr_mapcolor(sp[:legendfontcolor]), color = _inspectdr_mapcolor(sp[:legend_font_color]),
) )
l.frame_legend.fillcolor = _inspectdr_mapcolor(sp[:background_color_legend]) l.frame_legend.fillcolor = _inspectdr_mapcolor(sp[:legend_background_color])
#_round!() ensures values use integer spacings (looks better on screen): #_round!() ensures values use integer spacings (looks better on screen):
InspectDR._round!(InspectDR.autofit2font!(l, legend_width = 10.0)) #10 "em"s wide InspectDR._round!(InspectDR.autofit2font!(l, legend_width = 10.0)) #10 "em"s wide
return return

View File

@ -141,9 +141,12 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
title_loc = sp[:titlelocation] title_loc = sp[:titlelocation]
bgc_inside = plot_color(sp[:background_color_inside]) bgc_inside = plot_color(sp[:background_color_inside])
bgc_inside_a = alpha(bgc_inside) bgc_inside_a = alpha(bgc_inside)
update_clims(sp)
axis_opt = PGFPlotsX.Options( axis_opt = PGFPlotsX.Options(
"point meta max" => get_clims(sp)[2], "point meta max" => get_clims(sp)[2],
"point meta min" => get_clims(sp)[1], "point meta min" => get_clims(sp)[1],
"legend cell align" => "left",
"legend columns" => pgfx_legend_col(sp[:legend_column]),
"title" => sp[:title], "title" => sp[:title],
"title style" => PGFPlotsX.Options( "title style" => PGFPlotsX.Options(
pgfx_get_title_pos(title_loc)..., pgfx_get_title_pos(title_loc)...,
@ -203,8 +206,8 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
if hascolorbar(sp) if hascolorbar(sp)
cticks = get_colorbar_ticks(sp)[2] cticks = get_colorbar_ticks(sp)[2]
colorbar_style = PGFPlotsX.Options("title" => sp[:colorbar_title])
if sp[:colorbar] === :top if sp[:colorbar] === :top
colorbar_style = PGFPlotsX.Options("xlabel" => sp[:colorbar_title])
push!( push!(
colorbar_style, colorbar_style,
"at" => string((0.5, 1.05)), "at" => string((0.5, 1.05)),
@ -214,6 +217,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
"xticklabel style" => pgfx_get_colorbar_ticklabel_style(sp), "xticklabel style" => pgfx_get_colorbar_ticklabel_style(sp),
) )
else else
colorbar_style = PGFPlotsX.Options("ylabel" => sp[:colorbar_title])
push!( push!(
colorbar_style, colorbar_style,
"ytick" => string("{", join(cticks, ","), "}"), "ytick" => string("{", join(cticks, ","), "}"),
@ -245,12 +249,18 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
extra_sp = wraptuple(extra_sp) extra_sp = wraptuple(extra_sp)
push!(axis, extra_sp...) push!(axis, extra_sp...)
end end
if sp[:legendtitle] !== nothing if sp[:legend_title] !== nothing
legtfont = legendtitlefont(sp)
push!(axis, PGFPlotsX.Options("\\addlegendimage{empty legend}" => nothing)) push!(axis, PGFPlotsX.Options("\\addlegendimage{empty legend}" => nothing))
push!( push!(
axis, axis,
PGFPlotsX.LegendEntry( PGFPlotsX.LegendEntry(
string("\\hspace{-.6cm}{\\textbf{", sp[:legendtitle], "}}"), PGFPlotsX.Options(
"font" =>
pgfx_font(legtfont.pointsize, pgfx_thickness_scaling(sp)),
"text" => legtfont.color,
),
string("\\hspace{-.6cm}{\\textbf{", sp[:legend_title], "}}"),
false, false,
), ),
) )
@ -375,11 +385,9 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
) )
end end
end end
if ( if i == 1 &&
k == 1 && series[:subplot][:legend_position] != :none &&
series[:subplot][:legend] != :none &&
pgfx_should_add_to_legend(series) pgfx_should_add_to_legend(series)
)
pgfx_filllegend!(series_opt, opt) pgfx_filllegend!(series_opt, opt)
end end
end end
@ -396,6 +404,9 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
), ),
), ),
) )
if opt[:label] == ""
push!(arrow_opt, "forget plot" => nothing)
end
if arrow.side == :head if arrow.side == :head
x_arrow = opt[:x][rng][(end - 1):end] x_arrow = opt[:x][rng][(end - 1):end]
y_arrow = opt[:y][rng][(end - 1):end] y_arrow = opt[:y][rng][(end - 1):end]
@ -419,6 +430,7 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
:v => [y_arrow[i] - y_arrow[i - 1] for i in 2:2:lastindex(y_arrow)], :v => [y_arrow[i] - y_arrow[i - 1] for i in 2:2:lastindex(y_arrow)],
]) ])
arrow_plot = series_func(merge(series_opt, arrow_opt), coordinates) arrow_plot = series_func(merge(series_opt, arrow_opt), coordinates)
push!(series_opt, "forget plot" => nothing)
push!(axis, arrow_plot) push!(axis, arrow_plot)
coordinates = PGFPlotsX.Table(x_path, y_path) coordinates = PGFPlotsX.Table(x_path, y_path)
segment_plot = series_func(merge(series_opt, segment_opt), coordinates) segment_plot = series_func(merge(series_opt, segment_opt), coordinates)
@ -512,10 +524,29 @@ function pgfx_add_series!(::Val{:heatmap}, axis, series_opt, series, series_func
end end
function pgfx_add_series!(::Val{:mesh3d}, axis, series_opt, series, series_func, opt) function pgfx_add_series!(::Val{:mesh3d}, axis, series_opt, series, series_func, opt)
if opt[:connections] isa Tuple{Array,Array,Array}
# 0-based indexing
ptable = join( ptable = join(
[string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)], [string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)],
"\n ", "\n ",
) )
elseif typeof(opt[:connections]) <: AbstractVector{NTuple{3,Int}}
# 1-based indexing
ptable = join(
[
string(i - 1, " ", j - 1, " ", k - 1, "\\\\") for
(i, j, k) in opt[:connections]
],
"\n ",
)
else
throw(
ArgumentError(
"Argument connections has to be either a tuple of three arrays (0-based indexing)
or an AbstractVector{NTuple{3,Int}} (1-based indexing).",
),
)
end
push!( push!(
series_opt, series_opt,
"patch" => nothing, "patch" => nothing,
@ -633,7 +664,7 @@ function pgfx_add_series!(::Val{:xsticks}, axis, series_opt, series, series_func
end end
function pgfx_add_legend!(axis, series, opt, i = 1) function pgfx_add_legend!(axis, series, opt, i = 1)
if series[:subplot][:legend] != :none if series[:subplot][:legend_position] != :none
leg_entry = if opt[:label] isa AVec leg_entry = if opt[:label] isa AVec
get(opt[:label], i, "") get(opt[:label], i, "")
elseif opt[:label] isa AbstractString elseif opt[:label] isa AbstractString
@ -780,22 +811,22 @@ function pgfx_get_legend_pos(v::Tuple{S,Symbol}) where {S<:Real}
end end
function pgfx_get_legend_style(sp) function pgfx_get_legend_style(sp)
cstr = plot_color(sp[:background_color_legend]) cstr = plot_color(sp[:legend_background_color])
a = alpha(cstr) a = alpha(cstr)
fg_alpha = alpha(plot_color(sp[:foreground_color_legend])) fg_alpha = alpha(plot_color(sp[:legend_foreground_color]))
legfont = legendfont(sp) legfont = legendfont(sp)
PGFPlotsX.Options( PGFPlotsX.Options(
pgfx_linestyle( pgfx_linestyle(
pgfx_thickness_scaling(sp), pgfx_thickness_scaling(sp),
sp[:foreground_color_legend], sp[:legend_foreground_color],
fg_alpha, fg_alpha,
"solid", "solid",
) => nothing, ) => nothing,
"fill" => cstr, "fill" => cstr,
"fill opacity" => a, "fill opacity" => a,
"text opacity" => alpha(plot_color(sp[:legendfontcolor])), "text opacity" => alpha(plot_color(sp[:legend_font_color])),
"font" => pgfx_font(sp[:legendfontsize], pgfx_thickness_scaling(sp)), "font" => pgfx_font(sp[:legend_font_pointsize], pgfx_thickness_scaling(sp)),
"text" => plot_color(sp[:legendfontcolor]), "text" => plot_color(sp[:legend_font_color]),
"cells" => PGFPlotsX.Options( "cells" => PGFPlotsX.Options(
"anchor" => get( "anchor" => get(
(left = "west", right = "east", hcenter = "center"), (left = "west", right = "east", hcenter = "center"),
@ -803,7 +834,7 @@ function pgfx_get_legend_style(sp)
"west", "west",
), ),
), ),
pgfx_get_legend_pos(sp[:legend])..., pgfx_get_legend_pos(sp[:legend_position])...,
) )
end end
@ -929,6 +960,9 @@ function pgfx_linestyle(linewidth::Real, color, α = 1, linestyle = :solid)
) )
end end
pgfx_legend_col(s::Symbol) = s == :horizontal ? -1 : 1
pgfx_legend_col(n) = n
function pgfx_linestyle(plotattributes, i = 1) function pgfx_linestyle(plotattributes, i = 1)
lw = pgfx_thickness_scaling(plotattributes) * get_linewidth(plotattributes, i) lw = pgfx_thickness_scaling(plotattributes) * get_linewidth(plotattributes, i)
lc = single_color(get_linecolor(plotattributes, i)) lc = single_color(get_linecolor(plotattributes, i))
@ -950,8 +984,7 @@ function pgfx_font(fontsize::Nothing, thickness_scaling = 1, font = "\\selectfon
end end
function pgfx_should_add_to_legend(series::Series) function pgfx_should_add_to_legend(series::Series)
series.plotattributes[:primary] && series.plotattributes[:primary] && !(
!(
series.plotattributes[:seriestype] in ( series.plotattributes[:seriestype] in (
:hexbin, :hexbin,
:bins2d, :bins2d,
@ -1174,6 +1207,12 @@ function pgfx_sanitize_plot!(plt)
end end
elseif value isa Union{AbstractString,AbstractVector{<:AbstractString}} elseif value isa Union{AbstractString,AbstractVector{<:AbstractString}}
subplot.attr[key] = pgfx_sanitize_string.(value) subplot.attr[key] = pgfx_sanitize_string.(value)
elseif value isa Axis
for (k, v) in value.plotattributes
if v isa Union{AbstractString,AbstractVector{<:AbstractString}}
value.plotattributes[k] = pgfx_sanitize_string.(v)
end
end
end end
end end
end end
@ -1192,9 +1231,21 @@ function pgfx_sanitize_plot!(plt)
end end
## ##
end end
function wrap_power_labels(ticks)
# wrap the power part of label with }
tick_labels = similar(ticks)
for (i, label) in enumerate(ticks)
base, power = split(label, "^")
power = string("{", power, "}")
tick_labels[i] = string(base, "^", power)
end
tick_labels
end
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter) function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
# turn off scaled ticks # turn off scaled ticks
push!(opt, "scaled $(letter) ticks" => "false", string(letter, :label) => axis[:guide]) push!(opt, "scaled $(letter) ticks" => "false", string(letter, :label) => axis[:guide])
@ -1232,6 +1283,12 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
opt, opt,
string(letter, "label style") => PGFPlotsX.Options( string(letter, "label style") => PGFPlotsX.Options(
labelpos => nothing, labelpos => nothing,
"at" => string(
"{(ticklabel cs:",
get((left = 0, right = 1), axis[:guidefonthalign], 0.5),
")}",
),
"anchor" => "near ticklabel",
"font" => pgfx_font(axis[:guidefontsize], pgfx_thickness_scaling(sp)), "font" => pgfx_font(axis[:guidefontsize], pgfx_thickness_scaling(sp)),
"color" => cstr, "color" => cstr,
"draw opacity" => α, "draw opacity" => α,
@ -1244,7 +1301,8 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
# scale # scale
scale = axis[:scale] scale = axis[:scale]
if scale in (:log2, :ln, :log10) is_log_scale = scale in (:ln, :log2, :log10)
if is_log_scale
push!(opt, string(letter, :mode) => "log") push!(opt, string(letter, :mode) => "log")
scale == :ln || push!(opt, "log basis $letter" => "$(scale == :log2 ? 2 : 10)") scale == :ln || push!(opt, "log basis $letter" => "$(scale == :log2 ? 2 : 10)")
end end
@ -1257,11 +1315,10 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
end end
# grid on or off # grid on or off
if axis[:grid] && framestyle != :none push!(
push!(opt, "$(letter)majorgrids" => "true") opt,
else "$(letter)majorgrids" => axis[:grid] && framestyle != :none ? "true" : "false",
push!(opt, "$(letter)majorgrids" => "false") )
end
# limits # limits
lims = lims =
@ -1277,23 +1334,22 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] : ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] :
ticks[1] ticks[1]
push!(opt, string(letter, "tick") => string("{", join(tick_values, ","), "}")) push!(opt, string(letter, "tick") => string("{", join(tick_values, ","), "}"))
if axis[:showaxis] && axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto if axis[:showaxis] && is_log_scale && axis[:ticks] == :auto
# wrap the power part of label with } tick_labels = wrap_power_labels(ticks[2])
tick_labels = Vector{String}(undef, length(ticks[2])) if tick_labels isa Vector{String}
for (i, label) in enumerate(ticks[2])
base, power = split(label, "^")
power = string("{", power, "}")
tick_labels[i] = string(base, "^", power)
end
push!( push!(
opt, opt,
string(letter, "ticklabels") => string(letter, "ticklabels") =>
string("{\$", join(tick_labels, "\$,\$"), "\$}"), string("{\$", join(tick_labels, "\$,\$"), "\$}"),
) )
elseif tick_labels isa Vector{LaTeXString}
push!(opt, string(letter, "ticklabels") => join(tick_labels))
end
elseif axis[:showaxis] elseif axis[:showaxis]
tick_labels = tick_labels =
ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2] ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2]
if axis[:formatter] in (:scientific, :auto) is_log_scale && (tick_labels = wrap_power_labels(tick_labels))
if axis[:formatter] in (:scientific, :auto) && tick_labels isa Vector{String}
tick_labels = string.("\$", convert_sci_unicode.(tick_labels), "\$") tick_labels = string.("\$", convert_sci_unicode.(tick_labels), "\$")
tick_labels = replace.(tick_labels, Ref("×" => "\\times")) tick_labels = replace.(tick_labels, Ref("×" => "\\times"))
end end
@ -1409,7 +1465,7 @@ end
# Set the (left, top, right, bottom) minimum padding around the plot area # Set the (left, top, right, bottom) minimum padding around the plot area
# to fit ticks, tick labels, guides, colorbars, etc. # to fit ticks, tick labels, guides, colorbars, etc.
function _update_min_padding!(sp::Subplot{PGFPlotsXBackend}) function _update_min_padding!(sp::Subplot{PGFPlotsXBackend})
leg = sp[:legend] leg = sp[:legend_position]
if leg in (:best, :outertopright, :outerright, :outerbottomright) || if leg in (:best, :outertopright, :outerright, :outerbottomright) ||
(leg isa Tuple && leg[1] >= 1) (leg isa Tuple && leg[1] >= 1)
sp.minpad = (0mm, 0mm, 5mm, 0mm) sp.minpad = (0mm, 0mm, 5mm, 0mm)

View File

@ -338,12 +338,12 @@ function plotly_layout(plt::Plot)
end end
function plotly_add_legend!(plotattributes_out::KW, sp::Subplot) function plotly_add_legend!(plotattributes_out::KW, sp::Subplot)
plotattributes_out[:showlegend] = sp[:legend] != :none plotattributes_out[:showlegend] = sp[:legend_position] != :none
legend_position = plotly_legend_pos(sp[:legend]) legend_position = plotly_legend_pos(sp[:legend_position])
if sp[:legend] != :none if sp[:legend_position] != :none
plotattributes_out[:legend] = KW( plotattributes_out[:legend_position] = KW(
:bgcolor => rgba_string(sp[:background_color_legend]), :bgcolor => rgba_string(sp[:legend_background_color]),
:bordercolor => rgba_string(sp[:foreground_color_legend]), :bordercolor => rgba_string(sp[:legend_foreground_color]),
:borderwidth => 1, :borderwidth => 1,
:traceorder => "normal", :traceorder => "normal",
:xanchor => legend_position.xanchor, :xanchor => legend_position.xanchor,
@ -353,7 +353,7 @@ function plotly_add_legend!(plotattributes_out::KW, sp::Subplot)
:x => legend_position.coords[1], :x => legend_position.coords[1],
:y => legend_position.coords[2], :y => legend_position.coords[2],
:title => KW( :title => KW(
:text => sp[:legendtitle] === nothing ? "" : string(sp[:legendtitle]), :text => sp[:legend_title] === nothing ? "" : string(sp[:legend_title]),
:font => plotly_font(legendtitlefont(sp)), :font => plotly_font(legendtitlefont(sp)),
), ),
) )
@ -362,6 +362,7 @@ end
function plotly_legend_pos(pos::Symbol) function plotly_legend_pos(pos::Symbol)
xleft = 0.07 xleft = 0.07
xright = 1.0
ybot = 0.07 ybot = 0.07
ytop = 1.0 ytop = 1.0
xcenter = 0.55 xcenter = 0.55
@ -372,14 +373,14 @@ function plotly_legend_pos(pos::Symbol)
xouterright = 1.05 xouterright = 1.05
xouterleft = -0.15 xouterleft = -0.15
plotly_legend_position_mapping = ( plotly_legend_position_mapping = (
right = (coords = [1.0, ycenter], xanchor = "right", yanchor = "middle"), right = (coords = [xright, ycenter], xanchor = "right", yanchor = "middle"),
left = (coords = [xleft, ycenter], xanchor = "left", yanchor = "middle"), left = (coords = [xleft, ycenter], xanchor = "left", yanchor = "middle"),
top = (coords = [xcenter, ytop], xanchor = "center", yanchor = "top"), top = (coords = [xcenter, ytop], xanchor = "center", yanchor = "top"),
bottom = (coords = [xcenter, ybot], xanchor = "center", yanchor = "bottom"), bottom = (coords = [xcenter, ybot], xanchor = "center", yanchor = "bottom"),
bottomleft = (coords = [xleft, ybot], xanchor = "left", yanchor = "bottom"), bottomleft = (coords = [xleft, ybot], xanchor = "left", yanchor = "bottom"),
bottomright = (coords = [1.0, ybot], xanchor = "right", yanchor = "bottom"), bottomright = (coords = [xright, ybot], xanchor = "right", yanchor = "bottom"),
topright = (coords = [1.0, 1.0], xanchor = "right", yanchor = "top"), topright = (coords = [xright, ytop], xanchor = "right", yanchor = "top"),
topleft = (coords = [xleft, 1.0], xanchor = "left", yanchor = "top"), topleft = (coords = [xleft, ytop], xanchor = "left", yanchor = "top"),
outertop = (coords = [center, youtertop], xanchor = "upper", yanchor = "middle"), outertop = (coords = [center, youtertop], xanchor = "upper", yanchor = "middle"),
outerbottom = (coords = [center, youterbot], xanchor = "lower", yanchor = "middle"), outerbottom = (coords = [center, youterbot], xanchor = "lower", yanchor = "middle"),
outerleft = (coords = [xouterleft, center], xanchor = "left", yanchor = "top"), outerleft = (coords = [xouterleft, center], xanchor = "left", yanchor = "top"),
@ -400,7 +401,7 @@ function plotly_legend_pos(pos::Symbol)
xanchor = "lower", xanchor = "lower",
yanchor = "right", yanchor = "right",
), ),
default = (coords = [1.0, 1.0], xanchor = "auto", yanchor = "auto"), default = (coords = [xright, ytop], xanchor = "auto", yanchor = "auto"),
) )
legend_position = legend_position =
@ -499,7 +500,7 @@ function plotly_close_shapes(x, y)
end end
function plotly_data(series::Series, letter::Symbol, data) function plotly_data(series::Series, letter::Symbol, data)
axis = series[:subplot][Symbol(letter, :axis)] axis = series[:subplot][get_attr_symbol(letter, :axis)]
data = if axis[:ticks] == :native && data !== nothing data = if axis[:ticks] == :native && data !== nothing
plotly_native_data(axis, data) plotly_native_data(axis, data)
@ -678,6 +679,7 @@ function plotly_series(plt::Plot, series::Series)
if series[:connections] !== nothing if series[:connections] !== nothing
if typeof(series[:connections]) <: Tuple{Array,Array,Array} if typeof(series[:connections]) <: Tuple{Array,Array,Array}
# 0-based indexing
i, j, k = series[:connections] i, j, k = series[:connections]
if !(length(i) == length(j) == length(k)) if !(length(i) == length(j) == length(k))
throw( throw(
@ -689,10 +691,20 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out[:i] = i plotattributes_out[:i] = i
plotattributes_out[:j] = j plotattributes_out[:j] = j
plotattributes_out[:k] = k plotattributes_out[:k] = k
elseif typeof(series[:connections]) <: AbstractVector{NTuple{3,Int}}
# 1-based indexing
i, j, k = broadcast(
i -> [inds[i] - 1 for inds in series[:connections]],
(1, 2, 3),
)
plotattributes_out[:i] = i
plotattributes_out[:j] = j
plotattributes_out[:k] = k
else else
throw( throw(
ArgumentError( ArgumentError(
"Argument connections has to be a tuple of three arrays.", "Argument connections has to be either a tuple of three arrays (0-based indexing)
or an AbstractVector{NTuple{3,Int}} (1-based indexing).",
), ),
) )
end end
@ -740,14 +752,14 @@ function plotly_series(plt::Plot, series::Series)
end end
plotly_polar!(plotattributes_out, series) plotly_polar!(plotattributes_out, series)
plotly_hover!(plotattributes_out, series[:hover]) plotly_adjust_hover_label!(plotattributes_out, series[:hover])
return [plotattributes_out] return [merge(plotattributes_out, series[:extra_kwargs])]
end end
function plotly_series_shapes(plt::Plot, series::Series, clims) function plotly_series_shapes(plt::Plot, series::Series, clims)
segments = series_segments(series; check = true) segments = series_segments(series; check = true)
plotattributes_outs = Vector{KW}(undef, length(segments)) plotattributes_outs = [KW() for _ in 1:length(segments)]
# TODO: create a plotattributes_out for each polygon # TODO: create a plotattributes_out for each polygon
# x, y = series[:x], series[:y] # x, y = series[:x], series[:y]
@ -795,8 +807,8 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
end end
plotattributes_out[:showlegend] = k == 1 ? should_add_to_legend(series) : false plotattributes_out[:showlegend] = k == 1 ? should_add_to_legend(series) : false
plotly_polar!(plotattributes_out, series) plotly_polar!(plotattributes_out, series)
plotly_hover!(plotattributes_out, _cycle(series[:hover], i)) plotly_adjust_hover_label!(plotattributes_out, _cycle(series[:hover], i))
plotattributes_outs[k] = plotattributes_out plotattributes_outs[k] = merge(plotattributes_out, series[:extra_kwargs])
end end
if series[:fill_z] !== nothing if series[:fill_z] !== nothing
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill)) push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill))
@ -919,7 +931,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
end end
plotly_polar!(plotattributes_out, series) plotly_polar!(plotattributes_out, series)
plotly_hover!(plotattributes_out, _cycle(series[:hover], rng)) plotly_adjust_hover_label!(plotattributes_out, _cycle(series[:hover], rng))
if hasfillrange if hasfillrange
# if hasfillrange is true, return two dictionaries (one for original # if hasfillrange is true, return two dictionaries (one for original
@ -928,7 +940,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
plotattributes_out_fillrange[:showlegend] = false plotattributes_out_fillrange[:showlegend] = false
# if fillrange is provided as real or tuple of real, expand to array # if fillrange is provided as real or tuple of real, expand to array
if typeof(series[:fillrange]) <: Real if typeof(series[:fillrange]) <: Real
series[:fillrange] = fill(series[:fillrange], length(rng)) plotattributes_out[:fillrange] = fill(series[:fillrange], length(rng))
elseif typeof(series[:fillrange]) <: Tuple elseif typeof(series[:fillrange]) <: Tuple
f1 = f1 =
typeof(series[:fillrange][1]) <: Real ? typeof(series[:fillrange][1]) <: Real ?
@ -936,7 +948,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
f2 = f2 =
typeof(series[:fillrange][2]) <: Real ? typeof(series[:fillrange][2]) <: Real ?
fill(series[:fillrange][2], length(rng)) : series[:fillrange][2][rng] fill(series[:fillrange][2], length(rng)) : series[:fillrange][2][rng]
series[:fillrange] = (f1, f2) plotattributes_out[:fillrange] = (f1, f2)
end end
if isa(series[:fillrange], AbstractVector) if isa(series[:fillrange], AbstractVector)
plotattributes_out_fillrange[:y] = series[:fillrange][rng] plotattributes_out_fillrange[:y] = series[:fillrange][rng]
@ -957,6 +969,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
else else
plotattributes_outs[k] = plotattributes_out plotattributes_outs[k] = plotattributes_out
end end
plotattributes_outs[k] = merge(plotattributes_outs[k], series[:extra_kwargs])
end end
if series[:line_z] !== nothing if series[:line_z] !== nothing
@ -1001,28 +1014,30 @@ function plotly_polar!(plotattributes_out::KW, series::Series)
# convert polar plots x/y to theta/radius # convert polar plots x/y to theta/radius
if ispolar(series[:subplot]) if ispolar(series[:subplot])
theta, r = pop!(plotattributes_out, :x), pop!(plotattributes_out, :y) theta, r = pop!(plotattributes_out, :x), pop!(plotattributes_out, :y)
plotattributes_out[:t] = rad2deg.(theta) plotattributes_out[:theta] = rad2deg.(theta)
plotattributes_out[:r] = r plotattributes_out[:r] = r
plotattributes_out[:type] = :scatterpolar
end end
end end
function plotly_hover!(plotattributes_out::KW, hover) function plotly_adjust_hover_label!(plotattributes_out::KW, hover)
# hover text if hover === nothing
if hover === nothing || all(in([:none, false]), hover) return nothing
elseif all(in([:none, false]), hover)
plotattributes_out[:hoverinfo] = "none" plotattributes_out[:hoverinfo] = "none"
elseif any(!isnothing, hover) elseif any(!isnothing, hover)
plotattributes_out[:hoverinfo] = "text" plotattributes_out[:hoverinfo] = "text"
plotattributes_out[:text] = hover plotattributes_out[:text] = hover
end end
return nothing
end end
# get a list of dictionaries, each representing the series params # get a list of dictionaries, each representing the series params
function plotly_series(plt::Plot) function plotly_series(plt::Plot)
slist = [] if isempty(plt.series_list)
for series in plt.series_list return KW[]
append!(slist, plotly_series(plt, series))
end end
slist reduce(vcat, plotly_series(plt, series) for series in plt.series_list)
end end
# get json string for a list of dictionaries, each representing the series params # get json string for a list of dictionaries, each representing the series params
@ -1092,16 +1107,12 @@ end
function js_body(plt::Plot, uuid) function js_body(plt::Plot, uuid)
js = """ js = """
var PLOT = document.getElementById('$(uuid)'); Plotly.newPlot('$(uuid)', $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
""" """
end end
function plotly_show_js(io::IO, plot::Plot) function plotly_show_js(io::IO, plot::Plot)
data = [] data = plotly_series(plot)
for series in plot.series_list
append!(data, plotly_series(plot, series))
end
layout = plotly_layout(plot) layout = plotly_layout(plot)
JSON.print(io, Dict(:data => data, :layout => layout)) JSON.print(io, Dict(:data => data, :layout => layout))
end end

View File

@ -8,6 +8,7 @@ function plotlyjs_syncplot(plt::Plot{PlotlyJSBackend})
traces = PlotlyJS.GenericTrace[] traces = PlotlyJS.GenericTrace[]
for series_dict in plotly_series(plt) for series_dict in plotly_series(plt)
plotly_type = pop!(series_dict, :type) plotly_type = pop!(series_dict, :type)
series_dict[:transpose] = false
push!(traces, PlotlyJS.GenericTrace(plotly_type; series_dict...)) push!(traces, PlotlyJS.GenericTrace(plotly_type; series_dict...))
end end
PlotlyJS.addtraces!(plt.o, traces...) PlotlyJS.addtraces!(plt.o, traces...)

View File

@ -24,11 +24,30 @@ pycollections = PyPlot.pyimport("matplotlib.collections")
pyart3d = PyPlot.art3D pyart3d = PyPlot.art3D
pyrcparams = PyPlot.PyDict(PyPlot.matplotlib."rcParams") pyrcparams = PyPlot.PyDict(PyPlot.matplotlib."rcParams")
# "support" matplotlib v1.5 # "support" matplotlib v3.4
if PyPlot.version < v"3.4"
@warn("""You are using Matplotlib $(PyPlot.version), which is no longer
officialy supported by the Plots community. To ensure smooth Plots.jl
integration update your Matplotlib library to a version >= 3.4.0
If you have used Conda.jl to install PyPlot (default installation),
upgrade your matplotlib via Conda.jl and rebuild the PyPlot.
If you are not sure, here are the default instructions:
In Julia REPL:
```
import Pkg;
Pkg.add("Conda")
import Conda
Conda.update()
Pkg.build("PyPlot")
```
""")
end
set_facecolor_sym = if PyPlot.version < v"2" set_facecolor_sym = if PyPlot.version < v"2"
@warn(
"You are using Matplotlib $(PyPlot.version), which is no longer officialy supported by the Plots community. To ensure smooth Plots.jl integration update your Matplotlib library to a version >= 2.0.0"
)
:set_axis_bgcolor :set_axis_bgcolor
else else
:set_facecolor :set_facecolor
@ -60,6 +79,14 @@ end
# # anything else just gets a bluesred gradient # # anything else just gets a bluesred gradient
# py_colormap(c, α=nothing) = py_colormap(default_gradient(), α) # py_colormap(c, α=nothing) = py_colormap(default_gradient(), α)
for k in (:linthresh, :base, :label)
# add PyPlot specific symbols to cache
_attrsymbolcache[k] = Dict{Symbol,Symbol}()
for letter in (:x, :y, :z, Symbol(""), :top, :bottom, :left, :right)
_attrsymbolcache[k][letter] = Symbol(k, letter)
end
end
py_handle_surface(v) = v py_handle_surface(v) = v
py_handle_surface(z::Surface) = z.surf py_handle_surface(z::Surface) = z.surf
@ -162,6 +189,25 @@ function py_fillstepstyle(seriestype::Symbol)
return nothing return nothing
end end
py_fillstyle(::Nothing) = nothing
py_fillstyle(fillstyle::Symbol) = string(fillstyle)
function py_get_matching_math_font(parent_fontfamily)
# matplotlib supported math fonts according to
# https://matplotlib.org/stable/tutorials/text/mathtext.html
py_math_supported_fonts = Dict{String,String}(
"sans-serif" => "dejavusans",
"serif" => "dejavuserif",
"cm" => "cm",
"stix" => "stix",
"stixsans" => "stixsans",
)
# Fallback to "dejavusans" or "dejavuserif" in case the parentfont is different
# from supported by matplotlib fonts
matching_font(font) = occursin("serif", lowercase(font)) ? "dejavuserif" : "dejavusans"
return get(py_math_supported_fonts, parent_fontfamily, matching_font(parent_fontfamily))
end
# # untested... return a FontProperties object from a Plots.Font # # untested... return a FontProperties object from a Plots.Font
# function py_font(font::Font) # function py_font(font::Font)
# pyfont["FontProperties"]( # pyfont["FontProperties"](
@ -652,6 +698,50 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end end
end end
if st == :mesh3d
polygons = if series[:connections] isa AbstractVector{<:AbstractVector{Int}}
# Combination of any polygon types
broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections])
elseif series[:connections] isa AbstractVector{NTuple{N,Int}} where {N}
# Only N-gons - connections have to be 1-based (indexing)
broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections])
elseif series[:connections] isa NTuple{3,<:AbstractVector{Int}}
# Only triangles - connections have to be 0-based (indexing)
ci, cj, ck = series[:connections]
if !(length(ci) == length(cj) == length(ck))
throw(
ArgumentError(
"Argument connections must consist of equally sized arrays.",
),
)
end
broadcast(
j -> broadcast(i -> [x[i], y[i], z[i]], [ci[j] + 1, cj[j] + 1, ck[j] + 1]),
eachindex(ci),
)
else
throw(
ArgumentError(
"Unsupported `:connections` type $(typeof(series[:connections])) for seriestype=$st",
),
)
end
col = mplot3d.art3d.Poly3DCollection(
polygons,
linewidths = py_thickness_scale(plt, series[:linewidth]),
edgecolor = py_color(get_linecolor(series)),
facecolor = py_color(series[:fillcolor]),
alpha = get_fillalpha(series),
zorder = series[:series_plotindex],
)
handle = ax."add_collection3d"(col)
# Fix for handle: https://stackoverflow.com/questions/54994600/pyplot-legend-poly3dcollection-object-has-no-attribute-edgecolors2d
# It seems there aren't two different alpha values for edge and face
handle._facecolors2d = py_color(series[:fillcolor])
handle._edgecolors2d = py_color(get_linecolor(series))
push!(handles, handle)
end
if st == :image if st == :image
xmin, xmax = ignorenan_extrema(series[:x]) xmin, xmax = ignorenan_extrema(series[:x])
ymin, ymax = ignorenan_extrema(series[:y]) ymin, ymax = ignorenan_extrema(series[:y])
@ -709,24 +799,45 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
for segment in series_segments(series) for segment in series_segments(series)
i, rng = segment.attr_index, segment.range i, rng = segment.attr_index, segment.range
if length(rng) > 1 if length(rng) > 1
lc = get_linecolor(series, clims, i)
la = get_linealpha(series, i)
ls = get_linestyle(series, i)
fc = get_fillcolor(series, clims, i)
fa = get_fillalpha(series, i)
fs = get_fillstyle(series, i)
has_fs = !isnothing(fs)
path = pypath."Path"(hcat(x[rng], y[rng])) path = pypath."Path"(hcat(x[rng], y[rng]))
# shape outline (and potentially solid fill)
patches = pypatches."PathPatch"( patches = pypatches."PathPatch"(
path; path;
label = series[:label], label = series[:label],
zorder = series[:series_plotindex], zorder = series[:series_plotindex],
edgecolor = py_color( edgecolor = py_color(lc, la),
get_linecolor(series, clims, i), facecolor = py_color(fc, has_fs ? 0 : fa),
get_linealpha(series, i),
),
facecolor = py_color(
get_fillcolor(series, clims, i),
get_fillalpha(series, i),
),
linewidth = py_thickness_scale(plt, get_linewidth(series, i)), linewidth = py_thickness_scale(plt, get_linewidth(series, i)),
linestyle = py_linestyle(st, get_linestyle(series, i)), linestyle = py_linestyle(st, ls),
fill = true, fill = !has_fs,
) )
push!(handle, ax."add_patch"(patches)) push!(handle, ax."add_patch"(patches))
# shape hatched fill
# hatch color/alpha are controlled by edge (not face) color/alpha
if has_fs
patches = pypatches."PathPatch"(
path;
label = "",
zorder = series[:series_plotindex],
edgecolor = py_color(fc, fa),
facecolor = py_color(fc, 0), # don't fill with solid background
hatch = py_fillstyle(fs),
linewidth = 0, # don't replot shape outline (doesn't affect hatch linewidth)
linestyle = py_linestyle(st, ls),
fill = false,
)
push!(handle, ax."add_patch"(patches))
end
end end
end end
push!(handles, handle) push!(handles, handle)
@ -754,16 +865,23 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng) dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng)
end end
la = get_linealpha(series, i)
fc = get_fillcolor(series, clims, i)
fa = get_fillalpha(series, i)
fs = get_fillstyle(series, i)
has_fs = !isnothing(fs)
handle = getproperty(ax, f)( handle = getproperty(ax, f)(
args..., args...,
trues(n), trues(n),
false, false,
py_fillstepstyle(st); py_fillstepstyle(st);
zorder = series[:series_plotindex], zorder = series[:series_plotindex],
facecolor = py_color( # hatch color/alpha are controlled by edge (not face) color/alpha
get_fillcolor(series, clims, i), # if has_fs, set edge color/alpha <- fill color/alpha and face alpha <- 0
get_fillalpha(series, i), edgecolor = py_color(fc, has_fs ? fa : la),
), facecolor = py_color(fc, has_fs ? 0 : fa),
hatch = py_fillstyle(fs),
linewidths = 0, linewidths = 0,
) )
push!(handles, handle) push!(handles, handle)
@ -785,22 +903,13 @@ function py_set_lims(ax, sp::Subplot, axis::Axis)
getproperty(ax, Symbol("set_", letter, "lim"))(lfrom, lto) getproperty(ax, Symbol("set_", letter, "lim"))(lfrom, lto)
end end
function py_surround_latextext(latexstring, env) function py_set_ticks(sp, ax, ticks, letter)
if !isempty(latexstring) && latexstring[1] == '$' && latexstring[end] == '$'
unenclosed = latexstring[2:(end - 1)]
else
unenclosed = latexstring
end
PyPlot.LaTeXStrings.latexstring(env, "{", unenclosed, "}")
end
function py_set_ticks(sp, ax, ticks, letter, env)
ticks == :auto && return ticks == :auto && return
axis = getproperty(ax, Symbol(letter, "axis")) axis = getproperty(ax, get_attr_symbol(letter, :axis))
if ticks == :none || ticks === nothing || ticks == false if ticks == :none || ticks === nothing || ticks == false
kw = KW() kw = KW()
for dir in (:top, :bottom, :left, :right) for dir in (:top, :bottom, :left, :right)
kw[dir] = kw[Symbol(:label, dir)] = false kw[dir] = kw[get_attr_symbol(:label, dir)] = false
end end
axis."set_tick_params"(; which = "both", kw...) axis."set_tick_params"(; which = "both", kw...)
return return
@ -811,14 +920,7 @@ function py_set_ticks(sp, ax, ticks, letter, env)
axis."set_ticks"(ticks) axis."set_ticks"(ticks)
elseif ttype == :ticks_and_labels elseif ttype == :ticks_and_labels
axis."set_ticks"(ticks[1]) axis."set_ticks"(ticks[1])
axis."set_ticklabels"(ticks[2])
if get(sp[:extra_kwargs], :rawticklabels, false)
tick_labels = ticks[2]
else
tick_labels = [py_surround_latextext(ticklabel, env) for ticklabel in ticks[2]]
end
axis."set_ticklabels"(tick_labels)
else else
error("Invalid input for $(letter)ticks: $ticks") error("Invalid input for $(letter)ticks: $ticks")
end end
@ -856,15 +958,15 @@ function py_set_scale(ax, sp::Subplot, scale::Symbol, letter::Symbol)
arg = if scale == :identity arg = if scale == :identity
"linear" "linear"
else else
kw[Symbol(:base, pyletter)] = if scale == :ln kw[get_attr_symbol(:base, pyletter)] = if scale == :ln
elseif scale == :log2 elseif scale == :log2
2 2
elseif scale == :log10 elseif scale == :log10
10 10
end end
axis = sp[Symbol(letter, :axis)] axis = sp[get_attr_symbol(letter, :axis)]
kw[Symbol(:linthresh, pyletter)] = kw[get_attr_symbol(:linthresh, pyletter)] =
NaNMath.max(1e-16, py_compute_axis_minval(sp, axis)) NaNMath.max(1e-16, py_compute_axis_minval(sp, axis))
"symlog" "symlog"
end end
@ -879,7 +981,7 @@ end
function py_set_spine_color(spines, color) function py_set_spine_color(spines, color)
for loc in spines for loc in spines
spines[loc]."set_color"(color) getproperty(spines, loc)."set_color"(color)
end end
end end
@ -891,7 +993,7 @@ end
function py_set_axis_colors(sp, ax, a::Axis) function py_set_axis_colors(sp, ax, a::Axis)
py_set_spine_color(ax.spines, py_color(a[:foreground_color_border])) py_set_spine_color(ax.spines, py_color(a[:foreground_color_border]))
axissym = Symbol(a[:letter], :axis) axissym = get_attr_symbol(a[:letter], :axis)
if PyPlot.PyCall.hasproperty(ax, axissym) if PyPlot.PyCall.hasproperty(ax, axissym)
tickcolor = tickcolor =
sp[:framestyle] in (:zerolines, :grid) ? sp[:framestyle] in (:zerolines, :grid) ?
@ -959,6 +1061,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
py_thickness_scale(plt, sp[:titlefontsize]), py_thickness_scale(plt, sp[:titlefontsize]),
) )
getproperty(ax, func)."set_family"(sp[:titlefontfamily]) getproperty(ax, func)."set_family"(sp[:titlefontfamily])
getproperty(ax, func)."set_math_fontfamily"(
py_get_matching_math_font(sp[:titlefontfamily]),
)
getproperty(ax, func)."set_color"(py_color(sp[:titlefontcolor])) getproperty(ax, func)."set_color"(py_color(sp[:titlefontcolor]))
# ax[:set_title](sp[:title], loc = loc) # ax[:set_title](sp[:title], loc = loc)
end end
@ -1051,6 +1156,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
sp[:colorbar_title], sp[:colorbar_title],
size = py_thickness_scale(plt, sp[:colorbar_titlefontsize]), size = py_thickness_scale(plt, sp[:colorbar_titlefontsize]),
family = sp[:colorbar_titlefontfamily], family = sp[:colorbar_titlefontfamily],
math_fontfamily = py_get_matching_math_font(sp[:colorbar_titlefontfamily]),
color = py_color(sp[:colorbar_titlefontcolor]), color = py_color(sp[:colorbar_titlefontcolor]),
) )
@ -1058,9 +1164,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
cb."formatter".set_powerlimits((-Inf, Inf)) cb."formatter".set_powerlimits((-Inf, Inf))
cb."update_ticks"() cb."update_ticks"()
env = "\\mathregular" # matches the outer fonts https://matplotlib.org/tutorials/text/mathtext.html
ticks = get_colorbar_ticks(sp) ticks = get_colorbar_ticks(sp)
if sp[:colorbar] in (:top, :bottom) if sp[:colorbar] in (:top, :bottom)
axis = sp[:xaxis] # colorbar inherits from x axis axis = sp[:xaxis] # colorbar inherits from x axis
cbar_axis = cb."ax"."xaxis" cbar_axis = cb."ax"."xaxis"
@ -1072,11 +1176,14 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
end end
py_set_scale(cb.ax, sp, sp[:colorbar_scale], ticks_letter) py_set_scale(cb.ax, sp, sp[:colorbar_scale], ticks_letter)
sp[:colorbar_ticks] == :native ? nothing : sp[:colorbar_ticks] == :native ? nothing :
py_set_ticks(sp, cb.ax, ticks, ticks_letter, env) py_set_ticks(sp, cb.ax, ticks, ticks_letter)
for lab in cbar_axis."get_ticklabels"() for lab in cbar_axis."get_ticklabels"()
lab."set_fontsize"(py_thickness_scale(plt, sp[:colorbar_tickfontsize])) lab."set_fontsize"(py_thickness_scale(plt, sp[:colorbar_tickfontsize]))
lab."set_family"(sp[:colorbar_tickfontfamily]) lab."set_family"(sp[:colorbar_tickfontfamily])
lab."set_math_fontfamily"(
py_get_matching_math_font(sp[:colorbar_tickfontfamily]),
)
lab."set_color"(py_color(sp[:colorbar_tickfontcolor])) lab."set_color"(py_color(sp[:colorbar_tickfontcolor]))
end end
@ -1099,7 +1206,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
if !ispolar(sp) && !RecipesPipeline.is3d(sp) if !ispolar(sp) && !RecipesPipeline.is3d(sp)
for pos in ("left", "right", "top", "bottom") for pos in ("left", "right", "top", "bottom")
# Scale all axes by default first # Scale all axes by default first
ax.spines[pos]."set_linewidth"(py_thickness_scale(plt, 1)) getproperty(ax.spines, pos)."set_linewidth"(py_thickness_scale(plt, 1))
end end
# Then set visible some of them # Then set visible some of them
@ -1107,28 +1214,32 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
intensity = 0.5 intensity = 0.5
spine = sp[:yaxis][:mirror] ? "left" : "right" spine = sp[:yaxis][:mirror] ? "left" : "right"
ax.spines[spine]."set_alpha"(intensity) getproperty(ax.spines, spine)."set_alpha"(intensity)
ax.spines[spine]."set_linewidth"(py_thickness_scale(plt, intensity)) getproperty(ax.spines, spine)."set_linewidth"(
py_thickness_scale(plt, intensity),
)
spine = sp[:xaxis][:mirror] ? "bottom" : "top" spine = sp[:xaxis][:mirror] ? "bottom" : "top"
ax.spines[spine]."set_linewidth"(py_thickness_scale(plt, intensity)) getproperty(ax.spines, spine)."set_linewidth"(
ax.spines[spine]."set_alpha"(intensity) py_thickness_scale(plt, intensity),
)
getproperty(ax.spines, spine)."set_alpha"(intensity)
elseif sp[:framestyle] == :box elseif sp[:framestyle] == :box
ax.tick_params(top = true) # Add ticks too ax.tick_params(top = true) # Add ticks too
ax.tick_params(right = true) # Add ticks too ax.tick_params(right = true) # Add ticks too
elseif sp[:framestyle] in (:axes, :origin) elseif sp[:framestyle] in (:axes, :origin)
sp[:xaxis][:mirror] ? ax.spines["bottom"]."set_visible"(false) : sp[:xaxis][:mirror] ? ax.spines."bottom"."set_visible"(false) :
ax.spines["top"]."set_visible"(false) ax.spines."top"."set_visible"(false)
sp[:yaxis][:mirror] ? ax.spines["left"]."set_visible"(false) : sp[:yaxis][:mirror] ? ax.spines."left"."set_visible"(false) :
ax.spines["right"]."set_visible"(false) ax.spines."right"."set_visible"(false)
if sp[:framestyle] == :origin if sp[:framestyle] == :origin
ax.spines["bottom"]."set_position"("zero") ax.spines."bottom"."set_position"("zero")
ax.spines["left"]."set_position"("zero") ax.spines."left"."set_position"("zero")
end end
elseif sp[:framestyle] in (:grid, :none, :zerolines) elseif sp[:framestyle] in (:grid, :none, :zerolines)
if PyPlot.version >= v"3.4.1" # that is one where it worked, the API change may have some other value if PyPlot.version >= v"3.4.1" # that is one where it worked, the API change may have some other value
for spine in ax.spines for spine in ax.spines
ax.spines[string(spine)]."set_visible"(false) getproperty(ax.spines, string(spine))."set_visible"(false)
end end
else else
for (loc, spine) in ax.spines for (loc, spine) in ax.spines
@ -1162,7 +1273,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# axis attributes # axis attributes
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
axissym = Symbol(letter, :axis) axissym = get_attr_symbol(letter, :axis)
PyPlot.PyCall.hasproperty(ax, axissym) || continue PyPlot.PyCall.hasproperty(ax, axissym) || continue
axis = sp[axissym] axis = sp[axissym]
pyaxis = getproperty(ax, axissym) pyaxis = getproperty(ax, axissym)
@ -1172,7 +1283,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
end end
py_set_scale(ax, sp, axis) py_set_scale(ax, sp, axis)
axis[:ticks] == :native ? nothing : py_set_lims(ax, sp, axis) py_set_lims(ax, sp, axis)
if ispolar(sp) && letter == :y if ispolar(sp) && letter == :y
ax."set_rlabel_position"(90) ax."set_rlabel_position"(90)
end end
@ -1186,6 +1297,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
fontProperties = PyPlot.PyCall.PyDict( fontProperties = PyPlot.PyCall.PyDict(
Dict( Dict(
"family" => axis[:tickfontfamily], "family" => axis[:tickfontfamily],
# "math_fontfamily" =>
# py_get_matching_math_font(axis[:tickfontfamily]),
"size" => py_thickness_scale(plt, axis[:tickfontsize]), "size" => py_thickness_scale(plt, axis[:tickfontsize]),
"rotation" => axis[:tickfontrotation], "rotation" => axis[:tickfontrotation],
), ),
@ -1205,10 +1318,14 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
) )
end end
# workaround to set mathtext.fontspec per Text element py_set_ticks(sp, ax, ticks, letter)
env = "\\mathregular" # matches the outer fonts https://matplotlib.org/tutorials/text/mathtext.html
if axis[:ticks] == :native # It is easier to reset than to account for this
py_set_lims(ax, sp, axis)
pyaxis.set_major_locator(pyticker.AutoLocator())
pyaxis.set_major_formatter(pyticker.ScalarFormatter())
end
axis[:ticks] == :native ? nothing : py_set_ticks(sp, ax, ticks, letter, env)
# Tick marks # Tick marks
intensity = 0.5 # This value corresponds to scaling of other grid elements intensity = 0.5 # This value corresponds to scaling of other grid elements
pyaxis."set_tick_params"( pyaxis."set_tick_params"(
@ -1224,6 +1341,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
end end
pyaxis."label"."set_fontsize"(py_thickness_scale(plt, axis[:guidefontsize])) pyaxis."label"."set_fontsize"(py_thickness_scale(plt, axis[:guidefontsize]))
pyaxis."label"."set_family"(axis[:guidefontfamily]) pyaxis."label"."set_family"(axis[:guidefontfamily])
pyaxis."label"."set_math_fontfamily"(
py_get_matching_math_font(axis[:guidefontfamily]),
)
if (RecipesPipeline.is3d(sp)) if (RecipesPipeline.is3d(sp))
pyaxis."set_rotate_label"(false) pyaxis."set_rotate_label"(false)
@ -1290,13 +1410,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
if !sp[:xaxis][:showaxis] if !sp[:xaxis][:showaxis]
kw = KW() kw = KW()
if ispolar(sp) if ispolar(sp)
ax.spines["polar"].set_visible(false) ax.spines."polar".set_visible(false)
end end
for dir in (:top, :bottom) for dir in (:top, :bottom)
if !ispolar(sp) if !ispolar(sp)
ax.spines[string(dir)].set_visible(false) getproperty(ax.spines, string(dir)).set_visible(false)
end end
kw[dir] = kw[Symbol(:label, dir)] = false kw[dir] = kw[get_attr_symbol(:label, dir)] = false
end end
ax."xaxis"."set_tick_params"(; which = "both", kw...) ax."xaxis"."set_tick_params"(; which = "both", kw...)
end end
@ -1304,9 +1424,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
kw = KW() kw = KW()
for dir in (:left, :right) for dir in (:left, :right)
if !ispolar(sp) if !ispolar(sp)
ax.spines[string(dir)].set_visible(false) getproperty(ax.spines, string(dir)).set_visible(false)
end end
kw[dir] = kw[Symbol(:label, dir)] = false kw[dir] = kw[get_attr_symbol(:label, dir)] = false
end end
ax."yaxis"."set_tick_params"(; which = "both", kw...) ax."yaxis"."set_tick_params"(; which = "both", kw...)
end end
@ -1446,7 +1566,7 @@ end
py_legend_bbox(pos) = pos py_legend_bbox(pos) = pos
function py_add_legend(plt::Plot, sp::Subplot, ax) function py_add_legend(plt::Plot, sp::Subplot, ax)
leg = sp[:legend] leg = sp[:legend_position]
if leg != :none if leg != :none
# gotta do this to ensure both axes are included # gotta do this to ensure both axes are included
labels = [] labels = []
@ -1455,32 +1575,50 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
if should_add_to_legend(series) if should_add_to_legend(series)
clims = get_clims(sp, series) clims = get_clims(sp, series)
# add a line/marker and a label # add a line/marker and a label
push!(
handles,
if series[:seriestype] == :shape || series[:fillrange] !== nothing if series[:seriestype] == :shape || series[:fillrange] !== nothing
pypatches."Patch"( lc = get_linecolor(series, clims)
edgecolor = py_color( la = get_linealpha(series)
single_color(get_linecolor(series, clims)), ls = get_linestyle(series)
get_linealpha(series), fc = get_fillcolor(series, clims)
), fa = get_fillalpha(series)
facecolor = py_color( fs = get_fillstyle(series)
single_color(get_fillcolor(series, clims)), has_fs = !isnothing(fs)
get_fillalpha(series),
), # line (and potentially solid fill)
line_handle = pypatches."Patch"(
edgecolor = py_color(single_color(lc), la),
facecolor = py_color(single_color(fc), has_fs ? 0 : fa),
linewidth = py_thickness_scale( linewidth = py_thickness_scale(
plt, plt,
clamp(get_linewidth(series), 0, 5), clamp(get_linewidth(series), 0, 5),
), ),
linestyle = py_linestyle( linestyle = py_linestyle(series[:seriestype], ls),
series[:seriestype],
get_linestyle(series),
),
capstyle = "butt", capstyle = "butt",
) )
# hatched fill
# hatch color/alpha are controlled by edge (not face) color/alpha
if has_fs
fill_handle = pypatches."Patch"(
edgecolor = py_color(single_color(fc), fa),
facecolor = py_color(single_color(fc), 0), # don't fill with solid background
hatch = py_fillstyle(fs),
linewidth = 0, # don't replot shape outline (doesn't affect hatch linewidth)
linestyle = py_linestyle(series[:seriestype], ls),
capstyle = "butt",
)
# plot two handles on top of each other by passing in a tuple
# https://matplotlib.org/stable/tutorials/intermediate/legend_guide.html
push!(handles, (line_handle, fill_handle))
else
# plot line handle (which includes solid fill) only
push!(handles, line_handle)
end
elseif series[:seriestype] in elseif series[:seriestype] in
(:path, :straightline, :scatter, :steppre, :stepmid, :steppost) (:path, :straightline, :scatter, :steppre, :stepmid, :steppost)
hasline = get_linewidth(series) > 0 hasline = get_linewidth(series) > 0
PyPlot.plt."Line2D"( handle = PyPlot.plt."Line2D"(
(0, 1), (0, 1),
(0, 0), (0, 0),
color = py_color( color = py_color(
@ -1489,7 +1627,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
), ),
linewidth = py_thickness_scale( linewidth = py_thickness_scale(
plt, plt,
hasline * sp[:legendfontsize] / 8, hasline * sp[:legend_font_pointsize] / 8,
), ),
linestyle = py_linestyle(:path, get_linestyle(series)), linestyle = py_linestyle(:path, get_linestyle(series)),
solid_capstyle = "butt", solid_capstyle = "butt",
@ -1497,7 +1635,10 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
dash_capstyle = "butt", dash_capstyle = "butt",
dash_joinstyle = "miter", dash_joinstyle = "miter",
marker = py_marker(_cycle(series[:markershape], 1)), marker = py_marker(_cycle(series[:markershape], 1)),
markersize = py_thickness_scale(plt, 0.8 * sp[:legendfontsize]), markersize = py_thickness_scale(
plt,
0.8 * sp[:legend_font_pointsize],
),
markeredgecolor = py_color( markeredgecolor = py_color(
single_color(get_markerstrokecolor(series)), single_color(get_markerstrokecolor(series)),
get_markerstrokealpha(series), get_markerstrokealpha(series),
@ -1508,14 +1649,15 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
), ),
markeredgewidth = py_thickness_scale( markeredgewidth = py_thickness_scale(
plt, plt,
0.8 * get_markerstrokewidth(series) * sp[:legendfontsize] / 0.8 *
first(series[:markersize]), get_markerstrokewidth(series) *
sp[:legend_font_pointsize] / first(series[:markersize]),
), # retain the markersize/markerstroke ratio from the markers on the plot ), # retain the markersize/markerstroke ratio from the markers on the plot
) )
push!(handles, handle)
else else
series[:serieshandle][1] push!(handles, series[:serieshandle][1])
end, end
)
push!(labels, series[:label]) push!(labels, series[:label])
end end
end end
@ -1529,32 +1671,32 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
loc = py_legend_pos(leg), loc = py_legend_pos(leg),
bbox_to_anchor = py_legend_bbox(leg), bbox_to_anchor = py_legend_bbox(leg),
scatterpoints = 1, scatterpoints = 1,
fontsize = py_thickness_scale(plt, sp[:legendfontsize]), fontsize = py_thickness_scale(plt, sp[:legend_font_pointsize]),
facecolor = py_color(sp[:background_color_legend]), facecolor = py_color(sp[:legend_background_color]),
edgecolor = py_color(sp[:foreground_color_legend]), edgecolor = py_color(sp[:legend_foreground_color]),
framealpha = alpha(plot_color(sp[:background_color_legend])), framealpha = alpha(plot_color(sp[:legend_background_color])),
fancybox = false, # makes the legend box square fancybox = false, # makes the legend box square
borderpad = 0.8, # to match GR legendbox borderpad = 0.8, # to match GR legendbox
) )
frame = leg."get_frame"() frame = leg."get_frame"()
frame."set_linewidth"(py_thickness_scale(plt, 1)) frame."set_linewidth"(py_thickness_scale(plt, 1))
leg."set_zorder"(1000) leg."set_zorder"(1000)
if sp[:legendtitle] !== nothing if sp[:legend_title] !== nothing
leg."set_title"(sp[:legendtitle]) leg."set_title"(sp[:legend_title])
PyPlot.plt."setp"( PyPlot.plt."setp"(
leg."get_title"(), leg."get_title"(),
color = py_color(sp[:legendtitlefontcolor]), color = py_color(sp[:legend_title_font_color]),
family = sp[:legendtitlefontfamily], family = sp[:legend_title_font_family],
fontsize = py_thickness_scale(plt, sp[:legendtitlefontsize]), fontsize = py_thickness_scale(plt, sp[:legend_title_font_pointsize]),
) )
end end
for txt in leg."get_texts"() for txt in leg."get_texts"()
PyPlot.plt."setp"( PyPlot.plt."setp"(
txt, txt,
color = py_color(sp[:legendfontcolor]), color = py_color(sp[:legend_font_color]),
family = sp[:legendfontfamily], family = sp[:legend_font_family],
fontsize = py_thickness_scale(plt, sp[:legendfontsize]), fontsize = py_thickness_scale(plt, sp[:legend_font_pointsize]),
) )
end end
end end
@ -1583,7 +1725,12 @@ function _update_plot_object(plt::Plot{PyPlotBackend})
_cbar_width - 1mm, _cbar_width - 1mm,
height(sp.bbox) - 4mm, height(sp.bbox) - 4mm,
) )
pcts = bbox_to_pcts(cb_bbox, figw, figh) pcts = get(
sp[:extra_kwargs],
"3d_colorbar_axis",
bbox_to_pcts(cb_bbox, figw, figh),
)
sp.attr[:cbar_ax]."set_position"(pcts) sp.attr[:cbar_ax]."set_position"(pcts)
end end
end end

View File

@ -1,189 +1,373 @@
# https://github.com/JuliaPlots/UnicodePlots.jl
# https://github.com/Evizero/UnicodePlots.jl const _canvas_map = (
# don't warn on unsupported... there's just too many warnings!!
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
# --------------------------------------------------------------------------------------
_canvas_map() = (
braille = UnicodePlots.BrailleCanvas, braille = UnicodePlots.BrailleCanvas,
density = UnicodePlots.DensityCanvas,
heatmap = UnicodePlots.HeatmapCanvas,
lookup = UnicodePlots.LookupCanvas,
ascii = UnicodePlots.AsciiCanvas, ascii = UnicodePlots.AsciiCanvas,
block = UnicodePlots.BlockCanvas, block = UnicodePlots.BlockCanvas,
dot = UnicodePlots.DotCanvas, dot = UnicodePlots.DotCanvas,
density = UnicodePlots.DensityCanvas,
) )
# do all the magic here... build it all at once, since we need to know about all the series at the very beginning should_warn_on_unsupported(::UnicodePlotsBackend) = false
function rebuildUnicodePlot!(plt::Plot, width, height)
plt.o = []
function _before_layout_calcs(plt::Plot{UnicodePlotsBackend})
plt.o = UnicodePlots.Plot[]
up_width = UnicodePlots.DEFAULT_WIDTH[]
up_height = UnicodePlots.DEFAULT_HEIGHT[]
has_layout = prod(size(plt.layout)) > 1
for sp in plt.subplots for sp in plt.subplots
sp_kw = sp[:extra_kwargs]
xaxis = sp[:xaxis] xaxis = sp[:xaxis]
yaxis = sp[:yaxis] yaxis = sp[:yaxis]
xlim = axis_limits(sp, :x) xlim = collect(axis_limits(sp, :x))
ylim = axis_limits(sp, :y) ylim = collect(axis_limits(sp, :y))
zlim = collect(axis_limits(sp, :z))
F = float(eltype(xlim))
# make vectors # We set x/y to have a single point,
xlim = [xlim[1], xlim[2]] # since we need to create the plot with some data.
ylim = [ylim[1], ylim[2]] # Since this point is at the bottom left corner of the plot,
# it should be hidden by consecutive plotting commands.
x = Vector{F}(xlim)
y = Vector{F}(ylim)
z = Vector{F}(zlim)
# we set x/y to have a single point, since we need to create the plot with some data. # create a plot window with xlim/ylim set,
# since this point is at the bottom left corner of the plot, it shouldn't actually be shown # but the X/Y vectors are outside the bounds
x = Float64[xlim[1]] canvas = if (up_c = get(sp_kw, :canvas, :auto)) === :auto
y = Float64[ylim[1]] isijulia() ? :ascii : :braille
# create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds
ct = _canvas_type[]
canvas_type = if ct == :auto
isijulia() ? UnicodePlots.AsciiCanvas : UnicodePlots.BrailleCanvas
else else
_canvas_map()[ct] up_c
end end
# special handling for spy border = if (up_b = get(sp_kw, :border, :auto)) === :auto
if length(sp.series_list) == 1 isijulia() ? :ascii : :solid
series = sp.series_list[1] else
if series[:seriestype] == :spy up_b
push!( end
plt.o,
UnicodePlots.spy( # blank plots will not be shown
series[:z].surf, width = has_layout && isempty(series_list(sp)) ? 0 : get(sp_kw, :width, up_width)
width = width, height = get(sp_kw, :height, up_height)
plot_3d = is3d(sp)
blend = get(sp_kw, :blend, true)
grid = xaxis[:grid] && yaxis[:grid]
quiver = contour = false
for series in series_list(sp)
st = series[:seriestype]
blend &= get(series[:extra_kwargs], :blend, true)
quiver |= series[:arrow] isa Arrow # post-pipeline detection (:quiver -> :path)
contour |= st === :contour
if st === :histogram2d
xlim = ylim = (0, 0)
elseif st === :spy || st === :heatmap
width = height = 0
grid = false
end
end
grid &= !(quiver || contour)
blend &= !(quiver || contour)
plot_3d && (xlim = ylim = (0, 0)) # determined using projection
azimuth, elevation = sp[:camera] # PyPlot: azimuth = -60 & elevation = 30
projection = plot_3d ? get(sp_kw, :projection, :orthographic) : nothing
kw = (
compact = true,
title = texmath2unicode(sp[:title]),
xlabel = texmath2unicode(xaxis[:guide]),
ylabel = texmath2unicode(yaxis[:guide]),
grid = grid,
blend = blend,
height = height, height = height,
title = sp[:title],
canvas = canvas_type,
),
)
continue
end
end
# # make it a bar canvas if plotting bar
# if any(series -> series[:seriestype] == :bar, series_list(sp))
# canvas_type = UnicodePlots.BarplotGraphics
# end
o = UnicodePlots.Plot(
x,
y,
canvas_type;
width = width, width = width,
height = height, xscale = xaxis[:scale],
title = sp[:title], yscale = yaxis[:scale],
border = border,
xlim = xlim, xlim = xlim,
ylim = ylim, ylim = ylim,
border = isijulia() ? :ascii : :solid, # 3d
projection = projection,
elevation = elevation,
azimuth = azimuth,
zoom = get(sp_kw, :zoom, 1),
up = get(sp_kw, :up, :z),
) )
# set the axis labels o = UnicodePlots.Plot(x, y, plot_3d ? z : nothing, _canvas_map[canvas]; kw...)
UnicodePlots.xlabel!(o, xaxis[:guide])
UnicodePlots.ylabel!(o, yaxis[:guide])
# now use the ! functions to add to the plot
for series in series_list(sp) for series in series_list(sp)
addUnicodeSeries!(o, series.plotattributes, sp[:legend] != :none, xlim, ylim) o = addUnicodeSeries!(
sp,
o,
kw,
series,
sp[:legend_position] !== :none,
plot_3d,
)
end end
# save the object for ann in sp[:annotations]
push!(plt.o, o) x, y, val = locate_annotation(sp, ann...)
o = UnicodePlots.annotate!(
o,
x,
y,
texmath2unicode(val.str);
color = up_color(val.font.color),
halign = val.font.halign,
valign = val.font.valign,
)
end end
push!(plt.o, o) # save the object
end
end
up_color(col::UnicodePlots.UserColorType) = col
up_color(col::RGBA) =
(c = convert(ARGB32, col); map(Int, (red(c).i, green(c).i, blue(c).i)))
up_color(col) = :auto
function up_cmap(series)
rng = range(0, 1, length = length(UnicodePlots.COLOR_MAP_DATA[:viridis]))
[(red(c), green(c), blue(c)) for c in get(get_colorgradient(series), rng)]
end end
# add a single series # add a single series
function addUnicodeSeries!(o, plotattributes, addlegend::Bool, xlim, ylim) function addUnicodeSeries!(
# get the function, or special handling for step/bar/hist sp::Subplot{UnicodePlotsBackend},
st = plotattributes[:seriestype] up::UnicodePlots.Plot,
if st == :histogram2d kw,
UnicodePlots.densityplot!(o, plotattributes[:x], plotattributes[:y]) series,
return addlegend::Bool,
end plot_3d::Bool,
)
if st in (:path, :straightline) st = series[:seriestype]
func = UnicodePlots.lineplot! se_kw = series[:extra_kwargs]
elseif st == :scatter || plotattributes[:markershape] != :none
func = UnicodePlots.scatterplot!
# elseif st == :bar
# func = UnicodePlots.barplot!
elseif st == :shape
func = UnicodePlots.lineplot!
else
error("Linestyle $st not supported by UnicodePlots")
end
# get the series data and label # get the series data and label
x, y = if st == :straightline x, y = if st === :straightline
straightline_data(plotattributes) straightline_data(series)
elseif st == :shape elseif st === :shape
shape_data(plotattributes) shape_data(series)
else else
[collect(float(plotattributes[s])) for s in (:x, :y)] series[:x], series[:y]
end
label = addlegend ? plotattributes[:label] : ""
lc = plotattributes[:linecolor]
if typeof(lc) <: UnicodePlots.UserColorType
color = lc
elseif lc isa RGBA{Float64}
lc = convert(ARGB32, lc)
color = map(Int, (red(lc).i, green(lc).i, blue(lc).i))
else
color = :auto
end end
# add the series if ispolar(sp) || ispolar(series)
x, y = RecipesPipeline.unzip( return UnicodePlots.polarplot(x, y)
collect(Base.Iterators.filter(xy -> isfinite(xy[1]) && isfinite(xy[2]), zip(x, y))), end
# special handling (src/interface)
fix_ar = get(se_kw, :fix_ar, true)
if st === :histogram2d
return UnicodePlots.densityplot(x, y; kw...)
elseif st === :spy
return UnicodePlots.spy(Array(series[:z]); fix_ar = fix_ar, kw...)
elseif st in (:contour, :heatmap) # 2D
colormap = get(se_kw, :colormap, :none)
kw = (
kw...,
zlabel = sp[:colorbar_title],
colormap = colormap === :none ? up_cmap(series) : colormap,
colorbar = hascolorbar(sp),
)
if st === :contour
isfilledcontour(series) &&
@warn "Plots(UnicodePlots): filled contour is not implemented"
return UnicodePlots.contourplot(
x,
y,
Array(series[:z]);
kw...,
levels = series[:levels],
)
elseif st === :heatmap
return UnicodePlots.heatmap(Array(series[:z]); fix_ar = fix_ar, kw...)
end
elseif st in (:surface, :wireframe) # 3D
colormap = get(se_kw, :colormap, :none)
lines = get(se_kw, :lines, st === :wireframe)
zscale = get(se_kw, :zscale, :identity)
kw = (
kw...,
zlabel = sp[:colorbar_title],
colormap = colormap === :none ? up_cmap(series) : colormap,
colorbar = hascolorbar(sp),
color = st === :wireframe ? up_color(get_linecolor(series, 1)) : nothing,
zscale = zscale,
lines = lines,
)
return UnicodePlots.surfaceplot(x, y, Array(series[:z]); kw...)
elseif st === :mesh3d
return UnicodePlots.lineplot!(
up,
mesh3d_triangles(x, y, series[:z], series[:connections])...,
) )
func(o, x, y; color = color, name = label)
end end
# ------------------------------- # now use the ! functions to add to the plot
if st in (:path, :path3d, :straightline, :shape, :mesh3d)
# since this is such a hack, it's only callable using `png`... should error during normal `show` func = UnicodePlots.lineplot!
function png(plt::AbstractPlot{UnicodePlotsBackend}, fn::AbstractString) series_kw = (; head_tail = series[:arrow] isa Arrow ? series[:arrow].side : nothing)
fn = addExtension(fn, "png") elseif st in (:scatter, :scatter3d) || series[:markershape] !== :none
func = UnicodePlots.scatterplot!
# make some whitespace and show the plot series_kw = (; marker = series[:markershape])
println("\n\n\n\n\n\n") else
gui(plt) error("Plots(UnicodePlots): series type $st not supported")
# @osx_only begin
@static if Sys.isapple()
# BEGIN HACK
# wait while the plot gets drawn
sleep(0.5)
# use osx screen capture when my terminal is maximized and cursor starts at the bottom (I know, right?)
# TODO: compute size of plot to adjust these numbers (or maybe implement something good??)
run(`screencapture -R50,600,700,420 $fn`)
# END HACK (phew)
return
end end
error("Can only savepng on osx with UnicodePlots (though even then I wouldn't do it)") label = addlegend ? series[:label] : ""
for (n, segment) in enumerate(series_segments(series, st; check = true))
i, rng = segment.attr_index, segment.range
lc = get_linecolor(series, i)
up = func(
up,
x[rng],
y[rng],
plot_3d ? series[:z][rng] : nothing;
color = up_color(lc),
name = n == 1 ? label : "",
series_kw...,
)
end end
# ------------------------------- for (xi, yi, str, fnt) in EachAnn(series[:series_annotations], x, y)
up = UnicodePlots.annotate!(
# we don't do very much for subplots... just stack them vertically up,
xi,
function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend}) yi,
w, h = plt[:size] str;
plt.attr[:color_palette] = [RGB(0, 0, 0)] color = up_color(fnt.color),
rebuildUnicodePlot!(plt, div(w, 10), div(h, 20)) halign = fnt.halign,
valign = fnt.valign,
)
end end
up
end
# ------------------------------------------------------------------------------------------
function _show(io::IO, ::MIME"image/png", plt::Plot{UnicodePlotsBackend})
prepare_output(plt)
nr, nc = size(plt.layout)
s1 = zeros(Int, nr, nc)
s2 = zeros(Int, nr, nc)
canvas_type = nothing
imgs = []
sps = 0
for r in 1:nr
for c in 1:nc
if (l = plt.layout[r, c]) isa GridLayout && size(l) != (1, 1)
error("Plots(UnicodePlots): complex nested layout is currently unsupported")
else
img = UnicodePlots.png_image(plt.o[sps += 1])
canvas_type = eltype(img)
h, w = size(img)
s1[r, c] = h
s2[r, c] = w
push!(imgs, img)
end
end
end
if canvas_type !== nothing
m1 = maximum(s1; dims = 2)
m2 = maximum(s2; dims = 1)
img = zeros(canvas_type, sum(m1), sum(m2))
sps = 0
n1 = 1
for r in 1:nr
n2 = 1
for c in 1:nc
sp = imgs[sps += 1]
h, w = size(sp)
img[n1:(n1 + (h - 1)), n2:(n2 + (w - 1))] = sp
n2 += m2[c]
end
n1 += m1[r]
end
stream = UnicodePlots.FileIO.Stream{UnicodePlots.FileIO.format"PNG"}(io)
UnicodePlots.FileIO.save(stream, img)
end
nothing
end
Base.show(plt::Plot{UnicodePlotsBackend}) = show(stdout, plt)
Base.show(io::IO, plt::Plot{UnicodePlotsBackend}) = _show(io, MIME("text/plain"), plt)
# NOTE: _show(...) must be kept for Base.showable (src/output.jl)
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend}) function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
unicodeplots_rebuild(plt) prepare_output(plt)
foreach(x -> show(io, x), plt.o) nr, nc = size(plt.layout)
if nr == 1 && nc == 1 # fast path
n = length(plt.o)
for (i, p) in enumerate(plt.o)
show(io, p)
i < n && println(io)
end
else
have_color = Base.get_have_color()
buf = IOContext(PipeBuffer(), :color => have_color)
lines_colored = Array{Union{Nothing,Vector{String}}}(undef, nr, nc)
lines_uncolored = have_color ? similar(lines_colored) : lines_colored
l_max = zeros(Int, nr)
w_max = zeros(Int, nc)
sps = 0
for r in 1:nr
lmax = 0
for c in 1:nc
if (l = plt.layout[r, c]) isa GridLayout && size(l) != (1, 1)
error(
"Plots(UnicodePlots): complex nested layout is currently unsupported",
)
else
if get(l.attr, :blank, false)
lines_colored[r, c] = lines_uncolored[r, c] = nothing
else
sp = plt.o[sps += 1]
show(buf, sp)
colored = read(buf, String)
lines_colored[r, c] = lu = lc = split(colored, '\n')
if have_color
uncolored = UnicodePlots.no_ansi_escape(colored)
lines_uncolored[r, c] = lu = split(uncolored, '\n')
end
lmax = max(length(lc), lmax)
w_max[c] = max(maximum(length.(lu)), w_max[c])
end
end
end
l_max[r] = lmax
end
empty = String[' '^w for w in w_max]
for r in 1:nr
for n in 1:l_max[r]
for c in 1:nc
pre = c == 1 ? '\0' : ' '
lc = lines_colored[r, c]
if lc === nothing || length(lc) < n
print(io, pre, empty[c])
else
lu = lines_uncolored[r, c]
print(io, pre, lc[n], ' '^(w_max[c] - length(lu[n])))
end
end
n < l_max[r] && println(io)
end
r < nr && println(io)
end
end
nothing nothing
end end
# we only support MIME"text/plain", hence display(...) falls back to plain-text on stdout
function _display(plt::Plot{UnicodePlotsBackend}) function _display(plt::Plot{UnicodePlotsBackend})
unicodeplots_rebuild(plt) show(stdout, plt)
map(show, plt.o) println(stdout)
nothing
end end

View File

@ -5,49 +5,56 @@ process_clims(s::Union{Symbol,Nothing,Missing}) = ignorenan_extrema
# don't specialize on ::Function otherwise python functions won't work # don't specialize on ::Function otherwise python functions won't work
process_clims(f) = f process_clims(f) = f
function get_clims(sp::Subplot, op = process_clims(sp[:clims])) get_clims(sp::Subplot)::Tuple{Float64,Float64} =
haskey(sp.attr, :clims_calculated) ? sp[:clims_calculated] : update_clims(sp)
get_clims(series::Series)::Tuple{Float64,Float64} =
haskey(series.plotattributes, :clims_calculated) ?
series[:clims_calculated]::Tuple{Float64,Float64} : update_clims(series)
get_clims(sp::Subplot, series::Series)::Tuple{Float64,Float64} =
series[:colorbar_entry] ? get_clims(sp) : get_clims(series)
function update_clims(sp::Subplot, op = process_clims(sp[:clims]))::Tuple{Float64,Float64}
zmin, zmax = Inf, -Inf zmin, zmax = Inf, -Inf
for series in series_list(sp) for series in series_list(sp)
if series[:colorbar_entry] if series[:colorbar_entry]::Bool
zmin, zmax = _update_clims(zmin, zmax, get_clims(series, op)...) zmin, zmax = _update_clims(zmin, zmax, update_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 else
get_clims(series, op) update_clims(series, op)
end end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN) end
return sp[:clims_calculated] = zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end end
""" """
get_clims(::Series, op=Plots.ignorenan_extrema) update_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`, 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 which must return the tuple `(zmin, zmax)`. The default op is the extrema of the finite
values of the input. values of the input. The value is stored as a series property, which is retrieved by `get_clims`.
""" """
function get_clims(series::Series, op = ignorenan_extrema) function update_clims(series::Series, op = ignorenan_extrema)::Tuple{Float64,Float64}
zmin, zmax = Inf, -Inf zmin, zmax = Inf, -Inf
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface, :hexbin)
for vals in ( # keeping this unrolled has higher performance
series[:seriestype] in z_colored_series ? series[:z] : nothing, if series[:seriestype] _z_colored_series && series[:z] !== nothing
series[:line_z], zmin, zmax = update_clims(zmin, zmax, series[:z], op)
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
if series[:line_z] !== nothing
zmin, zmax = update_clims(zmin, zmax, series[:line_z], op)
end end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN) if series[:marker_z] !== nothing
zmin, zmax = update_clims(zmin, zmax, series[:marker_z], op)
end end
if series[:fill_z] !== nothing
zmin, zmax = update_clims(zmin, zmax, series[:fill_z], op)
end
return series[:clims_calculated] = zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
update_clims(zmin, zmax, vals::AbstractSurface, op)::Tuple{Float64,Float64} =
update_clims(zmin, zmax, vals.surf, op)
update_clims(zmin, zmax, vals::Any, op)::Tuple{Float64,Float64} =
_update_clims(zmin, zmax, op(vals)...)
update_clims(zmin, zmax, ::Nothing, ::Any)::Tuple{Float64,Float64} = zmin, zmax
_update_clims(zmin, zmax, emin, emax) = NaNMath.min(zmin, emin), NaNMath.max(zmax, emax) _update_clims(zmin, zmax, emin, emax) = NaNMath.min(zmin, emin), NaNMath.max(zmax, emax)
@ -94,4 +101,5 @@ end
function _update_subplot_colorbars(sp::Subplot) function _update_subplot_colorbars(sp::Subplot)
# Dynamic callback from the pipeline if needed # Dynamic callback from the pipeline if needed
update_clims(sp)
end end

View File

@ -43,13 +43,7 @@ vertices(shape::Shape) = collect(zip(shape.x, shape.y))
"return the vertex points from a Shape or Segments object" "return the vertex points from a Shape or Segments object"
coords(shape::Shape) = shape.x, shape.y coords(shape::Shape) = shape.x, shape.y
#coords(shapes::AVec{Shape}) = unzip(map(coords, shapes)) 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`" "get an array of tuples of points on a circle with radius `r`"
partialcircle(start_θ, end_θ, n = 20, r = 1) = partialcircle(start_θ, end_θ, n = 20, r = 1) =
@ -165,10 +159,15 @@ function scale!(shape::Shape, x::Real, y::Real = x, c = center(shape))
shape shape
end end
"""
scale(shape, x, y = x, c = center(shape))
scale!(shape, x, y = x, c = center(shape))
Scale shape by a factor.
"""
scale(shape::Shape, x::Real, y::Real = x, c = center(shape)) = scale(shape::Shape, x::Real, y::Real = x, c = center(shape)) =
scale!(deepcopy(shape), x, y, c) scale!(deepcopy(shape), x, y, c)
"translate a Shape in space"
function translate!(shape::Shape, x::Real, y::Real = x) function translate!(shape::Shape, x::Real, y::Real = x)
sx, sy = coords(shape) sx, sy = coords(shape)
for i in eachindex(sx) for i in eachindex(sx)
@ -178,22 +177,27 @@ function translate!(shape::Shape, x::Real, y::Real = x)
shape shape
end end
"""
translate(shape, x, y = x)
translate!(shape, x, y = x)
Translate a Shape in space.
"""
translate(shape::Shape, x::Real, y::Real = x) = translate!(deepcopy(shape), x, y) translate(shape::Shape, x::Real, y::Real = x) = translate!(deepcopy(shape), x, y)
rotate_x(x::Real, y::Real, Θ::Real, centerx::Real, centery::Real) = rotate_x(x::Real, y::Real, θ::Real, centerx::Real, centery::Real) =
((x - centerx) * cos(Θ) - (y - centery) * sin(Θ) + centerx) ((x - centerx) * cos(θ) - (y - centery) * sin(θ) + centerx)
rotate_y(x::Real, y::Real, Θ::Real, centerx::Real, centery::Real) = rotate_y(x::Real, y::Real, θ::Real, centerx::Real, centery::Real) =
((y - centery) * cos(Θ) + (x - centerx) * sin(Θ) + centery) ((y - centery) * cos(θ) + (x - centerx) * sin(θ) + centery)
rotate(x::Real, y::Real, θ::Real, c = center(shape)) = rotate(x::Real, y::Real, θ::Real, c) = (rotate_x(x, y, θ, c...), rotate_y(x, y, θ, c...))
(rotate_x(x, y, Θ, c...), rotate_y(x, y, Θ, c...))
function rotate!(shape::Shape, Θ::Real, c = center(shape)) function rotate!(shape::Shape, θ::Real, c = center(shape))
x, y = coords(shape) x, y = coords(shape)
for i in eachindex(x) for i in eachindex(x)
xi = rotate_x(x[i], y[i], Θ, c...) xi = rotate_x(x[i], y[i], θ, c...)
yi = rotate_y(x[i], y[i], Θ, c...) yi = rotate_y(x[i], y[i], θ, c...)
x[i], y[i] = xi, yi x[i], y[i] = xi, yi
end end
shape shape
@ -246,6 +250,7 @@ function font(args...; kw...)
for arg in args for arg in args
T = typeof(arg) T = typeof(arg)
@assert arg !== :match
if T == Font if T == Font
family = arg.family family = arg.family
@ -269,12 +274,12 @@ function font(args...; kw...)
catch catch
family = string(arg) family = string(arg)
end end
elseif typeof(arg) <: Integer elseif T <: Integer
pointsize = arg pointsize = arg
elseif typeof(arg) <: Real elseif T <: Real
rotation = convert(Float64, arg) rotation = convert(Float64, arg)
else else
@warn "Unused font arg: $arg ($(typeof(arg)))" @warn "Unused font arg: $arg ($T)"
end end
end end
@ -321,7 +326,7 @@ function scalefontsizes(factor::Number)
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
for k in keys(_initial_ax_fontsizes) for k in keys(_initial_ax_fontsizes)
scalefontsize(Symbol(letter, k), factor) scalefontsize(get_attr_symbol(letter, k), factor)
end end
end end
end end
@ -343,9 +348,9 @@ function scalefontsizes()
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
for k in keys(_initial_ax_fontsizes) for k in keys(_initial_ax_fontsizes)
if k in keys(_initial_fontsizes) if k in keys(_initial_fontsizes)
f = default(Symbol(letter, k)) f = default(get_attr_symbol(letter, k))
factor = f / _initial_fontsizes[k] factor = f / _initial_fontsizes[k]
scalefontsize(Symbol(letter, k), 1.0 / factor) scalefontsize(get_attr_symbol(letter, k), 1.0 / factor)
end end
end end
end end
@ -772,3 +777,20 @@ function extrema_plus_buffer(v, buffmult = 0.2)
buffer = vdiff * buffmult buffer = vdiff * buffmult
vmin - buffer, vmax + buffer vmin - buffer, vmax + buffer
end end
### Legend
@add_attributes subplot struct Legend
background_color = :match
foreground_color = :match
position = :best
title = nothing
font::Font = font(8)
title_font::Font = font(11)
column = 1
end :match = (
:legend_font_family,
:legend_font_color,
:legend_title_font_family,
:legend_title_font_color,
)

88
src/consts.jl Normal file
View File

@ -0,0 +1,88 @@
const _deprecated_attributes = Dict{Symbol,Symbol}(:orientation => :permute)
const _all_defaults = KW[_series_defaults, _plot_defaults, _subplot_defaults]
const _initial_defaults = deepcopy(_all_defaults)
const _initial_axis_defaults = deepcopy(_axis_defaults)
# add defaults for the letter versions
const _axis_defaults_byletter = KW()
function reset_axis_defaults_byletter!()
for letter in (:x, :y, :z)
_axis_defaults_byletter[letter] = KW()
for (k, v) in _axis_defaults
_axis_defaults_byletter[letter][k] = v
end
end
end
reset_axis_defaults_byletter!()
# to be able to reset font sizes to initial values
const _initial_plt_fontsizes =
Dict(:plot_titlefontsize => _plot_defaults[:plot_titlefontsize])
const _initial_sp_fontsizes = Dict(
:titlefontsize => _subplot_defaults[:titlefontsize],
:legend_font_pointsize => _subplot_defaults[:legend_font_pointsize],
:legend_title_font_pointsize => _subplot_defaults[:legend_title_font_pointsize],
:annotationfontsize => _subplot_defaults[:annotationfontsize],
:colorbar_tickfontsize => _subplot_defaults[:colorbar_tickfontsize],
:colorbar_titlefontsize => _subplot_defaults[:colorbar_titlefontsize],
)
const _initial_ax_fontsizes = Dict(
:tickfontsize => _axis_defaults[:tickfontsize],
:guidefontsize => _axis_defaults[:guidefontsize],
)
const _initial_fontsizes =
merge(_initial_plt_fontsizes, _initial_sp_fontsizes, _initial_ax_fontsizes)
const _internal_args =
[:plot_object, :series_plotindex, :markershape_to_add, :letter, :idxfilter]
const _axis_args = Set(keys(_axis_defaults))
const _series_args = Set(keys(_series_defaults))
const _subplot_args = Set(keys(_subplot_defaults))
const _plot_args = Set(keys(_plot_defaults))
const _magic_axis_args = [:axis, :tickfont, :guidefont, :grid, :minorgrid]
const _magic_subplot_args =
[:title_font, :legend_font, :legend_title_font, :plot_title_font, :colorbar_titlefont]
const _magic_series_args = [:line, :marker, :fill]
const _all_magic_args =
Set(union(_magic_axis_args, _magic_series_args, _magic_subplot_args))
const _all_axis_args = union(_axis_args, _magic_axis_args)
const _lettered_all_axis_args =
Set([Symbol(letter, kw) for letter in (:x, :y, :z) for kw in _all_axis_args])
const _all_subplot_args = union(_subplot_args, _magic_subplot_args)
const _all_series_args = union(_series_args, _magic_series_args)
const _all_plot_args = _plot_args
const _all_args =
union(_lettered_all_axis_args, _all_subplot_args, _all_series_args, _all_plot_args)
# add all pluralized forms to the _keyAliases dict
for arg in _all_args
add_aliases(arg, makeplural(arg))
end
# fill symbol cache
for letter in (:x, :y, :z)
_attrsymbolcache[letter] = Dict{Symbol,Symbol}()
for k in _axis_args
# populate attribute cache
lk = Symbol(letter, k)
_attrsymbolcache[letter][k] = lk
# allow the underscore version too: xguide or x_guide
add_aliases(lk, Symbol(letter, "_", k))
end
for k in (_magic_axis_args..., :(_discrete_indices))
_attrsymbolcache[letter][k] = Symbol(letter, k)
end
end
# add all non_underscored forms to the _keyAliases
add_non_underscore_aliases!(_keyAliases)

View File

@ -125,7 +125,8 @@ const _examples = PlotExample[
:( :(
begin begin
import FileIO import FileIO
path = download( import Downloads
path = Downloads.download(
"http://juliaplots.org/PlotReferenceImages.jl/Plots/pyplot/0.7.0/ref1.png", "http://juliaplots.org/PlotReferenceImages.jl/Plots/pyplot/0.7.0/ref1.png",
) )
img = FileIO.load(path) img = FileIO.load(path)
@ -848,7 +849,6 @@ const _examples = PlotExample[
[ [
quote quote
begin begin
using Plots
default( default(
titlefont = (20, "times"), titlefont = (20, "times"),
legendfontsize = 18, legendfontsize = 18,
@ -961,8 +961,10 @@ const _examples = PlotExample[
""" """
Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically. 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. 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, The connections can be specified in two ways: Either as a tuple of vectors where each vector
such that elements at the same position of these vectors form a triangle. contains the 0-based indices of one point of a triangle, such that elements at the same
position of these vectors form a triangle. Or as a vector of NTuple{3,Ints} where each element
contains the 1-based indices of the three points of a triangle.
""", """,
[ [
:( :(
@ -978,13 +980,14 @@ const _examples = PlotExample[
i = [0, 0, 0, 1] i = [0, 0, 0, 1]
j = [1, 2, 3, 2] j = [1, 2, 3, 2]
k = [2, 3, 1, 3] k = [2, 3, 1, 3]
# Or: cns = [(1, 2, 3), (1, 3, 4), (1, 4, 2), (2, 3, 4)] (1-based indexing)
# the four triangles gives above give a tetrahedron # the four triangles gives above give a tetrahedron
mesh3d( mesh3d(
x, x,
y, y,
z; z;
connections = (i, j, k), connections = (i, j, k), # connections = cns
title = "triangles", title = "triangles",
xlabel = "x", xlabel = "x",
ylabel = "y", ylabel = "y",
@ -1067,7 +1070,6 @@ const _examples = PlotExample[
"", "",
[ [
quote quote
using Plots
using TestImages using TestImages
img = testimage("lighthouse") img = testimage("lighthouse")
@ -1088,8 +1090,6 @@ const _examples = PlotExample[
"3d quiver", "3d quiver",
"", "",
[quote [quote
using Plots
ϕs = range(-π, π, length = 50) ϕs = range(-π, π, length = 50)
θs = range(0, π, length = 25) θs = range(0, π, length = 25)
θqs = range(1, π - 1, length = 25) θqs = range(1, π - 1, length = 25)
@ -1228,15 +1228,77 @@ const _examples = PlotExample[
), ),
], ],
), ),
PlotExample( # 56
"Bar plot customizations",
"""
Width of bars may be specified as `bar_width`.
The bars' baseline may be specified as `fillto`.
Each may be scalar, or a vector spcifying one value per bar.
""",
[
:(
begin
plot(
bar(
[-1, 0, 2, 3],
[1, 3, 6, 2],
fill_z = 4:-1:1,
alpha = [1, 0.2, 0.8, 0.5],
label = "",
bar_width = 1:4,
),
bar(
rand(5),
bar_width = 1.2,
alpha = 0.8,
color = [:lightsalmon, :tomato, :crimson, :firebrick, :darkred],
fillto = 0:-0.1:-0.4,
label = "reds",
),
)
end
),
],
),
PlotExample( # 57
"Vertical and horizonal spans",
"""
`vspan` and `hspan` can be used to shade horizontal and vertical ranges.
""",
[:(
begin
hspan([1, 2, 3, 4]; label = "hspan", legend = :topleft)
vspan!([2, 3]; alpha = 0.5, label = "vspan")
plot!([0, 2, 3, 5], [-1, 3, 2, 6]; c = :black, lw = 2, label = "line")
end
)],
),
PlotExample( # 58
"Stacked area chart",
"""
`areaplot` draws stacked area plots.
""",
[
:(
begin
areaplot(
1:3,
[1 2 3; 7 8 9; 4 5 6],
seriescolor = [:red :green :blue],
fillalpha = [0.2 0.3 0.4],
)
end
),
],
),
] ]
# Some constants for PlotDocs and PlotReferenceImages # Some constants for PlotDocs and PlotReferenceImages
_animation_examples = [2, 31] _animation_examples = [2, 31]
_backend_skips = Dict( _backend_skips = Dict(
:gr => [25, 30], :gr => [30],
:pyplot => [2, 25, 30, 31, 47, 49, 55], :pyplot => [2, 25, 30, 31, 49, 55, 56],
:plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51, 55], :plotlyjs => [2, 21, 24, 25, 30, 31, 49, 50, 51, 55, 56],
:plotly => [2, 21, 24, 25, 30, 31, 49, 50, 51, 55],
:pgfplotsx => [ :pgfplotsx => [
2, # animation 2, # animation
6, # images 6, # images
@ -1246,9 +1308,27 @@ _backend_skips = Dict(
32, # spy 32, # spy
49, # polar heatmap 49, # polar heatmap
51, # image with custom axes 51, # image with custom axes
56, # custom bar plot
],
:inspectdr => [4, 6, 10, 22, 24, 28, 30, 38, 43, 45, 47, 48, 49, 50, 51, 55, 56],
:unicodeplots => [
5, # limits issue
6, # embedded images unsupported
16, # nested layout unsupported
21, # custom markers unsupported
26, # nested layout unsupported
29, # nested layout unsupported
31, # nested layout unsupported
33, # grid lines unsupported
34, # framestyle unsupported
37, # ribbons / filled unsupported
43, # heatmap with DateTime
45, # error bars
49, # polar heatmap
51, # embedded images unsupported
55, # mirror unsupported, resolution too low
56, # barplots
], ],
:inspectdr => [4, 6, 10, 22, 24, 28, 30, 38, 43, 45, 47, 48, 49, 50, 51, 55],
:unicodeplots => [6, 10, 22, 24, 28, 38, 43, 45, 47, 49, 50, 51, 55],
:gaston => [ :gaston => [
2, # animations 2, # animations
31, # animations 31, # animations
@ -1256,6 +1336,7 @@ _backend_skips = Dict(
50, # TODO: 1D data not supported for pm3d 50, # TODO: 1D data not supported for pm3d
], ],
) )
_backend_skips[:plotly] = _backend_skips[:plotlyjs]
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
@ -1271,11 +1352,8 @@ function test_examples(pkgname::Symbol, idx::Int; debug = false, disp = true)
Base.eval(m, :(using Plots)) Base.eval(m, :(using Plots))
map(exprs -> Base.eval(m, exprs), _examples[idx].exprs) map(exprs -> Base.eval(m, exprs), _examples[idx].exprs)
plt = current() disp && Base.eval(m, :(gui(current())))
if disp current()
gui(plt)
end
plt
end end
# generate all plots and create a dict mapping idx --> plt # generate all plots and create a dict mapping idx --> plt

View File

@ -49,6 +49,9 @@ function _ijulia_display_dict(plt::Plot)
mime = "text/html" mime = "text/html"
out[mime] = sprint(show, MIME(mime), plt) out[mime] = sprint(show, MIME(mime), plt)
_ijulia__extra_mime_info!(plt, out) _ijulia__extra_mime_info!(plt, out)
elseif output_type == :pdf
mime = "application/pdf"
out[mime] = base64encode(show, MIME(mime), plt)
else else
error("Unsupported output type $output_type") error("Unsupported output type $output_type")
end end

View File

@ -89,7 +89,6 @@ function __init__()
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin @require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
if IJulia.inited if IJulia.inited
_init_ijulia_plotting() _init_ijulia_plotting()
IJulia.display_dict(plt::Plot) = _ijulia_display_dict(plt) IJulia.display_dict(plt::Plot) = _ijulia_display_dict(plt)
end end
end end
@ -98,7 +97,7 @@ function __init__()
global plotly_local_file_path[] = global plotly_local_file_path[] =
joinpath(@get_scratch!("plotly"), _plotly_min_js_filename) joinpath(@get_scratch!("plotly"), _plotly_min_js_filename)
if !isfile(plotly_local_file_path[]) if !isfile(plotly_local_file_path[])
download( Downloads.download(
"https://cdn.plot.ly/$(_plotly_min_js_filename)", "https://cdn.plot.ly/$(_plotly_min_js_filename)",
plotly_local_file_path[], plotly_local_file_path[],
) )

View File

@ -269,6 +269,9 @@ Base.getindex(layout::GridLayout, r::Int, c::Int) = layout.grid[r, c]
function Base.setindex!(layout::GridLayout, v, r::Int, c::Int) function Base.setindex!(layout::GridLayout, v, r::Int, c::Int)
layout.grid[r, c] = v layout.grid[r, c] = v
end end
function Base.setindex!(layout::GridLayout, v, ci::CartesianIndex)
layout.grid[ci] = v
end
leftpad(layout::GridLayout) = layout.minpad[1] leftpad(layout::GridLayout) = layout.minpad[1]
toppad(layout::GridLayout) = layout.minpad[2] toppad(layout::GridLayout) = layout.minpad[2]
@ -491,6 +494,19 @@ function layout_args(sztup::NTuple{3,Integer})
GridLayout(nr, nc), n GridLayout(nr, nc), n
end end
layout_args(nt::NamedTuple) = EmptyLayout(; nt...), 1
function layout_args(m::AbstractVecOrMat)
sz = size(m)
nr = sz[1]
nc = get(sz, 2, 1)
gl = GridLayout(nr, nc)
for ci in CartesianIndices(m)
gl[ci] = layout_args(m[ci])[1]
end
layout_args(gl)
end
# compute number of subplots # compute number of subplots
function layout_args(layout::GridLayout) function layout_args(layout::GridLayout)
# recursively get the size of the grid # recursively get the size of the grid
@ -498,7 +514,8 @@ function layout_args(layout::GridLayout)
layout, n layout, n
end end
layout_args(n_override::Integer, layout::GridLayout) = layout_args(layout) layout_args(n_override::Integer, layout::Union{AbstractVecOrMat,GridLayout}) =
layout_args(layout)
layout_args(huh) = error("unhandled layout type $(typeof(huh)): $huh") layout_args(huh) = error("unhandled layout type $(typeof(huh)): $huh")
@ -562,138 +579,6 @@ function build_layout(layout::GridLayout, n::Integer, plts::AVec{Plot})
layout, subplots, spmap layout, subplots, spmap
end end
# ----------------------------------------------------------------------
# @layout macro
function add_layout_pct!(kw::AKW, v::Expr, idx::Integer, nidx::Integer)
# dump(v)
# something like {0.2w}?
if v.head == :call && v.args[1] == :*
num = v.args[2]
if length(v.args) == 3 && isa(num, Number)
units = v.args[3]
if units == :h
return kw[:h] = num * pct
elseif units == :w
return kw[:w] = num * pct
elseif units in (:pct, :px, :mm, :cm, :inch)
idx == 1 && (kw[:w] = v)
(idx == 2 || nidx == 1) && (kw[:h] = v)
# return kw[idx == 1 ? :w : :h] = v
end
end
end
error("Couldn't match layout curly (idx=$idx): $v")
end
function add_layout_pct!(kw::AKW, v::Number, idx::Integer)
# kw[idx == 1 ? :w : :h] = v*pct
idx == 1 && (kw[:w] = v * pct)
(idx == 2 || nidx == 1) && (kw[:h] = v * pct)
end
isrow(v) = isa(v, Expr) && v.head in (:hcat, :row)
iscol(v) = isa(v, Expr) && v.head == :vcat
rowsize(v) = isrow(v) ? length(v.args) : 1
function create_grid(expr::Expr)
if iscol(expr)
create_grid_vcat(expr)
elseif isrow(expr)
:(
let cell = GridLayout(1, $(length(expr.args)))
$(
[
:(cell[1, $i] = $(create_grid(v))) for
(i, v) in enumerate(expr.args)
]...
)
cell
end
)
elseif expr.head == :curly
create_grid_curly(expr)
else
# if it's something else, just return that (might be an existing layout?)
esc(expr)
end
end
function create_grid_vcat(expr::Expr)
rowsizes = map(rowsize, expr.args)
rmin, rmax = extrema(rowsizes)
if rmin > 0 && rmin == rmax
# we have a grid... build the whole thing
# note: rmin is the number of columns
nr = length(expr.args)
nc = rmin
body = Expr(:block)
for r in 1:nr
arg = expr.args[r]
if isrow(arg)
for (c, item) in enumerate(arg.args)
push!(body.args, :(cell[$r, $c] = $(create_grid(item))))
end
else
push!(body.args, :(cell[$r, 1] = $(create_grid(arg))))
end
end
:(
let cell = GridLayout($nr, $nc)
$body
cell
end
)
else
# otherwise just build one row at a time
:(
let cell = GridLayout($(length(expr.args)), 1)
$(
[
:(cell[$i, 1] = $(create_grid(v))) for
(i, v) in enumerate(expr.args)
]...
)
cell
end
)
end
end
function create_grid_curly(expr::Expr)
kw = KW()
for (i, arg) in enumerate(expr.args[2:end])
add_layout_pct!(kw, arg, i, length(expr.args) - 1)
end
s = expr.args[1]
if isa(s, Expr) && s.head == :call && s.args[1] == :grid
create_grid(
:(grid(
$(s.args[2:end]...),
width = $(get(kw, :w, QuoteNode(:auto))),
height = $(get(kw, :h, QuoteNode(:auto))),
)),
)
elseif isa(s, Symbol)
:(EmptyLayout(
label = $(QuoteNode(s)),
width = $(get(kw, :w, QuoteNode(:auto))),
height = $(get(kw, :h, QuoteNode(:auto))),
))
else
error("Unknown use of curly brackets: $expr")
end
end
function create_grid(s::Symbol)
:(EmptyLayout(label = $(QuoteNode(s)), blank = $(s == :_)))
end
macro layout(mat::Expr)
create_grid(mat)
end
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# make all reference the same axis extrema/values. # make all reference the same axis extrema/values.

View File

@ -4,8 +4,7 @@ legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax, inout)
``` ```
Return `(x,y)` at an angle `theta` degrees from Return `(x,y)` at an angle `theta` degrees from
`(xcenter,ycenter)` on a rectangle defined by (`xmin`, `(xcenter,ycenter)` on a rectangle defined by (`xmin`, `xmax`, `ymin`, `ymax`).
`xmax`, `ymin`, `ymax`).
""" """
function legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax) function legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax)
(s, c) = sincosd(theta) (s, c) = sincosd(theta)

View File

@ -2,74 +2,65 @@
defaultOutputFormat(plt::Plot) = "png" defaultOutputFormat(plt::Plot) = "png"
function png(plt::Plot, fn::AbstractString) function png(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "png") open(addExtension(fn, "png"), "w") do io
io = open(fn, "w")
show(io, MIME("image/png"), plt) show(io, MIME("image/png"), plt)
close(io) end
end end
png(fn::AbstractString) = png(current(), fn) png(fn::AbstractString) = png(current(), fn)
function svg(plt::Plot, fn::AbstractString) function svg(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "svg") open(addExtension(fn, "svg"), "w") do io
io = open(fn, "w")
show(io, MIME("image/svg+xml"), plt) show(io, MIME("image/svg+xml"), plt)
close(io) end
end end
svg(fn::AbstractString) = svg(current(), fn) svg(fn::AbstractString) = svg(current(), fn)
function pdf(plt::Plot, fn::AbstractString) function pdf(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "pdf") open(addExtension(fn, "pdf"), "w") do io
io = open(fn, "w")
show(io, MIME("application/pdf"), plt) show(io, MIME("application/pdf"), plt)
close(io) end
end end
pdf(fn::AbstractString) = pdf(current(), fn) pdf(fn::AbstractString) = pdf(current(), fn)
function ps(plt::Plot, fn::AbstractString) function ps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "ps") open(addExtension(fn, "ps"), "w") do io
io = open(fn, "w")
show(io, MIME("application/postscript"), plt) show(io, MIME("application/postscript"), plt)
close(io) end
end end
ps(fn::AbstractString) = ps(current(), fn) ps(fn::AbstractString) = ps(current(), fn)
function eps(plt::Plot, fn::AbstractString) function eps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "eps") open(addExtension(fn, "eps"), "w") do io
io = open(fn, "w")
show(io, MIME("image/eps"), plt) show(io, MIME("image/eps"), plt)
close(io) end
end end
eps(fn::AbstractString) = eps(current(), fn) eps(fn::AbstractString) = eps(current(), fn)
function tex(plt::Plot, fn::AbstractString) function tex(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "tex") open(addExtension(fn, "tex"), "w") do io
io = open(fn, "w")
show(io, MIME("application/x-tex"), plt) show(io, MIME("application/x-tex"), plt)
close(io) end
end end
tex(fn::AbstractString) = tex(current(), fn) tex(fn::AbstractString) = tex(current(), fn)
function json(plt::Plot, fn::AbstractString) function json(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "json") open(addExtension(fn, "json"), "w") do io
io = open(fn, "w")
show(io, MIME("application/vnd.plotly.v1+json"), plt) show(io, MIME("application/vnd.plotly.v1+json"), plt)
close(io) end
end end
json(fn::AbstractString) = json(current(), fn) json(fn::AbstractString) = json(current(), fn)
function html(plt::Plot, fn::AbstractString) function html(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "html") open(addExtension(fn, "html"), "w") do io
io = open(fn, "w")
show(io, MIME("text/html"), plt) show(io, MIME("text/html"), plt)
close(io) end
end end
html(fn::AbstractString) = html(current(), fn) html(fn::AbstractString) = html(current(), fn)
function txt(plt::Plot, fn::AbstractString) function txt(plt::Plot, fn::AbstractString; color::Bool = true)
fn = addExtension(fn, "txt") open(addExtension(fn, "txt"), "w") do io
io = open(fn, "w") show(IOContext(io, :color => color), MIME("text/plain"), plt)
show(io, MIME("text/plain"), plt) end
close(io)
end end
txt(fn::AbstractString) = txt(current(), fn) txt(fn::AbstractString) = txt(current(), fn)
@ -88,6 +79,13 @@ const _savemap = Dict(
"txt" => txt, "txt" => txt,
) )
for out in Symbol.(unique(values(_savemap)))
@eval @doc """
$($out)([plot,], filename)
Save plot as $($out)-file.
""" $out
end
const _extension_map = Dict("tikz" => "tex") const _extension_map = Dict("tikz" => "tex")
function addExtension(fn::AbstractString, ext::AbstractString) function addExtension(fn::AbstractString, ext::AbstractString)
@ -196,6 +194,7 @@ Base.show(io::IO, m::MIME"text/plain", plt::Plot) = show(io, plt)
# for writing to io streams... first prepare, then callback # for writing to io streams... first prepare, then callback
for mime in ( for mime in (
"text/html", "text/html",
"text/latex",
"image/png", "image/png",
"image/eps", "image/eps",
"image/svg+xml", "image/svg+xml",
@ -216,6 +215,8 @@ for mime in (
end end
end end
Base.showable(::MIME"text/html", plt::Plot{UnicodePlotsBackend}) = false # Pluto
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) = Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) =
showjuno(io, MIME("text/html"), plt) showjuno(io, MIME("text/html"), plt)

View File

@ -8,24 +8,14 @@ function RecipesPipeline.warn_on_recipe_aliases!(
recipe_type::Symbol, recipe_type::Symbol,
@nospecialize(args) @nospecialize(args)
) )
for k in keys(plotattributes) pkeys = keys(plotattributes)
if !is_default_attribute(k) for k in pkeys
dk = get(_keyAliases, k, k) dk = get(_keyAliases, k, nothing)
if k !== dk if dk !== nothing
if recipe_type == :user kv = RecipesPipeline.pop_kw!(plotattributes, k)
signature_string = RecipesPipeline.userrecipe_signature_string(args) if dk pkeys
elseif recipe_type == :type plotattributes[dk] = kv
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 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] = RecipesPipeline.pop_kw!(plotattributes, k)
end end
end end
end end
@ -78,8 +68,19 @@ end
function _preprocess_userrecipe(kw::AKW) function _preprocess_userrecipe(kw::AKW)
_add_markershape(kw) _add_markershape(kw)
if get(kw, :permute, default(:permute)) != :none
l1, l2 = kw[:permute]
for k in _axis_args
k1 = _attrsymbolcache[l1][k]
k2 = _attrsymbolcache[l2][k]
kwk = keys(kw)
if k1 in kwk || k2 in kwk
kw[k1], kw[k2] = get(kw, k2, default(k2)), get(kw, k1, default(k1))
end
end
end
# map marker_z if it's a Function # map marker_z if it's a Function
if isa(get(kw, :marker_z, nothing), Function) if isa(get(kw, :marker_z, default(:marker_z)), Function)
# TODO: should this take y and/or z as arguments? # TODO: should this take y and/or z as arguments?
kw[:marker_z] = kw[:marker_z] =
isa(kw[:z], Nothing) ? map(kw[:marker_z], kw[:x], kw[:y]) : isa(kw[:z], Nothing) ? map(kw[:marker_z], kw[:x], kw[:y]) :
@ -87,16 +88,12 @@ function _preprocess_userrecipe(kw::AKW)
end end
# map line_z if it's a Function # map line_z if it's a Function
if isa(get(kw, :line_z, nothing), Function) if isa(get(kw, :line_z, default(:line_z)), Function)
kw[:line_z] = kw[:line_z] =
isa(kw[:z], Nothing) ? map(kw[:line_z], kw[:x], kw[:y]) : isa(kw[:z], Nothing) ? map(kw[:line_z], kw[:x], kw[:y]) :
map(kw[:line_z], kw[:x], kw[:y], kw[:z]) map(kw[:line_z], kw[:x], kw[:y], kw[:z])
end end
# convert a ribbon into a fillrange
if get(kw, :ribbon, nothing) !== nothing
make_fillrange_from_ribbon(kw)
end
return return
end end
@ -164,6 +161,22 @@ function RecipesPipeline.process_sliced_series_attributes!(plt::Plots.Plot, kw_l
kw_list[ind - 1] = tmp kw_list[ind - 1] = tmp
end end
end end
for kw in kw_list
rib = get(kw, :ribbon, default(:ribbon))
fr = get(kw, :fillrange, default(:fillrange))
# map ribbon if it's a Function
if rib isa Function
kw[:ribbon] = map(rib, kw[:x])
end
# convert a ribbon into a fillrange
if rib !== nothing
make_fillrange_from_ribbon(kw)
# map fillrange if it's a Function
elseif fr !== nothing && fr isa Function
kw[:fillrange] = map(fr, kw[:x])
end
end
return nothing return nothing
end end
@ -250,17 +263,17 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
v = v[series_idx(kw_list, kw)] v = v[series_idx(kw_list, kw)]
end end
for letter in (:x, :y, :z) for letter in (:x, :y, :z)
attr[Symbol(letter, k)] = v attr[get_attr_symbol(letter, k)] = v
end
end end
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 # Series recipes may need access to this information
lk = Symbol(letter, k) lk = get_attr_symbol(letter, k)
if haskey(attr, lk) if haskey(attr, lk)
kw[lk] = attr[lk] kw[lk] = attr[lk]
end end
end end
end
sp_attrs[sp] = attr sp_attrs[sp] = attr
end end
@ -286,17 +299,19 @@ end
function _add_plot_title!(plt) function _add_plot_title!(plt)
plot_title = plt[:plot_title] plot_title = plt[:plot_title]
plot_titleindex = nothing
if plot_title != "" if plot_title != ""
# make new subplot for plot title
if plt[:plot_titleindex] == 0
the_layout = plt.layout the_layout = plt.layout
vspan = plt[:plot_titlevspan] vspan = plt[:plot_titlevspan]
plt.layout = grid(2, 1, heights = (vspan, 1 - vspan)) plt.layout = grid(2, 1, heights = (vspan, 1 - vspan))
plt.layout.grid[1, 1] = subplot = Subplot(plt.backend, parent = plt.layout[1, 1]) plt.layout.grid[1, 1] =
subplot = Subplot(plt.backend, parent = plt.layout[1, 1])
plt.layout.grid[2, 1] = the_layout plt.layout.grid[2, 1] = the_layout
subplot.plt = plt subplot.plt = plt
# propagate arguments plt[:plot_titleXXX] --> subplot[:titleXXX]
for sym in filter(x -> startswith(string(x), "plot_title"), keys(_plot_defaults))
subplot[Symbol(string(sym)[(length("plot_") + 1):end])] = plt[sym]
end
top = plt.backend isa PyPlotBackend ? nothing : 0mm top = plt.backend isa PyPlotBackend ? nothing : 0mm
bot = 0mm bot = 0mm
plt[:force_minpad] = nothing, top, nothing, bot plt[:force_minpad] = nothing, top, nothing, bot
@ -306,7 +321,16 @@ function _add_plot_title!(plt)
subplot[:margin] = 0px subplot[:margin] = 0px
push!(plt.subplots, subplot) push!(plt.subplots, subplot)
end end
return nothing
# propagate arguments plt[:plot_titleXXX] --> subplot[:titleXXX]
plot_titleindex = plt[:plot_titleindex]
subplot = plt.subplots[plot_titleindex]
for sym in filter(x -> startswith(string(x), "plot_title"), keys(_plot_defaults))
subplot[Symbol(string(sym)[(length("plot_") + 1):end])] = plt[sym]
end
end
return plot_titleindex
end end
## Series recipes ## Series recipes
@ -325,6 +349,19 @@ RecipesPipeline.is_seriestype_supported(plt::Plot, st) = is_seriestype_supported
function RecipesPipeline.add_series!(plt::Plot, plotattributes) function RecipesPipeline.add_series!(plt::Plot, plotattributes)
sp = _prepare_subplot(plt, plotattributes) sp = _prepare_subplot(plt, plotattributes)
if plotattributes[:permute] != :none
letter1, letter2 = plotattributes[:permute]
if plotattributes[:markershape] == :hline &&
(plotattributes[:permute] == (:x, :y) || plotattributes[:permute] == (:y, :x))
plotattributes[:markershape] = :vline
elseif plotattributes[:markershape] == :vline && (
plotattributes[:permute] == (:x, :y) || plotattributes[:permute] == (:y, :x)
)
plotattributes[:markershape] = :hline
end
plotattributes[letter1], plotattributes[letter2] =
plotattributes[letter2], plotattributes[letter1]
end
_expand_subplot_extrema(sp, plotattributes, plotattributes[:seriestype]) _expand_subplot_extrema(sp, plotattributes, plotattributes[:seriestype])
_update_series_attributes!(plotattributes, plt, sp) _update_series_attributes!(plotattributes, plt, sp)
_add_the_series(plt, sp, plotattributes) _add_the_series(plt, sp, plotattributes)
@ -414,6 +451,16 @@ function _add_the_series(plt, sp, plotattributes)
warn_on_unsupported(plt.backend, plotattributes) warn_on_unsupported(plt.backend, plotattributes)
series = Series(plotattributes) series = Series(plotattributes)
push!(plt.series_list, series) push!(plt.series_list, series)
z_order = plotattributes[:z_order]
if z_order == :front
push!(sp.series_list, series) push!(sp.series_list, series)
_series_added(plt, series) elseif z_order == :back
pushfirst!(sp.series_list, series)
elseif z_order isa Integer
insert!(sp.series_list, z_order, series)
else
@error "Wrong type $(typeof(z_order)) for attribute z_order"
end
_series_added(plt, series)
_update_subplot_colorbars(sp)
end end

View File

@ -163,11 +163,11 @@ function plot!(plt1::Plot, plt2::Plot, plts_tail::Plot...; kw...)
cmdidx += 1 cmdidx += 1
end end
end end
_add_plot_title!(plt) ttl_idx = _add_plot_title!(plt)
# first apply any args for the subplots # first apply any args for the subplots
for (idx, sp) in enumerate(plt.subplots) for (idx, sp) in enumerate(plt.subplots)
_update_subplot_args(plt, sp, plotattributes, idx, false) _update_subplot_args(plt, sp, idx == ttl_idx ? KW() : plotattributes, idx, false)
end end
# finish up # finish up
@ -247,6 +247,12 @@ function prepare_output(plt::Plot)
_update_plot_object(plt) _update_plot_object(plt)
end end
"""
backend_object(plot)
Returns the backend representation of a Plot object.
Returns `nothing` if the backend does not support this.
"""
function backend_object(plt::Plot) function backend_object(plt::Plot)
prepare_output(plt) prepare_output(plt)
plt.o plt.o

View File

@ -1,17 +1,40 @@
#! format: off
should_precompile = true should_precompile = true
# Don't edit the following! Instead change the script for `snoop_bot`. # Don't edit the following! Instead change the script for `snoop_bot`.
ismultios = false ismultios = false
ismultiversion = false ismultiversion = true
# precompile_enclosure # precompile_enclosure
@static if !should_precompile @static if !should_precompile
# nothing # nothing
elseif !ismultios && !ismultiversion elseif !ismultios && !ismultiversion
@static if isfile( @static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile/precompile_Plots.jl"))
joinpath(@__DIR__, "../deps/SnoopCompile/precompile/precompile_Plots.jl"),
)
include("../deps/SnoopCompile/precompile/precompile_Plots.jl") include("../deps/SnoopCompile/precompile/precompile_Plots.jl")
_precompile_() _precompile_()
end end
else else
@static if v"1.6.0-DEV" <= VERSION <= v"1.6.9"
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile//1.6/precompile_Plots.jl"))
include("../deps/SnoopCompile/precompile//1.6/precompile_Plots.jl")
_precompile_()
end
elseif v"1.7.0-DEV" <= VERSION <= v"1.7.9"
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile//1.7/precompile_Plots.jl"))
include("../deps/SnoopCompile/precompile//1.7/precompile_Plots.jl")
_precompile_()
end
elseif v"1.8.0-DEV" <= VERSION <= v"1.8.9"
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile//1.8/precompile_Plots.jl"))
include("../deps/SnoopCompile/precompile//1.8/precompile_Plots.jl")
_precompile_()
end
elseif v"1.9.0-DEV" <= VERSION <= v"1.9.9"
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile//1.9/precompile_Plots.jl"))
include("../deps/SnoopCompile/precompile//1.9/precompile_Plots.jl")
_precompile_()
end
else
end
end # precompile_enclosure end # precompile_enclosure

View File

@ -47,7 +47,7 @@ num_series(x::AMat) = size(x, 2)
num_series(x) = 1 num_series(x) = 1
RecipesBase.apply_recipe(plotattributes::AKW, ::Type{T}, plt::AbstractPlot) where {T} = RecipesBase.apply_recipe(plotattributes::AKW, ::Type{T}, plt::AbstractPlot) where {T} =
throw(MethodError(T, "Unmatched plot recipe: $T")) nothing
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -438,7 +438,7 @@ end
procx, procy, xscale, yscale, baseline = _preprocess_barlike(plotattributes, x, y) procx, procy, xscale, yscale, baseline = _preprocess_barlike(plotattributes, x, y)
nx, ny = length(procx), length(procy) nx, ny = length(procx), length(procy)
axis = plotattributes[:subplot][isvertical(plotattributes) ? :xaxis : :yaxis] axis = plotattributes[:subplot][isvertical(plotattributes) ? :xaxis : :yaxis]
cv = [discrete_value!(axis, xi)[1] for xi in procx] cv = [discrete_value!(plotattributes, :x, xi)[1] for xi in procx]
procx = if nx == ny procx = if nx == ny
cv cv
elseif nx == ny + 1 elseif nx == ny + 1
@ -508,6 +508,18 @@ end
primary := true primary := true
x := xseg.pts x := xseg.pts
y := yseg.pts y := yseg.pts
# expand attributes to match indices in new series data
for k in _segmenting_vector_attributes _segmenting_array_attributes
v = get(plotattributes, k, nothing)
if v isa AVec
if eachindex(v) != eachindex(y)
@warn "Indices $(eachindex(v)) of attribute `$k` do not match data indices $(eachindex(y))."
end
# Each segment is 6 elements long, including the NaN separator.
# There is no trailing NaN, so the last repetition is dropped.
plotattributes[k] = @view repeat(v; inner = 6)[1:(end - 1)]
end
end
() ()
end end
@ -783,7 +795,7 @@ function _auto_binning_nbins(
elseif mode == :fd # FreedmanDiaconis rule elseif mode == :fd # FreedmanDiaconis rule
_cl(_span(v) / (2 * _iqr(v) / nd)) _cl(_span(v) / (2 * _iqr(v) / nd))
elseif mode == :wand elseif mode == :wand
_cl(wand_edges(v)) # this makes this function not type stable, but the type instability does not propagate wand_edges(v) # this makes this function not type stable, but the type instability does not propagate
else else
error("Unknown auto-binning mode $mode") error("Unknown auto-binning mode $mode")
end end
@ -1025,24 +1037,32 @@ export lens!
throw(ArgumentError("Inset bounding box needs to in relative coordinates.")) throw(ArgumentError("Inset bounding box needs to in relative coordinates."))
end end
sp = plt.subplots[sp_index] sp = plt.subplots[sp_index]
xl1, xl2 = xlims(plt.subplots[sp_index]) xscale = sp[:xaxis][:scale]
yscale = sp[:yaxis][:scale]
xl1, xl2 = xlims(sp)
bbx1 = xl1 + left(inset_bbox).value * (xl2 - xl1) bbx1 = xl1 + left(inset_bbox).value * (xl2 - xl1)
bbx2 = bbx1 + width(inset_bbox).value * (xl2 - xl1) bbx2 = bbx1 + width(inset_bbox).value * (xl2 - xl1)
yl1, yl2 = ylims(plt.subplots[sp_index]) yl1, yl2 = ylims(sp)
bby1 = yl1 + (1 - bottom(inset_bbox).value) * (yl2 - yl1) bby1 = yl1 + (1 - bottom(inset_bbox).value) * (yl2 - yl1)
bby2 = bby1 + height(inset_bbox).value * (yl2 - yl1) bby2 = bby1 + height(inset_bbox).value * (yl2 - yl1)
bbx = bbx1 + width(inset_bbox).value * (xl2 - xl1) / 2 bbx = bbx1 + width(inset_bbox).value * (xl2 - xl1) / 2 * (sp[:xaxis][:flip] ? -1 : 1)
bby = bby1 + height(inset_bbox).value * (yl2 - yl1) / 2 bby = bby1 + height(inset_bbox).value * (yl2 - yl1) / 2 * (sp[:yaxis][:flip] ? -1 : 1)
lens_index = last(plt.subplots)[:subplot_index] + 1 lens_index = last(plt.subplots)[:subplot_index] + 1
x1, x2 = plotattributes[:x] x1, x2 = RecipesPipeline.inverse_scale_func(xscale).(plotattributes[:x])
y1, y2 = plotattributes[:y] y1, y2 = RecipesPipeline.inverse_scale_func(yscale).(plotattributes[:y])
backup = copy(plotattributes) backup = copy(plotattributes)
empty!(plotattributes) empty!(plotattributes)
series_plotindex := backup[:series_plotindex] series_plotindex := backup[:series_plotindex]
seriestype := :path seriestype := :path
primary := false primary := false
linecolor := :lightgray linecolor := get(backup, :linecolor, :lightgray)
if haskey(backup, :linestyle)
linestyle := backup[:linestyle]
end
if haskey(backup, :linewidth)
linewidth := backup[:linewidth]
end
bbx_mag = (x1 + x2) / 2 bbx_mag = (x1 + x2) / 2
bby_mag = (y1 + y2) / 2 bby_mag = (y1 + y2) / 2
xi_lens, yi_lens = xi_lens, yi_lens =
@ -1054,8 +1074,8 @@ export lens!
@series begin @series begin
primary := false primary := false
subplot := sp_index subplot := sp_index
x := [xi_mag, xi_lens] x := RecipesPipeline.scale_func(xscale).([xi_mag, xi_lens])
y := [yi_mag, yi_lens] y := RecipesPipeline.scale_func(yscale).([yi_mag, yi_lens])
() ()
end end
end end
@ -1063,8 +1083,8 @@ export lens!
@series begin @series begin
primary := false primary := false
subplot := sp_index subplot := sp_index
x := [x1, x1, x2, x2, x1] x := RecipesPipeline.scale_func(xscale).([x1, x1, x2, x2, x1])
y := [y1, y2, y2, y1, y1] y := RecipesPipeline.scale_func(yscale).([y1, y2, y2, y1, y1])
() ()
end end
# add subplot # add subplot
@ -1073,8 +1093,8 @@ export lens!
plotattributes = merge(backup, copy(series.plotattributes)) plotattributes = merge(backup, copy(series.plotattributes))
subplot := lens_index subplot := lens_index
primary := false primary := false
xlims := (x1, x2) xlims := RecipesPipeline.scale_func(xscale).((x1, x2))
ylims := (y1, y2) ylims := RecipesPipeline.scale_func(yscale).((y1, y2))
() ()
end end
end end
@ -1120,6 +1140,13 @@ end
# Error Bars # Error Bars
function error_style!(plotattributes::AKW) function error_style!(plotattributes::AKW)
# errorbar color should soley determined by markerstrokecolor
if haskey(plotattributes, :marker_z)
reset_kw!(plotattributes, :marker_z)
end
if haskey(plotattributes, :line_z)
reset_kw!(plotattributes, :line_z)
end
msc = plotattributes[:markerstrokecolor] msc = plotattributes[:markerstrokecolor]
msc = if msc === :match msc = if msc === :match
plotattributes[:subplot][:foreground_color_subplot] plotattributes[:subplot][:foreground_color_subplot]
@ -1362,7 +1389,8 @@ function clamp_greys!(mat::AMat{<:Gray})
end end
@recipe function f(mat::AMat{<:Gray}) @recipe function f(mat::AMat{<:Gray})
n, m = axes(mat) n, m = map(a -> range(0.5, stop = a.stop + 0.5), axes(mat))
if is_seriestype_supported(:image) if is_seriestype_supported(:image)
seriestype := :image seriestype := :image
yflip --> true yflip --> true
@ -1380,7 +1408,7 @@ end
# images - colors # images - colors
@recipe function f(mat::AMat{T}) where {T<:Colorant} @recipe function f(mat::AMat{T}) where {T<:Colorant}
n, m = axes(mat) n, m = map(a -> range(0.5, stop = a.stop + 0.5), axes(mat))
if is_seriestype_supported(:image) if is_seriestype_supported(:image)
seriestype := :image seriestype := :image
@ -1604,7 +1632,6 @@ end
@nospecialize @nospecialize
"Adds ax+b... straight line over the current plot, without changing the axis limits"
abline!(plt::Plot, a, b; kw...) = abline!(plt::Plot, a, b; kw...) =
plot!(plt, [0, 1], [b, b + a]; seriestype = :straightline, kw...) plot!(plt, [0, 1], [b, b + a]; seriestype = :straightline, kw...)
@ -1649,16 +1676,6 @@ end
end end
end end
"""
areaplot([x,] y)
areaplot!([x,] y)
Draw a stacked area plot of the matrix y.
# Examples
```julia-repl
julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], fillalpha = [0.2 0.3 0.4])
```
"""
@userplot AreaPlot @userplot AreaPlot
@recipe function f(a::AreaPlot) @recipe function f(a::AreaPlot)

View File

@ -348,10 +348,10 @@ Make a box and whisker plot.
# Keyword arguments # Keyword arguments
- `notch`: Bool. Notch the box plot? (false) - `notch`: Bool. Notch the box plot? (false)
- `range`: Real. Values more than range*IQR below the first quartile - `whisker_range`: Real. Whiskers extend `whisker_range`*IQR below the first quartile
or above the third quartile are shown as outliers (1.5) and above the third quartile. Values outside this range are shown as outliers (1.5)
- `outliers`: Bool. Show outliers? (true) - `outliers`: Bool. Show outliers? (true)
- `whisker_width`: Real or Symbol. Length of whiskers (:match) - `whisker_width`: Real or Symbol. Length of whiskers; the options are `:match` to match the box width, `:half`, or a number to indicate the total length. (:half)
# Example # Example
```julia-repl ```julia-repl
@ -472,10 +472,33 @@ yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...)
"Specify x axis attributes for an existing plot" "Specify x axis attributes for an existing plot"
xaxis!(args...; kw...) = plot!(; xaxis = args, kw...) xaxis!(args...; kw...) = plot!(; xaxis = args, kw...)
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
"Specify y axis attributes for an existing plot" "Specify y axis attributes for an existing plot"
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...) yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
ygrid!(args...; kw...) = plot!(; ygrid = args, kw...) ygrid!(args...; kw...) = plot!(; ygrid = args, kw...)
@doc """
abline!([plot,] a, b; kwargs...)
Adds ax+b... straight line over the current plot, without changing the axis limits
""" abline!
@doc """
areaplot([x,] y)
areaplot!([x,] y)
Draw a stacked area plot of the matrix y.
# Examples
```julia-repl
julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], fillalpha = [0.2 0.3 0.4])
```
""" areaplot
@doc """
lens!([plot,] x, y, inset = (sp_index, bbox(x1, x2, y1, y2)))
Magnify a region of a plot given by `x` and `y`.
`sp_index` is the index of the subplot and `x1`, `x2`, `y1` and `y2` should be between `0` and `1`.
""" lens!
@specialize @specialize

View File

@ -103,7 +103,10 @@ function series_segments(series::Series, seriestype::Symbol = :path; check = fal
segments = if has_attribute_segments(series) segments = if has_attribute_segments(series)
Iterators.flatten(map(nan_segments) do r Iterators.flatten(map(nan_segments) do r
if seriestype in (:scatter, :scatter3d) if seriestype == :shape
warn_on_inconsistent_shape_attr(series, x, y, z, r)
(SeriesSegment(r, first(r)),)
elseif seriestype in (:scatter, :scatter3d)
(SeriesSegment(i:i, i) for i in r) (SeriesSegment(i:i, i) for i in r)
else else
(SeriesSegment(i:(i + 1), i) for i in first(r):(last(r) - 1)) (SeriesSegment(i:(i + 1), i) for i in first(r):(last(r) - 1))
@ -140,6 +143,16 @@ function warn_on_attr_dim_mismatch(series, x, y, z, segments)
end end
end end
function warn_on_inconsistent_shape_attr(series, x, y, z, r)
for attr in _segmenting_vector_attributes
v = get(series, attr, nothing)
if v isa AVec && length(unique(v[r])) > 1
@warn "Different values of `$attr` specified for different shape vertices. Only first one will be used."
break
end
end
end
# helpers to figure out if there are NaN values in a list of array types # helpers to figure out if there are NaN values in a list of array types
anynan(i::Int, args::Tuple) = any(a -> try anynan(i::Int, args::Tuple) = any(a -> try
isnan(_cycle(a, i)) isnan(_cycle(a, i))
@ -202,19 +215,12 @@ makevec(v::T) where {T} = T[v]
maketuple(x::Real) = (x, x) maketuple(x::Real) = (x, x)
maketuple(x::Tuple{T,S}) where {T,S} = x maketuple(x::Tuple{T,S}) where {T,S} = x
for i in 2:4 RecipesPipeline.unzip(v) = unzip(v)
@eval begin RecipesPipeline.unzip(points::AbstractVector{<:GeometryBasics.Point}) =
RecipesPipeline.unzip( unzip(Tuple.(points))
v::Union{AVec{<:Tuple{Vararg{T,$i} where T}},AVec{<:GeometryBasics.Point{$i}}}, RecipesPipeline.unzip(points::AbstractVector{GeometryBasics.Point{N,T}}) where {N,T} =
) = $(Expr(:tuple, (:([t[$j] for t in v]) for j in 1:i)...)) isbitstype(T) && sizeof(T) > 0 ? unzip(reinterpret(NTuple{N,T}, points)) :
end unzip(Tuple.(points))
end
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 # given 2-element lims and a vector of data x, widen lims to account for the extrema of x
function _expand_limits(lims, x) function _expand_limits(lims, x)
@ -371,8 +377,7 @@ nanappend!(a::AbstractVector, b) = (push!(a, NaN); append!(a, b))
function nansplit(v::AVec) function nansplit(v::AVec)
vs = Vector{eltype(v)}[] vs = Vector{eltype(v)}[]
while true while true
idx = findfirst(isnan, v) if (idx = findfirst(isnan, v)) === nothing
if idx <= 0
# no nans # no nans
push!(vs, v) push!(vs, v)
break break
@ -428,9 +433,9 @@ end
#turn tuple of fillranges to one path #turn tuple of fillranges to one path
function concatenate_fillrange(x, y::Tuple) function concatenate_fillrange(x, y::Tuple)
rib1, rib2 = first(y), last(y) rib1, rib2 = collect(first(y)), collect(last(y)) # collect needed until https://github.com/JuliaLang/julia/pull/37629 is merged
yline = vcat(rib1, (rib2)[end:-1:1]) yline = vcat(rib1, reverse(rib2))
xline = vcat(x, x[end:-1:1]) xline = vcat(x, reverse(x))
return xline, yline return xline, yline
end end
@ -499,7 +504,7 @@ for comp in (:line, :fill, :marker)
end end
end end
$get_compcolor(series, clims, i::Int = 1) = $get_compcolor(series, clims::Tuple{<:Number,<:Number}, i::Int = 1) =
$get_compcolor(series, clims[1], clims[2], i) $get_compcolor(series, clims[1], clims[2], i)
function $get_compcolor(series, i::Int = 1) function $get_compcolor(series, i::Int = 1)
@ -538,6 +543,7 @@ get_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
get_linewidth(series, i::Int = 1) = _cycle(series[:linewidth], i) get_linewidth(series, i::Int = 1) = _cycle(series[:linewidth], i)
get_linestyle(series, i::Int = 1) = _cycle(series[:linestyle], i) get_linestyle(series, i::Int = 1) = _cycle(series[:linestyle], i)
get_fillstyle(series, i::Int = 1) = _cycle(series[:fillstyle], i)
function get_markerstrokecolor(series, i::Int = 1) function get_markerstrokecolor(series, i::Int = 1)
msc = series[:markerstrokecolor] msc = series[:markerstrokecolor]
@ -556,6 +562,7 @@ const _segmenting_vector_attributes = (
:linestyle, :linestyle,
:fillcolor, :fillcolor,
:fillalpha, :fillalpha,
:fillstyle,
:markercolor, :markercolor,
:markeralpha, :markeralpha,
:markersize, :markersize,
@ -570,7 +577,6 @@ const _segmenting_array_attributes = :line_z, :fill_z, :marker_z
function has_attribute_segments(series::Series) function has_attribute_segments(series::Series)
# we want to check if a series needs to be split into segments just because # we want to check if a series needs to be split into segments just because
# of its attributes # of its attributes
series[:seriestype] == :shape && return false
# check relevant attributes if they have multiple inputs # check relevant attributes if they have multiple inputs
return any( return any(
series[attr] isa AbstractVector && length(series[attr]) > 1 for series[attr] isa AbstractVector && length(series[attr]) > 1 for
@ -645,7 +651,7 @@ function with(f::Function, args...; kw...)
newdefs[:xticks] = nothing newdefs[:xticks] = nothing
newdefs[:yticks] = nothing newdefs[:yticks] = nothing
newdefs[:grid] = false newdefs[:grid] = false
newdefs[:legend] = false newdefs[:legend_position] = false
end end
# dict to store old and new keyword args for anything that changes # dict to store old and new keyword args for anything that changes
@ -814,7 +820,7 @@ end
function extend_series_data!(series::Series, v, letter) function extend_series_data!(series::Series, v, letter)
copy_series!(series, letter) copy_series!(series, letter)
d = extend_by_data!(series[letter], v) d = extend_by_data!(series[letter], v)
expand_extrema!(series[:subplot][Symbol(letter, :axis)], d) expand_extrema!(series[:subplot][get_attr_symbol(letter, :axis)], d)
return d return d
end end
@ -980,21 +986,21 @@ titlefont(sp::Subplot) = font(;
) )
legendfont(sp::Subplot) = font(; legendfont(sp::Subplot) = font(;
family = sp[:legendfontfamily], family = sp[:legend_font_family],
pointsize = sp[:legendfontsize], pointsize = sp[:legend_font_pointsize],
valign = sp[:legendfontvalign], valign = sp[:legend_font_valign],
halign = sp[:legendfonthalign], halign = sp[:legend_font_halign],
rotation = sp[:legendfontrotation], rotation = sp[:legend_font_rotation],
color = sp[:legendfontcolor], color = sp[:legend_font_color],
) )
legendtitlefont(sp::Subplot) = font(; legendtitlefont(sp::Subplot) = font(;
family = sp[:legendtitlefontfamily], family = sp[:legend_title_font_family],
pointsize = sp[:legendtitlefontsize], pointsize = sp[:legend_title_font_pointsize],
valign = sp[:legendtitlefontvalign], valign = sp[:legend_title_font_valign],
halign = sp[:legendtitlefonthalign], halign = sp[:legend_title_font_halign],
rotation = sp[:legendtitlefontrotation], rotation = sp[:legend_title_font_rotation],
color = sp[:legendtitlefontcolor], color = sp[:legend_title_font_color],
) )
tickfont(ax::Axis) = font(; tickfont(ax::Axis) = font(;
@ -1178,16 +1184,10 @@ end
_document_argument(S::AbstractString) = _document_argument(S::AbstractString) =
_fmt_paragraph("`$S`: " * _arg_desc[Symbol(S)], leadingspaces = 6 + length(S)) _fmt_paragraph("`$S`: " * _arg_desc[Symbol(S)], leadingspaces = 6 + length(S))
function mesh3d_triangles(x, y, z, cns) function mesh3d_triangles(x, y, z, cns::Tuple{Array,Array,Array})
if typeof(cns) <: Tuple{Array,Array,Array}
ci, cj, ck = cns ci, cj, ck = cns
if !(length(ci) == length(cj) == length(ck)) if !(length(ci) == length(cj) == length(ck))
throw( throw(ArgumentError("Argument connections must consist of equally sized arrays."))
ArgumentError("Argument connections must consist of equally sized arrays."),
)
end
else
throw(ArgumentError("Argument connections has to be a tuple of three arrays."))
end end
X = zeros(eltype(x), 4length(ci)) X = zeros(eltype(x), 4length(ci))
Y = zeros(eltype(y), 4length(cj)) Y = zeros(eltype(y), 4length(cj))
@ -1212,3 +1212,37 @@ function mesh3d_triangles(x, y, z, cns)
end end
return X, Y, Z return X, Y, Z
end end
function mesh3d_triangles(x, y, z, cns::AbstractVector{NTuple{3,Int}})
X = zeros(eltype(x), 4length(cns))
Y = zeros(eltype(y), 4length(cns))
Z = zeros(eltype(z), 4length(cns))
@inbounds for I in 1:length(cns)
i = cns[I][1] # connections are 1-based
j = cns[I][2]
k = cns[I][3]
m = 4(I - 1) + 1
n = m + 1
o = m + 2
p = m + 3
X[m] = X[p] = x[i]
Y[m] = Y[p] = y[i]
Z[m] = Z[p] = z[i]
X[n] = x[j]
Y[n] = y[j]
Z[n] = z[j]
X[o] = x[k]
Y[o] = y[k]
Z[o] = z[k]
end
return X, Y, Z
end
# cache joined symbols so they can be looked up instead of constructed each time
const _attrsymbolcache = Dict{Symbol,Dict{Symbol,Symbol}}()
get_attr_symbol(letter::Symbol, keyword::String) = get_attr_symbol(letter, Symbol(keyword))
get_attr_symbol(letter::Symbol, keyword::Symbol) = _attrsymbolcache[letter][keyword]
texmath2unicode(s::AbstractString, pat = r"\$([^$]+)\$") =
replace(s, pat => m -> UnicodeFun.to_latex(m[2:(length(m) - 1)]))

View File

@ -13,7 +13,6 @@ function replace_rand!(ex::Expr)
end end
function fix_rand!(ex) function fix_rand!(ex)
replace_rand!(ex) replace_rand!(ex)
pushfirst!(ex.args[1].args, :(rng = StableRNG(PLOTS_SEED)))
end end
function image_comparison_tests( function image_comparison_tests(
@ -39,10 +38,13 @@ function image_comparison_tests(
# test function # test function
func = (fn, idx) -> begin func = (fn, idx) -> begin
eval(:(rng = StableRNG(PLOTS_SEED)))
for the_expr in example.exprs
expr = Expr(:block) expr = Expr(:block)
append!(expr.args, example.exprs) push!(expr.args, the_expr)
fix_rand!(expr) fix_rand!(expr)
eval(expr) eval(expr)
end
png(fn) png(fn)
end end

View File

@ -1,17 +1,26 @@
using Plots: guidefont, series_annotations, PLOTS_SEED using Plots: guidefont, series_annotations, PLOTS_SEED
import ImageMagick
using VisualRegressionTests using VisualRegressionTests
using Plots
using Random
using StableRNGs
using Test
using TestImages
using FileIO
using Gtk
using LibGit2
import GeometryBasics
using Dates
using RecipesBase using RecipesBase
using StableRNGs
using TestImages
using LibGit2
using Random
using FileIO
using Plots
using Dates
using JSON
using Test
using Gtk
import GeometryBasics
import ImageMagick
@testset "Infrastructure" begin
@test_nowarn JSON.Parser.parse(
String(read(joinpath(dirname(pathof(Plots)), "..", ".zenodo.json"))),
)
end
@testset "Plotly standalone" begin @testset "Plotly standalone" begin
@test_nowarn Plots._init_ijulia_plotting() @test_nowarn Plots._init_ijulia_plotting()
@ -26,136 +35,120 @@ using RecipesBase
end end
Plots.plotly_local_file_path[] = nothing Plots.plotly_local_file_path[] = nothing
Plots.use_local_dependencies[] = temp Plots.use_local_dependencies[] = temp
end # testset
include("test_defaults.jl")
include("test_pipeline.jl")
include("test_axes.jl")
include("test_contours.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")
include("test_plotly.jl")
reference_dir(args...) =
joinpath(homedir(), ".julia", "dev", "PlotReferenceImages", args...)
function reference_file(backend, i, version)
refdir = reference_dir("Plots", string(backend))
fn = "ref$i.png"
versions = sort(VersionNumber.(readdir(refdir)), rev = true)
reffn = joinpath(refdir, string(version), fn)
for v in versions
tmpfn = joinpath(refdir, string(v), fn)
if isfile(tmpfn)
reffn = tmpfn
break
end
end end
return reffn @testset "Utils" begin
end zipped = (
[(1, 2)],
reference_path(backend, version) = reference_dir("Plots", string(backend), string(version)) [("a", "b")],
[(1, "a"), (2, "b")],
if !isdir(reference_dir()) [(1, 2), (3, 4)],
mkpath(reference_dir()) [(1, 2, 3), (3, 4, 5)],
LibGit2.clone( [(1, 2, 3, 4), (3, 4, 5, 6)],
"https://github.com/JuliaPlots/PlotReferenceImages.jl.git", [(1, 2.0), (missing, missing)],
reference_dir(), [(1, missing), (missing, "a")],
[(missing, missing)],
[(missing, missing, missing), ("a", "b", "c")],
)
for z in zipped
@test isequal(collect(zip(Plots.RecipesPipeline.unzip(z)...)), z)
@test isequal(
collect(zip(Plots.RecipesPipeline.unzip(GeometryBasics.Point.(z))...)),
z,
) )
end 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)
include("imgcomp.jl") @test (==)(
# don't actually show the plots Plots.texmath2unicode(
Random.seed!(PLOTS_SEED) raw"Equation $y = \alpha \cdot x + \beta$ and eqn $y = \sin(x)^2$",
default(show = false, reuse = true) ),
is_ci() = get(ENV, "CI", "false") == "true" raw"Equation y = α ⋅ x + β and eqn y = sin(x)²",
const PLOTS_IMG_TOL = parse(Float64, get(ENV, "PLOTS_IMG_TOL", is_ci() ? "1e-4" : "1e-5"))
## Uncomment the following lines to update reference images for different backends
# @testset "GR" begin
# image_comparison_facts(:gr, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:gr])
# end
#
# plotly()
# @testset "Plotly" begin
# image_comparison_facts(:plotly, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:plotlyjs])
# end
#
# pyplot()
# @testset "PyPlot" begin
# image_comparison_facts(:pyplot, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:pyplot])
# end
#
# pgfplotsx()
# @testset "PGFPlotsX" begin
# image_comparison_facts(:pgfplotsx, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:pgfplotsx])
# end
# 10 Histogram2D
##
@testset "Backends" begin
@testset "GR" begin
ENV["PLOTS_TEST"] = "true"
ENV["GKSwstype"] = "100"
@test gr() == Plots.GRBackend()
@test backend() == Plots.GRBackend()
@static if haskey(ENV, "APPVEYOR")
@info "Skipping GR image comparison tests on AppVeyor"
else
image_comparison_facts(
:gr,
tol = PLOTS_IMG_TOL,
skip = Plots._backend_skips[:gr],
) )
end
end
@testset "UnicodePlots" begin @test Plots.isvector([1, 2])
@test unicodeplots() == Plots.UnicodePlotsBackend() @test !Plots.isvector(nothing)
@test backend() == Plots.UnicodePlotsBackend() @test Plots.ismatrix([1 2; 3 4])
@test !Plots.ismatrix(nothing)
@test Plots.isscalar(1.0)
@test !Plots.isscalar(nothing)
@test Plots.tovec([]) isa AbstractVector
@test Plots.tovec(nothing) isa AbstractVector
@test Plots.anynan(1, 3, (1, NaN, 3))
@test Plots.allnan(1, 2, (NaN, NaN, 1))
@test Plots.makevec([]) isa AbstractVector
@test Plots.makevec(1) isa AbstractVector
@test Plots.maketuple(1) == (1, 1)
@test Plots.maketuple((1, 1)) == (1, 1)
@test Plots.ok(1, 2)
@test !Plots.ok(1, 2, NaN)
@test Plots.ok((1, 2, 3))
@test !Plots.ok((1, 2, NaN))
@test Plots.nansplit([1, 2, NaN, 3, 4]) == [[1.0, 2.0], [3.0, 4.0]]
@test Plots.nanvcat([1, NaN]) |> length == 4
# lets just make sure it runs without error @test Plots.nop() === nothing
p = plot(rand(10)) @test_throws ErrorException Plots.notimpl()
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
p = bar(randn(10))
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
p = plot([1, 2], [3, 4])
annotate!(p, [(1.5, 3.2, Plots.text("Test", :red, :center))])
hline!(p, [3.1])
@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])
hline!(p, [3.1])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
@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, :auto)])
hline!(p, [3.1])
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
end
@testset "PlotlyJS" begin @test Plots.inch2px(1) isa AbstractFloat
@test plotlyjs() == Plots.PlotlyJSBackend() @test Plots.px2inch(1) isa AbstractFloat
@test backend() == Plots.PlotlyJSBackend() @test Plots.inch2mm(1) isa AbstractFloat
@test Plots.mm2inch(1) isa AbstractFloat
@test Plots.px2mm(1) isa AbstractFloat
@test Plots.mm2px(1) isa AbstractFloat
p = plot(rand(10)) p = plot()
@test isa(p, Plots.Plot) == true @test xlims() isa Tuple
@test_broken isa(display(p), Nothing) == true @test ylims() isa Tuple
@test zlims() isa Tuple
Plots.makekw(foo = 1, bar = 2) isa Dict
@test_throws ErrorException Plots.inline()
@test_throws ErrorException Plots._do_plot_show(plot(), :inline)
@test_throws ErrorException Plots.dumpcallstack()
Plots.debugplots(true)
Plots.debugplots(false)
Plots.debugshow(devnull, nothing)
Plots.debugshow(devnull, [1])
p = plot(1)
push!(p, 1.5)
push!(p, 1, 1.5)
# append!(p, [1., 2.])
append!(p, 1, 2.5, 2.5)
push!(p, (1.5, 2.5))
push!(p, 1, (1.5, 2.5))
append!(p, (1.5, 2.5))
append!(p, 1, (1.5, 2.5))
p = plot([1, 2, 3], [4, 5, 6])
@test Plots.xmin(p) == 1
@test Plots.xmax(p) == 3
@test Plots.ignorenan_extrema(p) == (1, 3)
@test Plots.get_attr_symbol(:x, "lims") == :xlims
@test Plots.get_attr_symbol(:x, :lims) == :xlims
@testset "NaN-separated Segments" begin
segments(args...) = collect(iter_segments(args...))
nan10 = fill(NaN, 10)
@test segments(11:20) == [1:10]
@test segments([NaN]) == []
@test segments(nan10) == []
@test segments([nan10; 1:5]) == [11:15]
@test segments([1:5; nan10]) == [1:5]
@test segments([nan10; 1:5; nan10; 1:5; nan10]) == [11:15, 26:30]
@test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10]
@test segments([nan10; 1:15], [1:15; nan10]) == [11:15]
end end
end end
@ -178,8 +171,10 @@ end
@test unicodeplots() == Plots.UnicodePlotsBackend() @test unicodeplots() == Plots.UnicodePlotsBackend()
@test backend() == Plots.UnicodePlotsBackend() @test backend() == Plots.UnicodePlotsBackend()
@testset "Plot" begin dsp = TextDisplay(IOContext(IOBuffer(), :color => true))
plots = [
@testset "plot" begin
for plt in [
histogram([1, 0, 0, 0, 0, 0]), histogram([1, 0, 0, 0, 0, 0]),
plot([missing]), plot([missing]),
plot([missing, missing]), plot([missing, missing]),
@ -189,62 +184,300 @@ end
plot([1 1; 1 missing]), plot([1 1; 1 missing]),
plot(["a" "b"; missing "d"], [1 2; 3 4]), plot(["a" "b"; missing "d"], [1 2; 3 4]),
] ]
for plt in plots display(dsp, plt)
display(plt)
end end
@test_nowarn plot(x -> x^2, 0, 2) @test_nowarn plot(x -> x^2, 0, 2)
end end
@testset "Bar" begin @testset "bar" begin
p = bar([3, 2, 1], [1, 2, 3]) p = bar([3, 2, 1], [1, 2, 3])
@test isa(p, Plots.Plot) @test p isa Plots.Plot
@test isa(display(p), Nothing) == true @test display(dsp, p) isa Nothing
end
@testset "gui" begin
open(tempname(), "w") do io
redirect_stdout(io) do
gui(plot())
end
end
end end
end end
@testset "EmptyAnim" begin @testset "Coverage" begin
anim = @animate for i in [] @testset "themes" begin
p = showtheme(:dark)
@test p isa Plots.Plot
end end
@test_throws ArgumentError gif(anim) @testset "plotattr" begin
tmp = tempname()
open(tmp, "w") do io
redirect_stdout(io) do
plotattr("seriestype")
plotattr(:Plot)
plotattr()
end
end
str = join(readlines(tmp), "")
@test occursin("seriestype", str)
@test occursin("Plot attributes", str)
end end
@testset "NaN-separated Segments" begin @testset "legend" begin
segments(args...) = collect(iter_segments(args...)) @test isa(
Plots.legend_pos_from_angle(20, 0.0, 0.5, 1.0, 0.0, 0.5, 1.0),
nan10 = fill(NaN, 10) NTuple{2,<:AbstractFloat},
@test segments(11:20) == [1:10]
@test segments([NaN]) == []
@test segments(nan10) == []
@test segments([nan10; 1:5]) == [11:15]
@test segments([1:5; nan10]) == [1:5]
@test segments([nan10; 1:5; nan10; 1:5; nan10]) == [11:15, 26:30]
@test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10]
@test segments([nan10; 1:15], [1:15; nan10]) == [11:15]
end
@testset "Utils" begin
zipped = (
[(1, 2)],
[("a", "b")],
[(1, "a"), (2, "b")],
[(1, 2), (3, 4)],
[(1, 2, 3), (3, 4, 5)],
[(1, 2, 3, 4), (3, 4, 5, 6)],
[(1, 2.0), (missing, missing)],
[(1, missing), (missing, "a")],
[(missing, missing)],
[(missing, missing, missing), ("a", "b", "c")],
) )
for z in zipped @test Plots.legend_anchor_index(-1) == 1
@test isequal(collect(zip(Plots.unzip(z)...)), z) @test Plots.legend_anchor_index(+0) == 2
@test isequal(collect(zip(Plots.unzip(GeometryBasics.Point.(z))...)), z) @test Plots.legend_anchor_index(+1) == 3
@test Plots.legend_angle(:foo_bar) == (45, :inner)
@test Plots.legend_angle(20.0) ==
Plots.legend_angle((20.0, :inner)) ==
(20.0, :inner)
@test Plots.legend_angle((20.0, 10.0)) == (20.0, 10.0)
end
end
@testset "Output" begin
@test Plots.defaultOutputFormat(plot()) == "png"
@test Plots.addExtension("foo", "bar") == "foo.bar"
fn = tempname()
gr()
let p = plot()
Plots.png(p, fn)
Plots.png(fn)
savefig(p, "$fn.png")
savefig("$fn.png")
Plots.pdf(p, fn)
Plots.pdf(fn)
savefig(p, "$fn.pdf")
savefig("$fn.pdf")
Plots.ps(p, fn)
Plots.ps(fn)
savefig(p, "$fn.ps")
savefig("$fn.ps")
Plots.svg(p, fn)
Plots.svg(fn)
savefig(p, "$fn.svg")
savefig("$fn.svg")
end
if Sys.islinux()
pgfplotsx()
let p = plot()
Plots.tex(p, fn)
Plots.tex(fn)
savefig(p, "$fn.tex")
savefig("$fn.tex")
end
end
unicodeplots()
let p = plot()
Plots.txt(p, fn)
Plots.txt(fn)
savefig(p, "$fn.txt")
savefig("$fn.txt")
end
plotlyjs()
let p = plot()
Plots.html(p, fn)
Plots.html(fn)
savefig(p, "$fn.html")
savefig("$fn.html")
if Sys.islinux()
Plots.eps(p, fn)
Plots.eps(fn)
savefig(p, "$fn.eps")
savefig("$fn.eps")
end
end
@test_throws ErrorException savefig("$fn.foo")
end
gr() # reset to default backend
for fn in (
"test_args.jl",
"test_defaults.jl",
"test_pipeline.jl",
"test_axes.jl",
"test_layouts.jl",
"test_contours.jl",
"test_axis_letter.jl",
"test_components.jl",
"test_shorthands.jl",
"integration_dates.jl",
"test_recipes.jl",
"test_hdf5plots.jl",
"test_pgfplotsx.jl",
"test_plotly.jl",
"test_animations.jl",
)
@testset "$fn" begin
include(fn)
end
end
reference_dir(args...) =
joinpath(homedir(), ".julia", "dev", "PlotReferenceImages", args...)
function reference_file(backend, i, version)
refdir = reference_dir("Plots", string(backend))
fn = "ref$i.png"
versions = sort(VersionNumber.(readdir(refdir)), rev = true)
reffn = joinpath(refdir, string(version), fn)
for v in versions
tmpfn = joinpath(refdir, string(v), fn)
if isfile(tmpfn)
reffn = tmpfn
break
end
end
return reffn
end
reference_path(backend, version) = reference_dir("Plots", string(backend), string(version))
if !isdir(reference_dir())
mkpath(reference_dir())
LibGit2.clone(
"https://github.com/JuliaPlots/PlotReferenceImages.jl.git",
reference_dir(),
)
end
include("imgcomp.jl")
Random.seed!(PLOTS_SEED)
default(show = false, reuse = true) # don't actually show the plots
is_ci() = get(ENV, "CI", "false") == "true"
const PLOTS_IMG_TOL = parse(
Float64,
get(ENV, "PLOTS_IMG_TOL", is_ci() ? Sys.iswindows() ? "2e-4" : "1e-4" : "1e-5"),
)
## Uncomment the following lines to update reference images for different backends
# @testset "GR" begin
# image_comparison_facts(:gr, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:gr])
# end
#
# plotly()
# @testset "Plotly" begin
# image_comparison_facts(:plotly, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:plotlyjs])
# end
#
# pyplot()
# @testset "PyPlot" begin
# image_comparison_facts(:pyplot, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:pyplot])
# end
#
# pgfplotsx()
# @testset "PGFPlotsX" begin
# image_comparison_facts(:pgfplotsx, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:pgfplotsx])
# end
##
@testset "Examples" begin
if Sys.islinux()
backends = (
:unicodeplots,
:pgfplotsx,
:inspectdr,
:plotlyjs,
:gaston,
# :pyplot, # FIXME: fails with system matplotlib
)
only = setdiff(
1:length(Plots._examples),
(Plots._backend_skips[be] for be in backends)...,
)
for be in backends
@info be
for (i, p) in Plots.test_examples(be, only = only, disp = false)
fn = tempname() * ".png"
png(p, fn)
@test filesize(fn) > 1_000
end
end
end
end
@testset "Backends" begin
@testset "UnicodePlots" begin
@test unicodeplots() == Plots.UnicodePlotsBackend()
@test backend() == Plots.UnicodePlotsBackend()
io = IOContext(IOBuffer(), :color => true)
# lets just make sure it runs without error
p = plot(rand(10))
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = bar(randn(10))
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = plot([1, 2], [3, 4])
annotate!(p, [(1.5, 3.2, Plots.text("Test", :red, :center))])
hline!(p, [3.1])
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
hline!(p, [3.1])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, :auto)])
hline!(p, [3.1])
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = plot((plot(i) for i in 1:4)..., layout = (2, 2))
@test p isa Plots.Plot
@test show(io, p) isa Nothing
end
@testset "GR" begin
ENV["PLOTS_TEST"] = "true"
ENV["GKSwstype"] = "100"
@test gr() == Plots.GRBackend()
@test backend() == Plots.GRBackend()
@static if haskey(ENV, "APPVEYOR")
@info "Skipping GR image comparison tests on AppVeyor"
else
image_comparison_facts(
:gr,
tol = PLOTS_IMG_TOL,
skip = Plots._backend_skips[:gr],
)
end
end
@testset "PlotlyJS" begin
@test plotlyjs() == Plots.PlotlyJSBackend()
@test backend() == Plots.PlotlyJSBackend()
p = plot(rand(10))
@test p isa Plots.Plot
@test_broken display(p) isa Nothing
end 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 end

61
test/test_animations.jl Normal file
View File

@ -0,0 +1,61 @@
@testset "Empty anim" begin
anim = @animate for i in []
end
@test_throws ArgumentError gif(anim)
end
@userplot CirclePlot
@recipe function f(cp::CirclePlot)
x, y, i = cp.args
n = length(x)
inds = circshift(1:n, 1 - i)
linewidth --> range(0, 10, length = n)
seriesalpha --> range(0, 1, length = n)
aspect_ratio --> 1
label --> false
x[inds], y[inds]
end
@testset "Circle plot" begin
n = 10
t = range(0, 2π, length = n)
x = sin.(t)
y = cos.(t)
anim = @animate for i in 1:n
circleplot(x, y, i)
end
@test filesize(gif(anim).filename) > 10_000
@test filesize(mov(anim).filename) > 10_000
@test filesize(mp4(anim).filename) > 10_000
@test filesize(webm(anim).filename) > 10_000
@gif for i in 1:n
circleplot(x, y, i, line_z = 1:n, cbar = false, framestyle = :zerolines)
end every 5
end
@testset "html" begin
p = plot([sin, cos], zeros(0), leg = false, xlims = (0, 2π), ylims = (-1, 1))
anim = Animation()
for x in range(0, stop = 2π, length = 10)
push!(p, x, Float64[sin(x), cos(x)])
frame(anim)
end
agif = gif(anim)
html = tempname() * ".html"
open(html, "w") do io
show(io, MIME("text/html"), agif)
end
@test filesize(html) > 10_000
@test showable(MIME("image/gif"), agif)
agif = mp4(anim)
html = tempname() * ".html"
open(html, "w") do io
show(io, MIME("text/html"), agif)
end
@test filesize(html) > 10_000
end

27
test/test_args.jl Normal file
View File

@ -0,0 +1,27 @@
using Plots, Test
@testset "Series Attributes" begin
pl = plot([[1, 2, 3], [2, 3, 4]], lw = 5)
@test hline!(deepcopy(pl), [1.75])[1].series_list[3][:label] ==
hline!(deepcopy(pl), [1.75], z_order = :front)[1].series_list[3][:label] ==
"y3"
@test hline!(deepcopy(pl), [1.75], z_order = :back)[1].series_list[1][:label] == "y3"
@test hline!(deepcopy(pl), [1.75], z_order = 2)[1].series_list[2][:label] == "y3"
end
@testset "Axis Attributes" begin
pl = @test_nowarn plot(; tickfont = font(10, "Times"))
for axis in (:xaxis, :yaxis, :zaxis)
@test pl[1][axis][:tickfontsize] == 10
@test pl[1][axis][:tickfontfamily] == "Times"
end
end
@testset "Permute recipes" begin
pl = bar(["a", "b", "c"], [1, 2, 3])
ppl = bar(["a", "b", "c"], [1, 2, 3], permute = (:x, :y))
@test xticks(ppl) == yticks(pl)
@test yticks(ppl) == xticks(pl)
@test filter(isfinite, pl[1][1][:x]) == filter(isfinite, ppl[1][1][:y])
@test filter(isfinite, pl[1][1][:y]) == filter(isfinite, ppl[1][1][:x])
end

View File

@ -63,3 +63,60 @@ end
@test twpl[:top_margin] == 2Plots.cm @test twpl[:top_margin] == 2Plots.cm
@test twpl[:bottom_margin] == 2Plots.cm @test twpl[:bottom_margin] == 2Plots.cm
end end
@testset "axis-aliases" begin
@test haskey(Plots._keyAliases, :xguideposition)
@test haskey(Plots._keyAliases, :x_guide_position)
@test !haskey(Plots._keyAliases, :xguide_position)
p = plot(1:2, xl = "x label")
@test p[1][:xaxis][:guide] === "x label"
p = plot(1:2, xrange = (0, 3))
@test xlims(p) === (0, 3)
p = plot(1:2, xtick = [1.25, 1.5, 1.75])
@test p[1][:xaxis][:ticks] == [1.25, 1.5, 1.75]
p = plot(1:2, xlabelfontsize = 4)
@test p[1][:xaxis][:guidefontsize] == 4
p = plot(1:2, xgα = 0.07)
@test p[1][:xaxis][:gridalpha] 0.07
p = plot(1:2, xgridls = :dashdot)
@test p[1][:xaxis][:gridstyle] === :dashdot
p = plot(1:2, xgridcolor = :red)
@test p[1][:xaxis][:foreground_color_grid] === RGBA{Float64}(1.0, 0.0, 0.0, 1.0)
p = plot(1:2, xminorgridcolor = :red)
@test p[1][:xaxis][:foreground_color_minor_grid] === RGBA{Float64}(1.0, 0.0, 0.0, 1.0)
p = plot(1:2, xgrid_lw = 0.01)
@test p[1][:xaxis][:gridlinewidth] 0.01
p = plot(1:2, xminorgrid_lw = 0.01)
@test p[1][:xaxis][:minorgridlinewidth] 0.01
p = plot(1:2, xtickor = :out)
@test p[1][:xaxis][:tick_direction] === :out
end
@testset "aliases" begin
compare(p::Plots.Plot, s::Symbol, val, op) =
op(p[1][:xaxis][s], val) && op(p[1][:yaxis][s], val) && op(p[1][:zaxis][s], val)
p = plot(1:2, guide = "all labels")
@test compare(p, :guide, "all labels", ===)
p = plot(1:2, label = "test")
@test compare(p, :guide, "", ===)
p = plot(1:2, lim = (0, 3))
@test xlims(p) === ylims(p) === zlims(p) === (0, 3)
p = plot(1:2, tick = [1.25, 1.5, 1.75])
@test compare(p, :ticks, [1.25, 1.5, 1.75], ==)
p = plot(1:2, labelfontsize = 4)
@test compare(p, :guidefontsize, 4, ==)
p = plot(1:2, gα = 0.07)
@test compare(p, :gridalpha, 0.07, )
p = plot(1:2, gridls = :dashdot)
@test compare(p, :gridstyle, :dashdot, ===)
p = plot(1:2, gridcolor = :red)
@test compare(p, :foreground_color_grid, RGBA{Float64}(1.0, 0.0, 0.0, 1.0), ===)
p = plot(1:2, minorgridcolor = :red)
@test compare(p, :foreground_color_minor_grid, RGBA{Float64}(1.0, 0.0, 0.0, 1.0), ===)
p = plot(1:2, grid_lw = 0.01)
@test compare(p, :gridlinewidth, 0.01, )
p = plot(1:2, minorgrid_lw = 0.01)
@test compare(p, :minorgridlinewidth, 0.01, )
p = plot(1:2, tickor = :out)
@test compare(p, :tick_direction, :out, ===)
end

View File

@ -3,6 +3,9 @@ using Plots, Test
@testset "Shapes" begin @testset "Shapes" begin
@testset "Type" begin @testset "Type" begin
square = Shape([(0, 0.0), (1, 0.0), (1, 1.0), (0, 1.0)]) square = Shape([(0, 0.0), (1, 0.0), (1, 1.0), (0, 1.0)])
@test Plots.get_xs(square) == [0, 1, 1, 0]
@test Plots.get_ys(square) == [0, 0, 1, 1]
@test Plots.vertices(square) == [(0, 0), (1, 0), (1, 1), (0, 1)]
@test isa(square, Shape{Int64,Float64}) @test isa(square, Shape{Int64,Float64})
@test coords(square) isa Tuple{Vector{S},Vector{T}} where {T,S} @test coords(square) isa Tuple{Vector{S},Vector{T}} where {T,S}
end end
@ -58,6 +61,25 @@ using Plots, Test
@test_nowarn p = plot(myshapes) @test_nowarn p = plot(myshapes)
@test p[1][1][:seriestype] == :shape @test p[1][1][:seriestype] == :shape
end end
@testset "Misc" begin
@test Plots.weave([1, 3], [2, 4]) == collect(1:4)
@test Plots.makeshape(3) isa Plots.Shape
@test Plots.makestar(3) isa Plots.Shape
@test Plots.makecross() isa Plots.Shape
@test Plots.makearrowhead(10.0) isa Plots.Shape
@test Plots.rotate(1.0, 2.0, 5.0, (0, 0)) isa Tuple
star = Plots.makestar(3)
star_scaled = Plots.scale(star, 0.5)
Plots.scale!(star, 0.5)
@test Plots.get_xs(star) == Plots.get_xs(star_scaled)
@test Plots.get_ys(star) == Plots.get_ys(star_scaled)
@test Plots.extrema_plus_buffer([1, 2], 0.1) == (0.9, 2.1)
end
end end
@testset "Brush" begin @testset "Brush" begin
@ -82,6 +104,39 @@ end
end end
end end
@testset "Text" begin
t = Plots.PlotText("foo")
f = Plots.font()
@test Plots.PlotText(nothing).str == "nothing"
@test length(t) == 3
@test text(t).str == "foo"
@test text(t, f).str == "foo"
@test text("bar", f).str == "bar"
@test text(true).str == "true"
end
@testset "Annotations" begin
ann = Plots.series_annotations(missing)
@test Plots.series_annotations(["1" "2"; "3" "4"]) isa AbstractMatrix
@test Plots.series_annotations(10).strs[1].str == "10"
@test Plots.series_annotations(nothing) === nothing
@test Plots.series_annotations(ann) == ann
@test Plots.annotations(["1" "2"; "3" "4"]) isa AbstractMatrix
@test Plots.annotations(ann) == ann
@test Plots.annotations([ann]) == [ann]
@test Plots.annotations(nothing) == []
t = Plots.text("foo")
sp = plot(1)[1]
@test Plots.locate_annotation(sp, 1, 2, t) == (1, 2, t)
@test Plots.locate_annotation(sp, 1, 2, 3, t) == (1, 2, 3, t)
@test Plots.locate_annotation(sp, (0.1, 0.2), t) isa Tuple
@test Plots.locate_annotation(sp, (0.1, 0.2, 0.3), t) isa Tuple
end
@testset "Fonts" begin @testset "Fonts" begin
@testset "Scaling" begin @testset "Scaling" begin
sizesToCheck = [ sizesToCheck = [
@ -158,3 +213,9 @@ end
@test pos == (0.1, 0.5) @test pos == (0.1, 0.5)
@test txt.str == "(a)" @test txt.str == "(a)"
end end
@testset "Bezier" begin
curve = Plots.BezierCurve([Plots.P2(0.0, 0.0), Plots.P2(0.5, 1.0), Plots.P2(1.0, 0.0)])
@test curve(0.75) == Plots.P2(0.75, 0.375)
@test length(coords(curve, 10)) == 10
end

View File

@ -1,4 +1,4 @@
using Plots, Test using Plots, Test, Plots.Colors
const PLOTS_DEFAULTS = Dict(:theme => :wong2, :fontfamily => :palantino) const PLOTS_DEFAULTS = Dict(:theme => :wong2, :fontfamily => :palantino)
Plots.__init__() Plots.__init__()
@ -6,8 +6,96 @@ Plots.__init__()
@testset "Loading theme" begin @testset "Loading theme" begin
pl = plot(1:5) pl = plot(1:5)
@test pl[1][1][:seriescolor] == RGBA(colorant"black") @test pl[1][1][:seriescolor] == RGBA(colorant"black")
@test guidefont(pl[1][:xaxis]).family == "palantino" @test Plots.guidefont(pl[1][:xaxis]).family == "palantino"
end end
empty!(PLOTS_DEFAULTS) empty!(PLOTS_DEFAULTS)
Plots.__init__() Plots.__init__()
@testset "default" begin
default(fillrange = 0)
@test Plots._series_defaults[:fillrange] == 0
pl = plot(1:5)
@test pl[1][1][:fillrange] == 0
default()
end
@testset "Legend defaults" begin
p = plot()
@test p[1][:legend_font_family] == "sans-serif"
@test p[1][:legend_font_pointsize] == 8
@test p[1][:legend_font_halign] == :hcenter
@test p[1][:legend_font_valign] == :vcenter
@test p[1][:legend_font_rotation] == 0.0
@test p[1][:legend_font_color] == RGB{Colors.N0f8}(0.0, 0.0, 0.0)
@test p[1][:legend_position] == :best
@test p[1][:legend_title] == nothing
@test p[1][:legend_title_font_family] == "sans-serif"
@test p[1][:legend_title_font_pointsize] == 11
@test p[1][:legend_title_font_halign] == :hcenter
@test p[1][:legend_title_font_valign] == :vcenter
@test p[1][:legend_title_font_rotation] == 0.0
@test p[1][:legend_title_font_color] == RGB{Colors.N0f8}(0.0, 0.0, 0.0)
@test p[1][:legend_background_color] == RGBA{Float64}(1.0, 1.0, 1.0, 1.0)
@test p[1][:legend_foreground_color] == RGB{Colors.N0f8}(0.0, 0.0, 0.0)
end # testset
@testset "Legend API" begin
p = plot(;
legendfontfamily = "serif",
legendfontsize = 12,
legendfonthalign = :left,
legendfontvalign = :top,
legendfontrotation = 1,
legendfontcolor = :red,
legend = :outertopleft,
legendtitle = "The legend",
legendtitlefontfamily = "helvetica",
legendtitlefontsize = 3,
legendtitlefonthalign = :right,
legendtitlefontvalign = :bottom,
legendtitlefontrotation = -5.2,
legendtitlefontcolor = :blue,
background_color_legend = :cyan,
foreground_color_legend = :green,
)
@test p[1][:legend_font_family] == "serif"
@test p[1][:legend_font_pointsize] == 12
@test p[1][:legend_font_halign] == :left
@test p[1][:legend_font_valign] == :top
@test p[1][:legend_font_rotation] == 1.0
@test p[1][:legend_font_color] == :red
@test p[1][:legend_position] == :outertopleft
@test p[1][:legend_title] == "The legend"
@test p[1][:legend_title_font_family] == "helvetica"
@test p[1][:legend_title_font_pointsize] == 3
@test p[1][:legend_title_font_halign] == :right
@test p[1][:legend_title_font_valign] == :bottom
@test p[1][:legend_title_font_rotation] == -5.2
@test p[1][:legend_title_font_color] == :blue
@test p[1][:legend_background_color] == RGBA{Float64}(0.0, 1.0, 1.0, 1.0)
@test p[1][:legend_foreground_color] == RGBA{Float64}(0.0, 0.5019607843137255, 0.0, 1.0)
#remember settings
plot(legend_font_pointsize = 20)
sp = plot!(label = "R")[1]
@test Plots.legendfont(sp).pointsize == 20
#setting whole font
sp = plot(
1:5,
legendfont = font(12),
legend_font_halign = :left,
foreground_color_subplot = :red,
)[1]
@test Plots.legendfont(sp).pointsize == 12
@test Plots.legendfont(sp).halign == :left
# match mechanism
@test sp[:legend_font_color] == sp[:foreground_color_subplot]
@test Plots.legendfont(sp).color == sp[:foreground_color_subplot]
# magic invocation
@test_nowarn sp = plot(; legendfont = 12)[1]
@test sp[:legend_font_pointsize] == 12
@test Plots.legendfont(sp).pointsize == 12
end # testset

98
test/test_layouts.jl Normal file
View File

@ -0,0 +1,98 @@
using Plots, Test
@testset "Subplot sclicing" begin
pl = @test_nowarn plot(
rand(4, 8),
layout = 4,
yscale = [:identity :identity :log10 :log10],
)
@test pl[1][:yaxis][:scale] == :identity
@test pl[2][:yaxis][:scale] == :identity
@test pl[3][:yaxis][:scale] == :log10
@test pl[4][:yaxis][:scale] == :log10
end
@testset "Plot title" begin
pl = plot(rand(4, 8), layout = 4, plot_title = "My title")
@test pl[:plot_title] == "My title"
@test pl[:plot_titleindex] == 5
plot!(pl)
@test pl[:plot_title] == "My title"
@test pl[:plot_titleindex] == 5
plot!(pl, plot_title = "My new title")
@test pl[:plot_title] == "My new title"
@test pl[:plot_titleindex] == 5
end
@testset "Plots.jl/issues/4083" begin
p = plot(plot(1:2), plot(1:2); border = :grid, plot_title = "abc")
@test p[1][:framestyle] === :grid
@test p[2][:framestyle] === :grid
@test p[3][:framestyle] === :none
end
@testset "Coverage" begin
p = plot((plot(i) for i in 1:4)..., layout = (2, 2))
sp = p[end]
@test sp isa Plots.Subplot
@test size(sp) == (1, 1)
@test length(sp) == 1
@test sp[1, 1] == sp
@test Plots.get_subplot(p, UInt32(4)) == sp
@test Plots.series_list(sp) |> first |> Plots.get_subplot isa Plots.Subplot
@test Plots.get_subplot(p, keys(p.spmap) |> first) isa Plots.Subplot
gl = p[2, 2]
@test gl isa Plots.GridLayout
@test length(gl) == 1
@test size(gl) == (1, 1)
@test Plots.layout_args(gl) == (gl, 1)
@test size(p, 1) == 2
@test size(p, 2) == 2
@test size(p) === (2, 2)
@test ndims(p) == 2
@test p[1][end] isa Plots.Series
show(devnull, p[1])
@test Plots.getplot(p) == p
@test Plots.getattr(p) == p.attr
@test Plots.backend_object(p) == p.o
@test occursin("Plot", string(p))
print(devnull, p)
@test Plots.to_pixels(1Plots.mm) isa AbstractFloat
@test Plots.ispositive(1Plots.mm)
@test size(Plots.defaultbox) == (0Plots.mm, 0Plots.mm)
show(devnull, Plots.defaultbox)
show(devnull, p.layout)
@test Plots.make_measure_hor(1Plots.mm) == 1Plots.mm
@test Plots.make_measure_vert(1Plots.mm) == 1Plots.mm
@test Plots.parent(p.layout) isa Plots.RootLayout
show(devnull, Plots.parent_bbox(p.layout))
rl = Plots.RootLayout()
show(devnull, rl)
@test parent(rl) === nothing
@test Plots.parent_bbox(rl) == Plots.defaultbox
@test Plots.bbox(rl) == Plots.defaultbox
el = Plots.EmptyLayout()
@test Plots.update_position!(el) === nothing
@test size(el) == (0, 0)
@test length(el) == 0
@test el[1, 1] === nothing
@test Plots.left(el) == 0Plots.mm
@test Plots.top(el) == 0Plots.mm
@test Plots.right(el) == 0Plots.mm
@test Plots.bottom(el) == 0Plots.mm
@test_throws ErrorException Plots.layout_args(nothing)
end

View File

@ -21,16 +21,19 @@ end
@test !haskey(axis.contents[1].options.dict, "fill") @test !haskey(axis.contents[1].options.dict, "fill")
@testset "Legends" begin @testset "Legends" begin
legends_plot = plot(rand(5, 2), lab = ["1" ""]) legends_plot = plot(rand(5, 2), lab = ["1" ""], arrow = true)
scatter!(legends_plot, rand(5)) scatter!(legends_plot, rand(5))
Plots._update_plot_object(legends_plot) Plots._update_plot_object(legends_plot)
axis_contents = Plots.pgfx_axes(legends_plot.o)[1].contents axis_contents = Plots.pgfx_axes(legends_plot.o)[1].contents
leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents) leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents)
series = filter(x -> x isa PGFPlotsX.Plot, axis_contents) series = filter(x -> x isa PGFPlotsX.Plot, axis_contents)
@test length(leg_entries) == 2 @test length(leg_entries) == 2
@test length(series) == 5
@test !haskey(series[1].options.dict, "forget plot") @test !haskey(series[1].options.dict, "forget plot")
@test haskey(series[2].options.dict, "forget plot") @test haskey(series[2].options.dict, "forget plot")
@test !haskey(series[3].options.dict, "forget plot") @test haskey(series[3].options.dict, "forget plot")
@test haskey(series[4].options.dict, "forget plot")
@test !haskey(series[5].options.dict, "forget plot")
end # testset end # testset
@testset "3D docs example" begin @testset "3D docs example" begin

View File

@ -17,3 +17,22 @@ end
@test all(RecipesPipeline.get_axis_limits(p1, :x) .== x) @test all(RecipesPipeline.get_axis_limits(p1, :x) .== x)
@test all(RecipesPipeline.get_axis_limits(p2, :x) .== x) @test all(RecipesPipeline.get_axis_limits(p2, :x) .== x)
end end
@testset "Slicing" begin
@test plot(1:5, fillrange = 0)[1][1][:fillrange] == 0
data4 = rand(4, 4)
mat = reshape(1:8, 2, 4)
for i in axes(data4, 1)
for attribute in (:fillrange, :ribbon)
@test plot(data4; NamedTuple{tuple(attribute)}(0)...)[1][i][attribute] == 0
@test plot(data4; NamedTuple{tuple(attribute)}(Ref([1, 2]))...)[1][i][attribute] ==
[1.0, 2.0]
@test plot(data4; NamedTuple{tuple(attribute)}(Ref([1 2]))...)[1][i][attribute] ==
(iseven(i) ? 2 : 1)
@test plot(data4; NamedTuple{tuple(attribute)}(Ref(mat))...)[1][i][attribute] ==
[2(i - 1) + 1, 2i]
end
@test plot(data4, ribbon = (mat, mat))[1][i][:ribbon] ==
([2(i - 1) + 1, 2i], [2(i - 1) + 1, 2i])
end
end

View File

@ -7,6 +7,7 @@ using Plots, Test
p = plot(rand(10)) p = plot(rand(10))
@test isa(p, Plots.Plot) == true @test isa(p, Plots.Plot) == true
@test_nowarn Plots.plotly_series(plot())
end end
@testset "Contours" begin @testset "Contours" begin
@ -54,4 +55,10 @@ using Plots, Test
end end
end end
end end
@testset "Extra kwargs" begin
pl = plot(1:5, test = "me")
@test Plots.plotly_series(pl)[1][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :plot)
@test Plots.plotly_layout(pl)[:test] == "me"
end
end end

View File

@ -1,6 +1,18 @@
using Plots, Test using Plots, Test
using OffsetArrays using OffsetArrays
@testset "User recipes" begin
struct LegendPlot end
@recipe function f(plot::LegendPlot)
legend --> :topleft
(1:3, 1:3)
end
pl = plot(LegendPlot(); legend = :right)
@test pl[1][:legend_position] == :right
pl = plot(LegendPlot())
@test pl[1][:legend_position] == :topleft
end
@testset "lens!" begin @testset "lens!" begin
pl = plot(1:5) pl = plot(1:5)
lens!(pl, [1, 2], [1, 2], inset = (1, bbox(0.0, 0.0, 0.2, 0.2)), colorbar = false) lens!(pl, [1, 2], [1, 2], inset = (1, bbox(0.0, 0.0, 0.2, 0.2)), colorbar = false)

View File

@ -7,42 +7,132 @@ using Plots, Test
xlims!((1, 20)) xlims!((1, 20))
@test xlims(p) == (1, 20) @test xlims(p) == (1, 20)
xlims!(p, (1, 21))
@test xlims(p) == (1, 21)
ylims!((-1, 1)) ylims!((-1, 1))
@test ylims(p) == (-1, 1) @test ylims(p) == (-1, 1)
ylims!(p, (-2, 2))
@test ylims(p) == (-2, 2)
zlims!((-1, 1)) zlims!((-1, 1))
@test zlims(p) == (-1, 1) @test zlims(p) == (-1, 1)
zlims!(p, (-2, 2))
@test zlims(p) == (-2, 2)
xlims!(-1, 11) xlims!(-1, 11)
@test xlims(p) == (-1, 11) @test xlims(p) == (-1, 11)
xlims!(p, -2, 12)
@test xlims(p) == (-2, 12)
ylims!((-10, 10)) ylims!((-10, 10))
@test ylims(p) == (-10, 10) @test ylims(p) == (-10, 10)
ylims!(p, (-11, 9))
@test ylims(p) == (-11, 9)
zlims!((-10, 10)) zlims!((-10, 10))
@test zlims(p) == (-10, 10) @test zlims(p) == (-10, 10)
zlims!(p, (-9, 8))
@test zlims(p) == (-9, 8)
end
@testset "Set Title / Labels" begin
p = plot()
title!(p, "Foo")
sp = p[1]
@test sp[:title] == "Foo"
xlabel!(p, "xlabel")
@test sp[:xaxis][:guide] == "xlabel"
ylabel!(p, "ylabel")
@test sp[:yaxis][:guide] == "ylabel"
end
@testset "Misc" begin
p = plot()
sp = p[1]
xflip!(p)
@test sp[:xaxis][:flip]
yflip!(p)
@test sp[:yaxis][:flip]
xgrid!(p, true)
@test sp[:xaxis][:grid]
xgrid!(p, false)
@test !sp[:xaxis][:grid]
ygrid!(p, true)
@test sp[:yaxis][:grid]
ygrid!(p, false)
@test !sp[:yaxis][:grid]
ann = [(7, 3, "(7,3)"), (3, 7, text("hey", 14, :left, :top, :green))]
annotate!(p, ann)
annotate!(p, ann...)
xaxis!(p, true)
@test sp[:xaxis][:showaxis]
xaxis!(p, false)
@test !sp[:xaxis][:showaxis]
yaxis!(p, true)
@test sp[:yaxis][:showaxis]
yaxis!(p, false)
@test !sp[:yaxis][:showaxis]
p = plot3d([1, 2], [1, 2], [1, 2])
plot3d!(p, [3, 4], [3, 4], [3, 4])
@test Plots.series_list(p[1])[1][:seriestype] == :path3d
end end
@testset "Set Ticks" begin @testset "Set Ticks" begin
p = plot([0, 2, 3, 4, 5, 6, 7, 8, 9, 10]) p = plot([0, 2, 3, 4, 5, 6, 7, 8, 9, 10])
sp = p[1]
xticks = 2:6 xticks = 2:6
xticks!(xticks) xticks!(xticks)
@test Plots.get_subplot(current(), 1).attr[:xaxis][:ticks] == xticks @test sp.attr[:xaxis][:ticks] == xticks
xticks = 1:5
xticks!(p, xticks)
@test sp.attr[:xaxis][:ticks] == xticks
yticks = 0.2:0.1:0.7 yticks = 0.2:0.1:0.7
yticks!(yticks) yticks!(yticks)
@test Plots.get_subplot(current(), 1).attr[:yaxis][:ticks] == yticks @test sp.attr[:yaxis][:ticks] == yticks
yticks = 0.1:0.5
yticks!(p, yticks)
@test sp.attr[:yaxis][:ticks] == yticks
xticks = [5, 6, 7.5] xticks = [5, 6, 7.5]
xlabels = ["a", "b", "c"] xlabels = ["a", "b", "c"]
xticks!(xticks, xlabels) xticks!(xticks, xlabels)
@test Plots.get_subplot(current(), 1).attr[:xaxis][:ticks] == (xticks, xlabels) @test sp.attr[:xaxis][:ticks] == (xticks, xlabels)
xticks = [5, 2]
xlabels = ["b", "a"]
xticks!(p, xticks, xlabels)
@test sp.attr[:xaxis][:ticks] == (xticks, xlabels)
yticks = [0.5, 0.6, 0.75] yticks = [0.5, 0.6, 0.75]
ylabels = ["z", "y", "x"] ylabels = ["z", "y", "x"]
yticks!(yticks, ylabels) yticks!(yticks, ylabels)
@test Plots.get_subplot(current(), 1).attr[:yaxis][:ticks] == (yticks, ylabels) @test sp.attr[:yaxis][:ticks] == (yticks, ylabels)
yticks = [0.5, 0.1]
ylabels = ["z", "y"]
yticks!(p, yticks, ylabels)
@test sp.attr[:yaxis][:ticks] == (yticks, ylabels)
end end
end end