Compare commits

..
1 Commits
Author SHA1 Message Date
Anshul SinghviandGitHub f58d585a20 Unify preamble pushes 2019-12-13 13:47:22 -05:00
69 changed files with 6781 additions and 8729 deletions
-6
View File
@@ -1,6 +0,0 @@
# Set default behaviour to automatically normalize line endings.
* text=auto
# Force bash scripts to always use lf line endings so that if a repo is accessed
# in Unix via a file share from Windows, the scripts will work.
*.sh text eol=lf
-32
View File
@@ -1,32 +0,0 @@
---
name: Bug report
about: Create a bug report
title: "[BUG]"
labels: bug
assignees: ''
---
<!-- Please search existing issues to avoid duplicates. -->
## Details
### Backends
This bug occurs on ( insert `x` below )
Backend | yes | no | untested
-------------|-----|-----|---------
gr (default) | | |
pyplot | | |
plotly | | |
plotlyjs | | |
pgfplotsx | | |
inspectdr | | |
### Versions
Plots.jl version:
Backend version (`]st -m`):
Output of `versioninfo()`:
-10
View File
@@ -1,10 +0,0 @@
---
name: Feature request
about: Suggest a feature or enhancement
title: "[FR]"
labels: feature request
assignees: ''
---
Please search existing issues to avoid duplicates.
+10 -3
View File
@@ -2,16 +2,23 @@ name: CompatHelper
on:
schedule:
- cron: '00 00 * * *'
- cron: '00 * * * *'
jobs:
CompatHelper:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
julia-version: [1.2.0]
julia-arch: [x86]
os: [ubuntu-latest]
steps:
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.julia-version }}
- name: Pkg.add("CompatHelper")
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
- name: CompatHelper.main()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }} # optional
run: julia -e 'using CompatHelper; CompatHelper.main()'
-89
View File
@@ -1,89 +0,0 @@
name: SnoopCompile
on:
push:
branches:
# - 'master' # NOTE: to run the bot only on pushes to master
defaults:
run:
shell: bash
jobs:
SnoopCompile:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
env:
GKS_ENCODING: "utf8"
GKSwstype: "100"
PLOTS_TEST: "true"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version: # NOTE: the versions below should match those in your botconfig
- '1.5'
os: # NOTE: should match the os setting of your botconfig
- ubuntu-latest
arch:
- x64
steps:
# Setup environment
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.version }}
- name: Install dependencies
run: |
julia --project -e 'using Pkg; Pkg.instantiate();'
julia -e 'using Pkg; Pkg.add( PackageSpec(name = "CompileBot", version = "1") ); Pkg.develop(PackageSpec(; path=pwd())); using CompileBot; CompileBot.addtestdep();'
# TESTCMD
- name: Default TESTCMD
run: echo "TESTCMD=julia" >> $GITHUB_ENV
- name: Ubuntu TESTCMD
if: startsWith(matrix.os,'ubuntu')
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
# Generate precompile files
- name: Generating precompile files
run: $TESTCMD --project -e 'include("deps/SnoopCompile/snoop_bot.jl")' # NOTE: must match path
# Run benchmarks
- name: Running Benchmark
run: $TESTCMD --project -e 'include("deps/SnoopCompile/snoop_bench.jl")' # NOTE: optional, if have benchmark file
- name: Upload all
uses: actions/upload-artifact@v2.0.1
with:
path: ./
Create_PR:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
needs: SnoopCompile
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download all
uses: actions/download-artifact@v2
- name: CompileBot postprocess
run: julia -e 'using Pkg; Pkg.add( PackageSpec(name = "CompileBot", version = "1") ); using CompileBot; CompileBot.postprocess();'
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Update precompile_*.jl file
title: "[AUTO] Update precompiles"
labels: SnoopCompile
branch: "Test_SnoopCompile_AutoPR_${{ github.ref }}"
Skip:
if: "contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- name: Skip CI 🚫
run: echo skip ci
-14
View File
@@ -1,14 +0,0 @@
name: TagBot
on:
issue_comment:
types:
- created
workflow_dispatch:
jobs:
TagBot:
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
runs-on: ubuntu-latest
steps:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
-34
View File
@@ -1,34 +0,0 @@
name: Run benchmarks
on:
pull_request:
jobs:
Benchmark:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
env:
GKS_ENCODING: "utf8"
GKSwstype: "100"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: 1
## Setup
- name: Ubuntu TESTCMD
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
- name: Install Plots dependencies
uses: julia-actions/julia-buildpkg@latest
- name: Install Benchmarking dependencies
run: julia -e 'using Pkg; pkg"add PkgBenchmark BenchmarkCI@0.1"'
- name: Run benchmarks
run: $TESTCMD -e 'using BenchmarkCI; BenchmarkCI.judge()'
- name: Print judgement
run: julia -e 'using BenchmarkCI; BenchmarkCI.displayjudgement()'
- name: Post results
run: julia -e 'using BenchmarkCI; BenchmarkCI.postjudge()'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-86
View File
@@ -1,86 +0,0 @@
name: ci
on:
push:
pull_request:
defaults:
run:
shell: bash
jobs:
CI:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
env:
GKS_ENCODING: "utf8"
GKSwstype: "100"
name: Julia ${{ matrix.version }} - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.version == 'nightly' }}
strategy:
fail-fast: false
matrix:
version:
- '1'
- 'nightly'
os:
- ubuntu-latest
- windows-latest
- macos-latest
arch:
- x64
# - x86
steps:
# Setup environment
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.version }}
- name: Cache artifacts
uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
## maybe required if we ever want to run graphical tests for plotly
# OS Dependencies
# - name: Ubuntu OS dependencies
# if: startsWith(matrix.os,'ubuntu')
# run: |
# ./test/install_wkhtmltoimage.sh
# TESTCMD
- name: Default TESTCMD
run: echo "TESTCMD=julia" >> $GITHUB_ENV
- name: Ubuntu TESTCMD
if: startsWith(matrix.os,'ubuntu')
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
# Julia Dependencies
- name: Install Julia dependencies
uses: julia-actions/julia-buildpkg@latest
# Run tests
- name: Run Graphical test
run: $TESTCMD --project -e 'using Pkg; Pkg.test(coverage=true);'
- name: Codecov
uses: julia-actions/julia-uploadcodecov@latest
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Skip:
if: "contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- name: Skip CI 🚫
run: echo skip ci
+1 -5
View File
@@ -4,11 +4,7 @@
.DS_Store
examples/.ipynb_checkpoints/*
examples/meetup/.ipynb_checkpoints/*
deps/plotly-*
deps/plotly-latest.min.js
deps/build.log
deps/deps.jl
Manifest.toml
dev/
test/tmpplotsave.hdf5
/.benchmarkci
/benchmark/*.json
+34
View File
@@ -0,0 +1,34 @@
# Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
os:
- linux
# - osx
julia:
- 1
- 1.2
- nightly
matrix:
allow_failures:
- julia: nightly
addons:
apt:
packages:
- at-spi2-core
- libgtk-3-dev
- xauth
- xvfb
sudo: required
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pwd ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./test/install_wkhtmltoimage.sh ; fi
notifications:
email: true
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- if [[ `uname` = "Linux" ]]; then TESTCMD="xvfb-run julia"; else TESTCMD="julia"; fi
- $TESTCMD -e 'using Pkg; Pkg.build(); Pkg.test(coverage=true)'
+19 -27
View File
@@ -1,7 +1,7 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "1.10.6"
version = "0.28.3"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
@@ -10,22 +10,20 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Measures = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
RecipesPipeline = "01d81517-befc-4cb6-b9ec-a95719d0359c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Scratch = "6c6a2e73-6563-6170-7368-637461726353"
Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
@@ -34,43 +32,37 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[compat]
Contour = "0.5"
FFMPEG = "0.2, 0.3, 0.4"
FixedPointNumbers = "0.6, 0.7, 0.8"
GR = "0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55"
GeometryBasics = "0.2, 0.3.1"
JSON = "0.21, 1"
Latexify = "0.14"
FFMPEG = "0.2"
FixedPointNumbers = "0.6"
GR = "0.44"
GeometryTypes = "0.7"
JSON = "0.21"
Measures = "0.3"
NaNMath = "0.3"
PlotThemes = "2"
PlotUtils = "1"
RecipesBase = "1"
RecipesPipeline = "0.3"
Reexport = "0.2, 1.0"
Requires = "1"
Scratch = "1"
PlotThemes = "1"
PlotUtils = "0.6.1"
RecipesBase = "0.6, 0.7"
Reexport = "0.2"
Requires = "0.5, 1.0"
Showoff = "0.3.1"
StatsBase = "0.32, 0.33"
julia = "1.5"
StatsBase = "0.32"
julia = "1"
[extras]
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44"
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"
[targets]
test = ["Distributions", "FileIO", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"]
test = ["FileIO", "GeometryTypes", "Gtk", "ImageMagick", "Images", "LaTeXStrings", "LibGit2", "PGFPlotsX", "Random", "RDatasets", "StatsPlots", "Test", "UnicodePlots", "VisualRegressionTests"]
+8 -17
View File
@@ -1,22 +1,13 @@
# Plots
[gh-ci-img]: https://github.com/JuliaPlots/Plots.jl/workflows/ci/badge.svg?branch=master
[gh-ci-url]: https://github.com/JuliaPlots/Plots.jl/actions?query=workflow%3Aci
[pkgeval-img]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/P/Plots.svg
[pkgeval-url]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/report.html
[gitter-img]: https://badges.gitter.im/tbreloff/Plots.jl.svg
[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-url]: http://docs.juliaplots.org/latest/
[![][gh-ci-img]][gh-ci-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)
[![][docs-img]][docs-url]
[![Codecov](https://codecov.io/gh/JuliaPlots/Plots.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaPlots/Plots.jl)
[![Build Status](https://travis-ci.org/JuliaPlots/Plots.jl.svg?branch=master)](https://travis-ci.org/JuliaPlots/Plots.jl)
[![Build status](https://ci.appveyor.com/api/projects/status/github/juliaplots/plots.jl?branch=master&svg=true)](https://ci.appveyor.com/project/mkborregaard/plots-jl)
[![Join the chat at https://gitter.im/tbreloff/Plots.jl](https://badges.gitter.im/tbreloff/Plots.jl.svg)](https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<a href="http://docs.juliaplots.org/latest/" target="_blank"><img src="https://img.shields.io/badge/docs-latest-blue.svg" alt="Latest documentation"></a>
<!-- [![Plots](http://pkg.julialang.org/badges/Plots_0.3.svg)](http://pkg.julialang.org/?pkg=Plots&ver=0.3) -->
<!-- [![Plots](http://pkg.julialang.org/badges/Plots_0.4.svg)](http://pkg.julialang.org/?pkg=Plots&ver=0.4) -->
<!-- [![Coverage Status](https://coveralls.io/repos/tbreloff/Plots.jl/badge.svg?branch=master)](https://coveralls.io/r/tbreloff/Plots.jl?branch=master) -->
<!-- [![codecov.io](http://codecov.io/github/tbreloff/Plots.jl/coverage.svg?branch=master)](http://codecov.io/github/tbreloff/Plots.jl?branch=master) -->
#### Created by Tom Breloff (@tbreloff)
+44
View File
@@ -0,0 +1,44 @@
environment:
matrix:
# - julia_version: 0.7
- julia_version: 1
- julia_version: 1.2
- julia_version: nightly
platform:
- x86 # 32-bit
- x64 # 64-bit
# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
matrix:
allow_failures:
- julia_version: nightly
branches:
only:
- master
- /release-.*/
notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false
install:
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
build_script:
- echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
test_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
-5
View File
@@ -1,5 +0,0 @@
[deps]
BenchmarkCI = "20533458-34a3-403d-a444-e18f38190b5b"
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
PkgBenchmark = "32113eaa-f34f-5b0d-bd6c-c81e245fc73d"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
-10
View File
@@ -1,10 +0,0 @@
using BenchmarkTools
using Plots
const SUITE = BenchmarkGroup()
julia_cmd = split(get(ENV, "TESTCMD", Base.JLOptions().julia_bin))
SUITE["load_plot_display"] = @benchmarkable run(`$julia_cmd --startup-file=no --project -e 'using Plots; display(plot(1:0.1:10, sin.(1:0.1:10)))'`)
SUITE["load"] = @benchmarkable run(`$julia_cmd --startup-file=no --project -e 'using Plots'`)
SUITE["plot"] = @benchmarkable p = plot(1:0.1:10, sin.(1:0.1:10)) samples=1 evals=1
SUITE["display"] = @benchmarkable display(p) setup=(p = plot(1:0.1:10, sin.(1:0.1:10))) samples=1 evals=1
-10
View File
@@ -1,10 +0,0 @@
ignore:
- "src/backends/inspectdr.jl"
- "src/backends/orca.jl"
- "src/backends/pgfplots.jl"
- "src/backends/plotly.jl"
- "src/backends/plotlyjs.jl"
- "src/backends/pyplot.jl"
- "src/backends/web.jl"
- "src/fileio.jl"
- "src/ijulia.jl"
-389
View File
@@ -1,389 +0,0 @@
const __bodyfunction__ = Dict{Method,Any}()
# Find keyword "body functions" (the function that contains the body
# as written by the developer, called after all missing keyword-arguments
# have been assigned values), in a manner that doesn't depend on
# gensymmed names.
# `mnokw` is the method that gets called when you invoke it without
# supplying any keywords.
function __lookup_kwbody__(mnokw::Method)
function getsym(arg)
isa(arg, Symbol) && return arg
@assert isa(arg, GlobalRef)
return arg.name
end
f = get(__bodyfunction__, mnokw, nothing)
if f === nothing
fmod = mnokw.module
# The lowered code for `mnokw` should look like
# %1 = mkw(kwvalues..., #self#, args...)
# return %1
# where `mkw` is the name of the "active" keyword body-function.
ast = Base.uncompressed_ast(mnokw)
if isa(ast, Core.CodeInfo) && length(ast.code) >= 2
callexpr = ast.code[end-1]
if isa(callexpr, Expr) && callexpr.head == :call
fsym = callexpr.args[1]
if isa(fsym, Symbol)
f = getfield(fmod, fsym)
elseif isa(fsym, GlobalRef)
if fsym.mod === Core && fsym.name === :_apply
f = getfield(mnokw.module, getsym(callexpr.args[2]))
elseif fsym.mod === Core && fsym.name === :_apply_iterate
f = getfield(mnokw.module, getsym(callexpr.args[3]))
else
f = getfield(fsym.mod, fsym.name)
end
else
f = missing
end
else
f = missing
end
else
f = missing
end
__bodyfunction__[mnokw] = f
end
return f
end
function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:label, :blank),Tuple{Symbol,Bool}},Type{EmptyLayout}})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:label, :width, :height),Tuple{Symbol,Symbol,Length{:pct,Float64}}},Type{EmptyLayout}})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,),Tuple{GridLayout}},Type{Subplot},GRBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,),Tuple{GridLayout}},Type{Subplot},PlotlyBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,),Tuple{Subplot{GRBackend}}},Type{Subplot},GRBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,),Tuple{Subplot{PlotlyBackend}}},Type{Subplot},PlotlyBackend})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights),Tuple{Bool,Array{Int64,1}}},typeof(_make_hist),Tuple{Array{Float64,1}},Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights),Tuple{Bool,Nothing}},typeof(_make_hist),Tuple{Array{Float64,1},Array{Float64,1}},Int64})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights),Tuple{Bool,Nothing}},typeof(_make_hist),Tuple{Array{Float64,1}},Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:flip,),Tuple{Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,),Tuple{Symbol}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,),Tuple{typeof(datetimeformatter)}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims),Tuple{Bool,Tuple{Float64,Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims, :flip),Tuple{Bool,Tuple{Float64,Float64},Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid,),Tuple{Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:gridlinewidth, :grid, :gridalpha, :gridstyle, :foreground_color_grid),Tuple{Int64,Bool,Float64,Symbol,RGBA{Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide,),Tuple{String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims, :flip, :ticks, :guide),Tuple{Tuple{Int64,Int64},Bool,StepRange{Int64,Int64},String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,),Tuple{Tuple{Float64,Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,),Tuple{Tuple{Int64,Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,),Tuple{Tuple{Int64,Int64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:rotation,),Tuple{Int64}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:scale, :guide),Tuple{Symbol,String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,),Tuple{Nothing}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,),Tuple{UnitRange{Int64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(: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),Array{Int64,1},Array{Float64,1}})
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}},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle),Tuple{Symbol,Symbol}},typeof(gr_polyline),StepRange{Int64,Int64},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle),Tuple{Symbol,Symbol}},typeof(gr_polyline),UnitRange{Int64},Array{Float64,1}})
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(heatmap)),Any,typeof(heatmap),Any,Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(hline!)),Any,typeof(hline!),Any})
Base.precompile(Tuple{Core.kwftype(typeof(lens!)),Any,typeof(lens!),Any,Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype),Tuple{Float64,Symbol}},typeof(plot!),Array{GeometryBasics.Point{2,Float64},1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype),Tuple{Float64,Symbol}},typeof(plot!),Plot{GRBackend},Array{GeometryBasics.Point{2,Float64},1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:annotation,),Tuple{Array{Tuple{Int64,Float64,PlotText},1}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype),Tuple{Tuple{Int64,Symbol,Float64,Array{Symbol,2}},Symbol}},typeof(plot!),Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color),Tuple{Int64,Symbol}},typeof(plot!),Function,Float64,Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color),Tuple{Int64,Symbol}},typeof(plot!),Plot{GRBackend},Function,Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype),Tuple{Tuple{Int64,Float64,Symbol},Array{Any,1},Symbol}},typeof(plot!),Plot{GRBackend},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype),Tuple{Tuple{Int64,Float64,Symbol},Array{Any,1},Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype),Tuple{Tuple{Int64,Float64,Symbol},Array{Any,1},Symbol}},typeof(plot!),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype),Tuple{Int64,Symbol,Symbol}},typeof(plot!),Array{Float64,1}})
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!),Array{Int64,1},Array{Float64,1}})
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},Array{Int64,1},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset),Tuple{Symbol,Tuple{Int64,BoundingBox{Tuple{Length{:w,Float64},Length{:h,Float64}},Tuple{Length{:w,Float64},Length{:h,Float64}}}}}},typeof(plot!),Plot{PlotlyBackend},Array{Int64,1},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,),Tuple{Symbol}},typeof(plot!),Array{Int64,1}})
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!),Array{Float64,1},Array{Float64,1},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,),Tuple{Int64}},typeof(plot!),Plot{GRBackend},Array{Float64,1},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:xgrid,),Tuple{Tuple{Symbol,Symbol,Int64,Symbol,Float64}}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis,),Tuple{Tuple{String,Symbol}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype),Tuple{Array{Float64,1},Tuple{Symbol,Float64,Stroke},Array{Float64,1},String,Symbol}},typeof(plot!),Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype),Tuple{Array{Float64,1},Tuple{Symbol,Float64,Stroke},Array{Float64,1},String,Symbol}},typeof(plot!),Plot{GRBackend},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype),Tuple{Array{Float64,1},Tuple{Symbol,Float64,Stroke},Array{Float64,1},String,Symbol}},typeof(plot!),Plot{PlotlyBackend},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:annotations, :leg),Tuple{Tuple{Int64,Float64,PlotText},Bool}},typeof(plot),Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:arrow,),Tuple{Int64}},typeof(plot),Array{Float64,1},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype),Tuple{Int64,Symbol}},typeof(plot),Array{String,1},Array{String,1},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bins, :weights, :seriestype),Tuple{Symbol,Array{Int64,1},Symbol}},typeof(plot),Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:color, :line, :marker),Tuple{Array{Symbol,2},Tuple{Symbol,Int64},Tuple{Array{Symbol,2},Int64,Float64,Stroke}}},typeof(plot),Array{Array{T,1} where T,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:connections, :seriestype),Tuple{Tuple{Array{Int64,1},Array{Int64,1},Array{Int64,1}},Symbol}},typeof(plot),Array{Int64,1},Array{Int64,1},Vararg{Array{Int64,1},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill, :seriestype),Tuple{Bool,Symbol}},typeof(plot),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks, :seriestype),Tuple{Array{Symbol,2},Array{String,2},Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Int64,String,Int64,UnitRange{Int64},Symbol}},typeof(plot),Array{Array{Float64,1},1},Array{Array{Float64,1},1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:grid, :title),Tuple{Tuple{Symbol,Symbol,Symbol,Int64,Float64},String}},typeof(plot),Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:lab, :w, :palette, :fill, :α),Tuple{String,Int64,PlotUtils.ContinuousColorGradient,Int64,Float64}},typeof(plot),StepRange{Int64,Int64},Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend),Tuple{Array{String,2},String,String,Int64,Symbol}},typeof(plot),Array{Function,1},Float64,Vararg{Float64,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label,),Tuple{Array{String,2}}},typeof(plot),Array{AbstractArray{Float64,1},1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :group, :linetype, :linecolor),Tuple{GridLayout,Array{String,1},Array{Symbol,2},Symbol}},typeof(plot),Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha),Tuple{Tuple{Int64,Int64},String,Int64,Float64}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha),Tuple{Tuple{Int64,Int64},String,Int64,Float64}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link),Tuple{Int64,Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link),Tuple{Int64,Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :palette, :bg_inside),Tuple{Int64,Array{PlotUtils.ContinuousColorGradient,2},Array{Symbol,2}}},typeof(plot),Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :t, :leg, :ticks, :border),Tuple{GridLayout,Array{Symbol,2},Bool,Nothing,Symbol}},typeof(plot),Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :title, :titlelocation, :left_margin, :bottom_margin, :xrotation),Tuple{GridLayout,Array{String,2},Symbol,Array{Length{:mm,Float64},2},Length{:mm,Float64},Int64}},typeof(plot),Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xlims),Tuple{GridLayout,Tuple{Int64,Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,),Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,),Tuple{Bool}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,),Tuple{Symbol}},typeof(plot),Array{Tuple{Int64,Real},1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,),Tuple{Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,),Tuple{Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :lab, :ms),Tuple{Tuple{Array{Symbol,2},Int64},Array{String,2},Int64}},typeof(plot),Array{Array{T,1} where T,1},Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :label, :legendtitle),Tuple{Tuple{Int64,Array{Symbol,2}},Array{String,2},String}},typeof(plot),Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :leg, :fill),Tuple{Int64,Bool,Tuple{Int64,Symbol}}},typeof(plot),Function,Function,Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :marker, :bg, :fg, :xlim, :ylim, :leg),Tuple{Tuple{Int64,Symbol,Symbol},Tuple{Shape,Int64,RGBA{Float64}},Symbol,Symbol,Tuple{Int64,Int64},Tuple{Int64,Int64},Bool}},typeof(plot),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line_z, :linewidth, :legend),Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Int64,Bool}},typeof(plot),Array{Float64,1},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:m, :lab, :bg, :xlim, :ylim, :seriestype),Tuple{Tuple{Int64,Symbol},Array{String,2},Symbol,Tuple{Int64,Int64},Tuple{Int64,Int64},Symbol}},typeof(plot),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker,),Tuple{Bool}},typeof(plot),Array{Union{Missing, Int64},1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker_z, :color, :legend, :seriestype),Tuple{typeof(+),Symbol,Bool,Symbol}},typeof(plot),Array{Float64,1},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :seriestype),Tuple{Int64,Symbol}},typeof(plot),Array{Float64,1},Array{Float64,1}})
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),Array{Complex{Float64},1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:proj, :m),Tuple{Symbol,Int64}},typeof(plot),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:projection, :seriestype),Tuple{Symbol,Symbol}},typeof(plot),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},UnitRange{Int64},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:quiver, :seriestype),Tuple{Tuple{Array{Float64,1},Array{Float64,1},Array{Float64,1}},Symbol}},typeof(plot),Array{Float64,1},Array{Float64,1},Vararg{Array{Float64,1},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:reg, :fill),Tuple{Bool,Tuple{Int64,Symbol}}},typeof(plot),Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,),Tuple{Int64}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,),Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,),Tuple{Tuple{LinRange{Float64},LinRange{Float64}}}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,),Tuple{typeof(sqrt)}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color),Tuple{Array{Symbol,2},Array{Symbol,1},Int64,Array{Symbol,1}}},typeof(plot),Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,),Tuple{Symbol}},typeof(plot),Array{DateTime,1},UnitRange{Int64},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,),Tuple{Symbol}},typeof(plot),Array{OHLC,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel),Tuple{Symbol,String,String,String}},typeof(plot),Array{Float64,1},Array{Float64,1},Vararg{Array{Float64,1},N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :l, :seriestype),Tuple{String,Float64,Symbol}},typeof(plot),Array{String,1},Array{Float64,1}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,),Tuple{Array{String,2}}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,),Tuple{Array{String,2}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,),Tuple{String}},typeof(plot),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,),Tuple{String}},typeof(plot),Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:w,),Tuple{Int64}},typeof(plot),Array{Float64,2}})
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),Array{Float64,2}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:yflip, :aspect_ratio),Tuple{Bool,Symbol}},typeof(plot),Array{Float64,1},Array{Int64,1},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:zcolor, :m, :leg, :cbar, :w),Tuple{StepRange{Int64,Int64},Tuple{Int64,Float64,Symbol,Stroke},Bool,Bool,Int64}},typeof(plot),Array{Float64,1},Array{Float64,1},Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(portfoliocomposition)),Any,typeof(portfoliocomposition),Any,Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(scatter!)),Any,typeof(scatter!),Any,Vararg{Any,N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(scatter!)),Any,typeof(scatter!),Any})
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip, :disp),Tuple{Array{Int64,1},Bool}},typeof(test_examples),Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip,),Tuple{Array{Int64,1}}},typeof(test_examples),Symbol})
Base.precompile(Tuple{Type{GridLayout},Int64,Vararg{Int64,N} where N})
Base.precompile(Tuple{Type{Shape},Array{Tuple{Float64,Float64},1}})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol,Any},AbstractArray{OHLC,1}})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol,Any},Array{Complex{Float64},1}})
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{: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{: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{:sticks}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol,Any},Type{Val{:xerror}},Any,Any,Any})
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},Array{Dict{Symbol,Any},1}})
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{PlotlyBackend},Dict{Symbol,Any},Array{Dict{Symbol,Any},1}})
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_attributes!),Plot{GRBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Array{Dict{Symbol,Any},1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{PlotlyBackend},Array{Dict{Symbol,Any},1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{GRBackend},DefaultsDict,Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{GRBackend},Dict{Symbol,Any},Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{PlotlyBackend},DefaultsDict,Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{PlotlyBackend},Dict{Symbol,Any},Symbol,Any})
Base.precompile(Tuple{typeof(_bin_centers),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}})
Base.precompile(Tuple{typeof(_cbar_unique),Array{Int64,1},String})
Base.precompile(Tuple{typeof(_cbar_unique),Array{Nothing,1},String})
Base.precompile(Tuple{typeof(_cbar_unique),Array{PlotUtils.ContinuousColorGradient,1},String})
Base.precompile(Tuple{typeof(_cbar_unique),Array{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},1},String})
Base.precompile(Tuple{typeof(_cbar_unique),Array{Symbol,1},String})
Base.precompile(Tuple{typeof(_cycle),Array{Float64,1},Array{Int64,1}})
Base.precompile(Tuple{typeof(_cycle),Array{Float64,1},StepRange{Int64,Int64}})
Base.precompile(Tuple{typeof(_cycle),Array{Float64,1},UnitRange{Int64}})
Base.precompile(Tuple{typeof(_cycle),Base.OneTo{Int64},Array{Int64,1}})
Base.precompile(Tuple{typeof(_cycle),StepRange{Int64,Int64},Array{Int64,1}})
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),Array{Float64,1},Bool,Bool})
Base.precompile(Tuple{typeof(_plot!),Plot,Any,Any})
Base.precompile(Tuple{typeof(_preprocess_barlike),DefaultsDict,Base.OneTo{Int64},Array{Float64,1}})
Base.precompile(Tuple{typeof(_preprocess_binlike),DefaultsDict,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}})
Base.precompile(Tuple{typeof(_replace_markershape),Array{Symbol,1}})
Base.precompile(Tuple{typeof(_update_min_padding!),GridLayout})
Base.precompile(Tuple{typeof(_update_plot_args),Plot{GRBackend},DefaultsDict})
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(backend),PlotlyBackend})
Base.precompile(Tuple{typeof(bbox),Float64,Float64,Float64,Float64})
Base.precompile(Tuple{typeof(bbox),Length{:mm,Float64},Length{:mm,Float64},Length{:mm,Float64},Length{:mm,Float64}})
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64})
Base.precompile(Tuple{typeof(contour),Any,Vararg{Any,N} where N})
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1},Tuple{Int64,Float64}})
Base.precompile(Tuple{typeof(create_grid),Expr})
Base.precompile(Tuple{typeof(error_coords),Array{Float64,1},Array{Float64,1},Array{Float64,1}})
Base.precompile(Tuple{typeof(error_zipit),Tuple{Array{Float64,1},Array{Float64,1},Array{Float64,1}}})
Base.precompile(Tuple{typeof(fakedata),Int64,Vararg{Int64,N} where N})
Base.precompile(Tuple{typeof(font),String,Vararg{Any,N} where N})
Base.precompile(Tuple{typeof(get_clims),Subplot{GRBackend},Series,Function})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Array{Float64,1},Array{String,1}}})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Array{Int64,1},Array{String,1}}})
Base.precompile(Tuple{typeof(get_series_color),Array{Symbol,1},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_series_color),Array{Symbol,1},Subplot{PlotlyBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_xy),Array{OHLC,1}})
Base.precompile(Tuple{typeof(get_xy),OHLC{Float64},Int64,Float64})
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor),NTuple{9,Float64}},Array{Float64,1}})
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor),Tuple{Int64,Float64,Float64,Float64,Int64,Float64,Float64,Float64,Float64}},Array{Float64,1}})
Base.precompile(Tuple{typeof(gr_display),Subplot{GRBackend},Length{:mm,Float64},Length{:mm,Float64},Array{Float64,1}})
Base.precompile(Tuple{typeof(gr_draw_colorbar),GRColorbar,Subplot{GRBackend},Tuple{Float64,Float64},Array{Float64,1}})
Base.precompile(Tuple{typeof(gr_draw_contour),Series,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,2},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_grid),Subplot{GRBackend},Axis,Segments{Tuple{Float64,Float64}}})
Base.precompile(Tuple{typeof(gr_draw_heatmap),Series,Array{Float64,1},Array{Float64,1},Array{Float64,2},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Array{Float64,1},Array{Float64,1},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Array{Int64,1},Array{Float64,1},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Array{Float64,1},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Array{Float64,1},Array{Float64,1},Int64,Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Array{Float64,1},Int64,Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Array{Float64,1},Nothing,Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},UnitRange{Int64},Tuple{Array{Float64,1},Array{Float64,1}},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRange{Int64,Int64},Array{Float64,1},Int64,Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_shapes),Series,Array{Float64,1},Array{Float64,1},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Array{Float64,1},Array{Float64,1},Array{Float64,1},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Array{Float64,1},Array{Float64,1},Array{Float64,2},Tuple{Float64,Float64}})
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Array{Float64,1},Array{Any,1}},Int64})
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Array{Float64,1},Array{String,1}},Int64})
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Array{Int64,1},Array{String,1}},Int64})
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Array{Float64,1},Array{String,1}}})
Base.precompile(Tuple{typeof(gr_label_ticks_3d),Subplot{GRBackend},Symbol,Tuple{Array{Float64,1},Array{String,1}}})
Base.precompile(Tuple{typeof(gr_polaraxes),Int64,Float64,Subplot{GRBackend}})
Base.precompile(Tuple{typeof(gr_polyline),Array{Float64,1},Array{Float64,1},Function})
Base.precompile(Tuple{typeof(gr_set_gradient),PlotUtils.ContinuousColorGradient})
Base.precompile(Tuple{typeof(gr_viewport_from_bbox),Subplot{GRBackend},BoundingBox{Tuple{Length{:mm,Float64},Length{:mm,Float64}},Tuple{Length{:mm,Float64},Length{:mm,Float64}}},Length{:mm,Float64},Length{:mm,Float64},Array{Float64,1}})
Base.precompile(Tuple{typeof(heatmap_edges),Array{Float64,1},Symbol})
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})
Base.precompile(Tuple{typeof(heatmap_edges),UnitRange{Int64},Symbol})
Base.precompile(Tuple{typeof(ignorenan_minimum),Array{Int64,1}})
Base.precompile(Tuple{typeof(iter_segments),Array{Float64,1},Array{Float64,1},UnitRange{Int64}})
Base.precompile(Tuple{typeof(iter_segments),Array{Float64,1}})
Base.precompile(Tuple{typeof(iter_segments),Base.OneTo{Int64},Array{Float64,1}})
Base.precompile(Tuple{typeof(layout_args),Int64})
Base.precompile(Tuple{typeof(make_fillrange_side),UnitRange{Int64},LinRange{Float64}})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Subplot{GRBackend},Axis,StepRange{Int64,Int64}})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Subplot{GRBackend},Axis,UnitRange{Int64}})
Base.precompile(Tuple{typeof(plot!),Any})
Base.precompile(Tuple{typeof(plot),Any,Any})
Base.precompile(Tuple{typeof(plot),Any})
Base.precompile(Tuple{typeof(processGridArg!),DefaultsDict,Bool,Symbol})
Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol,Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol,Any},Array{Symbol,2}})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol,Any},Int64})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol,Any},Symbol})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol,Any},Array{Symbol,2}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol,Any},RGBA{Float64}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol,Any},Shape})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol,Any},Stroke})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol,Any},Symbol})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol,Any},StepRange{Int64,Int64},Symbol})
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol,Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol,Any},Tuple{Int64,Int64},Symbol})
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Array{Float64,1}})
Base.precompile(Tuple{typeof(push!),Segments{Tuple{Float64,Float64,Float64}},Tuple{Float64,Int64,Int64},Tuple{Float64,Int64,Int64}})
Base.precompile(Tuple{typeof(quiver_using_arrows),DefaultsDict})
Base.precompile(Tuple{typeof(quiver_using_hack),DefaultsDict})
Base.precompile(Tuple{typeof(reset_axis_defaults_byletter!)})
Base.precompile(Tuple{typeof(slice_arg),Array{Length{:mm,Float64},2},Int64})
Base.precompile(Tuple{typeof(slice_arg),Array{PlotUtils.ContinuousColorGradient,2},Int64})
Base.precompile(Tuple{typeof(slice_arg),Array{RGBA{Float64},2},Int64})
Base.precompile(Tuple{typeof(slice_arg),Array{String,2},Int64})
Base.precompile(Tuple{typeof(slice_arg),Array{Symbol,2},Int64})
Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Int64})
Base.precompile(Tuple{typeof(spy),Any})
Base.precompile(Tuple{typeof(straightline_data),Tuple{Float64,Float64},Tuple{Float64,Float64},Array{Float64,1},Array{Float64,1},Int64})
Base.precompile(Tuple{typeof(stroke),Int64,Vararg{Any,N} where N})
Base.precompile(Tuple{typeof(text),String,Int64,Symbol,Vararg{Symbol,N} where N})
Base.precompile(Tuple{typeof(text),String,Symbol,Int64,Vararg{Any,N} where N})
Base.precompile(Tuple{typeof(text),String,Symbol})
Base.precompile(Tuple{typeof(title!),AbstractString})
Base.precompile(Tuple{typeof(unzip),Array{GeometryBasics.Point{2,Float64},1}})
Base.precompile(Tuple{typeof(vline!),Any})
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any,N} where N})
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
Base.precompile(Tuple{typeof(yaxis!),Any,Any})
let fbody = try __lookup_kwbody__(which(gr_polyline, (Array{Float64,1},Array{Float64,1},typeof(GR.fillarea),))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Symbol,Symbol,typeof(gr_polyline),Array{Float64,1},Array{Float64,1},typeof(GR.fillarea),))
end
end
let fbody = try __lookup_kwbody__(which(plot!, ())) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Any,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Any,))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Any,Vararg{Any,N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Any,Vararg{Any,N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Any,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Any,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Any,Vararg{Any,N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Any,Vararg{Any,N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Plot,))) 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,Vararg{Plot,N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Plot,Plot,Vararg{Plot,N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(text, (String,Int64,Vararg{Any,N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},typeof(text),String,Int64,Vararg{Any,N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(text, (String,Symbol,Vararg{Any,N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},typeof(text),String,Symbol,Vararg{Any,N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(title!, (AbstractString,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(title!),AbstractString,))
end
end
let fbody = try __lookup_kwbody__(which(vline!, (Any,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(vline!),Any,))
end
end
let fbody = try __lookup_kwbody__(which(yaxis!, (Any,Vararg{Any,N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(yaxis!),Any,Vararg{Any,N} where N,))
end
end
end
-4
View File
@@ -1,4 +0,0 @@
using Plots
Plots.test_examples(:gr, skip = Plots._backend_skips[:gr])
Plots.test_examples(:plotly, skip = Plots._backend_skips[:plotly], disp = false)
-8
View File
@@ -1,8 +0,0 @@
using CompileBot
snoop_bench(
BotConfig(
"Plots",
),
joinpath(@__DIR__, "precompile_script.jl"),
)
-8
View File
@@ -1,8 +0,0 @@
using CompileBot
snoop_bot(
BotConfig(
"Plots",
),
joinpath(@__DIR__, "precompile_script.jl"),
)
+18
View File
@@ -0,0 +1,18 @@
#TODO: download https://cdn.plot.ly/plotly-latest.min.js to deps/ if it doesn't exist
file_path = ""
if get(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL", "false") == "true"
global file_path
local_fn = joinpath(dirname(@__FILE__), "plotly-latest.min.js")
if !isfile(local_fn)
@info("Cannot find deps/plotly-latest.min.js... downloading latest version.")
download("https://cdn.plot.ly/plotly-latest.min.js", local_fn)
isfile(local_fn) && (file_path = local_fn)
else
file_path = local_fn
end
end
open("deps.jl", "w") do io
println(io, "const plotly_local_file_path = $(repr(file_path))")
end
+51
View File
@@ -0,0 +1,51 @@
# To figure out what should be precompiled, run this script, then move
# precompile_Plots.jl in precompiles_path (see below) to src/precompile.jl
# This script works by using SnoopCompile to log compilations that take place
# while running the examples on the GR backend. So SnoopCompile must be
# installed, and StatsPlots, RDatasets, and FileIO are also required for
# certain examples.
# If precompilation fails with an UndefVarError for a module, probably what is
# happening is that the module appears in the precompile statements, but is
# only visible to one of Plots' dependencies, and not Plots itself. Adding the
# module to the blacklist below will remove these precompile statements.
# Anonymous functions may appear in precompile statements as functions with
# hashes in their name. Those of the form "#something##kw" have to do with
# compiling functions with keyword arguments, and are named reproducibly, so
# can be kept. Others generally will not work. Currently, SnoopCompile includes
# some anonymous functions that not reproducible, but SnoopCompile PR #30
# (which looks about to be merged) will ensure that anonymous functions are
# actually defined before attempting to precompile them. Alternatively, we can
# keep only the keyword argument related anonymous functions by changing the
# regex that SnoopCompile uses to detect anonymous functions to
# r"#{1,2}[^\"#]+#{1,2}\d+" (see anonrex in SnoopCompile.jl). To exclude all
# precompile statements involving anonymous functions, "#" can also be added to
# the blacklist below.
using SnoopCompile
log_path = joinpath(tempdir(), "compiles.log")
precompiles_path = joinpath(tempdir(), "precompile")
# run examples with GR backend, logging what needs to be compiled
SnoopCompile.@snoopc log_path begin
using Plots
Plots.test_examples(:gr, disp=true)
end
# precompile calls containing the following strings are dropped
blacklist = [
# functions defined in examples
"PlotExampleModule",
# the following are not visible to Plots, only its dependencies
"CategoricalArrays",
"FixedPointNumbers",
"SparseArrays",
r"#{1,2}[^\"#]+#{1,2}\d+",
]
data = SnoopCompile.read(log_path)
pc = SnoopCompile.parcel(reverse!(data[2]), blacklist=blacklist)
SnoopCompile.write(precompiles_path, pc)
+21 -47
View File
@@ -1,21 +1,17 @@
module Plots
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optlevel"))
@eval Base.Experimental.@optlevel 1
end
const _current_plots_version = VersionNumber(split(first(filter(line -> occursin("version", line), readlines(normpath(@__DIR__, "..", "Project.toml")))), "\"")[2])
using Reexport
import GeometryBasics
import GeometryTypes
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random
using SparseArrays
import SparseArrays: findnz
using FFMPEG
@reexport using RecipesBase
import RecipesBase: plot, plot!, animate, is_explicit
import RecipesBase: plot, plot!, animate
using Base.Meta
@reexport using PlotUtils
@reexport using PlotThemes
@@ -25,6 +21,17 @@ import JSON
using Requires
if isfile(joinpath(@__DIR__, "..", "deps", "deps.jl"))
include(joinpath(@__DIR__, "..", "deps", "deps.jl"))
else
# This is a bit dirty, but I don't really see why anyone should be forced
# to build Plots, while it will just include exactly the below line
# as long as `ENV["PLOTS_HOST_DEPENDENCY_LOCAL"] = "true"` is not set.
# If the above env is set + `plotly_local_file_path == ""``,
# it will warn in the __init__ function to run build
const plotly_local_file_path = ""
end
export
grid,
bbox,
@@ -97,7 +104,6 @@ export
gif,
mov,
mp4,
webm,
animate,
@animate,
@gif,
@@ -113,11 +119,7 @@ export
center,
BezierCurve,
plotattr,
scalefontsize,
scalefontsizes,
resetfontsizes
plotattr
# ---------------------------------------------------------
@@ -154,12 +156,6 @@ const BBox = Measures.Absolute2DBox
# allow pixels and percentages
const px = AbsoluteLength(0.254)
const pct = Length{:pct, Float64}(1.0)
Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value)
Base.:*(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * m1.value)
Base.:/(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value / m2.value)
Base.:/(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value / m1.value)
export BBox, BoundingBox, mm, cm, inch, px, pct, pt, w, h
end
@@ -167,38 +163,15 @@ using .PlotMeasures
import .PlotMeasures: Length, AbsoluteLength, Measure, width, height
# ---------------------------------------------------------
import RecipesPipeline
import RecipesPipeline: SliceIt,
DefaultsDict,
Formatted,
AbstractSurface,
Surface,
Volume,
is3d,
is_surface,
needs_3d_axes,
group_as_matrix, # for StatsPlots
reset_kw!,
pop_kw!,
scale_func,
inverse_scale_func,
unzip,
dateformatter,
datetimeformatter,
timeformatter
# Use fixed version of Plotly instead of the latest one for stable dependency
# Ref: https://github.com/JuliaPlots/Plots.jl/pull/2779
const _plotly_min_js_filename = "plotly-1.57.1.min.js"
include("types.jl")
include("utils.jl")
include("components.jl")
include("axes.jl")
include("args.jl")
include("components.jl")
include("themes.jl")
include("plot.jl")
include("pipeline.jl")
include("series.jl")
include("layouts.jl")
include("subplots.jl")
include("recipes.jl")
@@ -228,8 +201,8 @@ let PlotOrSubplot = Union{Plot, Subplot}
global xlims!(plt::PlotOrSubplot, xmin::Real, xmax::Real; kw...) = plot!(plt; xlims = (xmin,xmax), kw...)
global ylims!(plt::PlotOrSubplot, ymin::Real, ymax::Real; kw...) = plot!(plt; ylims = (ymin,ymax), kw...)
global zlims!(plt::PlotOrSubplot, zmin::Real, zmax::Real; kw...) = plot!(plt; zlims = (zmin,zmax), kw...)
global xticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) = plot!(plt; xticks = ticks, kw...)
global yticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) = plot!(plt; yticks = ticks, kw...)
global xticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) where {T<:Real} = plot!(plt; xticks = ticks, kw...)
global yticks!(plt::PlotOrSubplot, ticks::TicksArgs; kw...) where {T<:Real} = plot!(plt; yticks = ticks, kw...)
global xticks!(plt::PlotOrSubplot,
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; xticks = (ticks,labels), kw...)
global yticks!(plt::PlotOrSubplot,
@@ -249,6 +222,7 @@ end
const CURRENT_BACKEND = CurrentBackend(:none)
include("precompile_includer.jl")
include("precompile.jl")
_precompile_()
end # module
+9 -15
View File
@@ -24,7 +24,6 @@ end
giffn() = (isijulia() ? "tmp.gif" : tempname()*".gif")
movfn() = (isijulia() ? "tmp.mov" : tempname()*".mov")
mp4fn() = (isijulia() ? "tmp.mp4" : tempname()*".mp4")
webmfn() = (isijulia() ? "tmp.webm" : tempname()*".webm")
mutable struct FrameIterator
itr
@@ -64,7 +63,6 @@ file_extension(fn) = Base.Filesystem.splitext(fn)[2][2:end]
gif(anim::Animation, fn = giffn(); kw...) = buildanimation(anim, fn; kw...)
mov(anim::Animation, fn = movfn(); kw...) = buildanimation(anim, fn, false; kw...)
mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim, fn, false; kw...)
webm(anim::Animation, fn = webmfn(); kw...) = buildanimation(anim, fn, false; kw...)
ffmpeg_framerate(fps) = "$fps"
ffmpeg_framerate(fps::Rational) = "$(fps.num)/$(fps.den)"
@@ -73,7 +71,6 @@ function buildanimation(anim::Animation, fn::AbstractString,
is_animated_gif::Bool=true;
fps::Real = 20, loop::Integer = 0,
variable_palette::Bool=false,
verbose=false,
show_msg::Bool=true)
if length(anim.frames) == 0
throw(ArgumentError("Cannot build empty animations"))
@@ -82,23 +79,20 @@ function buildanimation(anim::Animation, fn::AbstractString,
fn = abspath(expanduser(fn))
animdir = anim.dir
framerate = ffmpeg_framerate(fps)
verbose_level = (verbose isa Int ? verbose :
verbose ? 32 # "info"
: 16) # "error"
if is_animated_gif
if variable_palette
# generate a colorpalette for each frame for highest quality, but larger filesize
palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1"
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -lavfi "$palette" -loop $loop -y $fn`)
ffmpeg_exe(`-v 0 -framerate $framerate -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`)
else
# generate a colorpalette first so ffmpeg does not have to guess it
ffmpeg_exe(`-v $verbose_level -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
ffmpeg_exe(`-v 0 -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
# then apply the palette to get better results
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -loop $loop -y $fn`)
ffmpeg_exe(` -v 0 -framerate $framerate -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`)
end
else
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -vf format=yuv420p -loop $loop -y $fn`)
ffmpeg_exe(`-v 0 -framerate $framerate -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
end
show_msg && @info("Saved animation to ", fn)
@@ -112,8 +106,8 @@ function Base.show(io::IO, ::MIME"text/html", agif::AnimatedGif)
ext = file_extension(agif.filename)
if ext == "gif"
html = "<img src=\"data:image/gif;base64," * base64encode(read(agif.filename)) * "\" />"
elseif ext in ("mov", "mp4","webm")
mimetype = ext == "mov" ? "video/quicktime" : "video/$ext"
elseif ext in ("mov", "mp4")
mimetype = ext == "mov" ? "video/quicktime" : "video/mp4"
html = "<video controls><source src=\"data:$mimetype;base64," *
base64encode(read(agif.filename)) *
"\" type = \"$mimetype\"></video>"
@@ -169,16 +163,16 @@ function _animate(forloop::Expr, args...; callgif = false)
error("Unsupported animate filter: $args")
end
push!(block.args, :(if $filterexpr; Plots.frame($animsym); end))
push!(block.args, :(if $filterexpr; frame($animsym); end))
push!(block.args, :(global $countersym += 1))
# add a final call to `gif(anim)`?
retval = callgif ? :(Plots.gif($animsym)) : animsym
retval = callgif ? :(gif($animsym)) : animsym
# full expression:
esc(quote
$freqassert # if filtering, check frequency is an Integer > 0
$animsym = Plots.Animation() # init animation object
$animsym = Animation() # init animation object
global $countersym = 1 # init iteration counter
$forloop # for loop, saving a frame after each iteration
$retval # return the animation object, or the gif
+6 -8
View File
@@ -59,7 +59,7 @@ const _arg_desc = KW(
:foreground_color => "Color Type. Base color for all foregrounds.",
:size => "NTuple{2,Int}. (width_px, height_px) of the whole Plot",
:pos => "NTuple{2,Int}. (left_px, top_px) position of the GUI window (note: currently unimplemented)",
:window_title => "String. Title of the standalone gui-window.",
:window_title => "String. Title of the window.",
:show => "Bool. Should this command open/refresh a GUI/display? This allows displaying in scripts or functions without explicitly calling `display`",
:layout => "Integer (number of subplots), NTuple{2,Integer} (grid dimensions), AbstractLayout (for example `grid(2,2)`), or the return from the `@layout` macro. This builds the layout of subplots.",
:link => "Symbol. How/whether to link axis limits between subplots. Values: `:none`, `:x` (x axes are linked by columns), `:y` (y axes are linked by rows), `:both` (x and y are linked), `:all` (every subplot is linked together regardless of layout position).",
@@ -70,13 +70,12 @@ const _arg_desc = KW(
:dpi => "Number. Dots Per Inch of output figures",
:thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.",
:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.",
:extra_kwargs => "Either one of (`:plot`, `:subplot`, `:series`) to specify for which element extra keyword args are collected or a KW (Dict{Symbol,Any}) to pass a map of extra keyword args which may be specific to a backend. Default: `:series`.\n Example: `pgfplotsx(); scatter(1:5, extra_kwargs=Dict(:subplot=>Dict(\"axis line shift\" => \"10pt\"))`",
:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.",
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",
:warn_on_unsupported => "Bool. Warn on unsupported attributes, series types and marker shapes",
# subplot args
:title => "String. Subplot title.",
:titlelocation => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`",
:title_location => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`",
:titlefontfamily => "String or Symbol. Font family of subplot title.",
:titlefontsize => "Integer. Font pointsize of subplot title.",
:titlefonthalign => "Symbol. Font horizontal alignment of subplot title: :hcenter, :left, :right or :center",
@@ -90,14 +89,13 @@ const _arg_desc = KW(
:foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
:foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.",
:color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.",
:legend => "Bool (show the legend?) or (x,y) tuple or Symbol (legend position). 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 => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)",
:legendfontfamily => "String or Symbol. Font family of legend entries.",
:legendfontsize => "Integer. Font pointsize of legend entries.",
:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center",
:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center",
:legendfontrotation => "Real. Font rotation of legend entries",
:legendfontcolor => "Color Type. Font color of legend entries",
:legendtitle => "String. Legend title.",
:legendtitlefontfamily => "String or Symbol. Font family of the legend title.",
:legendtitlefontsize => "Integer. Font pointsize the legend title.",
:legendtitlefonthalign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center",
@@ -105,12 +103,12 @@ const _arg_desc = KW(
:legendtitlefontrotation => "Real. Font rotation of the legend title",
:legendtitlefontcolor => "Color Type. Font color of the legend title",
:colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)",
:clims => "`:auto`, NTuple{2,Number}, or a function that takes series data in and returns NTuple{2,Number}. Fixes the limits of the colorbar.",
:clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.",
:legendfont => "Font. Font of legend items.",
:legendtitlefont => "Font. Font of the legend title.",
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
:projection => "Symbol or String. '3d' or 'polar'",
:aspect_ratio => "Symbol (:equal or :none) or Number. Plot area is resized so that 1 y-unit is the same size as `aspect_ratio` x-units. With `:none`, images inherit aspect ratio of the plot area.",
:aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `aspect_ratio` x-units.",
:margin => "Measure (multiply by `mm`, `px`, etc). Base for individual margins... not directly used. Specifies the extra padding around subplots.",
:left_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the left of the subplot.",
:top_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the top of the subplot.",
+237 -381
View File
File diff suppressed because it is too large Load Diff
+230 -324
View File
@@ -7,20 +7,29 @@
# -------------------------------------------------------------------------
function Axis(sp::Subplot, letter::Symbol, args...; kw...)
explicit = KW(
# init with values from _plot_defaults
plotattributes = KW(
:letter => letter,
# :extrema => (Inf, -Inf),
:extrema => Extrema(),
:discrete_map => Dict(), # map discrete values to discrete indices
:continuous_values => zeros(0),
:discrete_values => [],
:use_minor => false,
:show => true, # show or hide the axis? (useful for linked subplots)
)
attr = DefaultsDict(explicit, _axis_defaults_byletter[letter])
# get defaults from letter version, unless match
for (k,v) in _axis_defaults
lk = Symbol(letter, k)
lv = _axis_defaults_byletter[lk]
plotattributes[k] = (lv == :match ? v : lv)
end
# merge!(plotattributes, _axis_defaults)
plotattributes[:discrete_values] = []
# update the defaults
attr!(Axis([sp], attr), args...; kw...)
attr!(Axis([sp], plotattributes), args...; kw...)
end
function get_axis(sp::Subplot, letter::Symbol)
@@ -32,9 +41,10 @@ function get_axis(sp::Subplot, letter::Symbol)
end::Axis
end
function process_axis_arg!(plotattributes::AKW, arg, letter = "")
function process_axis_arg!(plotattributes::KW, arg, letter = "")
T = typeof(arg)
arg = get(_scaleAliases, arg, arg)
if typeof(arg) <: Font
plotattributes[Symbol(letter,:tickfont)] = arg
plotattributes[Symbol(letter,:guidefont)] = arg
@@ -83,9 +93,6 @@ function attr!(axis::Axis, args...; kw...)
process_axis_arg!(plotattributes, arg)
end
# then preprocess keyword arguments
RecipesPipeline.preprocess_attributes!(KW(kw))
# then override for any keywords... only those keywords that already exists in plotattributes
for (k,v) in kw
if haskey(plotattributes, k)
@@ -94,12 +101,6 @@ function attr!(axis::Axis, args...; kw...)
for vi in v
discrete_value!(axis, vi)
end
#could perhaps use TimeType here, as Date and DateTime are both subtypes of TimeType
# or could perhaps check if dateformatter or datetimeformatter is in use
elseif k == :lims && isa(v, Tuple{Date,Date})
plotattributes[k] = (v[1].instant.periods.value, v[2].instant.periods.value)
elseif k == :lims && isa(v, Tuple{DateTime,DateTime})
plotattributes[k] = (v[1].instant.periods.value, v[2].instant.periods.value)
else
plotattributes[k] = v
end
@@ -122,27 +123,41 @@ Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.plotattributes, v,
Base.haskey(axis::Axis, k::Symbol) = haskey(axis.plotattributes, k)
ignorenan_extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax))
const _scale_funcs = Dict{Symbol,Function}(
:log10 => log10,
:log2 => log2,
:ln => log,
)
const _inv_scale_funcs = Dict{Symbol,Function}(
:log10 => exp10,
:log2 => exp2,
:ln => exp,
)
# const _label_func = Dict{Symbol,Function}(
# :log10 => x -> "10^$x",
# :log2 => x -> "2^$x",
# :ln => x -> "e^$x",
# )
const _label_func = Dict{Symbol,Function}(
:log10 => x -> "10^$x",
:log2 => x -> "2^$x",
:ln => x -> "e^$x",
)
scalefunc(scale::Symbol) = x -> get(_scale_funcs, scale, identity)(Float64(x))
invscalefunc(scale::Symbol) = x -> get(_inv_scale_funcs, scale, identity)(Float64(x))
labelfunc(scale::Symbol, backend::AbstractBackend) = get(_label_func, scale, string)
const _label_func_tex = Dict{Symbol,Function}(
:log10 => x -> "10^{$x}",
:log2 => x -> "2^{$x}",
:ln => x -> "e^{$x}",
)
labelfunc_tex(scale::Symbol) = get(_label_func_tex, scale, convert_sci_unicode)
function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
amin, amax = axis_limits(sp, axis[:letter])
# scale the limits
scale = axis[:scale]
sf = RecipesPipeline.scale_func(scale)
sf = scalefunc(scale)
# If the axis input was a Date or DateTime use a special logic to find
# "round" Date(Time)s as ticks
@@ -152,7 +167,7 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
# rather than on the input format
# TODO: maybe: non-trivial scale (:ln, :log2, :log10) for date/datetime
if ticks === nothing && scale == :identity
if axis[:formatter] == RecipesPipeline.dateformatter
if axis[:formatter] == dateformatter
# optimize_datetime_ticks returns ticks and labels(!) based on
# integers/floats corresponding to the DateTime type. Thus, the axes
# limits, which resulted from converting the Date type to integers,
@@ -163,7 +178,7 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
k_min = 2, k_max = 4)
# Now the ticks are converted back to floats corresponding to Dates.
return ticks / 864e5, labels
elseif axis[:formatter] == RecipesPipeline.datetimeformatter
elseif axis[:formatter] == datetimeformatter
return optimize_datetime_ticks(amin, amax; k_min = 2, k_max = 4)
end
end
@@ -187,18 +202,24 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
# chosen ticks is not too much bigger than amin - amax:
strict_span = false,
)
axis[:lims] = map(RecipesPipeline.inverse_scale_func(scale), (viewmin, viewmax))
axis[:lims] = map(invscalefunc(scale), (viewmin, viewmax))
else
scaled_ticks = map(sf, (filter(t -> amin <= t <= amax, ticks)))
end
unscaled_ticks = map(RecipesPipeline.inverse_scale_func(scale), scaled_ticks)
unscaled_ticks = map(invscalefunc(scale), scaled_ticks)
labels = if any(isfinite, unscaled_ticks)
formatter = axis[:formatter]
if formatter in (:auto, :plain, :scientific, :engineering)
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, formatter))
elseif formatter == :latex
map(x -> string("\$", replace(convert_sci_unicode(x), '×' => "\\times"), "\$"), Showoff.showoff(unscaled_ticks, :auto))
if formatter == :auto
# the default behavior is to make strings of the scaled values and then apply the labelfunc
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :auto))
elseif formatter == :plain
# Leave the numbers in plain format
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :plain))
elseif formatter == :scientific
Showoff.showoff(unscaled_ticks, :scientific)
elseif formatter == :latex
map(x -> string("\$", replace(convert_sci_unicode(x), '×' => "\\times"), "\$"), Showoff.showoff(unscaled_ticks, :auto))
else
# there was an override for the formatter... use that on the unscaled ticks
map(formatter, unscaled_ticks)
@@ -219,52 +240,48 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
end
# return (continuous_values, discrete_values) for the ticks on this axis
function get_ticks(sp::Subplot, axis::Axis; update = true)
if update || !haskey(axis.plotattributes, :optimized_ticks)
ticks = _transform_ticks(axis[:ticks])
if ticks in (:none, nothing, false)
axis.plotattributes[:optimized_ticks] = nothing
else
# treat :native ticks as :auto
ticks = ticks == :native ? :auto : ticks
function get_ticks(sp::Subplot, axis::Axis)
ticks = _transform_ticks(axis[:ticks])
ticks in (:none, nothing, false) && return nothing
dvals = axis[:discrete_values]
cv, dv = if typeof(ticks) <: Symbol
if !isempty(dvals)
# discrete ticks...
n = length(dvals)
rng = if ticks == :auto && n > 15
Δ = ceil(Int, n / 10)
Δ:Δ:n
else # if ticks == :all
1:n
end
axis[:continuous_values][rng], dvals[rng]
elseif ispolar(axis.sps[1]) && axis[:letter] == :x
#force theta axis to be full circle
(collect(0:pi/4:7pi/4), string.(0:45:315))
else
# compute optimal ticks and labels
optimal_ticks_and_labels(sp, axis)
end
elseif typeof(ticks) <: Union{AVec, Int}
if !isempty(dvals) && typeof(ticks) <: Int
rng = Int[round(Int,i) for i in range(1, stop=length(dvals), length=ticks)]
axis[:continuous_values][rng], dvals[rng]
else
# override ticks, but get the labels
optimal_ticks_and_labels(sp, axis, ticks)
end
elseif typeof(ticks) <: NTuple{2, Any}
# assuming we're passed (ticks, labels)
ticks
else
error("Unknown ticks type in get_ticks: $(typeof(ticks))")
# treat :native ticks as :auto
ticks = ticks == :native ? :auto : ticks
dvals = axis[:discrete_values]
cv, dv = if typeof(ticks) <: Symbol
if !isempty(dvals)
# discrete ticks...
n = length(dvals)
rng = if ticks == :auto
Int[round(Int,i) for i in range(1, stop=n, length=min(n,15))]
else # if ticks == :all
1:n
end
axis.plotattributes[:optimized_ticks] = (cv, dv)
axis[:continuous_values][rng], dvals[rng]
elseif ispolar(axis.sps[1]) && axis[:letter] == :x
#force theta axis to be full circle
(collect(0:pi/4:7pi/4), string.(0:45:315))
else
# compute optimal ticks and labels
optimal_ticks_and_labels(sp, axis)
end
elseif typeof(ticks) <: Union{AVec, Int}
if !isempty(dvals) && typeof(ticks) <: Int
rng = Int[round(Int,i) for i in range(1, stop=length(dvals), length=ticks)]
axis[:continuous_values][rng], dvals[rng]
else
# override ticks, but get the labels
optimal_ticks_and_labels(sp, axis, ticks)
end
elseif typeof(ticks) <: NTuple{2, Any}
# assuming we're passed (ticks, labels)
ticks
else
error("Unknown ticks type in get_ticks: $(typeof(ticks))")
end
axis.plotattributes[:optimized_ticks]
# @show ticks dvals cv dv
return cv, dv
end
_transform_ticks(ticks) = ticks
@@ -294,7 +311,7 @@ function get_minor_ticks(sp, axis, ticks)
minorticks = typeof(ticks[1])[]
for (i,hi) in enumerate(ticks[2:end])
lo = ticks[i]
if isfinite(lo) && isfinite(hi) && hi > lo
if isfinite(lo) && hi > lo
append!(minorticks,collect(lo + (hi-lo)/n :(hi-lo)/n: hi - (hi-lo)/2n))
end
end
@@ -344,7 +361,7 @@ function expand_extrema!(axis::Axis, v::AVec{N}) where N<:Number
end
function expand_extrema!(sp::Subplot, plotattributes::AKW)
function expand_extrema!(sp::Subplot, plotattributes::KW)
vert = isvertical(plotattributes)
# first expand for the data
@@ -389,7 +406,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
if fr === nothing && plotattributes[:seriestype] == :bar
fr = 0.0
end
if fr !== nothing && !RecipesPipeline.is3d(plotattributes)
if fr !== nothing && !all3D(plotattributes)
axis = sp.attr[vert ? :yaxis : :xaxis]
if typeof(fr) <: Tuple
for fri in fr
@@ -434,7 +451,7 @@ end
# push the limits out slightly
function widen(lmin, lmax, scale = :identity)
f, invf = RecipesPipeline.scale_func(scale), RecipesPipeline.inverse_scale_func(scale)
f, invf = scalefunc(scale), invscalefunc(scale)
span = f(lmax) - f(lmin)
# eps = NaNMath.max(1e-16, min(1e-2span, 1e-10))
eps = NaNMath.max(1e-16, 0.03span)
@@ -473,12 +490,11 @@ function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(l
lims = axis[:lims]
has_user_lims = (isa(lims, Tuple) || isa(lims, AVec)) && length(lims) == 2
if has_user_lims
lmin, lmax = lims
if lmin != :auto && isfinite(lmin)
amin = lmin
if isfinite(lims[1])
amin = lims[1]
end
if lmax != :auto && isfinite(lmax)
amax = lmax
if isfinite(lims[2])
amax = lims[2]
end
end
if amax <= amin && isfinite(amin)
@@ -504,7 +520,7 @@ function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(l
amin, amax
end
if !has_user_lims && consider_aspect && letter in (:x, :y) && !(sp[:aspect_ratio] in (:none, :auto) || RecipesPipeline.is3d(:sp))
if !has_user_lims && consider_aspect && letter in (:x, :y) && !(sp[:aspect_ratio] in (:none, :auto) || is3d(:sp))
aspect_ratio = isa(sp[:aspect_ratio], Number) ? sp[:aspect_ratio] : 1
plot_ratio = height(plotarea(sp)) / width(plotarea(sp))
dist = amax - amin
@@ -587,270 +603,160 @@ end
# -------------------------------------------------------------------------
function pie_labels(sp::Subplot, series::Series)
plotattributes = series.plotattributes
if haskey(plotattributes,:x_discrete_indices)
dvals = sp.attr[:xaxis].plotattributes[:discrete_values]
[dvals[idx] for idx in plotattributes[:x_discrete_indices]]
else
plotattributes[:x]
end
end
# -------------------------------------------------------------------------
# compute the line segments which should be drawn for this axis
function axis_drawing_info(sp, letter)
# find out which axis we are dealing with
asym = Symbol(letter, :axis)
isy = letter === :y
oletter = isy ? :x : :y
oasym = Symbol(oletter, :axis)
# get axis objects, ticks and minor ticks
ax, oax = sp[asym], sp[oasym]
amin, amax = axis_limits(sp, letter)
oamin, oamax = axis_limits(sp, oletter)
ticks = get_ticks(sp, ax, update = false)
minor_ticks = get_minor_ticks(sp, ax, ticks)
# initialize the segments
segments = Segments(2)
tick_segments = Segments(2)
grid_segments = Segments(2)
minorgrid_segments = Segments(2)
border_segments = Segments(2)
function axis_drawing_info(sp::Subplot)
xaxis, yaxis = sp[:xaxis], sp[:yaxis]
xmin, xmax = axis_limits(sp, :x)
ymin, ymax = axis_limits(sp, :y)
xticks = get_ticks(sp, xaxis)
yticks = get_ticks(sp, yaxis)
xminorticks = get_minor_ticks(sp, xaxis, xticks)
yminorticks = get_minor_ticks(sp, yaxis, yticks)
xaxis_segs = Segments(2)
yaxis_segs = Segments(2)
xtick_segs = Segments(2)
ytick_segs = Segments(2)
xgrid_segs = Segments(2)
ygrid_segs = Segments(2)
xminorgrid_segs = Segments(2)
yminorgrid_segs = Segments(2)
xborder_segs = Segments(2)
yborder_segs = Segments(2)
if sp[:framestyle] != :none
oa1, oa2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(ax[:mirror], oax[:flip]) ? (oamax, oamin) : (oamin, oamax)
end
if ax[:showaxis]
# xaxis
if xaxis[:showaxis]
if sp[:framestyle] != :grid
push!(segments, reverse_if((amin, oa1), isy), reverse_if((amax, oa1), isy))
# don't show the 0 tick label for the origin framestyle
if sp[:framestyle] == :origin && !(ticks in (:none, nothing, false)) && length(ticks) > 1
i = findfirst(==(0), ticks[1])
if i !== nothing
deleteat!(ticks[1], i)
deleteat!(ticks[2], i)
end
end
end
if sp[:framestyle] in (:semi, :box) # top spine
push!(
border_segments,
reverse_if((amin, oa2), isy),
reverse_if((amax, oa2), isy),
)
end
end
if !(ax[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(oax[:scale])
invf = RecipesPipeline.inverse_scale_func(oax[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(oamax) - f(oamin)))
(-t, t)
else
ticks_in = ax[:tick_direction] == :out ? -1 : 1
t = invf(f(oa1) + 0.012 * (f(oa2) - f(oa1)) * ticks_in)
(oa1, t)
end
for tick in ticks[1]
if ax[:showaxis]
push!(
tick_segments,
reverse_if((tick, tick_start), isy),
reverse_if((tick, tick_stop), isy),
)
end
if ax[:grid]
push!(
grid_segments,
reverse_if((tick, oamin), isy),
reverse_if((tick, oamax), isy),
)
end
end
if !(ax[:minorticks] in (:none, nothing, false)) || ax[:minorgrid]
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.006 * (f(oamax) - f(oamin)))
(-t, t)
y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
t = invf(f(oa1) + 0.006 * (f(oa2) - f(oa1)) * ticks_in)
(oa1, t)
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
end
for tick in minor_ticks
if ax[:showaxis]
push!(
tick_segments,
reverse_if((tick, tick_start), isy),
reverse_if((tick, tick_stop), isy),
)
end
if ax[:minorgrid]
push!(
minorgrid_segments,
reverse_if((tick, oamin), isy),
reverse_if((tick, oamax), isy),
)
end
push!(xaxis_segs, (xmin, y1), (xmax, y1))
# don't show the 0 tick label for the origin framestyle
if sp[:framestyle] == :origin && !(xticks in (:none, nothing, false)) && length(xticks) > 1
showticks = xticks[1] .!= 0
xticks = (xticks[1][showticks], xticks[2][showticks])
end
end
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2), (xmax, y2)) # top spine
end
end
if !(xaxis[:ticks] in (:none, nothing, false))
f = scalefunc(yaxis[:scale])
invf = invscalefunc(yaxis[:scale])
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
t1 = invf(f(ymin) + 0.015 * (f(ymax) - f(ymin)) * ticks_in)
t2 = invf(f(ymax) - 0.015 * (f(ymax) - f(ymin)) * ticks_in)
t3 = invf(f(0) + 0.015 * (f(ymax) - f(ymin)) * ticks_in)
return (
ticks = ticks,
segments = segments,
tick_segments = tick_segments,
grid_segments = grid_segments,
minorgrid_segments = minorgrid_segments,
border_segments = border_segments
)
end
function sort_3d_axes(a, b, c, letter)
if letter === :x
a, b, c
elseif letter === :y
b, a, c
else
c, b, a
end
end
function axis_drawing_info_3d(sp, letter)
near_letter = letter in (:x, :z) ? :y : :x
far_letter = letter in (:x, :y) ? :z : :x
ax = sp[Symbol(letter, :axis)]
nax = sp[Symbol(near_letter, :axis)]
fax = sp[Symbol(far_letter, :axis)]
amin, amax = axis_limits(sp, letter)
namin, namax = axis_limits(sp, near_letter)
famin, famax = axis_limits(sp, far_letter)
ticks = get_ticks(sp, ax, update = false)
minor_ticks = get_minor_ticks(sp, ax, ticks)
# initialize the segments
segments = Segments(3)
tick_segments = Segments(3)
grid_segments = Segments(3)
minorgrid_segments = Segments(3)
border_segments = Segments(3)
if sp[:framestyle] != :none# && letter === :x
na0, na1 = if sp[:framestyle] in (:origin, :zerolines)
0, 0
else
# reverse_if((namin, namax), xor(ax[:mirror], nax[:flip]))
reverse_if(reverse_if((namin, namax), letter === :y), xor(ax[:mirror], nax[:flip]))
for xtick in xticks[1]
if xaxis[:showaxis]
tick_start, tick_stop = if sp[:framestyle] == :origin
(0, t3)
else
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, t2) : (ymin, t1)
end
push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick
end
# sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick
xaxis[:grid] && push!(xgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid
end
end
fa0, fa1 = if sp[:framestyle] in (:origin, :zerolines)
0, 0
else
reverse_if((famin, famax), xor(ax[:mirror], fax[:flip]))
if !(xaxis[:minorticks] in (:none, nothing, false)) || xaxis[:minorgrid]
f = scalefunc(yaxis[:scale])
invf = invscalefunc(yaxis[:scale])
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
t1 = invf(f(ymin) + 0.01 * (f(ymax) - f(ymin)) * ticks_in)
t2 = invf(f(ymax) - 0.01 * (f(ymax) - f(ymin)) * ticks_in)
t3 = invf(f(0) + 0.01 * (f(ymax) - f(ymin)) * ticks_in)
for xminortick in xminorticks
if xaxis[:showaxis]
tick_start, tick_stop = if sp[:framestyle] == :origin
(0, t3)
else
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, t2) : (ymin, t1)
end
push!(xtick_segs, (xminortick, tick_start), (xminortick, tick_stop)) # bottom tick
end
# sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick
xaxis[:minorgrid] && push!(xminorgrid_segs, (xminortick, ymin), (xminortick, ymax)) # vertical grid
end
end
if ax[:showaxis]
# yaxis
if yaxis[:showaxis]
if sp[:framestyle] != :grid
push!(
segments,
sort_3d_axes(amin, na0, fa0, letter),
sort_3d_axes(amax, na0, fa0, letter),
)
x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax)
end
push!(yaxis_segs, (x1, ymin), (x1, ymax))
# don't show the 0 tick label for the origin framestyle
if sp[:framestyle] == :origin && !(ticks in (:none, nothing, false)) && length(ticks) > 1
i0 = findfirst(==(0), ticks[1])
if ind !== nothing
deleteat!(ticks[1], i0)
deleteat!(ticks[2], i0)
end
if sp[:framestyle] == :origin && !(yticks in (:none, nothing,false)) && length(yticks) > 1
showticks = yticks[1] .!= 0
yticks = (yticks[1][showticks], yticks[2][showticks])
end
end
if sp[:framestyle] in (:semi, :box)
push!(
border_segments,
sort_3d_axes(amin, na1, fa1, letter),
sort_3d_axes(amax, na1, fa1, letter),
)
sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (x2, ymin), (x2, ymax)) # right spine
end
if !(yaxis[:ticks] in (:none, nothing, false))
f = scalefunc(xaxis[:scale])
invf = invscalefunc(xaxis[:scale])
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
t1 = invf(f(xmin) + 0.015 * (f(xmax) - f(xmin)) * ticks_in)
t2 = invf(f(xmax) - 0.015 * (f(xmax) - f(xmin)) * ticks_in)
t3 = invf(f(0) + 0.015 * (f(xmax) - f(xmin)) * ticks_in)
for ytick in yticks[1]
if yaxis[:showaxis]
tick_start, tick_stop = if sp[:framestyle] == :origin
(0, t3)
else
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, t2) : (xmin, t1)
end
push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick
end
# sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick
yaxis[:grid] && push!(ygrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
end
end
# TODO this can be simplified, we do almost the same thing twice for grid and minorgrid
if !(ax[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(nax[:scale])
invf = RecipesPipeline.inverse_scale_func(nax[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(namax) - f(namin)))
(-t, t)
else
ticks_in = ax[:tick_direction] == :out ? -1 : 1
t = invf(f(na0) + 0.012 * (f(na1) - f(na0)) * ticks_in)
(na0, t)
end
if !(yaxis[:minorticks] in (:none, nothing, false)) || yaxis[:minorgrid]
f = scalefunc(xaxis[:scale])
invf = invscalefunc(xaxis[:scale])
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
t1 = invf(f(xmin) + 0.01 * (f(xmax) - f(xmin)) * ticks_in)
t2 = invf(f(xmax) - 0.01 * (f(xmax) - f(xmin)) * ticks_in)
t3 = invf(f(0) + 0.01 * (f(xmax) - f(xmin)) * ticks_in)
ga0, ga1 = sp[:framestyle] in (:origin, :zerolines) ? (namin, namax) : (na0, na1)
for tick in ticks[1]
if ax[:showaxis]
push!(
tick_segments,
sort_3d_axes(tick, tick_start, fa0, letter),
sort_3d_axes(tick, tick_stop, fa0, letter),
)
end
if ax[:grid]
push!(
grid_segments,
sort_3d_axes(tick, ga0, fa0, letter),
sort_3d_axes(tick, ga1, fa0, letter),
)
push!(
grid_segments,
sort_3d_axes(tick, ga1, fa0, letter),
sort_3d_axes(tick, ga1, fa1, letter),
)
end
end
if !(ax[:minorticks] in (:none, nothing, false)) || ax[:minorgrid]
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.006 * (f(namax) - f(namin)))
(-t, t)
else
t = invf(f(na0) + 0.006 * (f(na1) - f(na0)) * ticks_in)
(na0, t)
end
for tick in minor_ticks
if ax[:showaxis]
push!(
tick_segments,
sort_3d_axes(tick, tick_start, fa0, letter),
sort_3d_axes(tick, tick_stop, fa0, letter),
)
end
if ax[:minorgrid]
push!(
minorgrid_segments,
sort_3d_axes(tick, ga0, fa0, letter),
sort_3d_axes(tick, ga1, fa0, letter),
)
push!(
minorgrid_segments,
sort_3d_axes(tick, ga1, fa0, letter),
sort_3d_axes(tick, ga1, fa1, letter),
)
for ytick in yminorticks
if yaxis[:showaxis]
tick_start, tick_stop = if sp[:framestyle] == :origin
(0, t3)
else
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, t2) : (xmin, t1)
end
push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick
end
# sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick
yaxis[:minorgrid] && push!(yminorgrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
end
end
end
return (
ticks = ticks,
segments = segments,
tick_segments = tick_segments,
grid_segments = grid_segments,
minorgrid_segments = minorgrid_segments,
border_segments = border_segments
)
xticks, yticks, xaxis_segs, yaxis_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xminorgrid_segs, yminorgrid_segs, xborder_segs, yborder_segs
end
reverse_if(x, cond) = cond ? reverse(x) : x
axis_tuple(x, y, letter) = reverse_if((x, y), letter === :y)
axes_shift(t, i) = i % 3 == 0 ? t : i % 3 == 1 ? (t[3], t[1], t[2]) : (t[2], t[3], t[1])
+69 -200
View File
@@ -1,3 +1,5 @@
using Pkg
struct NoBackend <: AbstractBackend end
const _backendType = Dict{Symbol, DataType}(:none => NoBackend)
@@ -28,7 +30,7 @@ macro init_backend(s)
esc(quote
struct $T <: AbstractBackend end
export $sym
$sym(; kw...) = (default(; reset = false, kw...); backend($T()))
$sym(; kw...) = (default(; kw...); backend($T()))
backend_name(::$T) = Symbol($str)
backend_package_name(pkg::$T) = backend_package_name(Symbol($str))
push!(_backends, Symbol($str))
@@ -102,7 +104,7 @@ end
# Set the (left, top, right, bottom) minimum padding around the plot area
# to fit ticks, tick labels, guides, colorbars, etc.
function _update_min_padding!(sp::Subplot)
# TODO: something different when `RecipesPipeline.is3d(sp) == true`
# TODO: something different when `is3d(sp) == true`
leftpad = tick_padding(sp, sp[:yaxis]) + sp[:left_margin] + guide_padding(sp[:yaxis])
toppad = sp[:top_margin] + title_padding(sp)
rightpad = sp[:right_margin]
@@ -188,15 +190,11 @@ function backend(sym::Symbol)
end
end
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize, :pgfplots]
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize]
function warn_on_deprecated_backend(bsym::Symbol)
if bsym in _deprecated_backends
if bsym == :pgfplots
@warn("Backend $bsym has been deprecated. Use pgfplotsx instead.")
else
@warn("Backend $bsym has been deprecated.")
end
@warn("Backend $bsym has been deprecated.")
end
end
@@ -213,7 +211,7 @@ const _base_supported_args = [
:seriestype,
:seriescolor, :seriesalpha,
:smooth,
:xerror, :yerror, :zerror,
:xerror, :yerror,
:subplot,
:x, :y, :z,
:show, :size,
@@ -316,6 +314,7 @@ const _gr_attr = merge_with_base_supported([
:layout,
:title, :window_title,
:guide, :lims, :ticks, :scale, :flip,
:match_dimensions,
:titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign,
:titlefontrotation, :titlefontcolor,
:legendfontfamily, :legendfontsize, :legendfonthalign, :legendfontvalign,
@@ -342,18 +341,10 @@ const _gr_attr = merge_with_base_supported([
:contour_labels,
])
const _gr_seriestype = [
:path,
:scatter,
:straightline,
:heatmap,
:image,
:contour,
:path3d,
:scatter3d,
:surface,
:wireframe,
:volume,
:shape,
:path, :scatter, :straightline,
:heatmap, :pie, :image,
:contour, :path3d, :scatter3d, :surface, :wireframe, :volume,
:shape
]
const _gr_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
const _gr_marker = _allMarkers
@@ -366,10 +357,10 @@ is_marker_supported(::GRBackend, shape::Shape) = true
function _initialize_backend(pkg::PlotlyBackend)
try
@eval Main begin
import PlotlyBase
import ORCA
end
catch
@info "For saving to png with the Plotly backend PlotlyBase has to be installed."
@info "For saving to png with the Plotly backend ORCA has to be installed."
end
end
@@ -387,7 +378,7 @@ const _plotly_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :markerstrokestyle,
:fillrange, :fillcolor, :fillalpha,
:bins,
:title, :titlelocation,
:title, :title_location,
:titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign,
:titlefontcolor,
:legendfontfamily, :legendfontsize, :legendfontcolor,
@@ -417,18 +408,9 @@ const _plotly_attr = merge_with_base_supported([
])
const _plotly_seriestype = [
:path,
:scatter,
:heatmap,
:contour,
:surface,
:wireframe,
:path3d,
:scatter3d,
:shape,
:scattergl,
:straightline,
:mesh3d
:path, :scatter, :pie, :heatmap,
:contour, :surface, :wireframe, :path3d, :scatter3d, :shape, :scattergl,
:straightline
]
const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot]
const _plotly_marker = [
@@ -471,6 +453,7 @@ const _pgfplots_attr = merge_with_base_supported([
:polar,
# :normalize, :weights, :contours,
:aspect_ratio,
# :match_dimensions,
:tick_direction,
:framestyle,
:camera,
@@ -486,7 +469,7 @@ const _pgfplots_scale = [:identity, :ln, :log2, :log10]
function _initialize_backend(pkg::PlotlyJSBackend)
@eval Main begin
import PlotlyJS
import PlotlyJS, ORCA
export PlotlyJS
end
end
@@ -522,7 +505,7 @@ const _pyplot_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
:fillrange, :fillcolor, :fillalpha,
:bins, :bar_width, :bar_edges, :bar_position,
:title, :titlelocation, :titlefont,
:title, :title_location, :titlefont,
:window_title,
:guide, :guide_position, :lims, :ticks, :scale, :flip, :rotation,
:titlefontfamily, :titlefontsize, :titlefontcolor,
@@ -539,6 +522,7 @@ const _pyplot_attr = merge_with_base_supported([
:polar,
:normalize, :weights,
:contours, :aspect_ratio,
:match_dimensions,
:clims,
:inset_subplots,
:dpi,
@@ -549,22 +533,12 @@ const _pyplot_attr = merge_with_base_supported([
:contour_labels,
])
const _pyplot_seriestype = [
:path,
:steppre,
:steppost,
:shape,
:straightline,
:scatter,
:hexbin,
:heatmap,
:image,
:contour,
:contour3d,
:path3d,
:scatter3d,
:surface,
:wireframe,
]
:path, :steppre, :steppost, :shape, :straightline,
:scatter, :hexbin, #:histogram2d, :histogram,
# :bar,
:heatmap, :pie, :image,
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
]
const _pyplot_style = [:auto, :solid, :dash, :dot, :dashdot]
const _pyplot_marker = vcat(_allMarkers, :pixel)
const _pyplot_scale = [:identity, :ln, :log2, :log10]
@@ -594,9 +568,6 @@ const _unicodeplots_style = [:auto, :solid]
const _unicodeplots_marker = [:none, :auto, :circle]
const _unicodeplots_scale = [:identity]
# Additional constants
const _canvas_type = Ref(:auto)
# ------------------------------------------------------------------------------
# hdf5
@@ -611,7 +582,7 @@ const _hdf5_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
:fillrange, :fillcolor, :fillalpha,
:bins, :bar_width, :bar_edges, :bar_position,
:title, :titlelocation, :titlefont,
:title, :title_location, :titlefont,
:window_title,
:guide, :lims, :ticks, :scale, :flip, :rotation,
:tickfont, :guidefont, :legendfont,
@@ -624,44 +595,23 @@ const _hdf5_attr = merge_with_base_supported([
:polar,
:normalize, :weights,
:contours, :aspect_ratio,
:match_dimensions,
:clims,
:inset_subplots,
:dpi,
:colorbar_title,
])
const _hdf5_seriestype = [
:path,
:steppre,
:steppost,
:shape,
:straightline,
:scatter,
:hexbin,
:heatmap,
:image,
:contour,
:contour3d,
:path3d,
:scatter3d,
:surface,
:wireframe,
]
:path, :steppre, :steppost, :shape, :straightline,
:scatter, :hexbin, #:histogram2d, :histogram,
# :bar,
:heatmap, :pie, :image,
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
]
const _hdf5_style = [:auto, :solid, :dash, :dot, :dashdot]
const _hdf5_marker = vcat(_allMarkers, :pixel)
const _hdf5_scale = [:identity, :ln, :log2, :log10]
# Additional constants
#Dict has problems using "Types" as keys. Initialize in "_initialize_backend":
const HDF5PLOT_MAP_STR2TELEM = Dict{String, Type}()
const HDF5PLOT_MAP_TELEM2STR = Dict{Type, String}()
#Don't really like this global variable... Very hacky
mutable struct HDF5Plot_PlotRef
ref::Union{Plot, Nothing}
end
const HDF5PLOT_PLOTREF = HDF5Plot_PlotRef(nothing)
# ------------------------------------------------------------------------------
# inspectdr
@@ -679,7 +629,7 @@ const _inspectdr_attr = merge_with_base_supported([
:markerstrokestyle, #Causes warning not to have it... what is this?
:fillcolor, :fillalpha, #:fillrange,
# :bins, :bar_width, :bar_edges, :bar_position,
:title, :titlelocation,
:title, :title_location,
:window_title,
:guide, :lims, :scale, #:ticks, :flip, :rotation,
:titlefontfamily, :titlefontsize, :titlefontcolor,
@@ -696,6 +646,7 @@ const _inspectdr_attr = merge_with_base_supported([
:polar,
# :normalize, :weights,
# :contours, :aspect_ratio,
:match_dimensions,
# :clims,
# :inset_subplots,
:dpi,
@@ -722,85 +673,37 @@ const _inspectdr_scale = [:identity, :ln, :log2, :log10]
const _pgfplotsx_attr = merge_with_base_supported([
:annotations,
:background_color_legend,
:background_color_inside,
:background_color_outside,
:foreground_color_legend,
:foreground_color_grid,
:foreground_color_axis,
:foreground_color_text,
:foreground_color_border,
:background_color_legend, :background_color_inside, :background_color_outside,
:foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
:foreground_color_text, :foreground_color_border,
:label,
:seriescolor,
:seriesalpha,
:linecolor,
:linestyle,
:linewidth,
:linealpha,
:markershape,
:markercolor,
:markersize,
:markeralpha,
:markerstrokewidth,
:markerstrokecolor,
:markerstrokealpha,
:fillrange,
:fillcolor,
:fillalpha,
:seriescolor, :seriesalpha,
:linecolor, :linestyle, :linewidth, :linealpha,
:markershape, :markercolor, :markersize, :markeralpha,
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
:fillrange, :fillcolor, :fillalpha,
:bins,
:layout,
:title,
:window_title,
:guide,
:lims,
:ticks,
:scale,
:flip,
:titlefontfamily,
:titlefontsize,
:titlefonthalign,
:titlefontvalign,
:titlefontrotation,
:titlefontcolor,
:legendfontfamily,
:legendfontsize,
:legendfonthalign,
:legendfontvalign,
:legendfontrotation,
:legendfontcolor,
:tickfontfamily,
:tickfontsize,
:tickfonthalign,
:tickfontvalign,
:tickfontrotation,
:tickfontcolor,
:guidefontfamily,
:guidefontsize,
:guidefonthalign,
:guidefontvalign,
:guidefontrotation,
:guidefontcolor,
:grid,
:gridalpha,
:gridstyle,
:gridlinewidth,
:legend,
:legendtitle,
:colorbar,
:colorbar_title,
:colorbar_entry,
:fill_z,
:line_z,
:marker_z,
:levels,
:ribbon,
:quiver,
:title, :window_title,
:guide, :lims, :ticks, :scale, :flip,
:match_dimensions,
:titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign,
:titlefontrotation, :titlefontcolor,
:legendfontfamily, :legendfontsize, :legendfonthalign, :legendfontvalign,
:legendfontrotation, :legendfontcolor,
:tickfontfamily, :tickfontsize, :tickfonthalign, :tickfontvalign,
:tickfontrotation, :tickfontcolor,
:guidefontfamily, :guidefontsize, :guidefonthalign, :guidefontvalign,
:guidefontrotation, :guidefontcolor,
:grid, :gridalpha, :gridstyle, :gridlinewidth,
:legend, :legendtitle, :colorbar, :colorbar_title, :colorbar_entry,
:fill_z, :line_z, :marker_z, :levels,
:ribbon, :quiver,
:orientation,
:overwrite_figure,
:polar,
:aspect_ratio,
:normalize,
:weights,
:normalize, :weights,
:inset_subplots,
:bar_width,
:arrow,
@@ -809,47 +712,13 @@ const _pgfplotsx_attr = merge_with_base_supported([
:camera,
:contour_labels,
])
const _pgfplotsx_seriestype = [
:path,
:scatter,
:straightline,
:path3d,
:scatter3d,
:surface,
:wireframe,
:heatmap,
:mesh3d,
:contour,
:contour3d,
:quiver,
:shape,
:steppre,
:stepmid,
:steppost,
:ysticks,
:xsticks,
]
const _pgfplotsx_seriestype =
[:path, :scatter, :straightline,
:path3d, :scatter3d, :surface, :wireframe,
:heatmap, :contour, :contour3d,
:shape,
:steppre, :stepmid, :steppost, :ysticks, :xsticks]
const _pgfplotsx_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
const _pgfplotsx_marker = [
:none,
:auto,
:circle,
:rect,
:diamond,
:utriangle,
:dtriangle,
:ltriangle,
:rtriangle,
:cross,
:xcross,
:star5,
:pentagon,
:hline,
:vline,
Shape,
]
const _pgfplotsx_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :ltriangle, :rtriangle, :cross, :xcross, :star5, :pentagon, :hline, :vline, Shape]
const _pgfplotsx_scale = [:identity, :ln, :log2, :log10]
is_marker_supported(::PGFPlotsXBackend, shape::Shape) = true
# additional constants
const _pgfplotsx_series_ids = KW()
+1008 -1208
View File
File diff suppressed because it is too large Load Diff
+483 -493
View File
File diff suppressed because it is too large Load Diff
+23 -81
View File
@@ -79,58 +79,6 @@ end
# ---------------------------------------------------------------------------
function _inspectdr_getaxisticks(ticks, gridlines, xfrm)
TickCustom = InspectDR.TickCustom
_xfrm(coord) = InspectDR.axis2aloc(Float64(coord), xfrm.spec) #Ensure Float64 - in case
ttype = ticksType(ticks)
if ticks == :native
#keep current
elseif ttype == :ticks_and_labels
pos = ticks[1]; labels = ticks[2]; nticks = length(ticks[1])
newticks = TickCustom[TickCustom(_xfrm(pos[i]), labels[i]) for i in 1:nticks]
gridlines = InspectDR.GridLinesCustom(gridlines)
gridlines.major = newticks
gridlines.minor = []
gridlines.displayminor = false
elseif ttype == :ticks
nticks = length(ticks)
gridlines.major = Float64[_xfrm(t) for t in ticks]
gridlines.minor = []
gridlines.displayminor = false
elseif isnothing(ticks)
gridlines.major = []
gridlines.minor = []
else #Assume ticks == :native
#keep current
end
return gridlines #keep current
end
function _inspectdr_setticks(sp::Subplot, plot, strip, xaxis, yaxis)
InputXfrm1D = InspectDR.InputXfrm1D
_get_ticks(axis) = :native == axis[:ticks] ? (:native) : get_ticks(sp, axis)
wantnative(ticks) = (:native == ticks)
xticks = _get_ticks(xaxis)
yticks = _get_ticks(yaxis)
if wantnative(xticks) && wantnative(yticks)
#Don't "eval" tick values
return
end
#TODO: Allow InspectDR to independently "eval" x or y ticks
ext = InspectDR.getextents_aloc(plot, 1)
grid = InspectDR._eval(strip.grid, plot.xscale, strip.yscale, ext)
grid.xlines = _inspectdr_getaxisticks(xticks, grid.xlines, InputXfrm1D(plot.xscale))
grid.ylines = _inspectdr_getaxisticks(yticks, grid.ylines, InputXfrm1D(strip.yscale))
strip.grid = grid
end
# ---------------------------------------------------------------------------
function _inspectdr_getscale(s::Symbol, yaxis::Bool)
#TODO: Support :asinh, :sqrt
kwargs = yaxis ? (:tgtmajor=>8, :tgtminor=>2) : () #More grid lines on y-axis
@@ -219,7 +167,6 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
st = series[:seriestype]
sp = series[:subplot]
plot = sp.o
clims = get_clims(sp, series)
#Don't do anything without a "subplot" object: Will process later.
if nothing == plot; return; end
@@ -309,8 +256,8 @@ For st in :shape:
wfrm.glyph = InspectDR.glyph(
shape = _inspectdr_mapglyph(series[:markershape]),
size = _inspectdr_mapglyphsize(series[:markersize]),
color = _inspectdr_mapcolor(plot_color(get_markerstrokecolor(series), get_markerstrokealpha(series))),
fillcolor = _inspectdr_mapcolor(plot_color(get_markercolor(series, clims), get_markeralpha(series))),
color = _inspectdr_mapcolor(plot_color(series[:markerstrokecolor], series[:markerstrokealpha])),
fillcolor = _inspectdr_mapcolor(plot_color(series[:markercolor], series[:markeralpha])),
)
end
@@ -341,8 +288,8 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
ygrid_show = yaxis[:grid]
strip.grid = InspectDR.GridRect(
vmajor=xgrid_show, # vminor=xgrid_show,
hmajor=ygrid_show, # hminor=ygrid_show,
vmajor=xgrid_show, # vminor=xgrid_show,
hmajor=ygrid_show, # hminor=ygrid_show,
)
plot.xscale = _inspectdr_getscale(xaxis[:scale], false)
@@ -355,27 +302,18 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
xmin, xmax = -rmax, rmax
ymin, ymax = -rmax, rmax
end
plot.xext = InspectDR.PExtents1D() #reset
strip.yext = InspectDR.PExtents1D() #reset
plot.xext_full = InspectDR.PExtents1D(xmin, xmax)
strip.yext_full = InspectDR.PExtents1D(ymin, ymax)
#Set current extents = full extents (needed for _eval(strip.grid,...))
plot.xext = plot.xext_full
strip.yext = strip.yext_full
_inspectdr_setticks(sp, plot, strip, xaxis, yaxis)
a = plot.annotation
a.title = sp[:title]
a.xlabel = xaxis[:guide]; a.ylabels = [yaxis[:guide]]
l = plot.layout
#IMPORTANT: Don't forget to actually register changes
#(TODO: need to find a better way to set layout properties)
l[:frame_canvas].fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
l[:frame_canvas] = l[:frame_canvas] #register changes
l[:frame_data].fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
l[:frame_data] = l[:frame_data] #register changes
l[:frame_data].line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
l[:frame_data] = l[:frame_data] #register changes
l[:font_title] = InspectDR.Font(sp[:titlefontfamily],
_inspectdr_mapptsize(sp[:titlefontsize]),
color = _inspectdr_mapcolor(sp[:titlefontcolor])
@@ -396,7 +334,6 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
color = _inspectdr_mapcolor(sp[:legendfontcolor])
)
l[:frame_legend].fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
l[:frame_legend] = l[:frame_legend] #register changes
end
# called just before updating layout bounding boxes... in case you need to prep
@@ -410,9 +347,8 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend})
#Don't use window_title... probably not what you want.
#mplot.title = plt[:window_title]
end
mplot.layout[:frame].fillcolor = _inspectdr_mapcolor(plt[:background_color_outside])
mplot.layout[:frame] = mplot.layout[:frame] #register changes
resize!(mplot.subplots, length(plt.subplots))
nsubplots = length(plt.subplots)
for (i, sp) in enumerate(plt.subplots)
@@ -493,23 +429,29 @@ end
# ----------------------------------------------------------------
const _inspectdr_mimeformats_dpi = Dict(
"image/png" => "png"
)
const _inspectdr_mimeformats_nodpi = Dict(
"image/svg+xml" => "svg",
"application/eps" => "eps",
"image/eps" => "eps",
# "application/postscript" => "ps", #TODO: support once Cairo supports PSSurface
"application/pdf" => "pdf"
)
_inspectdr_show(io::IO, mime::MIME, ::Nothing, w, h) =
throw(ErrorException("Cannot show(::IO, ...) plot - not yet generated"))
function _inspectdr_show(io::IO, mime::MIME, mplot, w, h)
InspectDR._show(io, mime, mplot, Float64(w), Float64(h))
end
function _show(io::IO, mime::MIME{Symbol("image/png")}, plt::Plot{InspectDRBackend})
dpi = plt[:dpi] # TODO: support
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
for (mime, fmt) in _inspectdr_mimeformats_dpi
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend})
dpi = plt[:dpi]#TODO: support
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
end
end
for (mime, fmt) in (
"image/svg+xml" => "svg",
"application/eps" => "eps",
"image/eps" => "eps",
# "application/postscript" => "ps", # TODO: support once Cairo supports PSSurface
"application/pdf" => "pdf",
)
for (mime, fmt) in _inspectdr_mimeformats_nodpi
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend})
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
end
+24
View File
@@ -0,0 +1,24 @@
function plotlybase_syncplot(plt::Plot)
plt.o = ORCA.PlotlyBase.Plot()
traces = ORCA.PlotlyBase.GenericTrace[]
for series_dict in plotly_series(plt)
plotly_type = pop!(series_dict, :type)
push!(traces, ORCA.PlotlyBase.GenericTrace(plotly_type; series_dict...))
end
ORCA.PlotlyBase.addtraces!(plt.o, traces...)
layout = plotly_layout(plt)
w, h = plt[:size]
ORCA.PlotlyBase.relayout!(plt.o, layout, width = w, height = h)
return plt.o
end
const _orca_mimeformats = Dict(
"application/pdf" => "pdf",
"image/png" => "png",
"image/svg+xml" => "svg",
"image/eps" => "eps",
)
for (mime, fmt) in _orca_mimeformats
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyBackend}) = ORCA.PlotlyBase.savefig(io, plotlybase_syncplot(plt), format = $fmt)
end
@@ -166,7 +166,7 @@ function pgf_series(sp::Subplot, series::Series)
# function args
args = if st == :contour
plotattributes[:z].surf, plotattributes[:x], plotattributes[:y]
elseif RecipesPipeline.is3d(st)
elseif is3d(st)
plotattributes[:x], plotattributes[:y], plotattributes[:z]
elseif st == :straightline
straightline_data(series)
@@ -271,7 +271,7 @@ function pgf_fillrange_series(series, i, fillrange, args...)
push!(style, _pgf_series_extrastyle[st])
end
kw[:style] = join(style, ',')
func = RecipesPipeline.is3d(series) ? PGFPlots.Linear3 : PGFPlots.Linear
func = is3d(series) ? PGFPlots.Linear3 : PGFPlots.Linear
return func(pgf_fillrange_args(fillrange, args...)...; kw...)
end
@@ -444,7 +444,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
# add to style/kw for each axis
for letter in (:x, :y, :z)
if letter != :z || RecipesPipeline.is3d(sp)
if letter != :z || is3d(sp)
axisstyle, axiskw = pgf_axis(sp, letter)
append!(style, axisstyle)
merge!(kw, axiskw)
@@ -470,7 +470,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
push!(style, string("title style = {font = ", pgf_font(sp[:titlefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", sp[:titlefontrotation], "}"))
end
if get_aspect_ratio(sp) in (1, :equal)
if sp[:aspect_ratio] in (1, :equal)
kw[:axisEqual] = "true"
end
@@ -482,19 +482,19 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
fg_alpha = alpha(plot_color(sp[:foreground_color_legend]))
push!(style, string(
"legend style = {",
pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], fg_alpha, "solid", ), ",",
"fill = $cstr,",
"fill opacity = $bg_alpha,",
"text opacity = $(alpha(plot_color(sp[:legendfontcolor]))),",
"font = ", pgf_font(sp[:legendfontsize], pgf_thickness_scaling(sp)),
"legend style = {",
pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], fg_alpha, "solid", ), ",",
"fill = $cstr,",
"fill opacity = $bg_alpha,",
"text opacity = $(alpha(plot_color(sp[:legendfontcolor]))),",
"font = ", pgf_font(sp[:legendfontsize], pgf_thickness_scaling(sp)),
"}",
))
if any(s[:seriestype] == :contour for s in series_list(sp))
kw[:view] = "{0}{90}"
kw[:colorbar] = !(sp[:colorbar] in (:none, :off, :hide, false))
elseif RecipesPipeline.is3d(sp)
elseif is3d(sp)
azim, elev = sp[:camera]
kw[:view] = "{$(azim)}{$(elev)}"
end
+513 -1059
View File
File diff suppressed because it is too large Load Diff
+142 -238
View File
@@ -1,12 +1,15 @@
# https://plot.ly/javascript/getting-started
is_subplot_supported(::PlotlyBackend) = true
# is_string_supported(::PlotlyBackend) = true
const _plotly_framestyles = [:box, :axes, :zerolines, :grid, :none]
const _plotly_framestyle_defaults = Dict(:semi => :box, :origin => :zerolines)
function _plotly_framestyle(style::Symbol)
if style in (:box, :axes, :zerolines, :grid, :none)
if style in _plotly_framestyles
return style
else
default_style = get((semi = :box, origin = :zerolines), style, :axes)
default_style = get(_plotly_framestyle_defaults, style, :axes)
@warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was cosen instead.")
default_style
end
@@ -14,20 +17,30 @@ end
# --------------------------------------------------------------------------------------
const plotly_remote_file_path = "https://cdn.plot.ly/plotly-latest.min.js"
# if isatom()
# import Atom
# Atom.@msg evaljs(_js_code)
# end
using UUIDs
# ----------------------------------------------------------------
function labelfunc(scale::Symbol, backend::PlotlyBackend)
texfunc = labelfunc_tex(scale)
function (x)
tex_x = texfunc(x)
sup_x = replace( tex_x, r"\^{(.*)}"=>s"<sup>\1</sup>" )
# replace dash with \minus (U+2212)
replace(sup_x, "-" => "")
end
end
const _plotly_legend_pos = KW(
:right => [1., 0.5],
:left => [0., 0.5],
:top => [0.5, 1.],
:bottom => [0.5, 0.],
:bottomleft => [0., 0.],
:bottomright => [1., 0.],
:topright => [1., 1.],
:topleft => [0., 1.]
)
plotly_legend_pos(pos::Symbol) = get(_plotly_legend_pos, pos, [1.,1.])
plotly_legend_pos(v::Tuple{S,T}) where {S<:Real, T<:Real} = v
function plotly_font(font::Font, color = font.color)
KW(
@@ -95,7 +108,7 @@ function shrink_by(lo, sz, ratio)
end
function plotly_apply_aspect_ratio(sp::Subplot, plotarea, pcts)
aspect_ratio = get_aspect_ratio(sp)
aspect_ratio = sp[:aspect_ratio]
if aspect_ratio != :none
if aspect_ratio == :equal
aspect_ratio = 1.0
@@ -120,17 +133,16 @@ end
# this method gets the start/end in percentage of the canvas for this axis direction
function plotly_domain(sp::Subplot)
function plotly_domain(sp::Subplot, letter)
figw, figh = sp.plt[:size]
pcts = bbox_to_pcts(sp.plotarea, figw*px, figh*px)
pcts = plotly_apply_aspect_ratio(sp, sp.plotarea, pcts)
x_domain = [pcts[1], pcts[1] + pcts[3]]
y_domain = [pcts[2], pcts[2] + pcts[4]]
return x_domain, y_domain
i1,i2 = (letter == :x ? (1,3) : (2,4))
[pcts[i1], pcts[i1]+pcts[i2]]
end
function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
letter = axis[:letter]
framestyle = sp[:framestyle]
ax = KW(
@@ -147,11 +159,16 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
:mirror => framestyle == :box,
:showticklabels => axis[:showaxis],
)
if anchor !== nothing
ax[:anchor] = anchor
end
if domain !== nothing
ax[:domain] = domain
if letter in (:x,:y)
ax[:domain] = plotly_domain(sp, letter)
if is3d(sp)
# don't link 3d axes for synchronized interactivity
x_idx = y_idx = sp[:subplot_index]
else
x_idx, y_idx = plotly_link_indicies(plt, sp)
end
ax[:anchor] = "$(letter==:x ? "y$(y_idx)" : "x$(x_idx)")"
end
ax[:tickangle] = -axis[:rotation]
@@ -159,7 +176,7 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
lims = axis_limits(sp, letter)
if axis[:ticks] != :native || axis[:lims] != :auto
ax[:range] = map(RecipesPipeline.scale_func(axis[:scale]), lims)
ax[:range] = map(scalefunc(axis[:scale]), lims)
end
if !(axis[:ticks] in (nothing, :none, false))
@@ -228,7 +245,7 @@ function plotly_layout(plt::Plot)
# but vertically just below the top of the subplot bounding box
if sp[:title] != ""
bb = plotarea(sp)
tpos = sp[:titlelocation]
tpos = sp[:title_location]
xmm = if tpos == :left
left(bb)
elseif tpos == :right
@@ -246,42 +263,46 @@ function plotly_layout(plt::Plot)
# set to supported framestyle
sp[:framestyle] = _plotly_framestyle(sp[:framestyle])
if ispolar(sp)
# if any(is3d, seriesargs)
if is3d(sp)
azim = sp[:camera][1] - 90 #convert azimuthal to match GR behaviour
theta = 90 - sp[:camera][2] #spherical coordinate angle from z axis
plotattributes_out[:scene] = KW(
Symbol("xaxis$(spidx)") => plotly_axis(plt, sp[:xaxis], sp),
Symbol("yaxis$(spidx)") => plotly_axis(plt, sp[:yaxis], sp),
Symbol("zaxis$(spidx)") => plotly_axis(plt, sp[:zaxis], sp),
#2.6 multiplier set camera eye such that whole plot can be seen
:camera => KW(
:eye => KW(
:x => cosd(azim)*sind(theta)*2.6,
:y => sind(azim)*sind(theta)*2.6,
:z => cosd(theta)*2.6,
),
),
)
elseif ispolar(sp)
plotattributes_out[Symbol("angularaxis$(spidx)")] = plotly_polaraxis(sp, sp[:xaxis])
plotattributes_out[Symbol("radialaxis$(spidx)")] = plotly_polaraxis(sp, sp[:yaxis])
else
x_domain, y_domain = plotly_domain(sp)
if RecipesPipeline.is3d(sp)
azim = sp[:camera][1] - 90 #convert azimuthal to match GR behaviour
theta = 90 - sp[:camera][2] #spherical coordinate angle from z axis
plotattributes_out[Symbol(:scene, spidx)] = KW(
:domain => KW(:x => x_domain, :y => y_domain),
Symbol("xaxis$(spidx)") => plotly_axis(sp[:xaxis], sp),
Symbol("yaxis$(spidx)") => plotly_axis(sp[:yaxis], sp),
Symbol("zaxis$(spidx)") => plotly_axis(sp[:zaxis], sp),
#2.6 multiplier set camera eye such that whole plot can be seen
:camera => KW(
:eye => KW(
:x => cosd(azim)*sind(theta)*2.6,
:y => sind(azim)*sind(theta)*2.6,
:z => cosd(theta)*2.6,
),
),
)
else
plotattributes_out[Symbol("xaxis$(x_idx)")] =
plotly_axis(sp[:xaxis], sp, string("y", y_idx) , x_domain)
# don't allow yaxis to be reupdated/reanchored in a linked subplot
if spidx == y_idx
plotattributes_out[Symbol("yaxis$(y_idx)")] =
plotly_axis(sp[:yaxis], sp, string("x", x_idx), y_domain)
end
end
plotattributes_out[Symbol("xaxis$(x_idx)")] = plotly_axis(plt, sp[:xaxis], sp)
# don't allow yaxis to be reupdated/reanchored in a linked subplot
spidx == y_idx ? plotattributes_out[Symbol("yaxis$(y_idx)")] = plotly_axis(plt, sp[:yaxis], sp) : nothing
end
# legend
plotly_add_legend!(plotattributes_out, sp)
plotattributes_out[:showlegend] = sp[:legend] != :none
xpos,ypos = plotly_legend_pos(sp[:legend])
if sp[:legend] != :none
plotattributes_out[:legend] = KW(
:bgcolor => rgba_string(sp[:background_color_legend]),
:bordercolor => rgba_string(sp[:foreground_color_legend]),
:font => plotly_font(legendfont(sp)),
:tracegroupgap => 0,
:x => xpos,
:y => ypos
)
end
# annotations
for ann in sp[:annotations]
@@ -321,113 +342,38 @@ function plotly_layout(plt::Plot)
plotattributes_out[:hovermode] = "none"
end
plotattributes_out = recursive_merge(plotattributes_out, plt.attr[:extra_plot_kwargs])
plotattributes_out
end
function plotly_add_legend!(plotattributes_out::KW, sp::Subplot)
plotattributes_out[:showlegend] = sp[:legend] != :none
legend_position = plotly_legend_pos(sp[:legend])
if sp[:legend] != :none
plotattributes_out[:legend] = KW(
:bgcolor => rgba_string(sp[:background_color_legend]),
:bordercolor => rgba_string(sp[:foreground_color_legend]),
:borderwidth => 1,
:traceorder => "normal",
:xanchor => legend_position.xanchor,
:yanchor => legend_position.yanchor,
:font => plotly_font(legendfont(sp)),
:tracegroupgap => 0,
:x => legend_position.coords[1],
:y => legend_position.coords[2],
:title => KW(
:text => sp[:legendtitle] === nothing ? "" : string(sp[:legendtitle]),
:font => plotly_font(legendtitlefont(sp)),
),
)
end
end
function plotly_legend_pos(pos::Symbol)
xleft = 0.07
ybot = 0.07
ytop = 1.0
xcenter = 0.55
ycenter = 0.52
center = 0.5
youtertop = 1.1
youterbot = -0.15
xouterright = 1.05
xouterleft = -0.15
plotly_legend_position_mapping = (
right = (coords = [1.0, ycenter], xanchor = "right", yanchor = "middle"),
left = (coords = [xleft, ycenter], xanchor = "left", yanchor = "middle"),
top = (coords = [xcenter, ytop], xanchor = "center", yanchor = "top"),
bottom = (coords = [xcenter, ybot], xanchor = "center", yanchor = "bottom"),
bottomleft = (coords = [xleft, ybot], xanchor = "left", yanchor = "bottom"),
bottomright = (coords = [1.0, ybot], xanchor = "right", yanchor = "bottom"),
topright = (coords = [1.0, 1.0], xanchor = "right", yanchor = "top"),
topleft = (coords = [xleft, 1.0], xanchor = "left", yanchor = "top"),
outertop =(coords = [center, youtertop ], xanchor = "upper", yanchor = "middle"),
outerbottom =(coords = [center, youterbot], xanchor = "lower", yanchor = "middle"),
outerleft =(coords = [xouterleft, center], xanchor = "left", yanchor = "top"),
outerright =(coords = [xouterright, center], xanchor = "right", yanchor = "top"),
outertopleft =(coords = [xouterleft, ytop], xanchor = "upper", yanchor = "left"),
outertopright = (coords = [xouterright, ytop], xanchor = "upper", yanchor = "right"),
outerbottomleft =(coords = [xouterleft, ybot], xanchor = "lower", yanchor = "left"),
outerbottomright =(coords = [xouterright, ybot], xanchor = "lower", yanchor = "right"),
default = (coords = [1.0, 1.0], xanchor = "auto", yanchor = "auto")
)
legend_position = get(plotly_legend_position_mapping, pos, plotly_legend_position_mapping.default)
end
plotly_legend_pos(v::Tuple{S,T}) where {S<:Real, T<:Real} = (coords=v, xanchor="left", yanchor="top")
function plotly_layout_json(plt::Plot)
JSON.json(plotly_layout(plt), 4)
end
plotly_colorscale(cg::ColorGradient, α = nothing) =
[[v, rgba_string(plot_color(cg.colors[v], α))] for v in cg.values]
function plotly_colorscale(c::AbstractVector{<:Colorant}, α = nothing)
function plotly_colorscale(grad::ColorGradient, α)
[[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in eachindex(grad.colors)]
end
plotly_colorscale(c::Colorant,α) = plotly_colorscale(_as_gradient(c),α)
function plotly_colorscale(c::AbstractVector{<:RGBA}, α)
if length(c) == 1
return [
[0.0, rgba_string(plot_color(c[1], α))],
[1.0, rgba_string(plot_color(c[1], α))],
]
return [[0.0, rgba_string(plot_color(c[1], α))], [1.0, rgba_string(plot_color(c[1], α))]]
else
vals = range(0.0, stop = 1.0, length = length(c))
vals = range(0.0, stop=1.0, length=length(c))
return [[vals[i], rgba_string(plot_color(c[i], α))] for i in eachindex(c)]
end
end
function plotly_colorscale(cg::PlotUtils.CategoricalColorGradient, α = nothing)
n = length(cg)
cinds = repeat(1:n, inner = 2)
vinds = vcat((i:(i + 1) for i in 1:n)...)
return [
[cg.values[vinds[i]], rgba_string(plot_color(color_list(cg)[cinds[i]], α))]
for i in eachindex(cinds)
]
end
plotly_colorscale(c, α = nothing) = plotly_colorscale(_as_gradient(c), α)
# plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha)
get_plotly_marker(k, def) = get(
(
rect = "square",
xcross = "x",
x = "x",
utriangle = "triangle-up",
dtriangle = "triangle-down",
star5 = "star-triangle-up",
vline = "line-ns",
hline = "line-ew",
),
k,
def,
const _plotly_markers = KW(
:rect => "square",
:xcross => "x",
:x => "x",
:utriangle => "triangle-up",
:dtriangle => "triangle-down",
:star5 => "star-triangle-up",
:vline => "line-ns",
:hline => "line-ew",
)
# find indicies of axes to which the supblot links to
@@ -462,8 +408,8 @@ function plotly_data(series::Series, letter::Symbol, data)
data
end
if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe, :mesh3d)
handle_surface(data)
if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe)
plotly_surface_data(series, data)
else
plotly_data(data)
end
@@ -473,6 +419,10 @@ plotly_data(v::AbstractArray) = v
plotly_data(surf::Surface) = surf.surf
plotly_data(v::AbstractArray{R}) where {R<:Rational} = float(v)
plotly_surface_data(series::Series, a::AbstractVector) = a
plotly_surface_data(series::Series, a::AbstractMatrix) = transpose_z(series, a, false)
plotly_surface_data(series::Series, a::Surface) = plotly_surface_data(series, a.surf)
function plotly_native_data(axis::Axis, data::AbstractArray)
if !isempty(axis[:discrete_values])
construct_categorical_data(data, axis)
@@ -513,17 +463,9 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out = KW()
# these are the axes that the series should be mapped to
if RecipesPipeline.is3d(sp)
spidx = length(plt.subplots) > 1 ? sp[:subplot_index] : ""
plotattributes_out[:xaxis] = "x$spidx"
plotattributes_out[:yaxis] = "y$spidx"
plotattributes_out[:zaxis] = "z$spidx"
plotattributes_out[:scene] = "scene$spidx"
else
x_idx, y_idx = length(plt.subplots) > 1 ? plotly_link_indicies(plt, sp) : ("", "")
plotattributes_out[:xaxis] = "x$(x_idx)"
plotattributes_out[:yaxis] = "y$(y_idx)"
end
x_idx, y_idx = plotly_link_indicies(plt, sp)
plotattributes_out[:xaxis] = "x$(x_idx)"
plotattributes_out[:yaxis] = "y$(y_idx)"
plotattributes_out[:showlegend] = should_add_to_legend(series)
if st == :straightline
@@ -573,7 +515,7 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series)
elseif st in (:surface, :wireframe)
plotattributes_out[:type] = "surface"
plotattributes_out[:type] = "surface"
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
if st == :wireframe
plotattributes_out[:hidesurface] = true
@@ -588,34 +530,17 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
plotattributes_out[:opacity] = series[:fillalpha]
if series[:fill_z] !== nothing
plotattributes_out[:surfacecolor] = handle_surface(series[:fill_z])
plotattributes_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z])
end
plotattributes_out[:showscale] = hascolorbar(sp)
end
elseif st == :mesh3d
plotattributes_out[:type] = "mesh3d"
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
if series[:connections] !== nothing
if typeof(series[:connections]) <: Tuple{Array,Array,Array}
i,j,k = series[:connections]
if !(length(i) == length(j) == length(k))
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
end
plotattributes_out[:i] = i
plotattributes_out[:j] = j
plotattributes_out[:k] = k
else
throw(ArgumentError("Argument connections has to be a tuple of three arrays."))
end
end
plotattributes_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
plotattributes_out[:color] = rgba_string(plot_color(series[:fillcolor], series[:fillalpha]))
plotattributes_out[:opacity] = series[:fillalpha]
if series[:fill_z] !== nothing
plotattributes_out[:surfacecolor] = handle_surface(series[:fill_z])
end
plotattributes_out[:showscale] = hascolorbar(sp)
elseif st == :pie
plotattributes_out[:type] = "pie"
plotattributes_out[:labels] = pie_labels(sp, series)
plotattributes_out[:values] = y
plotattributes_out[:hoverinfo] = "label+percent+name"
else
@warn("Plotly: seriestype $st isn't supported.")
return KW()
@@ -625,7 +550,7 @@ function plotly_series(plt::Plot, series::Series)
if hasmarker
inds = eachindex(x)
plotattributes_out[:marker] = KW(
:symbol => get_plotly_marker(series[:markershape], string(series[:markershape])),
:symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])),
# :opacity => series[:markeralpha],
:size => 2 * _cycle(series[:markersize], inds),
:color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))),
@@ -705,11 +630,9 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
hasfillrange = st in (:path, :scatter, :scattergl, :straightline) &&
(isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple))
segments = iter_segments(series, st)
segments = iter_segments(series)
plotattributes_outs = fill(KW(), (hasfillrange ? 2 : 1 ) * length(segments))
needs_scatter_fix = !isscatter && hasmarker && !any(isnan,y) && length(segments) > 1
for (i,rng) in enumerate(segments)
plotattributes_out = deepcopy(plotattributes_base)
plotattributes_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
@@ -746,15 +669,13 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
# add "marker"
if hasmarker
mcolor = rgba_string(plot_color(get_markercolor(series, clims, i), get_markeralpha(series, i)))
lcolor = rgba_string(plot_color(get_markerstrokecolor(series, i), get_markerstrokealpha(series, i)))
plotattributes_out[:marker] = KW(
:symbol => get_plotly_marker(_cycle(series[:markershape], i), string(_cycle(series[:markershape], i))),
# :opacity => needs_scatter_fix ? [1, 0] : 1,
:symbol => get(_plotly_markers, _cycle(series[:markershape], i), string(_cycle(series[:markershape], i))),
# :opacity => series[:markeralpha],
:size => 2 * _cycle(series[:markersize], i),
:color => needs_scatter_fix ? [mcolor, "rgba(0, 0, 0, 0.000)"] : mcolor,
:color => rgba_string(plot_color(get_markercolor(series, clims, i), get_markeralpha(series, i))),
:line => KW(
:color => needs_scatter_fix ? [lcolor, "rgba(0, 0, 0, 0.000)"] : lcolor,
:color => rgba_string(plot_color(get_markerstrokecolor(series, i), get_markerstrokealpha(series, i))),
:width => _cycle(series[:markerstrokewidth], i),
),
)
@@ -799,7 +720,8 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
else
# if fillrange is a tuple with upper and lower limit, plotattributes_out_fillrange
# is the series that will do the filling
plotattributes_out_fillrange[:x], plotattributes_out_fillrange[:y] = concatenate_fillrange(x[rng], series[:fillrange])
fillrng = Tuple(series[:fillrange][i][rng] for i in 1:2)
plotattributes_out_fillrange[:x], plotattributes_out_fillrange[:y] = concatenate_fillrange(x[rng], fillrng)
plotattributes_out_fillrange[:line][:width] = 0
delete!(plotattributes_out, :fill)
delete!(plotattributes_out, :fillcolor)
@@ -826,17 +748,17 @@ function plotly_colorbar_hack(series::Series, plotattributes_base::KW, sym::Symb
plotattributes_out = deepcopy(plotattributes_base)
cmin, cmax = get_clims(series[:subplot])
plotattributes_out[:showlegend] = false
plotattributes_out[:type] = RecipesPipeline.is3d(series) ? :scatter3d : :scatter
plotattributes_out[:type] = is3d(series) ? :scatter3d : :scatter
plotattributes_out[:hoverinfo] = :none
plotattributes_out[:mode] = :markers
plotattributes_out[:x], plotattributes_out[:y] = [series[:x][1]], [series[:y][1]]
if RecipesPipeline.is3d(series)
if is3d(series)
plotattributes_out[:z] = [series[:z][1]]
end
# zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line)
plotattributes_out[:marker] = KW(
:size => 1e-10,
:opacity => 1e-10,
:size => 0,
:opacity => 0,
:color => [0.5],
:cmin => cmin,
:cmax => cmax,
@@ -858,9 +780,9 @@ end
function plotly_hover!(plotattributes_out::KW, hover)
# hover text
if hover === nothing || all(in([:none, false]), hover)
if hover in (:none, false)
plotattributes_out[:hoverinfo] = "none"
elseif any(!isnothing, hover)
elseif hover !== nothing
plotattributes_out[:hoverinfo] = "text"
plotattributes_out[:text] = hover
end
@@ -883,19 +805,25 @@ plotly_series_json(plt::Plot) = JSON.json(plotly_series(plt), 4)
html_head(plt::Plot{PlotlyBackend}) = plotly_html_head(plt)
html_body(plt::Plot{PlotlyBackend}) = plotly_html_body(plt)
const ijulia_initialized = Ref(false)
function plotly_html_head(plt::Plot)
plotly =
use_local_dependencies[] ? ("file:///" * plotly_local_file_path[]) : "https://cdn.plot.ly/$(_plotly_min_js_filename)"
include_mathjax = get(plt[:extra_plot_kwargs], :include_mathjax, "")
mathjax_file = include_mathjax != "cdn" ? ("file://" * include_mathjax) : "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"
mathjax_head = include_mathjax == "" ? "" : "<script src=\"$mathjax_file\"></script>\n\t\t"
if isijulia()
mathjax_head
else
"$mathjax_head<script src=$(repr(plotly))></script>"
local_file = ("file://" * plotly_local_file_path)
plotly = use_local_dependencies[] ? local_file : plotly_remote_file_path
if isijulia() && !ijulia_initialized[]
# using requirejs seems to be key to load a js depency in IJulia!
# https://requirejs.org/docs/start.html
# https://github.com/JuliaLang/IJulia.jl/issues/345
display("text/html", """
<script type="text/javascript">
requirejs([$(repr(plotly))], function(p) {
window.Plotly = p
});
</script>
""")
ijulia_initialized[] = true
end
return "<script src=$(repr(plotly))></script>"
end
function plotly_html_body(plt, style = nothing)
@@ -903,34 +831,12 @@ function plotly_html_body(plt, style = nothing)
w, h = plt[:size]
style = "width:$(w)px;height:$(h)px;"
end
requirejs_prefix = ""
requirejs_suffix = ""
if isijulia()
# require.js adds .js automatically
plotly_no_ext =
use_local_dependencies[] ? ("file:///" * plotly_local_file_path[]) : "https://cdn.plot.ly/$(_plotly_min_js_filename)"
plotly_no_ext = plotly_no_ext[1:end-3]
requirejs_prefix = """
requirejs.config({
paths: {
Plotly: '$(plotly_no_ext)'
}
});
require(['Plotly'], function (Plotly) {
"""
requirejs_suffix = "});"
end
uuid = UUIDs.uuid4()
html = """
<div id=\"$(uuid)\" style=\"$(style)\"></div>
<script>
$(requirejs_prefix)
PLOT = document.getElementById('$(uuid)');
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
$(requirejs_suffix)
</script>
"""
html
@@ -954,8 +860,6 @@ end
# ----------------------------------------------------------------
Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot{PlotlyBackend}) = true
function _show(io::IO, ::MIME"application/vnd.plotly.v1+json", plot::Plot{PlotlyBackend})
plotly_show_js(io, plot)
end
-23
View File
@@ -1,23 +0,0 @@
function plotlybase_syncplot(plt::Plot)
plt.o = PlotlyBase.Plot()
traces = PlotlyBase.GenericTrace[]
for series_dict in plotly_series(plt)
plotly_type = pop!(series_dict, :type)
push!(traces, PlotlyBase.GenericTrace(plotly_type; series_dict...))
end
PlotlyBase.addtraces!(plt.o, traces...)
layout = plotly_layout(plt)
w, h = plt[:size]
PlotlyBase.relayout!(plt.o, layout, width = w, height = h)
return plt.o
end
for (mime, fmt) in (
"application/pdf" => "pdf",
"image/png" => "png",
"image/svg+xml" => "svg",
"image/eps" => "eps",
)
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyBackend}) =
PlotlyBase.savefig(io, plotlybase_syncplot(plt), format = $fmt)
end
+8 -6
View File
@@ -19,12 +19,14 @@ end
# ------------------------------------------------------------------------------
for (mime, fmt) in (
const _plotlyjs_mimeformats = Dict(
"application/pdf" => "pdf",
"image/png" => "png",
"image/svg+xml" => "svg",
"image/eps" => "eps",
)
for (mime, fmt) in _plotlyjs_mimeformats
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plotlyjs_syncplot(plt), format = $fmt)
end
@@ -38,9 +40,11 @@ _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, standal
_display(plt::Plot{PlotlyJSBackend}) = display(plotlyjs_syncplot(plt))
function PlotlyJS.WebIO.render(plt::Plot{PlotlyJSBackend})
plt_html = sprint(show, MIME("text/html"), plt)
return PlotlyJS.WebIO.render(PlotlyJS.WebIO.dom"div"(innerHTML=plt_html))
@require WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" begin
function WebIO.render(plt::Plot{PlotlyJSBackend})
prepare_output(plt)
WebIO.render(plt.o)
end
end
function closeall(::PlotlyJSBackend)
@@ -48,5 +52,3 @@ function closeall(::PlotlyJSBackend)
close(current().o)
end
end
Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot{PlotlyJSBackend}) = true
+332 -392
View File
File diff suppressed because it is too large Load Diff
+11 -9
View File
@@ -3,17 +3,19 @@
# don't warn on unsupported... there's just too many warnings!!
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
warnOnUnsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
# --------------------------------------------------------------------------------------
const _canvas_type = Ref(:auto)
function _canvas_map()
(
braille = UnicodePlots.BrailleCanvas,
ascii = UnicodePlots.AsciiCanvas,
block = UnicodePlots.BlockCanvas,
dot = UnicodePlots.DotCanvas,
density = UnicodePlots.DensityCanvas,
KW(
:braille => UnicodePlots.BrailleCanvas,
:ascii => UnicodePlots.AsciiCanvas,
:block => UnicodePlots.BlockCanvas,
:dot => UnicodePlots.DotCanvas,
:density => UnicodePlots.DensityCanvas,
)
end
@@ -90,7 +92,7 @@ end
# add a single series
function addUnicodeSeries!(o, plotattributes, addlegend::Bool, xlim, ylim)
function addUnicodeSeries!(o, plotattributes::KW, addlegend::Bool, xlim, ylim)
# get the function, or special handling for step/bar/hist
st = plotattributes[:seriestype]
if st == :histogram2d
@@ -124,7 +126,7 @@ function addUnicodeSeries!(o, plotattributes, addlegend::Bool, xlim, ylim)
color = plotattributes[:linecolor] in UnicodePlots.color_cycle ? plotattributes[:linecolor] : :auto
# add the series
x, y = RecipesPipeline.unzip(collect(Base.Iterators.filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y))))
x, y = Plots.unzip(collect(Base.Iterators.filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y))))
func(o, x, y; color = color, name = label)
end
+1 -1
View File
@@ -45,7 +45,7 @@ function standalone_html_window(plt::AbstractPlot)
old = use_local_dependencies[] # save state to restore afterwards
# if we open a browser ourself, we can host local files, so
# when we have a local plotly downloaded this is the way to go!
use_local_dependencies[] = plotly_local_file_path[] === nothing ? false : isfile(plotly_local_file_path[])
use_local_dependencies[] = isfile(plotly_local_file_path)
filename = write_temp_html(plt)
open_browser_window(filename)
# restore for other backends
+91 -41
View File
@@ -1,5 +1,7 @@
const P2 = GeometryBasics.Point2{Float64}
const P3 = GeometryBasics.Point3{Float64}
const P2 = GeometryTypes.Point2{Float64}
const P3 = GeometryTypes.Point3{Float64}
nanpush!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); push!(a, b))
nanappend!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); append!(a, b))
@@ -27,7 +29,7 @@ end
Construct a polygon to be plotted
"""
Shape(verts::AVec) = Shape(RecipesPipeline.unzip(verts)...)
Shape(verts::AVec) = Shape(unzip(verts)...)
Shape(s::Shape) = deepcopy(s)
get_xs(shape::Shape) = shape.x
@@ -75,6 +77,7 @@ function weave(x,y; ordering = Vector[x,y])
ret
end
"create a star by weaving together points from an outer and inner circle. `n` is the number of arms"
function makestar(n; offset = -0.5, radius = 1.0)
z1 = offset * π
@@ -90,6 +93,7 @@ function makeshape(n; offset = -0.5, radius = 1.0)
Shape(partialcircle(z, z + 2π, n+1, radius))
end
function makecross(; offset = -0.5, radius = 1.0)
z2 = offset * π
z1 = z2 - π/8
@@ -99,6 +103,7 @@ function makecross(; offset = -0.5, radius = 1.0)
ordering=Vector[outercircle,innercircle,outercircle]))
end
from_polar(angle, dist) = P2(dist*cos(angle), dist*sin(angle))
function makearrowhead(angle; h = 2.0, w = 0.4)
@@ -107,6 +112,31 @@ function makearrowhead(angle; h = 2.0, w = 0.4)
from_polar(angle + 0.5π, w) - tip, (0,0)])
end
const _shape_keys = Symbol[
:circle,
:rect,
:star5,
:diamond,
:hexagon,
:cross,
:xcross,
:utriangle,
:dtriangle,
:rtriangle,
:ltriangle,
:pentagon,
:heptagon,
:octagon,
:star4,
:star6,
:star7,
:star8,
:vline,
:hline,
:+,
:x,
]
const _shapes = KW(
:circle => makeshape(20),
:rect => makeshape(4, offset=-0.25),
@@ -328,15 +358,9 @@ end
Scales all **current** font sizes by `factor`. For example `scalefontsizes(1.1)` increases all current font sizes by 10%. To reset to initial sizes, use `scalefontsizes()`
"""
function scalefontsizes(factor::Number)
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize)
scalefontsize(k, factor)
end
for letter in (:x,:y,:z)
for k in (:guidefontsize, :tickfontsize)
scalefontsize(Symbol(letter, k), factor)
end
end
end
"""
@@ -345,27 +369,15 @@ end
Resets font sizes to initial default values.
"""
function scalefontsizes()
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
f = default(k)
if k in keys(_initial_fontsizes)
factor = f / _initial_fontsizes[k]
scalefontsize(k, 1.0/factor)
end
end
for letter in (:x,:y,:z)
for k in (:guidefontsize, :tickfontsize)
if k in keys(_initial_fontsizes)
f = default(Symbol(letter, k))
factor = f / _initial_fontsizes[k]
scalefontsize(Symbol(letter, k), 1.0/factor)
end
end
end
for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize)
f = default(k)
if k in keys(_initial_fontsizes)
factor = f / _initial_fontsizes[k]
scalefontsize(k, 1.0/factor)
end
end
end
resetfontsizes() = scalefontsizes()
"Wrap a string with font info"
struct PlotText
str::AbstractString
@@ -579,12 +591,8 @@ annotations(sa::SeriesAnnotations) = sa
function process_annotation(sp::Subplot, xs, ys, labs, font = font())
anns = []
labs = makevec(labs)
xlength = length(methods(length, (typeof(xs),))) == 0 ? 1 : length(xs)
ylength = length(methods(length, (typeof(ys),))) == 0 ? 1 : length(ys)
for i in 1:max(xlength, ylength, length(labs))
x, y, lab = _cycle(xs, i), _cycle(ys, i), _cycle(labs, i)
x = typeof(x) <: TimeType ? Dates.value(x) : x
y = typeof(y) <: TimeType ? Dates.value(y) : y
for i in 1:max(length(xs), length(ys), length(labs))
x, y, lab = _cycle(xs, i), _cycle(ys, i), _cycle(labs, i)
if lab == :auto
alphabet = "abcdefghijklmnopqrstuvwxyz"
push!(anns, (x, y, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
@@ -610,9 +618,6 @@ function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol},
anns
end
function process_any_label(lab, font=Font())
lab isa Tuple ? text(lab...) : text( lab, font )
end
# Give each annotation coordinates based on specified position
function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText)
position_multiplier = Dict{Symbol, Tuple{Float64,Float64}}(
@@ -629,7 +634,6 @@ function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText)
(x, y, lab)
end
locate_annotation(sp::Subplot, x, y, label::PlotText) = (x, y, label)
locate_annotation(sp::Subplot, x, y, z, label::PlotText) = (x, y, z, label)
# -----------------------------------------------------------------------
"type which represents z-values for colors and sizes (and anything else that might come up)"
@@ -644,6 +648,23 @@ end
# -----------------------------------------------------------------------
abstract type AbstractSurface end
"represents a contour or surface mesh"
struct Surface{M<:AMat} <: AbstractSurface
surf::M
end
Surface(f::Function, x, y) = Surface(Float64[f(xi,yi) for yi in y, xi in x])
Base.Array(surf::Surface) = surf.surf
for f in (:length, :size)
@eval Base.$f(surf::Surface, args...) = $f(surf.surf, args...)
end
Base.copy(surf::Surface) = Surface(copy(surf.surf))
Base.eltype(surf::Surface{T}) where {T} = eltype(T)
function expand_extrema!(a::Axis, surf::Surface)
ex = a[:extrema]
for vi in surf.surf
@@ -663,7 +684,28 @@ end
# # I don't want to clash with ValidatedNumerics, but this would be nice:
# ..(a::T, b::T) = (a,b)
struct Volume{T}
v::Array{T,3}
x_extents::Tuple{T,T}
y_extents::Tuple{T,T}
z_extents::Tuple{T,T}
end
default_extents(::Type{T}) where {T} = (zero(T), one(T))
function Volume(v::Array{T,3},
x_extents = default_extents(T),
y_extents = default_extents(T),
z_extents = default_extents(T)) where T
Volume(v, x_extents, y_extents, z_extents)
end
Base.Array(vol::Volume) = vol.v
for f in (:length, :size)
@eval Base.$f(vol::Volume, args...) = $f(vol.v, args...)
end
Base.copy(vol::Volume{T}) where {T} = Volume{T}(copy(vol.v), vol.x_extents, vol.y_extents, vol.z_extents)
Base.eltype(vol::Volume{T}) where {T} = T
# -----------------------------------------------------------------------
@@ -727,9 +769,17 @@ function add_arrows(func::Function, x::AVec, y::AVec)
end
end
# -----------------------------------------------------------------------
"Represents data values with formatting that should apply to the tick labels."
struct Formatted{T}
data::T
formatter::Function
end
# -----------------------------------------------------------------------
"create a BezierCurve for plotting"
mutable struct BezierCurve{T <: GeometryBasics.Point}
mutable struct BezierCurve{T <: GeometryTypes.Point}
control_points::Vector{T}
end
@@ -744,7 +794,7 @@ end
@deprecate curve_points coords
coords(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, Base.range(first(range), stop=last(range), length=n))
coords(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, Base.range(range..., length=n))
# build a BezierCurve which leaves point p vertically upwards and arrives point q vertically upwards.
# may create a loop if necessary. Assumes the view is [0,1]
+515 -1136
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -4,7 +4,7 @@ const use_local_plotlyjs = Ref(false)
function _init_ijulia_plotting()
# IJulia is more stable with local file
use_local_plotlyjs[] = plotly_local_file_path[] === nothing ? false : isfile(plotly_local_file_path[])
use_local_plotlyjs[] = isfile(plotly_local_file_path)
ENV["MPLBACKEND"] = "Agg"
end
@@ -54,9 +54,9 @@ function _ijulia_display_dict(plt::Plot)
elseif output_type == :html
mime = "text/html"
out[mime] = sprint(show, MIME(mime), plt)
_ijulia__extra_mime_info!(plt, out)
else
error("Unsupported output type $output_type")
end
_ijulia__extra_mime_info!(plt, out)
out
end
+23 -18
View File
@@ -1,12 +1,9 @@
using REPL
using Scratch
const plotly_local_file_path = Ref{Union{Nothing, String}}(nothing)
function _plots_defaults()
if isdefined(Main, :PLOTS_DEFAULTS)
copy(Dict{Symbol,Any}(Main.PLOTS_DEFAULTS))
Dict{Symbol,Any}(Main.PLOTS_DEFAULTS)
else
Dict{Symbol,Any}()
end
@@ -16,9 +13,10 @@ end
function __init__()
user_defaults = _plots_defaults()
if haskey(user_defaults, :theme)
theme(pop!(user_defaults, :theme); user_defaults...)
else
default(; user_defaults...)
theme(user_defaults[:theme])
end
for (k,v) in user_defaults
k == :theme || default(k, v)
end
insert!(Base.Multimedia.displays, findlast(x -> x isa Base.TextDisplay || x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, PlotsDisplay())
@@ -33,41 +31,49 @@ function __init__()
@require HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" begin
fn = joinpath(@__DIR__, "backends", "hdf5.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d" begin
fn = joinpath(@__DIR__, "backends", "inspectdr.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PGFPlots = "3b7a836e-365b-5785-a47d-02c71176b4aa" begin
fn = joinpath(@__DIR__, "backends", "deprecated", "pgfplots.jl")
fn = joinpath(@__DIR__, "backends", "pgfplots.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" begin
fn = joinpath(@__DIR__, "backends", "plotlybase.jl")
@require ORCA = "47be7bcc-f1a6-5447-8b36-7eeeff7534fd" begin
fn = joinpath(@__DIR__, "backends", "orca.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925" begin
fn = joinpath(@__DIR__, "backends", "pgfplotsx.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" begin
fn = joinpath(@__DIR__, "backends", "plotlyjs.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" begin
fn = joinpath(@__DIR__, "backends", "pyplot.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" begin
fn = joinpath(@__DIR__, "backends", "unicodeplots.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
@@ -78,17 +84,16 @@ function __init__()
end
end
if get(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL", "false") == "true"
global plotly_local_file_path[] = joinpath(@get_scratch!("plotly"), _plotly_min_js_filename)
if !isfile(plotly_local_file_path[])
download("https://cdn.plot.ly/$(_plotly_min_js_filename)", plotly_local_file_path[])
if haskey(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL")
use_local_plotlyjs[] = ENV["PLOTS_HOST_DEPENDENCY_LOCAL"] == "true"
use_local_dependencies[] = isfile(plotly_local_file_path) && use_local_plotlyjs[]
if use_local_plotlyjs[] && !isfile(plotly_local_file_path)
@warn("PLOTS_HOST_DEPENDENCY_LOCAL is set to true, but no local plotly file found. run Pkg.build(\"Plots\") and make sure PLOTS_HOST_DEPENDENCY_LOCAL is set to true")
end
use_local_plotlyjs[] = true
else
use_local_dependencies[] = use_local_plotlyjs[]
end
use_local_dependencies[] = use_local_plotlyjs[]
@require FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" begin
_show(io::IO, mime::MIME"image/png", plt::Plot{<:PDFBackends}) = _show_pdfbackends(io, mime, plt)
+40 -10
View File
@@ -4,6 +4,34 @@
to_pixels(m::AbsoluteLength) = m.value / 0.254
const _cbar_width = 5mm
#Base.broadcast(::typeof(Base.:.*), m::Measure, n::Number) = m * n
#Base.broadcast(::typeof(Base.:.*), m::Number, n::Measure) = m * n
Base.:-(m::Measure, a::AbstractArray) = map(ai -> m - ai, a)
Base.:-(a::AbstractArray, m::Measure) = map(ai -> ai - m, a)
Base.zero(::Type{typeof(mm)}) = 0mm
Base.one(::Type{typeof(mm)}) = 1mm
Base.typemin(::typeof(mm)) = -Inf*mm
Base.typemax(::typeof(mm)) = Inf*mm
Base.convert(::Type{F}, l::AbsoluteLength) where {F<:AbstractFloat} = convert(F, l.value)
# TODO: these are unintuitive and may cause tricky bugs
# Base.:+(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 + m2.value))
# Base.:+(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * (1 + m1.value))
# Base.:-(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 - m2.value))
# Base.:-(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * (m1.value - 1))
Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value)
Base.:*(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * m1.value)
Base.:/(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value / m2.value)
Base.:/(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value / m1.value)
Base.zero(::Type{typeof(pct)}) = 0pct
Base.one(::Type{typeof(pct)}) = 1pct
Base.typemin(::typeof(pct)) = 0pct
Base.typemax(::typeof(pct)) = 1pct
const defaultbox = BoundingBox(0mm, 0mm, 0mm, 0mm)
left(bbox::BoundingBox) = bbox.x0[1]
@@ -230,7 +258,7 @@ end
grid(args...; kw...)
Create a grid layout for subplots. `args` specify the dimensions, e.g.
`grid(3,2, widths = (0.6,0.4))` creates a grid with three rows and two
`grid(3,2, widths = (0.6,04))` creates a grid with three rows and two
columns of different width.
"""
grid(args...; kw...) = GridLayout(args...; kw...)
@@ -317,8 +345,10 @@ end
# recursively compute the bounding boxes for the layout and plotarea (relative to canvas!)
function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm,0mm,0mm,0mm])
nr, nc = size(layout)
# # create a matrix for each minimum padding direction
# _update_min_padding!(layout)
minpad_left = map(leftpad, layout.grid)
minpad_top = map(toppad, layout.grid)
minpad_right = map(rightpad, layout.grid)
@@ -377,10 +407,10 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm,0mm,0
# this is the minimum perimeter as decided by this child's parent, so that
# all children on this border have the same value
min_child_perimeter = [
c == 1 ? layout.minpad[1] : pad_left[c],
r == 1 ? layout.minpad[2] : pad_top[r],
c == nc ? layout.minpad[3] : pad_right[c],
r == nr ? layout.minpad[4] : pad_bottom[r]
c == 1 ? layout.minpad[1] : 0mm,
r == 1 ? layout.minpad[2] : 0mm,
c == nc ? layout.minpad[3] : 0mm,
r == nr ? layout.minpad[4] : 0mm
]
# recursively update the child's children
@@ -434,11 +464,11 @@ end
# constructors
# pass the layout arg through
function layout_args(plotattributes::AKW)
layout_args(plotattributes[:layout])
function layout_args(plotattributes::KW)
layout_args(get(plotattributes, :layout, default(:layout)))
end
function layout_args(plotattributes::AKW, n_override::Integer)
function layout_args(plotattributes::KW, n_override::Integer)
layout, n = layout_args(n_override, get(plotattributes, :layout, n_override))
if n != n_override
error("When doing layout, n ($n) != n_override ($(n_override)). You're probably trying to force existing plots into a layout that doesn't fit them.")
@@ -586,7 +616,7 @@ end
# ----------------------------------------------------------------------
# @layout macro
function add_layout_pct!(kw::AKW, v::Expr, idx::Integer, nidx::Integer)
function add_layout_pct!(kw::KW, v::Expr, idx::Integer, nidx::Integer)
# dump(v)
# something like {0.2w}?
if v.head == :call && v.args[1] == :*
@@ -607,7 +637,7 @@ function add_layout_pct!(kw::AKW, v::Expr, idx::Integer, nidx::Integer)
error("Couldn't match layout curly (idx=$idx): $v")
end
function add_layout_pct!(kw::AKW, v::Number, idx::Integer)
function add_layout_pct!(kw::KW, 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)
+96 -102
View File
@@ -1,62 +1,57 @@
defaultOutputFormat(plt::Plot) = "png"
function png(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "png")
io = open(fn, "w")
show(io, MIME("image/png"), plt)
close(io)
fn = addExtension(fn, "png")
io = open(fn, "w")
show(io, MIME("image/png"), plt)
close(io)
end
png(fn::AbstractString) = png(current(), fn)
function svg(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "svg")
io = open(fn, "w")
show(io, MIME("image/svg+xml"), plt)
close(io)
fn = addExtension(fn, "svg")
io = open(fn, "w")
show(io, MIME("image/svg+xml"), plt)
close(io)
end
svg(fn::AbstractString) = svg(current(), fn)
function pdf(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "pdf")
io = open(fn, "w")
show(io, MIME("application/pdf"), plt)
close(io)
fn = addExtension(fn, "pdf")
io = open(fn, "w")
show(io, MIME("application/pdf"), plt)
close(io)
end
pdf(fn::AbstractString) = pdf(current(), fn)
function ps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "ps")
io = open(fn, "w")
show(io, MIME("application/postscript"), plt)
close(io)
fn = addExtension(fn, "ps")
io = open(fn, "w")
show(io, MIME("application/postscript"), plt)
close(io)
end
ps(fn::AbstractString) = ps(current(), fn)
function eps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "eps")
io = open(fn, "w")
show(io, MIME("image/eps"), plt)
close(io)
fn = addExtension(fn, "eps")
io = open(fn, "w")
show(io, MIME("image/eps"), plt)
close(io)
end
eps(fn::AbstractString) = eps(current(), fn)
function tex(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "tex")
io = open(fn, "w")
show(io, MIME("application/x-tex"), plt)
close(io)
fn = addExtension(fn, "tex")
io = open(fn, "w")
show(io, MIME("application/x-tex"), plt)
close(io)
end
tex(fn::AbstractString) = tex(current(), fn)
function json(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "json")
io = open(fn, "w")
show(io, MIME("application/vnd.plotly.v1+json"), plt)
close(io)
end
json(fn::AbstractString) = json(current(), fn)
function html(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "html")
io = open(fn, "w")
@@ -65,40 +60,40 @@ function html(plt::Plot, fn::AbstractString)
end
html(fn::AbstractString) = html(current(), fn)
function txt(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "txt")
io = open(fn, "w")
show(io, MIME("text/plain"), plt)
close(io)
end
txt(fn::AbstractString) = txt(current(), fn)
# ----------------------------------------------------------------
const _savemap = Dict(
"png" => png,
"svg" => svg,
"pdf" => pdf,
"ps" => ps,
"ps" => ps,
"eps" => eps,
"tex" => tex,
"json" => json,
"html" => html,
"tikz" => tex,
"txt" => txt,
)
)
const _extension_map = Dict("tikz" => "tex")
function getExtension(fn::AbstractString)
pieces = split(fn, ".")
length(pieces) > 1 || error("Can't extract file extension: ", fn)
ext = pieces[end]
haskey(_savemap, ext) || error("Invalid file extension: ", fn)
ext
end
function addExtension(fn::AbstractString, ext::AbstractString)
oldfn, oldext = splitext(fn)
oldext = chop(oldext, head = 1, tail = 0)
if get(_extension_map, oldext, oldext) == ext
return fn
try
oldext = getExtension(fn)
if oldext == ext
return fn
else
return string(fn, ".", ext)
return "$fn.$ext"
end
catch
return "$fn.$ext"
end
end
"""
@@ -109,28 +104,27 @@ type is inferred from the file extension. All backends support png and pdf
file types, some also support svg, ps, eps, html and tex.
"""
function savefig(plt::Plot, fn::AbstractString)
fn = abspath(expanduser(fn))
fn = abspath(expanduser(fn))
# get the extension
local ext
try
ext = getExtension(fn)
catch
# if we couldn't extract the extension, add the default
ext = defaultOutputFormat(plt)
fn = addExtension(fn, ext)
end
# get the extension
_, ext = splitext(fn)
ext = chop(ext, head = 1, tail = 0)
if isempty(ext)
ext = defaultOutputFormat(plt)
end
# save it
if haskey(_savemap, ext)
func = _savemap[ext]
return func(plt, fn)
else
error("Invalid file extension: ", fn)
end
# save it
func = get(_savemap, ext) do
error("Unsupported extension $ext with filename ", fn)
end
func(plt, fn)
end
savefig(fn::AbstractString) = savefig(current(), fn)
# ---------------------------------------------------------
"""
gui([plot])
@@ -153,13 +147,17 @@ end
_do_plot_show(plt, showval::Bool) = showval && gui(plt)
function _do_plot_show(plt, showval::Symbol)
showval == :gui && gui(plt)
showval in (:inline, :ijulia) && inline(plt)
showval in (:inline,:ijulia) && inline(plt)
end
# ---------------------------------------------------------
const _best_html_output_type =
KW(:pyplot => :png, :unicodeplots => :txt, :plotlyjs => :html, :plotly => :html)
const _best_html_output_type = KW(
:pyplot => :png,
:unicodeplots => :txt,
:plotlyjs => :html,
:plotly => :html
)
# a backup for html... passes to svg or png depending on the html_output_format arg
function _show(io::IO, ::MIME"text/html", plt::Plot)
@@ -169,12 +167,7 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end
if output_type == :png
# @info("writing png to html output")
print(
io,
"<img src=\"data:image/png;base64,",
base64encode(show, MIME("image/png"), plt),
"\" />",
)
print(io, "<img src=\"data:image/png;base64,", base64encode(show, MIME("image/png"), plt), "\" />")
elseif output_type == :svg
# @info("writing svg to html output")
show(io, MIME("image/svg+xml"), plt)
@@ -186,7 +179,7 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end
# delegate showable to _show instead
function Base.showable(m::M, plt::P) where {M <: MIME, P <: Plot}
function Base.showable(m::M, plt::P) where {M<:MIME, P<:Plot}
return hasmethod(_show, Tuple{IO, M, P})
end
@@ -194,32 +187,25 @@ function _display(plt::Plot)
@warn("_display is not defined for this backend.")
end
Base.show(io::IO, m::MIME"text/plain", plt::Plot) = show(io, plt)
# for writing to io streams... first prepare, then callback
for mime in (
"text/html",
"image/png",
"image/eps",
"image/svg+xml",
"application/eps",
"application/pdf",
"application/postscript",
"application/x-tex",
"application/vnd.plotly.v1+json",
)
for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml",
"application/eps", "application/pdf", "application/postscript",
"application/x-tex", "application/vnd.plotly.v1+json")
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
if haskey(io, :juno_plotsize)
showjuno(io, m, plt)
showjuno(io, m, plt)
else
prepare_output(plt)
_show(io, m, plt)
prepare_output(plt)
_show(io, m, plt)
end
return nothing
end
end
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) =
showjuno(io, MIME("text/html"), plt)
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) = showjuno(io, MIME("text/html"), plt)
# default text/plain for all backends
_show(io::IO, ::MIME{Symbol("text/plain")}, plt::Plot) = show(io, plt)
"Close all open gui windows of the current backend"
closeall() = closeall(backend())
@@ -246,28 +232,36 @@ closeall() = closeall(backend())
# Atom PlotPane
# ---------------------------------------------------------
function showjuno(io::IO, m, plt)
sz = collect(plt[:size])
dpi = plt[:dpi]
thickness_scaling = plt[:thickness_scaling]
jsize = get(io, :juno_plotsize, [400, 500])
jratio = get(io, :juno_dpi_ratio, 1)
plt[:dpi] = jratio * Plots.DPI
scale = minimum(jsize[i] / sz[i] for i in 1:2)
plt[:size] = [s * scale for s in sz]
plt[:dpi] = jratio*Plots.DPI
plt[:thickness_scaling] *= scale
prepare_output(plt)
try
_showjuno(io, m, plt)
_showjuno(io, m, plt)
finally
plt[:dpi] = dpi
plt[:size] = sz
plt[:dpi] = dpi
plt[:thickness_scaling] = thickness_scaling
end
end
function _showjuno(io::IO, m::MIME"image/svg+xml", plt)
if Symbol(plt.attr[:html_output_format]) :svg
throw(MethodError(show, (typeof(m), typeof(plt))))
else
_show(io, m, plt)
end
if Symbol(plt.attr[:html_output_format]) :svg
throw(MethodError(show, (typeof(m), typeof(plt))))
else
_show(io, m, plt)
end
end
Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot) = false
Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot) = showable(MIME"text/html"(), plt)
_showjuno(io::IO, m, plt) = _show(io, m, plt)
+224 -177
View File
@@ -1,73 +1,103 @@
# RecipesPipeline API
## Warnings
function RecipesPipeline.warn_on_recipe_aliases!(
plt::Plot,
plotattributes::AKW,
recipe_type::Symbol,
@nospecialize(args)
)
for k in keys(plotattributes)
if !is_default_attribute(k)
dk = get(_keyAliases, k, k)
if k !== dk
if recipe_type == :user
signature_string = RecipesPipeline.userrecipe_signature_string(args)
elseif recipe_type == :type
signature_string = RecipesPipeline.typerecipe_signature_string(args)
elseif recipe_type == :plot
signature_string = RecipesPipeline.plotrecipe_signature_string(args)
elseif recipe_type == :series
signature_string = RecipesPipeline.seriesrecipe_signature_string(args)
else
throw(ArgumentError("Invalid recipe type `$recipe_type`"))
# ------------------------------------------------------------------
# preprocessing
function command_idx(kw_list::AVec{KW}, kw::KW)
Int(kw[:series_plotindex]) - Int(kw_list[1][:series_plotindex]) + 1
end
function _expand_seriestype_array(plotattributes::KW, args)
sts = get(plotattributes, :seriestype, :path)
if typeof(sts) <: AbstractArray
delete!(plotattributes, :seriestype)
rd = Vector{RecipeData}(undef, size(sts, 1))
for r in axes(sts, 1)
dc = copy(plotattributes)
dc[:seriestype] = sts[r:r,:]
rd[r] = RecipeData(dc, args)
end
rd
else
RecipeData[RecipeData(copy(plotattributes), args)]
end
end
function _preprocess_args(plotattributes::KW, args, still_to_process::Vector{RecipeData})
# the grouping mechanism is a recipe on a GroupBy object
# we simply add the GroupBy object to the front of the args list to allow
# the recipe to be applied
if haskey(plotattributes, :group)
args = (extractGroupArgs(plotattributes[:group], args...), args...)
end
# if we were passed a vector/matrix of seriestypes and there's more than one row,
# we want to duplicate the inputs, once for each seriestype row.
if !isempty(args)
append!(still_to_process, _expand_seriestype_array(plotattributes, args))
end
# remove subplot and axis args from plotattributes... they will be passed through in the kw_list
if !isempty(args)
for (k,v) in plotattributes
for defdict in (_subplot_defaults,
_axis_defaults,
_axis_defaults_byletter)
if haskey(defdict, k)
delete!(plotattributes, k)
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
## Grouping
RecipesPipeline.splittable_attribute(plt::Plot, key, val::SeriesAnnotations, len) =
RecipesPipeline.splittable_attribute(plt, key, val.strs, len)
function RecipesPipeline.split_attribute(plt::Plot, key, val::SeriesAnnotations, indices)
split_strs = RecipesPipeline.split_attribute(plt, key, val.strs, indices)
return SeriesAnnotations(split_strs, val.font, val.baseshape, val.scalefactor)
end
## Preprocessing attributes
function RecipesPipeline.preprocess_axis_args!(plt::Plot, plotattributes, letter)
# Fix letter for seriestypes that are x only but data gets passed as y
if treats_y_as_x(get(plotattributes, :seriestype, :path))
if get(plotattributes, :orientation, :vertical) == :vertical
letter = :x
end
end
plotattributes[:letter] = letter
RecipesPipeline.preprocess_axis_args!(plt, plotattributes)
args
end
RecipesPipeline.preprocess_attributes!(plt::Plot, plotattributes) =
RecipesPipeline.preprocess_attributes!(plotattributes) # in src/args.jl
RecipesPipeline.is_axis_attribute(plt::Plot, attr) = is_axis_attr_noletter(attr) # in src/args.jl
RecipesPipeline.is_subplot_attribute(plt::Plot, attr) = is_subplot_attr(attr) # in src/args.jl
# ------------------------------------------------------------------
# user recipes
## User recipes
function _process_userrecipes(plt::Plot, plotattributes::KW, args)
still_to_process = RecipeData[]
args = _preprocess_args(plotattributes, args, still_to_process)
function RecipesPipeline.process_userrecipe!(plt::Plot, kw_list, kw)
# for plotting recipes, swap out the args and update the parameter dictionary
# we are keeping a stack of series that still need to be processed.
# each pass through the loop, we pop one off and apply the recipe.
# the recipe will return a list a Series objects... the ones that are
# finished (no more args) get added to the kw_list, the ones that are not
# are placed on top of the stack and are then processed further.
kw_list = KW[]
while !isempty(still_to_process)
# grab the first in line to be processed and either add it to the kw_list or
# pass it through apply_recipe to generate a list of RecipeData objects (data + attributes)
# for further processing.
next_series = popfirst!(still_to_process)
# recipedata should be of type RecipeData. if it's not then the inputs must not have been fully processed by recipes
if !(typeof(next_series) <: RecipeData)
error("Inputs couldn't be processed... expected RecipeData but got: $next_series")
end
if isempty(next_series.args)
_process_userrecipe(plt, kw_list, next_series)
else
rd_list = RecipesBase.apply_recipe(next_series.plotattributes, next_series.args...)
prepend!(still_to_process,rd_list)
end
end
# don't allow something else to handle it
plotattributes[:smooth] = false
kw_list
end
function _process_userrecipe(plt::Plot, kw_list::Vector{KW}, recipedata::RecipeData)
# when the arg tuple is empty, that means there's nothing left to recursively
# process... finish up and add to the kw_list
kw = recipedata.plotattributes
preprocessArgs!(kw)
_preprocess_userrecipe(kw)
warn_on_unsupported_scales(plt.backend, kw)
warnOnUnsupported_scales(plt.backend, kw)
# add the plot index
plt.n += 1
kw[:series_plotindex] = plt.n
@@ -78,20 +108,21 @@ function RecipesPipeline.process_userrecipe!(plt::Plot, kw_list, kw)
return
end
function _preprocess_userrecipe(kw::AKW)
function _preprocess_userrecipe(kw::KW)
_add_markershape(kw)
# if there was a grouping, filter the data here
_filter_input_data!(kw)
# map marker_z if it's a Function
if isa(get(kw, :marker_z, nothing), Function)
# TODO: should this take y and/or z as arguments?
kw[:marker_z] = isa(kw[:z], Nothing) ? map(kw[:marker_z], kw[:x], kw[:y]) :
map(kw[:marker_z], kw[:x], kw[:y], kw[:z])
kw[:marker_z] = isa(kw[:z], Nothing) ? map(kw[:marker_z], kw[:x], kw[:y]) : map(kw[:marker_z], kw[:x], kw[:y], kw[:z])
end
# map line_z if it's a Function
if isa(get(kw, :line_z, nothing), Function)
kw[:line_z] = isa(kw[:z], Nothing) ? map(kw[:line_z], kw[:x], kw[:y]) :
map(kw[:line_z], kw[:x], kw[:y], kw[:z])
kw[:line_z] = isa(kw[:z], Nothing) ? map(kw[:line_z], kw[:x], kw[:y]) : map(kw[:line_z], kw[:x], kw[:y], kw[:z])
end
# convert a ribbon into a fillrange
@@ -101,10 +132,10 @@ function _preprocess_userrecipe(kw::AKW)
return
end
function _add_errorbar_kw(kw_list::Vector{KW}, kw::AKW)
function _add_errorbar_kw(kw_list::Vector{KW}, kw::KW)
# handle error bars by creating new recipedata data... these will have
# the same recipedata index as the recipedata they are copied from
for esym in (:xerror, :yerror, :zerror)
for esym in (:xerror, :yerror)
if get(kw, esym, nothing) !== nothing
# we make a copy of the KW and apply an errorbar recipe
errkw = copy(kw)
@@ -116,65 +147,65 @@ function _add_errorbar_kw(kw_list::Vector{KW}, kw::AKW)
end
end
function _add_smooth_kw(kw_list::Vector{KW}, kw::AKW)
function _add_smooth_kw(kw_list::Vector{KW}, kw::KW)
# handle smoothing by adding a new series
if get(kw, :smooth, false)
x, y = kw[:x], kw[:y]
β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y)
sx = [ignorenan_minimum(x), ignorenan_maximum(x)]
sy = β .* sx .+ α
push!(
kw_list,
merge(
copy(kw),
KW(
:seriestype => :path,
:x => sx,
:y => sy,
:fillrange => nothing,
:label => "",
:primary => false,
),
),
)
push!(kw_list, merge(copy(kw), KW(
:seriestype => :path,
:x => sx,
:y => sy,
:fillrange => nothing,
:label => "",
:primary => false,
)))
end
end
# ------------------------------------------------------------------
# plot recipes
RecipesPipeline.get_axis_limits(plt::Plot, letter) = axis_limits(plt[1], letter)
## Plot recipes
RecipesPipeline.type_alias(plt::Plot) = get(_typeAliases, st, st)
## Plot setup
function RecipesPipeline.plot_setup!(plt::Plot, plotattributes, kw_list)
_plot_setup(plt, plotattributes, kw_list)
_subplot_setup(plt, plotattributes, kw_list)
return nothing
end
function RecipesPipeline.process_sliced_series_attributes!(plt::Plots.Plot, kw_list)
# swap errors
err_inds = findall(kw -> get(kw, :seriestype, :path) in (:xerror, :yerror, :zerror), kw_list)
for ind in err_inds
if get(kw_list[ind-1],:seriestype,:path) == :scatter
tmp = copy(kw_list[ind])
kw_list[ind] = copy(kw_list[ind-1])
kw_list[ind-1] = tmp
# Grab the first in line to be processed and pass it through apply_recipe
# to generate a list of RecipeData objects (data + attributes).
# If we applied a "plot recipe" without error, then add the returned datalist's KWs,
# otherwise we just add the original KW.
function _process_plotrecipe(plt::Plot, kw::KW, kw_list::Vector{KW}, still_to_process::Vector{KW})
if !isa(get(kw, :seriestype, nothing), Symbol)
# seriestype was never set, or it's not a Symbol, so it can't be a plot recipe
push!(kw_list, kw)
return
end
try
st = kw[:seriestype]
st = kw[:seriestype] = get(_typeAliases, st, st)
datalist = RecipesBase.apply_recipe(kw, Val{st}, plt)
for data in datalist
preprocessArgs!(data.plotattributes)
if data.plotattributes[:seriestype] == st
error("Plot recipe $st returned the same seriestype: $(data.plotattributes)")
end
push!(still_to_process, data.plotattributes)
end
catch err
if isa(err, MethodError)
push!(kw_list, kw)
else
rethrow()
end
end
return nothing
return
end
# TODO: Should some of this logic be moved to RecipesPipeline?
function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
# ------------------------------------------------------------------
# setup plot and subplot
function _plot_setup(plt::Plot, plotattributes::KW, kw_list::Vector{KW})
# merge in anything meant for the Plot
for kw in kw_list, (k, v) in kw
for kw in kw_list, (k,v) in kw
haskey(_plot_defaults, k) && (plotattributes[k] = pop!(kw, k))
end
@@ -185,7 +216,7 @@ function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
# create the layout and subplots from the inputs
plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr)
for (idx, sp) in enumerate(plt.subplots)
for (idx,sp) in enumerate(plt.subplots)
sp.plt = plt
sp.attr[:subplot_index] = idx
end
@@ -210,7 +241,7 @@ function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
else
parent = plt.layout
end
sp = Subplot(backend(), parent = parent)
sp = Subplot(backend(), parent=parent)
sp.plt = plt
push!(plt.subplots, sp)
push!(plt.inset_subplots, sp)
@@ -221,39 +252,33 @@ function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
plt[:inset_subplots] = nothing
end
function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
function _subplot_setup(plt::Plot, plotattributes::KW, kw_list::Vector{KW})
# we'll keep a map of subplot to an attribute override dict.
# Subplot/Axis attributes set by a user/series recipe apply only to the
# Subplot object which they belong to.
# TODO: allow matrices to still apply to all subplots
sp_attrs = Dict{Subplot, Any}()
sp_attrs = Dict{Subplot,Any}()
for kw in kw_list
# get the Subplot object to which the series belongs.
sps = get(kw, :subplot, :auto)
sp = get_subplot(
plt,
_cycle(
sps == :auto ? plt.subplots : plt.subplots[sps],
series_idx(kw_list, kw),
),
)
sp = get_subplot(plt, _cycle(sps == :auto ? plt.subplots : plt.subplots[sps], command_idx(kw_list,kw)))
kw[:subplot] = sp
# extract subplot/axis attributes from kw and add to sp_attr
attr = KW()
for (k, v) in collect(kw)
if is_subplot_attr(k) || is_axis_attr(k)
for (k,v) in collect(kw)
if haskey(_subplot_defaults, k) || haskey(_axis_defaults_byletter, k)
attr[k] = pop!(kw, k)
end
if is_axis_attr_noletter(k)
if haskey(_axis_defaults, k)
v = pop!(kw, k)
for letter in (:x, :y, :z)
attr[Symbol(letter, k)] = v
for letter in (:x,:y,:z)
attr[Symbol(letter,k)] = v
end
end
for k in (:scale,), letter in (:x, :y, :z)
for k in (:scale,), letter in (:x,:y,:z)
# Series recipes may need access to this information
lk = Symbol(letter, k)
lk = Symbol(letter,k)
if haskey(attr, lk)
kw[lk] = attr[lk]
end
@@ -263,7 +288,7 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
end
# override subplot/axis args. `sp_attrs` take precendence
for (idx, sp) in enumerate(plt.subplots)
for (idx,sp) in enumerate(plt.subplots)
attr = if !haskey(plotattributes, :subplot) || plotattributes[:subplot] == idx
merge(plotattributes, get(sp_attrs, sp, KW()))
else
@@ -276,35 +301,9 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
link_axes!(plt.layout, plt[:link])
end
function series_idx(kw_list::AVec{KW}, kw::AKW)
Int(kw[:series_plotindex]) - Int(kw_list[1][:series_plotindex]) + 1
end
## Series recipes
function RecipesPipeline.slice_series_attributes!(plt::Plot, kw_list, kw)
sp::Subplot = kw[:subplot]
# in series attributes given as vector with one element per series,
# select the value for current series
_slice_series_args!(kw, plt, sp, series_idx(kw_list, kw))
return nothing
end
RecipesPipeline.series_defaults(plt::Plot) = _series_defaults # in args.jl
RecipesPipeline.is_seriestype_supported(plt::Plot, st) = is_seriestype_supported(st)
function RecipesPipeline.add_series!(plt::Plot, plotattributes)
sp = _prepare_subplot(plt, plotattributes)
_expand_subplot_extrema(sp, plotattributes, plotattributes[:seriestype])
_update_series_attributes!(plotattributes, plt, sp)
_add_the_series(plt, sp, plotattributes)
end
# getting ready to add the series... last update to subplot from anything
# that might have been added during series recipes
function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where {T}
function _prepare_subplot(plt::Plot{T}, plotattributes::KW) where T
st::Symbol = plotattributes[:seriestype]
sp::Subplot{T} = plotattributes[:subplot]
sp_idx = get_subplot_index(plt, sp)
@@ -313,7 +312,7 @@ function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where {T}
st = _override_seriestype_check(plotattributes, st)
# change to a 3d projection for this subplot?
if RecipesPipeline.needs_3d_axes(st)
if is3d(st)
sp.attr[:projection] = "3d"
end
@@ -325,12 +324,14 @@ function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where {T}
sp
end
function _override_seriestype_check(plotattributes::AKW, st::Symbol)
# ------------------------------------------------------------------
# series types
function _override_seriestype_check(plotattributes::KW, st::Symbol)
# do we want to override the series type?
if !RecipesPipeline.is3d(st) && !(st in (:contour, :contour3d, :quiver))
if !is3d(st) && !(st in (:contour,:contour3d))
z = plotattributes[:z]
if !isa(z, Nothing) &&
(size(plotattributes[:x]) == size(plotattributes[:y]) == size(z))
if !isa(z, Nothing) && (size(plotattributes[:x]) == size(plotattributes[:y]) == size(z))
st = (st == :scatter ? :scatter3d : :path3d)
plotattributes[:seriestype] = st
end
@@ -338,14 +339,30 @@ function _override_seriestype_check(plotattributes::AKW, st::Symbol)
st
end
function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
function _prepare_annotations(sp::Subplot, plotattributes::KW)
# strip out series annotations (those which are based on series x/y coords)
# and add them to the subplot attr
sp_anns = annotations(sp[:annotations])
# series_anns = annotations(pop!(plotattributes, :series_annotations, []))
# if isa(series_anns, SeriesAnnotations)
# series_anns.x = plotattributes[:x]
# series_anns.y = plotattributes[:y]
# elseif length(series_anns) > 0
# x, y = plotattributes[:x], plotattributes[:y]
# nx, ny, na = map(length, (x,y,series_anns))
# n = max(nx, ny, na)
# series_anns = [(x[mod1(i,nx)], y[mod1(i,ny)], text(series_anns[mod1(i,na)])) for i=1:n]
# end
# sp.attr[:annotations] = vcat(sp_anns, series_anns)
end
function _expand_subplot_extrema(sp::Subplot, plotattributes::KW, st::Symbol)
# adjust extrema and discrete info
if st == :image
xmin, xmax = ignorenan_extrema(plotattributes[:x])
ymin, ymax = ignorenan_extrema(plotattributes[:y])
xmin, xmax = ignorenan_extrema(plotattributes[:x]); ymin, ymax = ignorenan_extrema(plotattributes[:y])
expand_extrema!(sp[:xaxis], (xmin, xmax))
expand_extrema!(sp[:yaxis], (ymin, ymax))
elseif !(st in (:histogram, :bins2d, :histogram2d))
elseif !(st in (:pie, :histogram, :bins2d, :histogram2d))
expand_extrema!(sp, plotattributes)
end
# expand for zerolines (axes through origin)
@@ -356,23 +373,53 @@ function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
end
function _add_the_series(plt, sp, plotattributes)
extra_kwargs = warn_on_unsupported_args(plt.backend, plotattributes)
if (kw = plt[:extra_kwargs]) isa AbstractDict
plt[:extra_plot_kwargs] = get(kw,:plot,KW())
sp[:extra_kwargs] = get(kw,:subplot, KW())
plotattributes[:extra_kwargs] = get(kw,:series,KW())
elseif plt[:extra_kwargs] == :plot
plt[:extra_plot_kwargs] = extra_kwargs
elseif plt[:extra_kwargs] == :subplot
sp[:extra_kwargs] = extra_kwargs
elseif plt[:extra_kwargs] == :series
plotattributes[:extra_kwargs] = extra_kwargs
else
ArgumentError("Unsupported type for extra keyword arguments")
end
warn_on_unsupported(plt.backend, plotattributes)
warnOnUnsupported_args(plt.backend, plotattributes)
warnOnUnsupported(plt.backend, plotattributes)
series = Series(plotattributes)
push!(plt.series_list, series)
push!(sp.series_list, series)
_series_added(plt, series)
end
# -------------------------------------------------------------------------------
# this method recursively applies series recipes when the seriestype is not supported
# natively by the backend
function _process_seriesrecipe(plt::Plot, plotattributes::KW)
# replace seriestype aliases
st = Symbol(plotattributes[:seriestype])
st = plotattributes[:seriestype] = get(_typeAliases, st, st)
# shapes shouldn't have fillrange set
if plotattributes[:seriestype] == :shape
plotattributes[:fillrange] = nothing
end
# if it's natively supported, finalize processing and pass along to the backend, otherwise recurse
if is_seriestype_supported(st)
sp = _prepare_subplot(plt, plotattributes)
_prepare_annotations(sp, plotattributes)
_expand_subplot_extrema(sp, plotattributes, st)
_update_series_attributes!(plotattributes, plt, sp)
_add_the_series(plt, sp, plotattributes)
else
# get a sub list of series for this seriestype
datalist = RecipesBase.apply_recipe(plotattributes, Val{st}, plotattributes[:x], plotattributes[:y], plotattributes[:z])
# assuming there was no error, recursively apply the series recipes
for data in datalist
if isa(data, RecipeData)
preprocessArgs!(data.plotattributes)
if data.plotattributes[:seriestype] == st
error("The seriestype didn't change in series recipe $st. This will cause a StackOverflow.")
end
_process_seriesrecipe(plt, data.plotattributes)
else
@warn("Unhandled recipe: $(data)")
break
end
end
end
nothing
end
+90 -18
View File
@@ -43,14 +43,13 @@ The main plot command. Use `plot` to create a new plot object, and `plot!` to ad
There are lots of ways to pass in data, and lots of keyword arguments... just try it and it will likely work as expected.
When you pass in matrices, it splits by columns. To see the list of available attributes, use the `plotattr([attr])`
function, where `attr` is the symbol `:Series`, `:Subplot`, `:Plot`, or `:Axis`. Pass any attribute to `plotattr`
as a String to look up its docstring, e.g., `plotattr("seriestype")`.
function, where `attr` is the symbol `:Series:`, `:Subplot:`, `:Plot` or `:Axis`. Pass any attribute to `plotattr`
as a String to look up its docstring; e.g. `plotattr("seriestype")`.
"""
function plot(args...; kw...)
@nospecialize
# this creates a new plot with args/kw and sets it to be the current plot
plotattributes = KW(kw)
RecipesPipeline.preprocess_attributes!(plotattributes)
preprocessArgs!(plotattributes)
# create an empty Plot then process
plt = Plot()
@@ -61,9 +60,8 @@ end
# build a new plot from existing plots
# note: we split into plt1 and plts_tail so we can dispatch correctly
function plot(plt1::Plot, plts_tail::Plot...; kw...)
@nospecialize
plotattributes = KW(kw)
RecipesPipeline.preprocess_attributes!(plotattributes)
preprocessArgs!(plotattributes)
# build our plot vector from the args
n = length(plts_tail) + 1
@@ -98,7 +96,7 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...)
series_attr = KW()
for (k,v) in plotattributes
if is_series_attr(k)
if haskey(_series_defaults, k)
series_attr[k] = pop!(plotattributes,k)
end
end
@@ -121,7 +119,7 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...)
sp.attr[:subplot_index] = idx
for series in serieslist
merge!(series.plotattributes, series_attr)
_slice_series_args!(series.plotattributes, plt, sp, cmdidx)
_add_defaults!(series.plotattributes, plt, sp, cmdidx)
push!(plt.series_list, series)
_series_added(plt, series)
cmdidx += 1
@@ -142,8 +140,7 @@ end
# this adds to the current plot, or creates a new plot if none are current
function plot!(args...; kw...)
@nospecialize
function plot!(args...; kw...)
local plt
try
plt = current()
@@ -155,9 +152,8 @@ end
# this adds to a specific plot... most plot commands will flow through here
function plot!(plt::Plot, args...; kw...)
@nospecialize
plotattributes = KW(kw)
RecipesPipeline.preprocess_attributes!(plotattributes)
preprocessArgs!(plotattributes)
# merge!(plt.user_attr, plotattributes)
_plot!(plt, plotattributes, args)
end
@@ -167,12 +163,88 @@ end
# this is the core plotting function. recursively apply recipes to build
# a list of series KW dicts.
# note: at entry, we only have those preprocessed args which were passed in... no default values yet
function _plot!(plt::Plot, plotattributes, args)
@nospecialize
RecipesPipeline.recipe_pipeline!(plt, plotattributes, args)
function _plot!(plt::Plot, plotattributes::KW, args::Tuple)
plotattributes[:plot_object] = plt
if !isempty(args) && !isdefined(Main, :StatsPlots) &&
first(split(string(typeof(args[1])), ".")) == "DataFrames"
@warn("You're trying to plot a DataFrame, but this functionality is provided by StatsPlots")
end
# --------------------------------
# "USER RECIPES"
# --------------------------------
kw_list = _process_userrecipes(plt, plotattributes, args)
# @info(1)
# map(DD, kw_list)
# --------------------------------
# "PLOT RECIPES"
# --------------------------------
# "plot recipe", which acts like a series type, and is processed before
# the plot layout is created, which allows for setting layouts and other plot-wide attributes.
# we get inputs which have been fully processed by "user recipes" and "type recipes",
# so we can expect standard vectors, surfaces, etc. No defaults have been set yet.
still_to_process = kw_list
kw_list = KW[]
while !isempty(still_to_process)
next_kw = popfirst!(still_to_process)
_process_plotrecipe(plt, next_kw, kw_list, still_to_process)
end
# @info(2)
# map(DD, kw_list)
# --------------------------------
# Plot/Subplot/Layout setup
# --------------------------------
_plot_setup(plt, plotattributes, kw_list)
_subplot_setup(plt, plotattributes, kw_list)
# !!! note: At this point, kw_list is fully decomposed into individual series... one KW per series. !!!
# !!! The next step is to recursively apply series recipes until the backend supports that series type !!!
# --------------------------------
# "SERIES RECIPES"
# --------------------------------
# @info(3)
# map(DD, kw_list)
for kw in kw_list
sp::Subplot = kw[:subplot]
# idx = get_subplot_index(plt, sp)
# # we update subplot args in case something like the color palatte is part of the recipe
# _update_subplot_args(plt, sp, kw, idx, true)
# set default values, select from attribute cycles, and generally set the final attributes
_add_defaults!(kw, plt, sp, command_idx(kw_list,kw))
# now we have a fully specified series, with colors chosen. we must recursively handle
# series recipes, which dispatch on seriestype. If a backend does not natively support a seriestype,
# we check for a recipe that will convert that series type into one made up of lower-level components.
# For example, a histogram is just a bar plot with binned data, a bar plot is really a filled step plot,
# and a step plot is really just a path. So any backend that supports drawing a path will implicitly
# be able to support step, bar, and histogram plots (and any recipes that use those components).
_process_seriesrecipe(plt, kw)
end
# --------------------------------
current(plt)
# do we want to force display?
# if plt[:show]
# gui(plt)
# end
_do_plot_show(plt, plt[:show])
return plt
plt
end
@@ -210,12 +282,12 @@ end
# plot to a Subplot
function plot(sp::Subplot, args...; kw...)
@nospecialize
plt = sp.plt
plot(plt, args...; kw..., subplot = findfirst(isequal(sp), plt.subplots))
end
function plot!(sp::Subplot, args...; kw...)
@nospecialize
plt = sp.plt
plot!(plt, args...; kw..., subplot = findfirst(isequal(sp), plt.subplots))
end
# --------------------------------------------------------------------
+873
View File
@@ -0,0 +1,873 @@
function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
precompile(Tuple{typeof(Plots.gr_draw_marker), Float64, Float64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_display), Plots.Subplot{Plots.GRBackend}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.legendtitlefont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.shape_data), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.preprocessArgs!), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.replaceAlias!), Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Float64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.preprocessArgs!), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.warnOnUnsupported), Plots.GRBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.legendtitlefont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.layout_args), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.contour_levels), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots.color_or_nothing!), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.warnOnUnsupported_args), Plots.GRBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.gr_display), Plots.Subplot{Plots.GRBackend}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{Any, 1}}})
precompile(Tuple{typeof(Plots.gr_text), Float64, Float64, String})
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64, Array{Plots.Plot{T} where T<:RecipesBase.AbstractBackend, 1}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Float64, Float64, Plots.Shape})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.axis_drawing_info), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.get_markercolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.gr_xaxis_height), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.layout_args), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.iscontour), Plots.Series})
precompile(Tuple{typeof(Plots.__init__)})
precompile(Tuple{typeof(Plots.gr_set_gradient), PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots.get_clims), Plots.Series})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.gr_draw_colorbar), Plots.GRColorbar, Plots.Subplot{Plots.GRBackend}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64, Array{Plots.Plot{T} where T<:RecipesBase.AbstractBackend, 1}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{String, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots.default_should_widen), Plots.Axis})
precompile(Tuple{typeof(Plots.add_layout_pct!), Base.Dict{Symbol, Any}, Expr, Int64, Int64})
precompile(Tuple{typeof(Plots.gr_set_linecolor), PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.getxy), Plots.Plot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots.recompute_lengths), Array{Measures.Measure, 1}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.has_attribute_segments), Plots.Series})
precompile(Tuple{typeof(Plots.gr_set_viewport_cmap), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.gr_polaraxes), Int64, Float64, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Float64})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.is_attr_supported), Symbol})
precompile(Tuple{typeof(Plots._backend_instance), Symbol})
precompile(Tuple{typeof(Plots.axis_drawing_info), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._backend_instance), Symbol})
precompile(Tuple{typeof(Plots._plots_defaults)})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.pie_labels), Plots.Subplot{Plots.GRBackend}, Plots.Series})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._preprocess_barlike), Base.Dict{Symbol, Any}, Array{Int64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Axis, Plots.Axis})
precompile(Tuple{typeof(Plots.showaxis), Symbol, Symbol})
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Base.StepRange{Int64, Int64}, Symbol})
precompile(Tuple{typeof(Plots._heatmap_edges), Array{Float64, 1}, Bool})
precompile(Tuple{typeof(Plots.convertToAnyVector), Int64, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.gr_get_color), Plots.Series})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Int64, 1}, String})
precompile(Tuple{typeof(Plots.gr_viewport_from_bbox), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.ensure_gradient!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Nothing, 1}, String})
precompile(Tuple{typeof(Plots.isvertical), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.hasgrid), Symbol, Symbol})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Symbol, 1}, String})
precompile(Tuple{typeof(Plots.titlefont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.gr_set_yticks_font), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol, Bool, Bool})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Plots.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy}})
precompile(Tuple{typeof(Plots.series_annotations_shapes!), Plots.Series, Symbol})
precompile(Tuple{typeof(Plots.aliasesAndAutopick), Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Symbol}, Array{Symbol, 1}, Int64})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Char})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.default_should_widen), Plots.Axis})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy}})
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, String, Symbol})
precompile(Tuple{typeof(Plots.warnOnUnsupported_scales), Plots.GRBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_series_attributes!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, String})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{String, 1}}})
precompile(Tuple{typeof(Plots.iscontour), Plots.Series})
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Tuple{Int64, Int64}, Symbol})
precompile(Tuple{typeof(Plots.gr_display), Plots.Plot{Plots.GRBackend}, String})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.reset_extrema!), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_inqtext), Int64, Int64, String})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._cbar_unique), Array{PlotUtils.ColorGradient, 1}, String})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.convert_to_polar), Array{Float64, 1}, Array{Float64, 1}, Tuple{Int64, Float64}})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.GridLayout})
precompile(Tuple{typeof(Plots._process_seriesrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.ispolar), Plots.Series})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.gr_xaxis_height), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.UnitRange{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Int64})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.process_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText, Plots.Font})
precompile(Tuple{typeof(Plots._add_defaults!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{Any, 1}}, Int64})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.colorbar_style), Plots.Series})
precompile(Tuple{typeof(Plots._process_seriesrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._add_markershape), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.make_steps), Array{Float64, 1}, Symbol})
precompile(Tuple{typeof(Plots.wraptuple), Int64})
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Array{T, 1} where T, 1}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._bin_centers), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_yaxis_width), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._pick_default_backend)})
precompile(Tuple{typeof(Plots.gr_legend_pos), Plots.Subplot{Plots.GRBackend}, Float64, Float64})
precompile(Tuple{typeof(Plots.get_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.get_clims), Plots.Series})
precompile(Tuple{typeof(Plots.gr_draw_marker), Float64, Float64, Int64, Symbol})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Float64, Int64, Symbol})
precompile(Tuple{typeof(Plots.straightline_data), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.is_marker_supported), Symbol})
precompile(Tuple{typeof(Plots.straightline_data), Tuple{Int64, Int64}, Tuple{Float64, Float64}, Array{Float64, 1}, Array{Float64, 1}, Int64})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.get_markerstrokecolor), Plots.Series, Int64})
precompile(Tuple{typeof(Plots._preprocess_userrecipe), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots._update_subplot_periphery), Plots.Subplot{Plots.GRBackend}, Array{Any, 1}})
precompile(Tuple{typeof(Plots.gr_set_line), Float64, Symbol, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.make_steps), Array{Int64, 1}, Symbol})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Function, 1}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.filter_data), Base.UnitRange{Int64}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.is3d), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Int64, Symbol})
precompile(Tuple{typeof(Plots._update_series_attributes!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Float64, Int64, Bool})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Float64})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Plots.Spy}})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
precompile(Tuple{typeof(Plots.recompute_lengths), Array{Measures.Measure, 1}})
precompile(Tuple{typeof(Plots._preprocess_barlike), Base.Dict{Symbol, Any}, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.create_grid_curly), Expr})
precompile(Tuple{typeof(Plots._replace_linewidth), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, 1}, String})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.frame), Plots.Animation})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.xlims), Int64})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol, Bool, Bool})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Array{Any, 1}})
precompile(Tuple{typeof(Plots.filter_data), Array{Float64, 1}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.gr_lims), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Bool, Nothing})
precompile(Tuple{typeof(Plots.make_steps), Base.UnitRange{Int64}, Symbol})
precompile(Tuple{typeof(Plots.reset_extrema!), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.gr_set_markercolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Array{Any, 1}, Int64, Bool})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots.gr_inqtext), Int64, Int64, String})
precompile(Tuple{typeof(Plots._add_errorbar_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Bool})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Nothing, Int64, Bool})
precompile(Tuple{typeof(Plots.get_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_get_color), Plots.Series})
precompile(Tuple{typeof(Plots.fg_color), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Array{Float64, 1}, 1}})
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Int64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.shape_data), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots._prepare_annotations), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.should_add_to_legend), Plots.Series})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.is_scale_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout, Array{Measures.Length{:mm, Float64}, 1}})
precompile(Tuple{typeof(Plots._series_index), Base.Dict{Symbol, Any}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._process_plotrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Tuple{Int64, Int64}, Int64, Bool})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.warnOnUnsupported_args), Plots.GRBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.backend), Symbol})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.convert_sci_unicode), String})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Measures.Length{:mm, Float64}, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Int64, Int64, Bool})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.build_layout), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots._cycle), Array{String, 1}, Int64})
precompile(Tuple{typeof(Plots.ensure_gradient!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.make_fillrange_side), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.setxy!), Plots.Plot{Plots.GRBackend}, Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Bool, Int64, Bool})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.link_subplots), Array{RecipesBase.AbstractLayout, 1}, Symbol})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, String, Int64, Bool})
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Bool})
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Function, 1}})
precompile(Tuple{typeof(Plots._update_subplot_periphery), Plots.Subplot{Plots.GRBackend}, Array{Any, 1}})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Array{Float64, 2}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Int64})
precompile(Tuple{typeof(Plots.process_fillrange), Int64, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.make_fillrange_side), Array{Float64, 1}, Int64})
precompile(Tuple{typeof(Plots.iter_segments), Plots.Series})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.GridLayout})
precompile(Tuple{typeof(Plots.like_histogram), Symbol})
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots._replace_linewidth), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.get_markercolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.update_inset_bboxes!), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.GroupBy, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_text_size), String})
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Function, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots._process_seriesrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout, Array{Measures.Length{:mm, Float64}, 1}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.slice_arg), ColorTypes.RGBA{Float64}, Int64})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots._cycle), Base.StepRange{Int64, Int64}, Int64})
precompile(Tuple{typeof(Plots.ignorenan_maximum), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.warnOnUnsupported), Plots.GRBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Float64, Int64, Bool})
precompile(Tuple{typeof(Plots.isvertical), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.warnOnUnsupported_scales), Plots.GRBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Base.Missing})
precompile(Tuple{typeof(Plots.gr_fill_viewport), Array{Float64, 1}, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots._process_plotrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.create_grid_curly), Expr})
precompile(Tuple{typeof(Plots._add_markershape), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._add_defaults!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Bool})
precompile(Tuple{typeof(Plots._add_smooth_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.title!), String})
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Float64})
precompile(Tuple{typeof(Plots.has_attribute_segments), Plots.Series})
precompile(Tuple{typeof(Plots.supported_markers)})
isdefined(Plots, Symbol("#kw##histogram2d")) && precompile(Tuple{getfield(Plots, Symbol("#kw##histogram2d")), NamedTuple{(:nbins, :show_empty_bins, :normed, :aspect_ratio), Tuple{Tuple{Int64, Int64}, Bool, Bool, Int64}}, typeof(Plots.histogram2d), Array{Base.Complex{Float64}, 1}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.tickfont), Plots.Axis})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{String, 1}}, Int64})
precompile(Tuple{typeof(Plots._update_clims), Float64, Float64, Int64, Int64})
precompile(Tuple{typeof(Plots.wand_edges), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Plots.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots._preprocess_userrecipe), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.is_marker_supported), Symbol})
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots._subplot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Plots.Stroke})
precompile(Tuple{typeof(Plots.calc_num_subplots), Plots.GridLayout})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.extendSeriesData), Array{Float64, 1}, Float64})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Int64, Int64, Bool})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Plots.Shape})
precompile(Tuple{typeof(Plots.is_style_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.compute_gridsize), Int64, Int64, Int64})
precompile(Tuple{typeof(Plots.gr_set_fill), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots._subplot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.compute_xyz), Array{String, 1}, Array{Float64, 1}, Nothing})
precompile(Tuple{typeof(Plots.is3d), Symbol})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots._update_axis_links), Plots.Plot{Plots.GRBackend}, Plots.Axis, Symbol})
precompile(Tuple{typeof(Plots._update_series_attributes!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.xlims), Int64})
precompile(Tuple{typeof(Plots._preprocess_binlike), Base.Dict{Symbol, Any}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Array{String, 1}, Int64})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.supported_styles)})
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Function, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._cycle), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int64})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Array{Int64, 1}, Int64})
precompile(Tuple{typeof(Plots._add_errorbar_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Nothing})
precompile(Tuple{typeof(Plots.arrow), Int64})
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, Array{String, 1}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Int64})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.filter_data!), Base.Dict{Symbol, Any}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.add_layout_pct!), Base.Dict{Symbol, Any}, Expr, Int64, Int64})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Array{Any, 1}, Int64, Bool})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{String, 1}}, Int64})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, String, Int64, Bool})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_set_yticks_font), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_viewport_from_bbox), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.like_surface), Symbol})
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.convertLegendValue), Bool})
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Measures.Length{:mm, Float64}, Int64, Bool})
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ColorGradient, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Bool, Int64, Bool})
precompile(Tuple{typeof(Plots.link_axes!), Plots.GridLayout, Symbol})
precompile(Tuple{typeof(Plots.process_ribbon), Int64, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Tuple{Int64, Int64}, Int64, Bool})
precompile(Tuple{typeof(Plots._update_axis_colors), Plots.Axis})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Nothing, Int64, Bool})
precompile(Tuple{typeof(Plots.gr_text), Float64, Float64, String})
precompile(Tuple{typeof(Plots.update_inset_bboxes!), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.backend)})
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._pick_default_backend)})
precompile(Tuple{typeof(Plots.trueOrAllTrue), typeof(identity), Array{Symbol, 2}})
precompile(Tuple{typeof(Plots.nanappend!), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.get_linealpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_xy), Plots.OHLC{Float64}, Int64, Float64})
precompile(Tuple{typeof(Plots.tickfont), Plots.Axis})
precompile(Tuple{typeof(Plots.legendfont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.all3D), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.fakedata), Int64, Int64})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ColorGradient, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.convertLegendValue), Symbol})
precompile(Tuple{typeof(Plots.gr_yaxis_width), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Bool})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Axis, Plots.Axis})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Float64})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Bool, Symbol})
precompile(Tuple{typeof(Plots.should_add_to_legend), Plots.Series})
precompile(Tuple{typeof(Plots.gr_set_xticks_font), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.guidefont), Plots.Axis})
precompile(Tuple{typeof(Plots.gr_set_textcolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Float64, Symbol})
isdefined(Plots, Symbol("#kw##scatter!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter!")), NamedTuple{(:zcolor, :m, :ms, :lab), Tuple{Array{Float64, 1}, Tuple{Symbol, Float64, Plots.Stroke}, Array{Float64, 1}, String}}, typeof(Plots.scatter!), Array{Float64, 1}})
isdefined(Plots, Symbol("#kw##gr_set_font")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_set_font")), NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}}, typeof(Plots.gr_set_font), Plots.Font})
precompile(Tuple{typeof(Plots.backend), Symbol})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
isdefined(Plots, Symbol("#kw##contour")) && precompile(Tuple{getfield(Plots, Symbol("#kw##contour")), NamedTuple{(:fill,), Tuple{Bool}}, typeof(Plots.contour), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Array{T, 1} where T, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.iter_segments), Base.UnitRange{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.allAlphas), Int64})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.Shape})
precompile(Tuple{typeof(Plots.series_annotations), Array{Any, 1}})
precompile(Tuple{typeof(Plots.gr_set_fillcolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.colorbar_style), Plots.Series})
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Array{Float64, 1}, Symbol, Tuple{Int64, Int64}})
isdefined(Plots, Symbol("#kw##hline!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##hline!")), NamedTuple{(:line,), Tuple{Tuple{Int64, Symbol, Float64, Array{Symbol, 2}}}}, typeof(Plots.hline!), Array{Float64, 2}})
precompile(Tuple{typeof(Plots._display), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.font), String, Int})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.isijulia)})
precompile(Tuple{typeof(Plots.gr_colorbar_colors), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.iter_segments), Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotarea!), Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Array{Symbol, 2}, Int64})
precompile(Tuple{typeof(Plots._transform_ticks), Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Float64})
precompile(Tuple{typeof(Plots.compute_xyz), Nothing, Nothing, Nothing})
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64})
precompile(Tuple{typeof(Plots.command_idx), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._plot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.yaxis!), String, Symbol})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.gr_set_xticks_font), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}}, Symbol})
precompile(Tuple{typeof(Plots.rowsize), Expr})
isdefined(Plots, Symbol("#kw##pie")) && precompile(Tuple{getfield(Plots, Symbol("#kw##pie")), NamedTuple{(:title, :l), Tuple{String, Float64}}, typeof(Plots.pie), Array{String, 1}, Int})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.ohlc), Array{Plots.OHLC{T} where T<:Real, 1}})
precompile(Tuple{typeof(Plots.get_fillalpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots._add_smooth_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._cycle), Int64, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.create_grid), Symbol})
precompile(Tuple{typeof(Plots.gr_text_size), String, Int64})
precompile(Tuple{typeof(Plots._apply_type_recipe), Base.Dict{Symbol, Any}, typeof(identity)})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Array{Float64, 1}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.gr_text_size), String, Int64})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Array{Symbol, 2}, Symbol})
precompile(Tuple{typeof(Plots.compute_xyz), Nothing, Array{Union{Base.Missing, Float64}, 1}, Nothing})
precompile(Tuple{typeof(Plots.gr_contour_levels), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.slice_arg), Tuple{Int64, Int64}, Int64})
precompile(Tuple{typeof(Plots.straightline_data), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.UnitRange{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, typeof(identity), Nothing})
precompile(Tuple{typeof(Plots.compute_xyz), Array{String, 1}, Array{String, 1}, Plots.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.layout_args), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Nothing})
precompile(Tuple{typeof(Plots.layout_args), Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Bool})
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, Array{Float64, 1}, Nothing})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.stroke), Int64, Int})
precompile(Tuple{typeof(Plots.slice_arg), Array{Symbol, 2}, Int64})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Float64})
isdefined(Plots, Symbol("#kw##heatmap")) && precompile(Tuple{getfield(Plots, Symbol("#kw##heatmap")), NamedTuple{(:aspect_ratio,), Tuple{Int64}}, typeof(Plots.heatmap), Array{String, 1}, Int})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, String, Int64})
precompile(Tuple{typeof(Plots.is3d), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.wraptuple), Nothing})
precompile(Tuple{typeof(Plots.gr_set_viewport_polar)})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.wrap_surfaces), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_axis_links), Plots.Plot{Plots.GRBackend}, Plots.Axis, Symbol})
precompile(Tuple{typeof(Plots._show), Base.IOStream, Base.Multimedia.MIME{Symbol("image/png")}, Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.Stroke})
precompile(Tuple{typeof(Plots.inline), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.UnitRange{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.get_xy), Array{Plots.OHLC{T} where T<:Real, 1}, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots._update_clims), Float64, Float64, Float64, Float64})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots._override_seriestype_check), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Nothing})
precompile(Tuple{typeof(Plots.process_ribbon), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.gr_update_colorbar!), Plots.GRColorbar, Plots.Series})
precompile(Tuple{typeof(Plots.is_attr_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.autopick), Array{ColorTypes.RGBA{Float64}, 1}, Int64})
precompile(Tuple{typeof(Plots.ensure_gradient!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots._cycle), Array{Plots.Subplot{T} where T<:RecipesBase.AbstractBackend, 1}, Int64})
isdefined(Plots, Symbol("#kw##scatter")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter")), NamedTuple{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks), Tuple{Array{Symbol, 2}, Array{String, 2}, Base.ReshapedArray{Int64, 2, Base.UnitRange{Int64}, Tuple{}}, Int64, String, Int64, Base.UnitRange{Int64}}}, typeof(Plots.scatter), Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots.frame), Plots.Animation, Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.get_markeralpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots._binbarlike_baseline), Float64, Symbol})
precompile(Tuple{typeof(Plots._cycle), Array{Any, 1}, Int64})
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}, Plots.Series})
precompile(Tuple{typeof(Plots._transform_ticks), Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.create_grid_vcat), Expr})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Bool})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.ylims), Int64})
precompile(Tuple{typeof(Plots.fg_color), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.slice_arg), Base.StepRange{Int64, Int64}, Int64})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
precompile(Tuple{typeof(Plots.extractGroupArgs), Array{String, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.get_linestyle), Plots.Series})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
isdefined(Plots, Symbol("#kw##gr_polyline")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_polyline")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Plots.Plot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots.get_linealpha), Plots.Series})
precompile(Tuple{typeof(Plots.slice_arg), Tuple{Int64, Float64}, Int64})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.gr_set_gradient), Plots.Series})
precompile(Tuple{typeof(Plots.get_markerstrokealpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots._hist_edge), Tuple{Array{Float64, 1}}, Int64, Symbol})
precompile(Tuple{typeof(Plots._display), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.allStyles), Int64})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.get_series_color), Int64, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.addExtension), String, String})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.color_or_nothing!), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.xlims), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.guidefont), Plots.Axis})
precompile(Tuple{typeof(Plots.bottom), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.is_2tuple), Int64})
precompile(Tuple{typeof(Plots.unzip), Array{Tuple{Float64, Float64, Float64}, 1}})
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.png), Plots.Plot{Plots.GRBackend}, String})
isdefined(Plots, Symbol("#kw##gr_set_font")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_set_font")), NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}}, typeof(Plots.gr_set_font), Plots.Font})
precompile(Tuple{typeof(Plots.compute_xyz), Nothing, Array{Float64, 1}, Nothing})
precompile(Tuple{typeof(Plots.slice_arg), Array{Measures.Length{:mm, Float64}, 2}, Int64})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots._update_axis_colors), Plots.Axis})
precompile(Tuple{typeof(Plots.iter_segments), Array{Int64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.ispolar), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, ColorTypes.RGBA{Float64}, Symbol})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Float64})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.wraptuple), Float64})
precompile(Tuple{typeof(Plots.process_fillrange), Nothing, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._replace_markershape), Array{Symbol, 2}})
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, Array{Float64, 1}, Plots.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.replaceAliases!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.vline!), Array{Int64, 1}})
precompile(Tuple{typeof(Plots.get_linewidth), Plots.Series})
precompile(Tuple{typeof(Plots.series_annotations), Nothing})
precompile(Tuple{typeof(Plots.ignorenan_maximum), Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}, typeof(identity)})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Symbol})
precompile(Tuple{typeof(Plots.ignorenan_minimum), Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.slice_arg), Array{ColorTypes.RGBA{Float64}, 2}, Int64})
precompile(Tuple{typeof(Plots.gr_set_font), Plots.Font})
precompile(Tuple{typeof(Plots.convert_sci_unicode), String})
precompile(Tuple{typeof(Plots.get_linewidth), Plots.Series, Int64})
isdefined(Plots, Symbol("#kw##scatter!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter!")), NamedTuple{(:markersize, :c), Tuple{Int64, Symbol}}, typeof(Plots.scatter!), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.process_ribbon), typeof(identity), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.slice_arg), Int64, Int64})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Plots.GridLayout, Int64})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Float64}})
precompile(Tuple{typeof(Plots.slice_arg), Symbol, Int64})
precompile(Tuple{typeof(Plots._cycle), Float64, Int64})
precompile(Tuple{typeof(Plots.attr), Plots.EmptyLayout, Symbol})
precompile(Tuple{typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.process_ribbon), Nothing, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.bbox!), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.create_grid), Expr})
isdefined(Plots, Symbol("#kw##histogram2d")) && precompile(Tuple{getfield(Plots, Symbol("#kw##histogram2d")), NamedTuple{(:nbins,), Tuple{Int64}}, typeof(Plots.histogram2d), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.right), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.slice_arg), String, Int64})
precompile(Tuple{typeof(Plots.prepareSeriesData), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Symbol, Int64, Symbol, Float64}})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.legendfont), Plots.Subplot{Plots.GRBackend}})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid, :ticks), Tuple{Bool, Nothing}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Plots.Spy}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.aliasesAndAutopick), Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Symbol}, Array{Symbol, 1}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Bool, Int64})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.titlefont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.link_axes!), Plots.GridLayout, Symbol})
precompile(Tuple{typeof(Plots.slice_arg), Float64, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Int64})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:scale, :guide), Tuple{Symbol, String}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}})
isdefined(Plots, Symbol("#kw##scatter!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter!")), NamedTuple{(:marker, :series_annotations), Tuple{Tuple{Int64, Float64, Symbol}, Array{Any, 1}}}, typeof(Plots.scatter!), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots._preprocess_barlike), Base.Dict{Symbol, Any}, Base.UnitRange{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_lims), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Bool, Nothing})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Array{Symbol, 2}, Int64, Float64, Plots.Stroke}})
precompile(Tuple{typeof(Plots.process_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText})
isdefined(Plots, Symbol("#kw##portfoliocomposition")) && precompile(Tuple{getfield(Plots, Symbol("#kw##portfoliocomposition")), NamedTuple{(:labels,), Tuple{Array{String, 2}}}, typeof(Plots.portfoliocomposition), Array{Float64, 2}, Int})
precompile(Tuple{typeof(Plots.plotarea!), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.autopick_ignore_none_auto), Array{Symbol, 1}, Int64})
isdefined(Plots, Symbol("#kw##scatter")) && precompile(Tuple{getfield(Plots, Symbol("#kw##scatter")), NamedTuple{(:m, :lab, :bg, :xlim, :ylim), Tuple{Tuple{Int64, Symbol}, Array{String, 2}, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}}}, typeof(Plots.scatter), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.get_axis), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.ylims), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.labelfunc), Symbol, Plots.GRBackend})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Plots.Shape, Symbol})
precompile(Tuple{typeof(Plots.attr), Plots.EmptyLayout, Symbol, Symbol})
precompile(Tuple{typeof(Plots.bbox!), Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.series_annotations_shapes!), Plots.Series, Symbol})
precompile(Tuple{typeof(Plots.widen), Float64, Float64, Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Array{RecipesBase.AbstractLayout, 1}, Symbol})
precompile(Tuple{typeof(Plots.filter_data), Nothing, Array{Int64, 1}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.annotate!), Array{Tuple{Int64, Float64, Plots.PlotText}, 1}})
precompile(Tuple{typeof(Plots._prepare_annotations), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Array{String, 1}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Int64}})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:foreground_color_grid, :grid, :gridalpha, :gridstyle, :gridlinewidth), Tuple{ColorTypes.RGBA{Float64}, Bool, Float64, Symbol, Int64}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.nobigs), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.slice_arg), Base.UnitRange{Int64}, Int64})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, ColorTypes.RGB{Float64}, Int64})
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Bool})
precompile(Tuple{typeof(Plots.locate_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText})
precompile(Tuple{typeof(Plots.tovec), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Float64, Symbol}})
precompile(Tuple{typeof(Plots._cycle), ColorTypes.RGBA{Float64}, Int64})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Symbol})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol, Float64, Array{Symbol, 2}}})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Float64, Array{Symbol, 2}, Int64}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Symbol, Symbol, Int64, Float64}})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.compute_xyz), Array{Float64, 1}, typeof(identity), Nothing})
precompile(Tuple{typeof(Plots._filter_input_data!), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Union{Base.Missing, Number}, 1}})
precompile(Tuple{typeof(Plots.supported_markers), Plots.GRBackend})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Plots.Series})
precompile(Tuple{typeof(Plots.wraptuple), Bool})
precompile(Tuple{typeof(Plots.text), String, Int64, Symbol, Symbol})
precompile(Tuple{typeof(Plots.rightpad), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Int32, 1}})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#@layout")) && precompile(Tuple{getfield(Plots, Symbol("#@layout")), LineNumberNode, Module, Expr})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Nothing})
precompile(Tuple{typeof(Plots.get_linestyle), Plots.Series, Int64})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:lims, :flip, :ticks, :guide), Tuple{Tuple{Int64, Int64}, Bool, Base.StepRange{Int64, Int64}, String}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.leftpad), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.xgrid!), Plots.Plot{Plots.GRBackend}, Symbol, Int})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:guide,), Tuple{String}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:formatter,), Tuple{Symbol}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Int64, 1}})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:rotation,), Tuple{Int64}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.text), String, Symbol, Int64, Int})
precompile(Tuple{typeof(Plots.supported_styles), Plots.GRBackend})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:flip,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Int64, 1}})
precompile(Tuple{typeof(Plots._process_userrecipes), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{String, Tuple{Int64, Int64}, Base.StepRange{Int64, Int64}, Symbol}})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.bottompad), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.slice_arg), Base.ReshapedArray{Int64, 2, Base.UnitRange{Int64}, Tuple{}}, Int64})
precompile(Tuple{typeof(Plots.contour), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.font), String, Int})
precompile(Tuple{typeof(Plots._preprocess_args), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}, Array{RecipesBase.RecipeData, 1}})
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{String, Symbol}})
precompile(Tuple{typeof(Plots.calc_num_subplots), Plots.EmptyLayout})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol}})
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Float64, Float64, Symbol})
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots._scale_adjusted_values), Type{Float64}, Array{Float64, 1}, Symbol})
precompile(Tuple{typeof(Plots._process_userrecipe), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}, RecipesBase.RecipeData})
precompile(Tuple{typeof(Plots.layout_args), Int64})
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.toppad), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.trueOrAllTrue), typeof(Plots.is3d), Symbol})
precompile(Tuple{typeof(Plots.gui), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Float64, Symbol, Plots.Stroke}})
precompile(Tuple{typeof(Plots.ylims), Int64})
precompile(Tuple{typeof(Plots._cycle), Plots.Shape, Int64})
precompile(Tuple{typeof(Plots.rowsize), Symbol})
precompile(Tuple{typeof(Plots.create_grid_vcat), Expr})
precompile(Tuple{typeof(Plots.gr_update_colorbar!), Plots.GRColorbar, Plots.Series})
precompile(Tuple{typeof(Plots.font), Symbol, Int})
precompile(Tuple{typeof(Plots._transform_ticks), Nothing})
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.get_fillalpha), Plots.Series})
precompile(Tuple{typeof(Plots.wraptuple), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.fakedata), Int64, Int64})
precompile(Tuple{typeof(Plots.wraptuple), Plots.SeriesAnnotations})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Plots.Axis})
precompile(Tuple{typeof(Plots.slice_arg), Nothing, Int64})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Bool})
precompile(Tuple{typeof(Plots.gr_set_gradient), Plots.Series})
precompile(Tuple{typeof(Plots.prepareSeriesData), Base.LinRange{Float64}})
precompile(Tuple{typeof(Plots.font), Int64, Int})
precompile(Tuple{typeof(Plots.hascolorbar), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_display), Plots.Plot{Plots.GRBackend}, String})
precompile(Tuple{typeof(Plots.gr_set_font), Plots.Font})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Float64, Plots.Stroke}})
precompile(Tuple{typeof(Plots.slice_arg), Array{String, 2}, Int64})
precompile(Tuple{typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.wraptuple), Array{Any, 1}})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout})
precompile(Tuple{typeof(Plots._cycle), Nothing, Int64})
precompile(Tuple{typeof(Plots._replace_markershape), Plots.Shape})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Array{Symbol, 2}, Symbol})
precompile(Tuple{typeof(Plots.transpose_z), Plots.Series, Array{Float64, 2}, Bool})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Array{Symbol, 2}}})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Array{Symbol, 2}, Symbol})
precompile(Tuple{typeof(Plots._cycle), Int64, Int64})
precompile(Tuple{typeof(Plots.create_grid), Expr})
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.is_2tuple), Symbol})
precompile(Tuple{typeof(Plots._create_backend_figure), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{}})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots._cycle), Symbol, Int64})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.Subplot{Plots.GRBackend}, Array{Measures.Length{:mm, Float64}, 1}})
precompile(Tuple{typeof(Plots.text), String, Symbol})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Array{Union{Base.Missing, Float64}, 1}})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Tuple{Float64, Float64}, Int64})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Bool})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Int64, Int64})
precompile(Tuple{typeof(Plots.series_annotations), Plots.SeriesAnnotations})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol, Symbol}})
precompile(Tuple{typeof(Plots.get_subplot), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Plots.Shape, Int64, ColorTypes.RGBA{Float64}}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Float64, Symbol}})
precompile(Tuple{typeof(Plots.make_steps), Nothing, Symbol})
precompile(Tuple{typeof(Plots.annotations), Array{Any, 1}})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.bar), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Array{Symbol, 2}, Int64}})
precompile(Tuple{typeof(Plots._transform_ticks), Symbol})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._show), Base.IOStream, Base.Multimedia.MIME{Symbol("image/png")}, Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Union{Base.Missing, Number}, 1}})
precompile(Tuple{typeof(Plots.link_axes!), Array{RecipesBase.AbstractLayout, 1}, Symbol})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Int64, Int64}, Bool}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Float64, Int64})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout})
precompile(Tuple{typeof(Plots.process_ribbon), Tuple{Base.LinRange{Float64}, Base.LinRange{Float64}}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots.convertToAnyVector), Array{Float64, 2}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.splittable_kw), Symbol, Symbol, Int64})
precompile(Tuple{typeof(Plots.gr_draw_marker), Int64, Int64, Int64, Symbol})
precompile(Tuple{typeof(Plots.default), Symbol})
precompile(Tuple{typeof(Plots.layout_args), Plots.GridLayout})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:ticks,), Tuple{Base.UnitRange{Int64}}}, typeof(Plots.attr!), Plots.Axis})
precompile(Tuple{typeof(Plots.make_fillrange_from_ribbon), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots.hascolorbar), Plots.Subplot{Plots.GRBackend}})
isdefined(Plots, Symbol("#kw##_make_hist")) && precompile(Tuple{getfield(Plots, Symbol("#kw##_make_hist")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
precompile(Tuple{typeof(Plots.ignorenan_minimum), Array{Int64, 1}})
isdefined(Plots, Symbol("#kw##gr_polyline")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_polyline")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Base.UnitRange{Int64}, Array{Float64, 1}})
isdefined(Plots, Symbol("#kw##histogram")) && precompile(Tuple{getfield(Plots, Symbol("#kw##histogram")), NamedTuple{(:bins, :weights), Tuple{Symbol, Array{Int64, 1}}}, typeof(Plots.histogram), Array{Float64, 1}})
isdefined(Plots, Symbol("#kw##_make_hist")) && precompile(Tuple{getfield(Plots, Symbol("#kw##_make_hist")), NamedTuple{(:normed, :weights), Tuple{Bool, Array{Int64, 1}}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}}, Symbol})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Plots.Axis})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:grid,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#kw##gr_polyline")) && precompile(Tuple{getfield(Plots, Symbol("#kw##gr_polyline")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Array{Int64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._cycle), Base.UnitRange{Int64}, Array{Int64, 1}})
isdefined(Plots, Symbol("#kw##attr!")) && precompile(Tuple{getfield(Plots, Symbol("#kw##attr!")), NamedTuple{(:ticks,), Tuple{Nothing}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#kw##_make_hist")) && precompile(Tuple{getfield(Plots, Symbol("#kw##_make_hist")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Float64, 2}})
precompile(Tuple{typeof(Plots.prepareSeriesData), Array{Float64, 1}})
precompile(Tuple{typeof(Plots._process_userrecipe), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}, RecipesBase.RecipeData})
precompile(Tuple{typeof(Plots.build_layout), Base.Dict{Symbol, Any}})
isdefined(Plots, Symbol("#kw##test_examples")) && precompile(Tuple{getfield(Plots, Symbol("#kw##test_examples")), NamedTuple{(:disp,), Tuple{Bool}}, typeof(Plots.test_examples), Symbol})
isdefined(Plots, Symbol("#kw##_make_hist")) && precompile(Tuple{getfield(Plots, Symbol("#kw##_make_hist")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}}, Symbol})
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol})
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.allStyles), Symbol})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol})
precompile(Tuple{typeof(Plots.get_axis), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.backend)})
precompile(Tuple{typeof(Plots.backend), Plots.GRBackend})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol})
end
-20
View File
@@ -1,20 +0,0 @@
should_precompile = true
# Don't edit the following! Instead change the script for `snoop_bot`.
ismultios = false
ismultiversion = false
# precompile_enclosure
@static if !should_precompile
# nothing
elseif !ismultios && !ismultiversion
@static if isfile(joinpath(
@__DIR__,
"../deps/SnoopCompile/precompile/precompile_Plots.jl",
))
include("../deps/SnoopCompile/precompile/precompile_Plots.jl")
_precompile_()
end
else
end # precompile_enclosure
+239 -652
View File
File diff suppressed because it is too large Load Diff
+650
View File
@@ -0,0 +1,650 @@
# create a new "build_series_args" which converts all inputs into xs = Any[xitems], ys = Any[yitems].
# Special handling for: no args, xmin/xmax, parametric, dataframes
# Then once inputs have been converted, build the series args, map functions, etc.
# This should cut down on boilerplate code and allow more focused dispatch on type
# note: returns meta information... mainly for use with automatic labeling from DataFrames for now
const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}}
const MaybeNumber = Union{Number, Missing}
const MaybeString = Union{AbstractString, Missing}
const DataPoint = Union{MaybeNumber, MaybeString}
prepareSeriesData(x) = error("Cannot convert $(typeof(x)) to series data for plotting")
prepareSeriesData(::Nothing) = nothing
prepareSeriesData(f::Function) = f
prepareSeriesData(a::AbstractArray{<:MaybeNumber}) = replace!(
x -> ismissing(x) || isinf(x) ? NaN : x,
map(float,a))
prepareSeriesData(a::AbstractArray{<:MaybeString}) = replace(x -> ismissing(x) ? "" : x, a)
prepareSeriesData(s::Surface{<:AMat{<:MaybeNumber}}) = Surface(prepareSeriesData(s.surf))
prepareSeriesData(s::Surface) = s # non-numeric Surface, such as an image
prepareSeriesData(v::Volume) = Volume(prepareSeriesData(v.v), v.x_extents, v.y_extents, v.z_extents)
# default: assume x represents a single series
convertToAnyVector(x, plotattributes) = Any[prepareSeriesData(x)]
# fixed number of blank series
convertToAnyVector(n::Integer, plotattributes) = Any[zeros(0) for i in 1:n]
# vector of data points is a single series
convertToAnyVector(v::AVec{<:DataPoint}, plotattributes) = Any[prepareSeriesData(v)]
# list of things (maybe other vectors, functions, or something else)
function convertToAnyVector(v::AVec, plotattributes)
if all(x -> x isa MaybeNumber, v)
convertToAnyVector(Vector{MaybeNumber}(v), plotattributes)
elseif all(x -> x isa MaybeString, v)
convertToAnyVector(Vector{MaybeString}(v), plotattributes)
else
vcat((convertToAnyVector(vi, plotattributes) for vi in v)...)
end
end
# Matrix is split into columns
function convertToAnyVector(v::AMat{<:DataPoint}, plotattributes)
if all3D(plotattributes)
Any[prepareSeriesData(Surface(v))]
else
Any[prepareSeriesData(v[:, i]) for i in axes(v, 2)]
end
end
# --------------------------------------------------------------------
# Fillranges & ribbons
process_fillrange(range::Number, plotattributes) = [range]
process_fillrange(range, plotattributes) = convertToAnyVector(range, plotattributes)
process_ribbon(ribbon::Number, plotattributes) = [ribbon]
process_ribbon(ribbon, plotattributes) = convertToAnyVector(ribbon, plotattributes)
# ribbon as a tuple: (lower_ribbons, upper_ribbons)
process_ribbon(ribbon::Tuple{Any,Any}, plotattributes) = collect(zip(convertToAnyVector(ribbon[1], plotattributes),
convertToAnyVector(ribbon[2], plotattributes)))
# --------------------------------------------------------------------
# TODO: can we avoid the copy here? one error that crops up is that mapping functions over the same array
# result in that array being shared. push!, etc will add too many items to that array
compute_x(x::Nothing, y::Nothing, z) = axes(z,1)
compute_x(x::Nothing, y, z) = axes(y,1)
compute_x(x::Function, y, z) = map(x, y)
compute_x(x, y, z) = copy(x)
# compute_y(x::Void, y::Function, z) = error()
compute_y(x::Nothing, y::Nothing, z) = axes(z,2)
compute_y(x, y::Function, z) = map(y, x)
compute_y(x, y, z) = copy(y)
compute_z(x, y, z::Function) = map(z, x, y)
compute_z(x, y, z::AbstractMatrix) = Surface(z)
compute_z(x, y, z::Nothing) = nothing
compute_z(x, y, z) = copy(z)
nobigs(v::AVec{BigFloat}) = map(Float64, v)
nobigs(v::AVec{BigInt}) = map(Int64, v)
nobigs(v) = v
@noinline function compute_xyz(x, y, z)
x = compute_x(x,y,z)
y = compute_y(x,y,z)
z = compute_z(x,y,z)
nobigs(x), nobigs(y), nobigs(z)
end
# not allowed
compute_xyz(x::Nothing, y::FuncOrFuncs{F}, z) where {F<:Function} = error("If you want to plot the function `$y`, you need to define the x values!")
compute_xyz(x::Nothing, y::Nothing, z::FuncOrFuncs{F}) where {F<:Function} = error("If you want to plot the function `$z`, you need to define x and y values!")
compute_xyz(x::Nothing, y::Nothing, z::Nothing) = error("x/y/z are all nothing!")
# --------------------------------------------------------------------
# we are going to build recipes to do the processing and splitting of the args
# ensure we dispatch to the slicer
struct SliceIt end
# the catch-all recipes
@recipe function f(::Type{SliceIt}, x, y, z)
# handle data with formatting attached
if typeof(x) <: Formatted
xformatter := x.formatter
x = x.data
end
if typeof(y) <: Formatted
yformatter := y.formatter
y = y.data
end
if typeof(z) <: Formatted
zformatter := z.formatter
z = z.data
end
xs = convertToAnyVector(x, plotattributes)
ys = convertToAnyVector(y, plotattributes)
zs = convertToAnyVector(z, plotattributes)
fr = pop!(plotattributes, :fillrange, nothing)
fillranges = process_fillrange(fr, plotattributes)
mf = length(fillranges)
rib = pop!(plotattributes, :ribbon, nothing)
ribbons = process_ribbon(rib, plotattributes)
mr = length(ribbons)
# @show zs
mx = length(xs)
my = length(ys)
mz = length(zs)
if mx > 0 && my > 0 && mz > 0
for i in 1:max(mx, my, mz)
# add a new series
di = copy(plotattributes)
xi, yi, zi = xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)]
di[:x], di[:y], di[:z] = compute_xyz(xi, yi, zi)
# handle fillrange
fr = fillranges[mod1(i,mf)]
di[:fillrange] = isa(fr, Function) ? map(fr, di[:x]) : fr
# handle ribbons
rib = ribbons[mod1(i,mr)]
di[:ribbon] = isa(rib, Function) ? map(rib, di[:x]) : rib
push!(series_list, RecipeData(di, ()))
end
end
nothing # don't add a series for the main block
end
# this is the default "type recipe"... just pass the object through
@recipe f(::Type{T}, v::T) where {T<:Any} = v
# this should catch unhandled "series recipes" and error with a nice message
@recipe f(::Type{V}, x, y, z) where {V<:Val} = error("The backend must not support the series type $V, and there isn't a series recipe defined.")
_apply_type_recipe(plotattributes, v) = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1]
# Handle type recipes when the recipe is defined on the elements.
# This sort of recipe should return a pair of functions... one to convert to number,
# and one to format tick values.
function _apply_type_recipe(plotattributes, v::AbstractArray)
isempty(skipmissing(v)) && return Float64[]
x = first(skipmissing(v))
args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args
if length(args) == 2 && typeof(args[1]) <: Function && typeof(args[2]) <: Function
numfunc, formatter = args
Formatted(map(numfunc, v), formatter)
else
v
end
end
# # special handling for Surface... need to properly unwrap and re-wrap
# function _apply_type_recipe(plotattributes, v::Surface)
# T = eltype(v.surf)
# @show T
# if T <: Integer || T <: AbstractFloat
# v
# else
# ret = _apply_type_recipe(plotattributes, v.surf)
# if typeof(ret) <: Formatted
# Formatted(Surface(ret.data), ret.formatter)
# else
# v
# end
# end
# end
# don't do anything for ints or floats
_apply_type_recipe(plotattributes, v::AbstractArray{T}) where {T<:Union{Integer,AbstractFloat}} = v
# handle "type recipes" by converting inputs, and then either re-calling or slicing
@recipe function f(x, y, z)
did_replace = false
newx = _apply_type_recipe(plotattributes, x)
x === newx || (did_replace = true)
newy = _apply_type_recipe(plotattributes, y)
y === newy || (did_replace = true)
newz = _apply_type_recipe(plotattributes, z)
z === newz || (did_replace = true)
if did_replace
newx, newy, newz
else
SliceIt, x, y, z
end
end
@recipe function f(x, y)
did_replace = false
newx = _apply_type_recipe(plotattributes, x)
x === newx || (did_replace = true)
newy = _apply_type_recipe(plotattributes, y)
y === newy || (did_replace = true)
if did_replace
newx, newy
else
SliceIt, x, y, nothing
end
end
@recipe function f(y)
newy = _apply_type_recipe(plotattributes, y)
if y !== newy
newy
else
SliceIt, nothing, y, nothing
end
end
# if there's more than 3 inputs, it can't be passed directly to SliceIt
# so we'll apply_type_recipe to all of them
@recipe function f(v1, v2, v3, v4, vrest...)
did_replace = false
newargs = map(v -> begin
newv = _apply_type_recipe(plotattributes, v)
if newv !== v
did_replace = true
end
newv
end, (v1, v2, v3, v4, vrest...))
if !did_replace
error("Couldn't process recipe args: $(map(typeof, (v1, v2, v3, v4, vrest...)))")
end
newargs
end
# # --------------------------------------------------------------------
# # 1 argument
# # --------------------------------------------------------------------
# helper function to ensure relevant attributes are wrapped by Surface
function wrap_surfaces(plotattributes::KW)
if haskey(plotattributes, :fill_z)
v = plotattributes[:fill_z]
if !isa(v, Surface)
plotattributes[:fill_z] = Surface(v)
end
end
end
@recipe f(n::Integer) = is3d(get(plotattributes,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing)
all3D(plotattributes::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image, :plots_heatmap), get(plotattributes, :seriestype, :none))
# return a surface if this is a 3d plot, otherwise let it be sliced up
@recipe function f(mat::AMat{T}) where T<:Union{Integer,AbstractFloat,Missing}
if all3D(plotattributes)
n,m = axes(mat)
wrap_surfaces(plotattributes)
SliceIt, m, n, Surface(mat)
else
SliceIt, nothing, mat, nothing
end
end
# if a matrix is wrapped by Formatted, do similar logic, but wrap data with Surface
@recipe function f(fmt::Formatted{T}) where T<:AbstractMatrix
if all3D(plotattributes)
mat = fmt.data
n,m = axes(mat)
wrap_surfaces(plotattributes)
SliceIt, m, n, Formatted(Surface(mat), fmt.formatter)
else
SliceIt, nothing, fmt, nothing
end
end
# assume this is a Volume, so construct one
@recipe function f(vol::AbstractArray{T,3}, args...) where T<:Union{Number,Missing}
seriestype := :volume
SliceIt, nothing, Volume(vol, args...), nothing
end
# # images - grays
function clamp_greys!(mat::AMat{T}) where T<:Gray
for i in eachindex(mat)
mat[i].val < 0 && (mat[i] = Gray(0))
mat[i].val > 1 && (mat[i] = Gray(1))
end
mat
end
@recipe function f(mat::AMat{T}) where T<:Gray
n, m = axes(mat)
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, m, n, Surface(clamp_greys!(mat))
else
seriestype := :heatmap
yflip --> true
cbar --> false
fillcolor --> ColorGradient([:black, :white])
SliceIt, m, n, Surface(clamp!(convert(Matrix{Float64}, mat), 0., 1.))
end
end
# # images - colors
@recipe function f(mat::AMat{T}) where T<:Colorant
n, m = axes(mat)
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, m, n, Surface(mat)
else
seriestype := :heatmap
yflip --> true
cbar --> false
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, m, n, Surface(z)
end
end
#
# # plotting arbitrary shapes/polygons
@recipe function f(shape::Shape)
seriestype --> :shape
coords(shape)
end
@recipe function f(shapes::AVec{Shape})
seriestype --> :shape
coords(shapes)
end
@recipe function f(shapes::AMat{Shape})
seriestype --> :shape
for j in axes(shapes,2)
@series coords(vec(shapes[:,j]))
end
end
# Dicts: each entry is a data point (x,y)=(key,value)
@recipe f(d::AbstractDict) = collect(keys(d)), collect(values(d))
# function without range... use the current range of the x-axis
@recipe function f(f::FuncOrFuncs{F}) where F<:Function
plt = plotattributes[:plot_object]
xmin, xmax = if haskey(plotattributes, :xlims)
plotattributes[:xlims]
else
try
axis_limits(plt[1], :x)
catch
xinv = invscalefunc(get(plotattributes, :xscale, :identity))
xm = tryrange(f, xinv.([-5,-1,0,0.01]))
xm, tryrange(f, filter(x->x>xm, xinv.([5,1,0.99, 0, -0.01])))
end
end
f, xmin, xmax
end
# try some intervals over which the function may be defined
function tryrange(F::AbstractArray, vec)
rets = [tryrange(f, vec) for f in F] # get the preferred for each
maxind = maximum(indexin(rets, vec)) # get the last attempt that succeeded (most likely to fit all)
rets .= [tryrange(f, vec[maxind:maxind]) for f in F] # ensure that all functions compute there
rets[1]
end
function tryrange(F, vec)
for v in vec
try
tmp = F(v)
return v
catch
end
end
error("$F is not a Function, or is not defined at any of the values $vec")
end
#
# # --------------------------------------------------------------------
# # 2 arguments
# # --------------------------------------------------------------------
#
#
# # if functions come first, just swap the order (not to be confused with parametric functions...
# # as there would be more than one function passed in)
@recipe function f(f::FuncOrFuncs{F}, x) where F<:Function
F2 = typeof(x)
@assert !(F2 <: Function || (F2 <: AbstractArray && F2.parameters[1] <: Function)) # otherwise we'd hit infinite recursion here
x, f
end
#
# # --------------------------------------------------------------------
# # 3 arguments
# # --------------------------------------------------------------------
#
#
# # 3d line or scatter
@recipe function f(x::AVec, y::AVec, z::AVec)
# st = get(plotattributes, :seriestype, :none)
# if st == :scatter
# plotattributes[:seriestype] = :scatter3d
# elseif !is3d(st)
# plotattributes[:seriestype] = :path3d
# end
SliceIt, x, y, z
end
@recipe function f(x::AMat, y::AMat, z::AMat)
# st = get(plotattributes, :seriestype, :none)
# if size(x) == size(y) == size(z)
# if !is3d(st)
# seriestype := :path3d
# end
# end
wrap_surfaces(plotattributes)
SliceIt, x, y, z
end
#
# # surface-like... function
@recipe function f(x::AVec, y::AVec, zf::Function)
# x = X <: Number ? sort(x) : x
# y = Y <: Number ? sort(y) : y
wrap_surfaces(plotattributes)
SliceIt, x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported
end
#
# # surface-like... matrix grid
@recipe function f(x::AVec, y::AVec, z::AMat)
if !like_surface(get(plotattributes, :seriestype, :none))
plotattributes[:seriestype] = :contour
end
wrap_surfaces(plotattributes)
SliceIt, x, y, Surface(z)
end
# # images - grays
@recipe function f(x::AVec, y::AVec, mat::AMat{T}) where T<:Gray
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, x, y, Surface(mat)
else
seriestype := :heatmap
yflip --> true
cbar --> false
fillcolor --> ColorGradient([:black, :white])
SliceIt, x, y, Surface(convert(Matrix{Float64}, mat))
end
end
# # images - colors
@recipe function f(x::AVec, y::AVec, mat::AMat{T}) where T<:Colorant
if is_seriestype_supported(:image)
seriestype := :image
yflip --> true
SliceIt, x, y, Surface(mat)
else
seriestype := :heatmap
yflip --> true
cbar --> false
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, x, y, Surface(z)
end
end
#
#
# # --------------------------------------------------------------------
# # Parametric functions
# # --------------------------------------------------------------------
#
# # special handling... xmin/xmax with parametric function(s)
@recipe function f(f::Function, xmin::Number, xmax::Number)
xscale, yscale = [get(plotattributes, sym, :identity) for sym=(:xscale,:yscale)]
_scaled_adapted_grid(f, xscale, yscale, xmin, xmax)
end
@recipe function f(fs::AbstractArray{F}, xmin::Number, xmax::Number) where F<:Function
xscale, yscale = [get(plotattributes, sym, :identity) for sym=(:xscale,:yscale)]
xs = Array{Any}(undef, length(fs))
ys = Array{Any}(undef, length(fs))
for (i, (x, y)) in enumerate(_scaled_adapted_grid(f, xscale, yscale, xmin, xmax) for f in fs)
xs[i] = x
ys[i] = y
end
xs, ys
end
@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, u::AVec) where {F<:Function,G<:Function} = mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u)
@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, umin::Number, umax::Number, n = 200) where {F<:Function,G<:Function} = fx, fy, range(umin, stop = umax, length = n)
function _scaled_adapted_grid(f, xscale, yscale, xmin, xmax)
(xf, xinv), (yf, yinv) = ((scalefunc(s),invscalefunc(s)) for s in (xscale,yscale))
xs, ys = adapted_grid(yf∘f∘xinv, xf.((xmin, xmax)))
xinv.(xs), yinv.(ys)
end
#
# # special handling... 3D parametric function(s)
@recipe function f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, u::AVec) where {F<:Function,G<:Function,H<:Function}
mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u)
end
@recipe function f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, umin::Number, umax::Number, numPoints = 200) where {F<:Function,G<:Function,H<:Function}
fx, fy, fz, range(umin, stop = umax, length = numPoints)
end
#
#
# # --------------------------------------------------------------------
# # Lists of tuples and GeometryTypes.Points
# # --------------------------------------------------------------------
#
@recipe f(v::AVec{<:Tuple}) = unzip(v)
@recipe f(v::AVec{<:GeometryTypes.Point}) = unzip(v)
@recipe f(tup::Tuple) = [tup]
@recipe f(p::GeometryTypes.Point) = [p]
# Special case for 4-tuples in :ohlc series
@recipe f(xyuv::AVec{<:Tuple{R1,R2,R3,R4}}) where {R1,R2,R3,R4} = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv)
#
# # --------------------------------------------------------------------
# # handle grouping
# # --------------------------------------------------------------------
# @recipe function f(groupby::GroupBy, args...)
# for (i,glab) in enumerate(groupby.groupLabels)
# # create a new series, with the label of the group, and an idxfilter (to be applied in slice_and_dice)
# # TODO: use @series instead
# @show i, glab, groupby.groupIds[i]
# di = copy(plotattributes)
# get!(di, :label, string(glab))
# get!(di, :idxfilter, groupby.groupIds[i])
# push!(series_list, RecipeData(di, args))
# end
# nothing
# end
splittable_kw(key, val, lengthGroup) = false
splittable_kw(key, val::AbstractArray, lengthGroup) = !(key in (:group, :color_palette)) && length(axes(val,1)) == lengthGroup
splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengthGroup))
splittable_kw(key, val::SeriesAnnotations, lengthGroup) = splittable_kw(key, val.strs, lengthGroup)
split_kw(key, val::AbstractArray, indices) = val[indices, fill(Colon(), ndims(val)-1)...]
split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in val)
function split_kw(key, val::SeriesAnnotations, indices)
split_strs = split_kw(key, val.strs, indices)
return SeriesAnnotations(split_strs, val.font, val.baseshape, val.scalefactor)
end
function groupedvec2mat(x_ind, x, y::AbstractArray, groupby, def_val = y[1])
y_mat = Array{promote_type(eltype(y), typeof(def_val))}(undef, length(keys(x_ind)), length(groupby.groupLabels))
fill!(y_mat, def_val)
for i in eachindex(groupby.groupLabels)
xi = x[groupby.groupIds[i]]
yi = y[groupby.groupIds[i]]
y_mat[getindex.(Ref(x_ind), xi), i] = yi
end
return y_mat
end
groupedvec2mat(x_ind, x, y::Tuple, groupby) = Tuple(groupedvec2mat(x_ind, x, v, groupby) for v in y)
group_as_matrix(t) = false
# split the group into 1 series per group, and set the label and idxfilter for each
@recipe function f(groupby::GroupBy, args...)
lengthGroup = maximum(union(groupby.groupIds...))
if !(group_as_matrix(args[1]))
for (i,glab) in enumerate(groupby.groupLabels)
@series begin
label --> string(glab)
idxfilter --> groupby.groupIds[i]
for (key,val) in plotattributes
if splittable_kw(key, val, lengthGroup)
:($key) := split_kw(key, val, groupby.groupIds[i])
end
end
args
end
end
else
g = args[1]
if length(g.args) == 1
x = zeros(Int, lengthGroup)
for indexes in groupby.groupIds
x[indexes] = eachindex(indexes)
end
last_args = g.args
else
x = g.args[1]
last_args = g.args[2:end]
end
x_u = unique(sort(x))
x_ind = Dict(zip(x_u, eachindex(x_u)))
for (key,val) in plotattributes
if splittable_kw(key, val, lengthGroup)
:($key) := groupedvec2mat(x_ind, x, val, groupby)
end
end
label --> reshape(groupby.groupLabels, 1, :)
typeof(g)((x_u, (groupedvec2mat(x_ind, x, arg, groupby, NaN) for arg in last_args)...))
end
end
+14 -40
View File
@@ -1,5 +1,3 @@
@nospecialize
"""
scatter(x,y)
scatter!(x,y)
@@ -71,7 +69,7 @@ Make a histogram bar plot. See `histogram`.
"""
stephist(x)
stephist!(x)
stephist(x)
Make a histogram step plot (bin counts are represented using horizontal lines
instead of bars). See `histogram`.
@@ -253,7 +251,7 @@ Draw contour lines of the `Surface` z.
# Example
```julia-repl
julia> x = y = range(-20, stop = 20, length = 100)
julia> x = y = range(-20, 20, length = 100)
julia> contour(x, y, (x, y) -> x^2 + y^2)
```
"""
@@ -273,8 +271,7 @@ Draw a 3D surface plot.
# Example
```julia-repl
julia> using LinearAlgebra
julia> x = y = range(-3, stop = 3, length = 100)
julia> x = y = range(-3, 3, length = 100)
julia> surface(x, y, (x, y) -> sinc(norm([x, y])))
```
"""
@@ -320,27 +317,6 @@ julia> scatter3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
"""
@shorthands scatter3d
"""
mesh3d(x,y,z)
mesh3d(x,y,z; connections)
Plot a 3d mesh. On Plotly the triangles can be specified using the connections argument.
# Example
```Julia
x=[0, 1, 2, 0]
y=[0, 0, 1, 2]
z=[0, 2, 0, 1]
i=[0, 0, 0, 1]
j=[1, 2, 3, 2]
k=[2, 3, 1, 3]
plot(x,y,z,seriestype=:mesh3d;connections=(i,j,k))
```
"""
@shorthands mesh3d
"""
boxplot(x, y)
boxplot!(x, y)
@@ -404,7 +380,8 @@ julia> curves([1,2,3,4],[1,1,2,4])
@shorthands curves
"Plot a pie diagram"
@shorthands pie
pie(args...; kw...) = plot(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
pie!(args...; kw...) = plot!(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
"Plot with seriestype :path3d"
plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d)
@@ -420,13 +397,13 @@ xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...)
ylabel!(s::AbstractString; kw...) = plot!(; ylabel = s, kw...)
"Set xlims for an existing plot"
xlims!(lims::Tuple; kw...) = plot!(; xlims = lims, kw...)
xlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; xlims = lims, kw...)
"Set ylims for an existing plot"
ylims!(lims::Tuple; kw...) = plot!(; ylims = lims, kw...)
ylims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; ylims = lims, kw...)
"Set zlims for an existing plot"
zlims!(lims::Tuple; kw...) = plot!(; zlims = lims, kw...)
zlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; zlims = lims, kw...)
xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin,xmax), kw...)
ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...)
@@ -434,10 +411,10 @@ zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmi
"Set xticks for an existing plot"
xticks!(v::TicksArgs; kw...) = plot!(; xticks = v, kw...)
xticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; xticks = v, kw...)
"Set yticks for an existing plot"
yticks!(v::TicksArgs; kw...) = plot!(; yticks = v, kw...)
yticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; yticks = v, kw...)
xticks!(
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...)
@@ -451,8 +428,8 @@ Add annotations to an existing plot.
# Arguments
- `anns`: An `AbstractVector` of tuples of the form `(x,y,text)`. The `text` object
can be a `String` or `PlotText`.
- `anns`: An `AbstractVector` of tuples of the form (x,y,text). The text object
can be an String or PlotText
# Example
```julia-repl
@@ -460,9 +437,8 @@ julia> plot(1:10)
julia> annotate!([(7,3,"(7,3)"),(3,7,text("hey", 14, :left, :top, :green))])
```
"""
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
annotate!(anns::Tuple...; kw...) = plot!(; annotation = collect(anns), kw...)
annotate!(anns::AVec{<:Tuple}; kw...) = plot!(; annotation = anns, kw...)
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
annotate!(anns::AVec{T}; kw...) where {T<:Tuple} = plot!(; annotation = anns, kw...)
"Flip the current plots' x axis"
xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...)
@@ -477,5 +453,3 @@ xaxis!(args...; kw...) = plot!(; xaxis = args
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
ygrid!(args...; kw...) = plot!(; ygrid = args, kw...)
@specialize
+7 -19
View File
@@ -7,7 +7,7 @@ function Subplot(::T; parent = RootLayout()) where T<:AbstractBackend
(20mm, 5mm, 2mm, 10mm),
defaultbox,
defaultbox,
DefaultsDict(KW(), _subplot_defaults),
KW(),
nothing,
nothing
)
@@ -42,24 +42,12 @@ get_subplot_index(plt::Plot, sp::Subplot) = findfirst(x -> x === sp, plt.subplot
series_list(sp::Subplot) = sp.series_list # filter(series -> series.plotattributes[:subplot] === sp, sp.plt.series_list)
function should_add_to_legend(series::Series)
series.plotattributes[:primary] &&
series.plotattributes[:label] != "" &&
!(
series.plotattributes[:seriestype] in (
:hexbin,
:bins2d,
:histogram2d,
:hline,
:vline,
:contour,
:contourf,
:contour3d,
:surface,
:wireframe,
:heatmap,
:image,
)
)
series.plotattributes[:primary] && series.plotattributes[:label] != "" &&
!(series.plotattributes[:seriestype] in (
:hexbin,:bins2d,:histogram2d,:hline,:vline,
:contour,:contourf,:contour3d,:surface,:wireframe,
:heatmap, :pie, :image
))
end
# ----------------------------------------------------------------------
+23 -16
View File
@@ -4,25 +4,35 @@
Specify the colour theme for plots.
"""
function theme(s::Symbol; kw...)
defaults = copy(PlotThemes._themes[s].defaults)
defaults = PlotThemes._themes[s].defaults
_theme(s, defaults; kw...)
end
function _theme(s::Symbol, defaults::AKW; kw...)
function _theme(s::Symbol, defaults::KW; kw...)
# Reset to defaults to overwrite active theme
reset_defaults()
# Set the theme's gradient as default
if haskey(defaults, :colorgradient)
PlotUtils.default_cgrad(pop!(defaults, :colorgradient))
PlotUtils.clibrary(:misc)
PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s))
pop!(defaults, :colorgradient)
else
PlotUtils.default_cgrad(:default)
PlotUtils.clibrary(:Plots)
PlotUtils.default_cgrad(default = :sequential, sequential = :inferno)
end
# maybe overwrite the theme's gradient
kw = KW(kw)
if haskey(kw, :colorgradient)
PlotUtils.default_cgrad(pop!(kw, :colorgradient))
kwgrad = pop!(kw, :colorgradient)
for clib in clibraries()
if kwgrad in cgradients(clib)
PlotUtils.clibrary(clib)
PlotUtils.default_cgrad(default = :sequential, sequential = kwgrad)
break
end
end
end
# Set the theme's defaults
@@ -47,12 +57,12 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
defaults = PlotThemes._themes[thm].defaults
# get the gradient
gradient_colors = color_list(cgrad(get(defaults, :colorgradient, :default)))
gradient_colors = get(defaults, :colorgradient, cgrad(:inferno).colors)
colorgradient = cgrad(cfunc.(RGB.(gradient_colors)))
# get the palette
cp = color_list(palette(get(defaults, :palette, :default)))
cp = cfunc.(RGB.(cp))
palette = get(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17))
palette = cfunc.(RGB.(palette))
# apply the theme
for k in keys(defaults)
@@ -79,7 +89,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
for j in 1:4
@series begin
subplot := 1
color_palette := cp
palette := palette
seriestype := :path
cumsum(randn(50))
end
@@ -87,7 +97,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
@series begin
subplot := 2
seriestype := :scatter
color_palette := cp
palette := palette
marker := (:circle, :diamond, :star5, :square)[j]
randn(10), randn(10)
end
@@ -96,7 +106,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
@series begin
subplot := 3
seriestype := :histogram
color_palette := cp
palette := palette
randn(1000) .+ (0:2:4)'
end
@@ -110,8 +120,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
subplot := 4
seriestype := :heatmap
seriescolor := colorgradient
xticks := (-2π:2π:2π, string.(-2:2:2, "π"))
yticks := (-2π:2π:2π, string.(-2:2:2, "π"))
ticks := -5:5:5
x, y, z
end
@@ -119,14 +128,12 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
subplot := 5
seriestype := :surface
seriescolor := colorgradient
xticks := (-2π:2π:2π, string.(-2:2:2, "π"))
yticks := (-2π:2π:2π, string.(-2:2:2, "π"))
x, y, z
end
n = 100
ts = range(0, stop = 10π, length = n)
x = (0.1ts) .* cos.(ts)
x = ts .* cos.(ts)
y = (0.1ts) .* sin.(ts)
z = 1:n
+7 -6
View File
@@ -5,7 +5,6 @@
const AVec = AbstractVector
const AMat = AbstractMatrix
const KW = Dict{Symbol,Any}
const AKW = AbstractDict{Symbol,Any}
const TicksArgs = Union{AVec{T}, Tuple{AVec{T}, AVec{S}}, Symbol} where {T<:Real, S<:AbstractString}
struct PlotsDisplay <: AbstractDisplay end
@@ -18,10 +17,11 @@ end
wrap(obj::T) where {T} = InputWrapper{T}(obj)
Base.isempty(wrapper::InputWrapper) = false
# -----------------------------------------------------------
mutable struct Series
plotattributes::DefaultsDict
plotattributes::KW
end
attr(series::Series, k::Symbol) = series.plotattributes[k]
@@ -36,7 +36,7 @@ mutable struct Subplot{T<:AbstractBackend} <: AbstractLayout
minpad::Tuple # leftpad, toppad, rightpad, bottompad
bbox::BoundingBox # the canvas area which is available to this subplot
plotarea::BoundingBox # the part where the data goes
attr::DefaultsDict # args specific to this subplot
attr::KW # args specific to this subplot
o # can store backend-specific data... like a pyplot ax
plt # the enclosing Plot object (can't give it a type because of no forward declarations)
end
@@ -48,7 +48,7 @@ Base.show(io::IO, sp::Subplot) = print(io, "Subplot{$(sp[:subplot_index])}")
# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
mutable struct Axis
sps::Vector{Subplot}
plotattributes::DefaultsDict
plotattributes::KW
end
mutable struct Extrema
@@ -67,7 +67,8 @@ const SubplotMap = Dict{Any, Subplot}
mutable struct Plot{T<:AbstractBackend} <: AbstractPlot{T}
backend::T # the backend type
n::Int # number of series
attr::DefaultsDict # arguments for the whole plot
attr::KW # arguments for the whole plot
user_attr::KW # raw arg inputs (after aliases). these are used as the input dict in `_plot!`
series_list::Vector{Series} # arguments for each series
o # the backend's plot object
subplots::Vector{Subplot}
@@ -78,7 +79,7 @@ mutable struct Plot{T<:AbstractBackend} <: AbstractPlot{T}
end
function Plot()
Plot(backend(), 0, DefaultsDict(KW(), _plot_defaults), Series[], nothing,
Plot(backend(), 0, KW(), KW(), Series[], nothing,
Subplot[], SubplotMap(), EmptyLayout(),
Subplot[], false)
end
+429 -367
View File
File diff suppressed because it is too large Load Diff
+16 -41
View File
@@ -1,36 +1,15 @@
import Plots._current_plots_version
# replace `f(args...)` with `f(rng, args...)` for `f ∈ (rand, randn)`
function replace_rand!(ex) end
function replace_rand!(ex::Expr)
for arg in ex.args
replace_rand!(arg)
end
if ex.head === :call && ex.args[1] (:rand, :randn)
pushfirst!(ex.args, ex.args[1])
ex.args[2] = :rng
end
end
function fix_rand!(ex)
replace_rand!(ex)
pushfirst!(ex.args[1].args, :(rng = StableRNG(1234)))
end
function image_comparison_tests(
pkg::Symbol,
idx::Int;
debug = false,
popup = !is_ci(),
sigma = [1, 1],
tol = 1e-2,
)
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = !is_ci(), sigma = [1,1], tol = 1e-2)
Plots._debugMode.on = debug
example = Plots._examples[idx]
Plots.theme(:default)
@info("Testing plot: $pkg:$idx:$(example.header)")
backend(pkg)
backend()
default(size = (500, 300))
default(size=(500,300))
# ensure consistent results
Random.seed!(1234)
fn = "ref$idx.png"
reffn = reference_file(pkg, idx, _current_plots_version)
@@ -40,29 +19,25 @@ function image_comparison_tests(
func = (fn, idx) -> begin
expr = Expr(:block)
append!(expr.args, example.exprs)
fix_rand!(expr)
eval(expr)
png(fn)
end
# the test
vtest = VisualTest(func, reffn, idx)
test_images(vtest, popup = popup, sigma = sigma, tol = tol, newfn = newfn)
test_images(vtest, popup=popup, sigma=sigma, tol=tol, newfn = newfn)
end
function image_comparison_facts(
pkg::Symbol;
skip = [], # skip these examples (int index)
only = nothing, # limit to these examples (int index)
debug = false, # print debug information?
sigma = [1, 1], # number of pixels to "blur"
tol = 1e-2,
) # acceptable error (percent)
for i = 1:length(Plots._examples)
i in skip && continue
if only === nothing || i in only
@test image_comparison_tests(pkg, i, debug = debug, sigma = sigma, tol = tol) |>
success == true
end
function image_comparison_facts(pkg::Symbol;
skip = [], # skip these examples (int index)
only = nothing, # limit to these examples (int index)
debug = false, # print debug information?
sigma = [1,1], # number of pixels to "blur"
tol = 1e-2) # acceptable error (percent)
for i in 1:length(Plots._examples)
i in skip && continue
if only === nothing || i in only
@test image_comparison_tests(pkg, i, debug=debug, sigma=sigma, tol=tol) |> success == true
end
end
end
-60
View File
@@ -1,60 +0,0 @@
using Plots, Test, Dates
@testset "Limits" begin
y=[1.0*i*i for i in 1:10]
x=[Date(2019,11,i) for i in 1:10]
rx=[x[3],x[5]]
p = plot(x,y, widen = false)
vspan!(p, rx, label="", alpha=0.2)
ref_ylims = (y[1], y[end])
ref_xlims = (x[1].instant.periods.value, x[end].instant.periods.value)
@test Plots.ylims(p) == ref_ylims
@test Plots.xlims(p) == ref_xlims
#@static if (haskey(ENV, "APPVEYOR") || haskey(ENV, "CI"))
@static if haskey(ENV, "APPVEYOR")
@info "Skipping display tests on AppVeyor"
else
@test isa(display(p), Nothing) == true
closeall()
end
end # testset
@testset "Date xlims" begin
y=[1.0*i*i for i in 1:10]
x=[Date(2019,11,i) for i in 1:10]
span = (Date(2019,10,31), Date(2019,11,11))
ref_xlims = map(date->date.instant.periods.value, span)
p = plot(x,y, xlims=span, widen = false)
@test Plots.xlims(p) == ref_xlims
#@static if (haskey(ENV, "APPVEYOR") || haskey(ENV, "CI"))
@static if haskey(ENV, "APPVEYOR")
@info "Skipping display tests on AppVeyor"
else
@test isa(display(p), Nothing) == true
closeall()
end
end # testset
@testset "DateTime xlims" begin
y=[1.0*i*i for i in 1:10]
x=[DateTime(2019,11,i,11) for i in 1:10]
span = (DateTime(2019,10,31,11,59,59), DateTime(2019,11,11,12,01,15))
ref_xlims = map(date->date.instant.periods.value, span)
p = plot(x,y, xlims=span, widen = false)
@test Plots.xlims(p) == ref_xlims
#@static if (haskey(ENV, "APPVEYOR") || haskey(ENV, "CI"))
@static if haskey(ENV, "APPVEYOR")
@info "Skipping display tests on AppVeyor"
else
@test isa(display(p), Nothing) == true
closeall()
end
end # testset
+5 -80
View File
@@ -2,40 +2,12 @@ import ImageMagick
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 GeometryTypes
@testset "Plotly standalone" begin
@test_nowarn Plots._init_ijulia_plotting()
@test Plots.plotly_local_file_path[] === nothing
temp = Plots.use_local_dependencies[]
withenv("PLOTS_HOST_DEPENDENCY_LOCAL" => true) do
Plots.__init__()
@test Plots.plotly_local_file_path[] isa String
@test isfile(Plots.plotly_local_file_path[])
@test Plots.use_local_dependencies[] = true
@test_nowarn Plots._init_ijulia_plotting()
end
Plots.plotly_local_file_path[] = nothing
Plots.use_local_dependencies[] = temp
end # testset
include("test_defaults.jl")
include("test_axes.jl")
include("test_axis_letter.jl")
include("test_components.jl")
include("test_shorthands.jl")
include("integration_dates.jl")
include("test_recipes.jl")
include("test_hdf5plots.jl")
include("test_pgfplotsx.jl")
reference_dir(args...) = joinpath(homedir(), ".julia", "dev", "PlotReferenceImages", args...)
@@ -69,32 +41,7 @@ include("imgcomp.jl")
Random.seed!(1234)
default(show=false, reuse=true)
is_ci() = get(ENV, "CI", "false") == "true"
const IMG_TOL = VERSION < v"1.4" && Sys.iswindows() ? 1e-1 : is_ci() ? 1e-2 : 1e-3
## Uncomment the following lines to update reference images for different backends
# @testset "GR" begin
# image_comparison_facts(:gr, tol=IMG_TOL, skip = Plots._backend_skips[:gr])
# end
#
# plotly()
# @testset "Plotly" begin
# image_comparison_facts(:plotly, tol=IMG_TOL, skip = Plots._backend_skips[:plotlyjs])
# end
#
# pyplot()
# @testset "PyPlot" begin
# image_comparison_facts(:pyplot, tol=IMG_TOL, skip = Plots._backend_skips[:pyplot])
# end
#
# pgfplotsx()
# @testset "PGFPlotsX" begin
# image_comparison_facts(:pgfplotsx, tol=IMG_TOL, skip = Plots._backend_skips[:pgfplotsx])
# end
# 10 Histogram2D
##
img_tol = is_ci() ? 10e-2 : 10e-2
@testset "Backends" begin
@@ -104,10 +51,8 @@ const IMG_TOL = VERSION < v"1.4" && Sys.iswindows() ? 1e-1 : is_ci() ? 1e-2 : 1e
@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=IMG_TOL, skip = Plots._backend_skips[:gr])
@static if Sys.islinux()
image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
end
end
@@ -122,21 +67,6 @@ const IMG_TOL = VERSION < v"1.4" && Sys.iswindows() ? 1e-1 : is_ci() ? 1e-2 : 1e
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
end
@@ -202,11 +132,6 @@ end
[(missing,missing)], [(missing,missing,missing),("a","b","c")])
for z in zipped
@test isequal(collect(zip(Plots.unzip(z)...)), z)
@test isequal(collect(zip(Plots.unzip(GeometryBasics.Point.(z))...)), z)
@test isequal(collect(zip(Plots.unzip(GeometryTypes.Point.(z))...)), z)
end
op1 = Plots.process_clims((1.0, 2.0))
op2 = Plots.process_clims((1, 2.0))
data = randn(100, 100)
@test op1(data) == op2(data)
@test Plots.process_clims(nothing) == Plots.process_clims(missing) == Plots.process_clims(:auto)
end
-23
View File
@@ -1,23 +0,0 @@
using Plots, Test
@testset "Showaxis" begin
for value in Plots._allShowaxisArgs
@test plot(1:5, showaxis = value)[1][:yaxis][:showaxis] isa Bool
end
@test plot(1:5, showaxis = :y)[1][:yaxis][:showaxis] == true
@test plot(1:5, showaxis = :y)[1][:xaxis][:showaxis] == false
end
@testset "Magic axis" begin
@test plot(1, axis=nothing)[1][:xaxis][:ticks] == []
@test plot(1, axis=nothing)[1][:yaxis][:ticks] == []
end # testset
@testset "Categorical ticks" begin
p1 = plot('A':'M', 1:13)
p2 = plot('A':'Z', 1:26)
p3 = plot('A':'Z', 1:26, ticks = :all)
@test Plots.get_ticks(p1[1], p1[1][:xaxis])[2] == string.('A':'M')
@test Plots.get_ticks(p2[1], p2[1][:xaxis])[2] == string.('C':3:'Z')
@test Plots.get_ticks(p3[1], p3[1][:xaxis])[2] == string.('A':'Z')
end
-25
View File
@@ -1,25 +0,0 @@
using Plots, Test
@testset "axis letter" begin
using Plots, RecipesBase
# a custom type for dispacthing the axis-letter-testing recipe
struct MyType <: Number
val::Float64
end
value(m::MyType) = m.val
data = MyType.(sort(randn(20)))
# A recipe that puts the axis letter in the title
@recipe function f(::Type{T}, m::T) where T <: AbstractArray{<:MyType}
title --> string(plotattributes[:letter])
value.(m)
end
@testset "$f (orientation = $o)" for f in [histogram, barhist, stephist, scatterhist], o in [:vertical, :horizontal]
@test f(data, orientation=o).subplots[1].attr[:title] == (o == :vertical ? "x" : "y")
end
@testset "$f" for f in [hline, hspan]
@test f(data).subplots[1].attr[:title] == "y"
end
@testset "$f" for f in [vline, vspan]
@test f(data).subplots[1].attr[:title] == "x"
end
end
-111
View File
@@ -1,111 +0,0 @@
using Plots, Test
@testset "Shapes" begin
@testset "Copy" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
square2 = Shape(square)
@test square2.x == square.x
@test square2.y == square.y
end
@testset "Center" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
@test Plots.center(square) == (0.5,0.5)
end
@testset "Translate" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
squareUp = Shape([(0,1),(1,1),(1,2),(0,2)])
squareUpRight = Shape([(1,1),(2,1),(2,2),(1,2)])
@test Plots.translate(square,0,1).x == squareUp.x
@test Plots.translate(square,0,1).y == squareUp.y
@test Plots.center(translate!(square,1)) == (1.5,1.5)
end
@testset "Rotate" begin
# 2 radians rotation matrix
R2 = [cos(2) sin(2); -sin(2) cos(2)]
coords = [0 0; 1 0; 1 1; 0 1]'
coordsRotated2 = R2*(coords.-0.5).+0.5
square = Shape([(0,0),(1,0),(1,1),(0,1)])
# make a new, rotated square
square2 = Plots.rotate(square, -2)
@test square2.x coordsRotated2[1,:]
@test square2.y coordsRotated2[2,:]
# unrotate the new square in place
rotate!(square2, 2)
@test square2.x coords[1,:]
@test square2.y coords[2,:]
end
end
@testset "Brush" begin
@testset "Colors" begin
baseline = brush(1, RGB(0,0,0))
@test brush(:black) == baseline
@test brush("black") == baseline
end
@testset "Weight" begin
@test brush(10).size == 10
@test brush(0.1).size == 1
end
@testset "Alpha" begin
@test brush(0.4).alpha == 0.4
@test brush(20).alpha == nothing
end
@testset "Bad Argument" begin
# using test_logs because test_warn seems to not work anymore
@test_logs (:warn,"Unused brush arg: nothing (Nothing)") begin
brush(nothing)
end
end
end
@testset "Fonts" begin
@testset "Scaling" begin
sizesToCheck = [:titlefontsize, :legendfontsize, :legendtitlefontsize,
:xtickfontsize, :ytickfontsize, :ztickfontsize,
:xguidefontsize, :yguidefontsize, :zguidefontsize,]
# get inital font sizes
initialSizes = [Plots.default(s) for s in sizesToCheck ]
#scale up font sizes
scalefontsizes(2)
# get inital font sizes
doubledSizes = [Plots.default(s) for s in sizesToCheck ]
@test doubledSizes == initialSizes*2
# reset font sizes
resetfontsizes()
finalSizes = [Plots.default(s) for s in sizesToCheck ]
@test finalSizes == initialSizes
end
end
@testset "Series Annotations" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
@test_logs (:warn,"Unused SeriesAnnotations arg: triangle (Symbol)") begin
p = plot([1,2,3],
series_annotations=(["a"],
2, # pass a scale factor
(1,4), # pass two scale factors (overwrites first one)
square, # pass a shape
font(:courier), # pass an annotation font
:triangle # pass an incorrect argument
))
sa = p.series_list[1].plotattributes[:series_annotations]
@test sa.strs == ["a"]
@test sa.font.family == "courier"
@test sa.baseshape == square
@test sa.scalefactor == (1,4)
end
end
-11
View File
@@ -1,11 +0,0 @@
using Plots, Test
const PLOTS_DEFAULTS = Dict(:theme => :wong2)
Plots.__init__()
@testset "Loading theme" begin
@test plot(1:5)[1][1][:seriescolor] == RGBA(colorant"black")
end
empty!(PLOTS_DEFAULTS)
Plots.__init__()
-21
View File
@@ -1,21 +0,0 @@
using Plots, HDF5
@testset "HDF5_Plots" begin
fname = "tmpplotsave.hdf5"
hdf5()
x = 1:10
psrc=plot(x, x.*x); #Create some plot
Plots.hdf5plot_write(psrc, fname)
#Read back file:
gr() #Choose some fast backend likely to work in test environment.
pread = Plots.hdf5plot_read(fname)
#Make sure data made it through:
@test psrc.subplots[1].series_list[1][:x] == pread.subplots[1].series_list[1][:x]
@test psrc.subplots[1].series_list[1][:y] == pread.subplots[1].series_list[1][:y]
#display(pread) #Don't display. Regression env might not support
end #testset
+124 -399
View File
@@ -1,411 +1,136 @@
using Plots, Test
pgfplotsx()
function create_plot(args...; kwargs...)
pgfx_plot = plot(args...; kwargs...)
return pgfx_plot, repr("application/x-tex", pgfx_plot)
function create_plot( args...; kwargs... )
pgfx_plot = plot(args...; kwargs...)
return pgfx_plot, repr("application/x-tex", pgfx_plot)
end
function create_plot!(args...; kwargs...)
pgfx_plot = plot!(args...; kwargs...)
return pgfx_plot, repr("application/x-tex", pgfx_plot)
function create_plot!( args...; kwargs... )
pgfx_plot = plot!(args...; kwargs...)
return pgfx_plot, repr("application/x-tex", pgfx_plot)
end
@testset "PGFPlotsX" begin
pgfx_plot = plot(1:5)
Plots._update_plot_object(pgfx_plot)
@test pgfx_plot.o.the_plot isa PGFPlotsX.TikzDocument
@test pgfx_plot.series_list[1].plotattributes[:quiver] === nothing
axis = Plots.pgfx_axes(pgfx_plot.o)[1]
@test count(x -> x isa PGFPlotsX.Plot, axis.contents) == 1
@test !haskey(axis.contents[1].options.dict, "fill")
pgfx_plot = plot(1:5)
Plots._update_plot_object(pgfx_plot)
@test pgfx_plot.o.the_plot isa PGFPlotsX.TikzDocument
@test pgfx_plot.series_list[1].plotattributes[:quiver] === nothing
@testset "Legends" begin
legends_plot = plot(rand(5, 2), lab = ["1" ""])
scatter!(legends_plot, rand(5))
Plots._update_plot_object(legends_plot)
axis_contents = Plots.pgfx_axes(legends_plot.o)[1].contents
leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents)
series = filter(x -> x isa PGFPlotsX.Plot, axis_contents)
@test length(leg_entries) == 2
@test !haskey(series[1].options.dict, "forget plot")
@test haskey(series[2].options.dict, "forget plot")
@test !haskey(series[3].options.dict, "forget plot")
end # testset
@testset "3D docs example" begin
n = 100
ts = range(0, stop=8π, length=n)
x = ts .* map(cos, ts)
y = (0.1ts) .* map(sin, ts)
z = 1:n
pl = plot(x, y, z, zcolor=reverse(z), m=(10, 0.8, :blues, Plots.stroke(0)), leg=false, cbar=true, w=5)
pgfx_plot = plot!(pl, zeros(n), zeros(n), 1:n, w=10)
Plots._update_plot_object(pgfx_plot)
if @test_nowarn(haskey(Plots.pgfx_axes(pgfx_plot.o)[1].options.dict, "colorbar") == true)
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colorbar"] === nothing
end
end # testset
@testset "Color docs example" begin
y = rand(100)
plot(0:10:100, rand(11, 4), lab="lines", w=3, palette=:grays, fill=0, α=0.6)
pl = scatter!(y, zcolor=abs.(y .- 0.5), m=(:heat, 0.8, Plots.stroke(1, :green)), ms=10 * abs.(y .- 0.5) .+ 4, lab="grad")
Plots._update_plot_object(pl)
axis = Plots.pgfx_axes(pl.o)[1]
@test count( x->x isa PGFPlotsX.LegendEntry, axis.contents ) == 5
@test count( x->x isa PGFPlotsX.Plot, axis.contents ) == 108 # each marker is its own plot, fillranges create 2 plot-objects
marker = axis.contents[15]
@test marker isa PGFPlotsX.Plot
@test marker.options["mark"] == "*"
@test marker.options["mark options"]["color"] == RGBA{Float64}( colorant"green", 0.8)
@test marker.options["mark options"]["line width"] == 1
end # testset
@testset "Plot in pieces" begin
plot(rand(100) / 3, reg=true, fill=(0, :green))
scatter!(rand(100), markersize=6, c=:orange)
end # testset
@testset "Marker types" begin
markers = filter((m->begin
m in Plots.supported_markers()
end), Plots._shape_keys)
markers = reshape(markers, 1, length(markers))
n = length(markers)
x = (range(0, stop=10, length=n + 2))[2:end - 1]
y = repeat(reshape(reverse(x), 1, :), n, 1)
scatter(x, y, m=(8, :auto), lab=map(string, markers), bg=:linen, xlim=(0, 10), ylim=(0, 10))
end # testset
@testset "Layout" begin
plot(Plots.fakedata(100, 10), layout=4, palette=[:grays :blues :heat :lightrainbow], bg_inside=[:orange :pink :darkblue :black])
end # testset
@testset "Polar plots" begin
Θ = range(0, stop=1.5π, length=100)
r = abs.(0.1 * randn(100) + sin.(3Θ))
plot(Θ, r, proj=:polar, m=2)
end # testset
@testset "Drawing shapes" begin
verts = [(-1.0, 1.0), (-1.28, 0.6), (-0.2, -1.4), (0.2, -1.4), (1.28, 0.6), (1.0, 1.0), (-1.0, 1.0), (-0.2, -0.6), (0.0, -0.2), (-0.4, 0.6), (1.28, 0.6), (0.2, -1.4), (-0.2, -1.4), (0.6, 0.2), (-0.2, 0.2), (0.0, -0.2), (0.2, 0.2), (-0.2, -0.6)]
x = 0.1:0.2:0.9
y = 0.7 * rand(5) .+ 0.15
plot(x, y, line=(3, :dash, :lightblue), marker=(Shape(verts), 30, RGBA(0, 0, 0, 0.2)), bg=:pink, fg=:darkblue, xlim=(0, 1), ylim=(0, 1), leg=false)
end # testset
@testset "Histogram 2D" begin
histogram2d(randn(10000), randn(10000), nbins=20)
end # testset
@testset "Heatmap-like" begin
xs = [string("x", i) for i = 1:10]
ys = [string("y", i) for i = 1:4]
z = float((1:4) * reshape(1:10, 1, :))
pgfx_plot = heatmap(xs, ys, z, aspect_ratio=1)
Plots._update_plot_object(pgfx_plot)
if @test_nowarn(haskey(Plots.pgfx_axes(pgfx_plot.o)[1].options.dict, "colorbar") == true)
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colorbar"] === nothing
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colormap name"] == "plots1"
end
@testset "3D docs example" begin
n = 100
ts = range(0, stop = 8π, length = n)
x = ts .* map(cos, ts)
y = (0.1ts) .* map(sin, ts)
z = 1:n
pl = plot(
x,
y,
z,
zcolor = reverse(z),
m = (10, 0.8, :blues, Plots.stroke(0)),
leg = false,
cbar = true,
w = 5,
)
pgfx_plot = plot!(pl, zeros(n), zeros(n), 1:n, w = 10)
Plots._update_plot_object(pgfx_plot)
if @test_nowarn(
haskey(Plots.pgfx_axes(pgfx_plot.o)[1].options.dict, "colorbar") == true
)
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colorbar"] === nothing
end
end # testset
@testset "Color docs example" begin
y = rand(100)
plot(
0:10:100,
rand(11, 4),
lab = "lines",
w = 3,
palette = :grays,
fill = 0,
α = 0.6,
)
pl = scatter!(
y,
zcolor = abs.(y .- 0.5),
m = (:hot, 0.8, Plots.stroke(1, :green)),
ms = 10 * abs.(y .- 0.5) .+ 4,
lab = ["grad", "", "ient"],
)
Plots._update_plot_object(pl)
axis = Plots.pgfx_axes(pl.o)[1]
@test count(x -> x isa PGFPlotsX.LegendEntry, axis.contents) == 6
@test count(x -> x isa PGFPlotsX.Plot, axis.contents) == 108 # each marker is its own plot, fillranges create 2 plot-objects
marker = axis.contents[15]
@test marker isa PGFPlotsX.Plot
@test marker.options["mark"] == "*"
@test marker.options["mark options"]["color"] ==
RGBA{Float64}(colorant"green", 0.8)
@test marker.options["mark options"]["line width"] == 0.75 # 1px is 0.75pt
end # testset
@testset "Plot in pieces" begin
pic = plot(rand(100) / 3, reg = true, fill = (0, :green))
scatter!(pic, rand(100), markersize = 6, c = :orange)
Plots._update_plot_object(pic)
axis_contents = Plots.pgfx_axes(pic.o)[1].contents
leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents)
series = filter(x -> x isa PGFPlotsX.Plot, axis_contents)
@test length(leg_entries) == 2
@test length(series) == 4
@test haskey(series[1].options.dict, "forget plot")
@test !haskey(series[2].options.dict, "forget plot")
@test haskey(series[3].options.dict, "forget plot")
@test !haskey(series[4].options.dict, "forget plot")
end # testset
@testset "Marker types" begin
markers = filter((m -> begin
m in Plots.supported_markers()
end), Plots._shape_keys)
markers = reshape(markers, 1, length(markers))
n = length(markers)
x = (range(0, stop = 10, length = n + 2))[2:(end-1)]
y = repeat(reshape(reverse(x), 1, :), n, 1)
scatter(
x,
y,
m = (8, :auto),
lab = map(string, markers),
bg = :linen,
xlim = (0, 10),
ylim = (0, 10),
)
end # testset
@testset "Layout" begin
plot(
Plots.fakedata(100, 10),
layout = 4,
palette = [:grays :blues :hot :rainbow],
bg_inside = [:orange :pink :darkblue :black],
)
end # testset
@testset "Polar plots" begin
Θ = range(0, stop = 1.5π, length = 100)
r = abs.(0.1 * randn(100) + sin.(3Θ))
plot(Θ, r, proj = :polar, m = 2)
end # testset
@testset "Drawing shapes" begin
verts = [
(-1.0, 1.0),
(-1.28, 0.6),
(-0.2, -1.4),
(0.2, -1.4),
(1.28, 0.6),
(1.0, 1.0),
(-1.0, 1.0),
(-0.2, -0.6),
(0.0, -0.2),
(-0.4, 0.6),
(1.28, 0.6),
(0.2, -1.4),
(-0.2, -1.4),
(0.6, 0.2),
(-0.2, 0.2),
(0.0, -0.2),
(0.2, 0.2),
(-0.2, -0.6),
]
x = 0.1:0.2:0.9
y = 0.7 * rand(5) .+ 0.15
plot(
x,
y,
line = (3, :dash, :lightblue),
marker = (Shape(verts), 30, RGBA(0, 0, 0, 0.2)),
bg = :pink,
fg = :darkblue,
xlim = (0, 1),
ylim = (0, 1),
leg = false,
)
end # testset
@testset "Histogram 2D" begin
histogram2d(randn(10000), randn(10000), nbins = 20)
end # testset
@testset "Heatmap-like" begin
xs = [string("x", i) for i = 1:10]
ys = [string("y", i) for i = 1:4]
z = float((1:4) * reshape(1:10, 1, :))
pgfx_plot = heatmap(xs, ys, z, aspect_ratio = 1)
Plots._update_plot_object(pgfx_plot)
if @test_nowarn(
haskey(Plots.pgfx_axes(pgfx_plot.o)[1].options.dict, "colorbar") == true
)
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colorbar"] === nothing
@test Plots.pgfx_axes(pgfx_plot.o)[1]["colormap name"] == "plots1"
end
pgfx_plot = wireframe(xs, ys, z, aspect_ratio=1)
# TODO: clims are wrong
end # testset
@testset "Contours" begin
x = 1:0.5:20
y = 1:0.5:10
f(x, y) = begin
(3x + y ^ 2) * abs(sin(x) + cos(y))
end
X = repeat(reshape(x, 1, :), length(y), 1)
Y = repeat(y, 1, length(x))
Z = map(f, X, Y)
p2 = contour(x, y, Z)
p1 = contour(x, y, f, fill=true)
plot(p1, p2)
# TODO: colorbar for filled contours
end # testset
@testset "Varying colors" begin
t = range(0, stop=1, length=100)
θ = (6π) .* t
x = t .* cos.(θ)
y = t .* sin.(θ)
p1 = plot(x, y, line_z=t, linewidth=3, legend=false)
p2 = scatter(x, y, marker_z=((x, y)->begin
x + y
end), color=:bluesreds, legend=false)
plot(p1, p2)
end # testset
@testset "Framestyles" begin
scatter(fill(randn(10), 6), fill(randn(10), 6), framestyle=[:box :semi :origin :zerolines :grid :none], title=[":box" ":semi" ":origin" ":zerolines" ":grid" ":none"], color=permutedims(1:6), layout=6, label="", markerstrokewidth=0, ticks=-2:2)
# TODO: support :semi
end # testset
@testset "Quiver" begin
x = -2pi:0.2:2*pi
y = sin.(x)
pgfx_plot = wireframe(xs, ys, z, aspect_ratio = 1)
# TODO: clims are wrong
end # testset
@testset "Contours" begin
x = 1:0.5:20
y = 1:0.5:10
f(x, y) = begin
(3x + y^2) * abs(sin(x) + cos(y))
end
X = repeat(reshape(x, 1, :), length(y), 1)
Y = repeat(y, 1, length(x))
Z = map(f, X, Y)
p2 = contour(x, y, Z)
p1 = contour(x, y, f, fill = true)
plot(p1, p2)
# TODO: colorbar for filled contours
end # testset
@testset "Varying colors" begin
t = range(0, stop = 1, length = 100)
θ = (6π) .* t
x = t .* cos.(θ)
y = t .* sin.(θ)
p1 = plot(x, y, line_z = t, linewidth = 3, legend = false)
p2 = scatter(
x,
y,
marker_z = ((x, y) -> begin
x + y
end),
color = :bwr,
legend = false,
)
plot(p1, p2)
end # testset
@testset "Framestyles" begin
scatter(
fill(randn(10), 6),
fill(randn(10), 6),
framestyle = [:box :semi :origin :zerolines :grid :none],
title = [":box" ":semi" ":origin" ":zerolines" ":grid" ":none"],
color = permutedims(1:6),
layout = 6,
label = "",
markerstrokewidth = 0,
ticks = -2:2,
)
# TODO: support :semi
end # testset
@testset "Quiver" begin
x = (-2pi):0.2:(2*pi)
y = sin.(x)
u = ones(length(x))
v = cos.(x)
arrow_plot = plot(x, y, quiver = (u, v), arrow = true)
# TODO: could adjust limits to fit arrows if too long, but how?
# TODO: get latex available on CI
# mktempdir() do path
# @test_nowarn savefig(arrow_plot, path*"arrow.pdf")
# end
end # testset
@testset "Annotations" begin
y = rand(10)
pgfx_plot = plot(
y,
annotations = (3, y[3], Plots.text("this is \\#3", :left)),
leg = false,
)
Plots._update_plot_object(pgfx_plot)
axis_content = Plots.pgfx_axes(pgfx_plot.o)[1].contents
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 1
mktempdir() do path
file_path = joinpath(path, "annotations.tex")
@test_nowarn savefig(pgfx_plot, file_path)
open(file_path) do io
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 1
end
end
annotate!([
(5, y[5], Plots.text("this is \\#5", 16, :red, :center)),
(10, y[10], Plots.text("this is \\#10", :right, 20, "courier")),
])
Plots._update_plot_object(pgfx_plot)
axis_content = Plots.pgfx_axes(pgfx_plot.o)[1].contents
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 3
mktempdir() do path
file_path = joinpath(path, "annotations.tex")
@test_nowarn savefig(pgfx_plot, file_path)
open(file_path) do io
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 3
end
end
annotation_plot = scatter!(
range(2, stop = 8, length = 6),
rand(6),
marker = (50, 0.2, :orange),
series_annotations = [
"series",
"annotations",
"map",
"to",
"series",
Plots.text("data", :green),
],
)
Plots._update_plot_object(annotation_plot)
axis_content = Plots.pgfx_axes(annotation_plot.o)[1].contents
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 9
mktempdir() do path
file_path = joinpath(path, "annotations.tex")
@test_nowarn savefig(annotation_plot, file_path)
open(file_path) do io
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 9
end
# test .tikz extension
file_path = joinpath(path, "annotations.tikz")
@test_nowarn savefig(annotation_plot, file_path)
@test_nowarn open(file_path) do io
end
end
end # testset
@testset "Ribbon" begin
aa = rand(10)
bb = rand(10)
cc = rand(10)
conf = [aa - cc bb - cc]
ribbon_plot =
plot(collect(1:10), fill(1, 10), ribbon = (conf[:, 1], conf[:, 2]))
Plots._update_plot_object(ribbon_plot)
axis = Plots.pgfx_axes(ribbon_plot.o)[1]
plots = filter(x -> x isa PGFPlotsX.Plot, axis.contents)
@test length(plots) == 3
@test haskey(plots[1].options.dict, "fill")
@test haskey(plots[2].options.dict, "fill")
@test !haskey(plots[3].options.dict, "fill")
@test ribbon_plot.o !== nothing
@test ribbon_plot.o.the_plot !== nothing
end # testset
@testset "Markers and Paths" begin
pl = plot(
5 .- ones(9),
markershape = [:utriangle, :rect],
markersize = 8,
color = [:red, :black],
)
Plots._update_plot_object(pl)
axis = Plots.pgfx_axes(pl.o)[1]
plots = filter(x -> x isa PGFPlotsX.Plot, axis.contents)
@test length(plots) == 9
end # testset
end # testset
@testset "Extra kwargs" begin
pl = plot(1:5, test = "me")
@test pl[1][1].plotattributes[:extra_kwargs][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :subplot)
@test pl[1].attr[:extra_kwargs][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :plot)
@test pl.attr[:extra_plot_kwargs][:test] == "me"
pl = plot(
1:5,
extra_kwargs = Dict(
:plot => Dict(:test => "me"),
:series => Dict(:and => "me too"),
),
)
@test pl.attr[:extra_plot_kwargs][:test] == "me"
@test pl[1][1].plotattributes[:extra_kwargs][:and] == "me too"
pl = plot(
plot(1:5, title = "Line"),
scatter(
1:5,
title = "Scatter",
extra_kwargs = Dict(:subplot => Dict("axis line shift" => "10pt")),
),
)
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test !haskey(axes[1].options.dict, "axis line shift")
@test haskey(axes[2].options.dict, "axis line shift")
pl = plot(
x -> x,
-1:1;
add = raw"\node at (0,0.5) {\huge hi};",
extra_kwargs = :subplot,
)
@test pl[1][:extra_kwargs] == Dict(:add => raw"\node at (0,0.5) {\huge hi};")
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test filter(x -> x isa String, axes[1].contents)[1] ==
raw"\node at (0,0.5) {\huge hi};"
plot!(pl)
@test pl[1][:extra_kwargs] == Dict(:add => raw"\node at (0,0.5) {\huge hi};")
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test filter(x -> x isa String, axes[1].contents)[1] ==
raw"\node at (0,0.5) {\huge hi};"
end # testset
@testset "Titlefonts" begin
pl = plot(1:5, title = "Test me", titlefont = (2, :left))
@test pl[1][:title] == "Test me"
@test pl[1][:titlefontsize] == 2
@test pl[1][:titlefonthalign] == :left
Plots._update_plot_object(pl)
ax_opt = Plots.pgfx_axes(pl.o)[1].options
@test ax_opt["title"] == "Test me"
@test(haskey(ax_opt.dict, "title style")) isa Test.Pass
pl = plot(1:5, plot_title = "Test me", plot_titlefont = (2, :left))
@test pl[:plot_title] == "Test me"
@test pl[:plot_titlefontsize] == 2
@test pl[:plot_titlefonthalign] == :left
pl = heatmap(
rand(3, 3),
colorbar_title = "Test me",
colorbar_titlefont = (12, :right),
)
@test pl[1][:colorbar_title] == "Test me"
@test pl[1][:colorbar_titlefontsize] == 12
@test pl[1][:colorbar_titlefonthalign] == :right
u = ones(length(x))
v = cos.(x)
plot( x, y, quiver = (u, v), arrow = true )
# TODO: could adjust limits to fit arrows if too long, but how?
end # testset
@testset "Annotations" begin
y = rand(10)
plot(y, annotations=(3, y[3], Plots.text("this is \\#3", :left)), leg=false)
annotate!([(5, y[5], Plots.text("this is \\#5", 16, :red, :center)), (10, y[10], Plots.text("this is \\#10", :right, 20, "courier"))])
scatter!(range(2, stop=8, length=6), rand(6), marker=(50, 0.2, :orange), series_annotations=["series", "annotations", "map", "to", "series", Plots.text("data", :green)])
end # testset
end # testset
-33
View File
@@ -1,33 +0,0 @@
using Plots, Test
using OffsetArrays
@testset "lens!" begin
pl = plot(1:5)
lens!(pl, [1,2], [1,2], inset = (1, bbox(0.0,0.0,0.2,0.2)), colorbar = false)
@test length(pl.series_list) == 4
@test pl[2][:colorbar] == :none
end # testset
@testset "vline, vspan" begin
vl = vline([1], widen = false)
@test Plots.xlims(vl) == (1,2)
@test Plots.ylims(vl) == (1,2)
vl = vline([1], xlims=(0,2), widen = false)
@test Plots.xlims(vl) == (0,2)
vl = vline([1], ylims=(-3,5), widen = false)
@test Plots.ylims(vl) == (-3,5)
vsp = vspan([1,3], widen = false)
@test Plots.xlims(vsp) == (1,3)
@test Plots.ylims(vsp) == (0,1) # TODO: might be problematic on log-scales
vsp = vspan([1,3], xlims=(-2,5), widen = false)
@test Plots.xlims(vsp) == (-2,5)
vsp = vspan([1,3], ylims=(-2,5), widen = false)
@test Plots.ylims(vsp) == (-2,5)
end # testset
@testset "offset axes" begin
tri = OffsetVector(vcat(1:5, 4:-1:1), 11:19)
sticks = plot(tri, seriestype = :sticks)
@test length(sticks) == 1
end
-48
View File
@@ -1,48 +0,0 @@
using Plots, Test
@testset "Shorthands" begin
@testset "Set Lims" begin
p = plot(rand(10))
xlims!((1,20))
@test xlims(p) == (1,20)
ylims!((-1,1))
@test ylims(p) == (-1,1)
zlims!((-1,1))
@test zlims(p) == (-1,1)
xlims!(-1,11)
@test xlims(p) == (-1,11)
ylims!((-10,10))
@test ylims(p) == (-10,10)
zlims!((-10,10))
@test zlims(p) == (-10,10)
end
@testset "Set Ticks" begin
p = plot([0,2,3,4,5,6,7,8,9,10])
xticks = 2:6
xticks!(xticks)
@test Plots.get_subplot(current(),1).attr[:xaxis][:ticks] == xticks
yticks = 0.2:0.1:0.7
yticks!(yticks)
@test Plots.get_subplot(current(),1).attr[:yaxis][:ticks] == yticks
xticks = [5,6,7.5]
xlabels = ["a","b","c"]
xticks!(xticks, xlabels)
@test Plots.get_subplot(current(),1).attr[:xaxis][:ticks] == (xticks, xlabels)
yticks = [.5,.6,.75]
ylabels = ["z","y","x"]
yticks!(yticks, ylabels)
@test Plots.get_subplot(current(),1).attr[:yaxis][:ticks] == (yticks, ylabels)
end
end