Compare commits

..

3 Commits

Author SHA1 Message Date
Simon Christ 5b7856e4f9 bump version [skip ci] 2020-04-16 15:12:19 +02:00
Simon Christ 35c78dc169 fix test 2020-04-16 14:45:03 +02:00
Simon Christ ae953ab7e1 fix px to pt conversion for markers 2020-04-16 14:18:10 +02:00
68 changed files with 5279 additions and 7606 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 <backend(s)>`):
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'
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
+2 -5
View File
@@ -1,12 +1,9 @@
name: TagBot
on:
issue_comment:
types:
- created
workflow_dispatch:
schedule:
- cron: 0 * * * *
jobs:
TagBot:
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
runs-on: ubuntu-latest
steps:
- uses: JuliaRegistries/TagBot@v1
-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 }}
-89
View File
@@ -1,89 +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);'
$TESTCMD -e 'using Pkg; Pkg.activate(tempdir()); Pkg.develop(path=abspath(".")); Pkg.add("StatsPlots"); Pkg.test("StatsPlots");'
$TESTCMD -e 'using Pkg; Pkg.activate(tempdir()); Pkg.develop(path=abspath(".")); Pkg.add("GraphRecipes"); Pkg.test("GraphRecipes");'
- name: Codecov
uses: julia-actions/julia-uploadcodecov@latest
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Skip:
if: "contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- name: Skip CI 🚫
run: echo skip ci
-50
View File
@@ -1,50 +0,0 @@
name: docs
on:
push:
branches:
- master
tags: '*'
jobs:
Build_docs:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
with:
repository: JuliaPlots/PlotDocs.jl
- uses: julia-actions/setup-julia@v1
- name: Cache artifacts
uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- name: Install dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y qt5-default \
ttf-mscorefonts-installer \
poppler-utils \
pdf2svg \
texlive-latex-base \
texlive-binaries \
texlive-pictures \
texlive-latex-extra \
texlive-luatex \
ghostscript-x \
libgconf2-4
sudo fc-cache -vr
- name: build documentation
env:
PYTHON: ""
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
run: |
xvfb-run julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.add(PackageSpec(name="Plots", rev=split(ENV["GITHUB_REF"], "/", limit=3)[3])); Pkg.instantiate()'
xvfb-run julia --color=yes --project=docs/ -e 'withenv("GITHUB_REPOSITORY" => "JuliaPlots/PlotDocs.jl") do; include("docs/make.jl"); end'
+1 -4
View File
@@ -4,12 +4,9 @@
.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
.vscode/
+44
View File
@@ -0,0 +1,44 @@
# Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
os:
- linux
# - osx
julia:
- 1.0
- 1
- nightly
matrix:
allow_failures:
- julia: nightly
addons:
apt:
packages:
- at-spi2-core
- libgtk-3-dev
- xauth
- xvfb
env:
- GKS_ENCODING="utf8"
cache:
directories:
- $HOME/.julia/artifacts
sudo: required
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pwd ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./test/install_wkhtmltoimage.sh ; fi
notifications:
email: true
after_success:
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())'
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- if [[ `uname` = "Linux" ]]; then TESTCMD="xvfb-run julia"; else TESTCMD="julia"; fi
- $TESTCMD -e 'using Pkg; Pkg.build(); Pkg.test(coverage=true)'
-697
View File
@@ -1,697 +0,0 @@
{
"title": "Plots.jl",
"license": "MIT",
"creators": [
{
"affiliation": "Elemental Cognition",
"name": "Tom Breloff"
}
],
"contributors":[
{
"affiliation": "TU Wien",
"name": "Daniel Schwabeneder",
"orcid": "0000-0002-0412-0777",
"type": "ProjectLeader"
},
{
"affiliation": "GLOBE Institute",
"name": "Michael Krabbe Borregaard",
"type": "ProjectLeader"
},
{
"affiliation": "Leibniz Universit\u00e4t Hannover",
"name": "Simon Christ",
"orcid": "0000-0002-5866-1472",
"type": "ProjectLeader"
},
{
"affiliation": "Forschungszentrum J\u00fclich",
"name": "Josef Heinen",
"orcid": "0000-0001-6509-1925",
"type": "ProjectMember"
},
{
"name": "Yuval",
"type": "Other"
},
{
"name": "Andrew Palugniok",
"type": "ProjectMember"
},
{
"affiliation": "@beacon-biosignals",
"name": "Simon Danisch",
"type": "Other"
},
{
"affiliation": "Veos Digital (https://veos.digital/)",
"name": "Pietro Vertechi",
"type": "ProjectMember"
},
{
"affiliation": "Korea Advanced Inst. of Science and Technology (KAIST)",
"name": "Zhanibek Omarov",
"type": "ProjectMember",
"orcid": "0000-0002-8783-8791"
},
{
"name": "Thatcher Chamberlin",
"type": "Other"
},
{
"name": "@ma-laforge",
"type": "ProjectMember"
},
{
"affiliation": "Massachusetts Institute of Technology",
"name": "Christopher Rackauckas",
"orcid": "0000-0001-5850-0663",
"type": "Other"
},
{
"affiliation": "Max Planck Institute for Physics",
"name": "Oliver Schulz",
"type": "Other"
},
{
"affiliation": "@JuliaComputing",
"name": "Sebastian Pfitzner",
"type": "Other"
},
{
"name": "Takafumi Arakaki",
"type": "Other"
},
{
"affiliation": "University of Manitoba",
"name": "Amin Yahyaabadi",
"type": "Other"
},
{
"name": "Jack Devine",
"type": "Other"
},
{
"name": "Sebastian Pech",
"type": "Other"
},
{
"affiliation": "@JuliaComputing",
"name": "Patrick Kofod Mogensen",
"type": "Other",
"orcid": "0000-0002-4910-1932"
},
{
"name": "Samuel S. Watson",
"type": "Other"
},
{
"affiliation": "UC Davis",
"name": "Naoki Saito",
"orcid": "0000-0001-5234-4719",
"type": "Other"
},
{
"affiliation": "University of Southern California (USC)",
"name": "Benoit Pasquier",
"orcid": "0000-0002-3838-5976",
"type": "Other"
},
{
"affiliation": "NTNU Trondheim",
"name": "Ronny Bergmann",
"orcid": "0000-0001-8342-7218",
"type": "Other"
},
{
"name": "Andy Nowacki",
"affiliation": "University of Leeds",
"orcid": "0000-0001-7669-7383",
"type": "Other"
},
{
"name": "Ian Butterworth",
"type": "Other"
},
{
"affiliation": "Lund University",
"name": "David Gustavsson",
"type": "Other"
},
{
"name": "Anshul Singhvi",
"type": "Other"
},
{
"name": "david-macmahon",
"type": "Other"
},
{
"name": "Fredrik Ekre",
"type": "Other"
},
{
"name": "Maaz Bin Tahir Saeed",
"type": "Other"
},
{
"name": "Kristoffer Carlsson",
"type": "Other"
},
{
"name": "Will Kearney",
"type": "Other"
},
{
"name": "Niklas Korsbo",
"type": "Other"
},
{
"name": "Miles Lucas",
"type": "Other"
},
{
"name": "@Godisemo",
"type": "Other"
},
{
"name": "Florian Oswald",
"type": "Other"
},
{
"name": "Diego Javier Zea",
"type": "Other"
},
{
"name": "@WillRam",
"type": "Other"
},
{
"name": "Fedor Bezrukov",
"type": "Other"
},
{
"name": "Spencer Lyon",
"type": "Other"
},
{
"name": "Darwin Darakananda",
"type": "Other"
},
{
"name": "Lukas Hauertmann",
"type": "Other"
},
{
"name": "Huckleberry Febbo",
"type": "Other"
},
{
"name": "@H-M-H",
"type": "Other"
},
{
"name": "Josh Day",
"type": "Other"
},
{
"name": "@wfgra",
"type": "Other"
},
{
"name": "Sheehan Olver",
"type": "Other"
},
{
"name": "Jerry Ling",
"type": "Other"
},
{
"name": "Jks Liu",
"type": "Other"
},
{
"name": "Seth Axen",
"type": "Other"
},
{
"name": "@o01eg",
"type": "Other"
},
{
"name": "Sebastian Micluța-Câmpeanu",
"type": "Other"
},
{
"name": "Tim Holy",
"type": "Other"
},
{
"name": "Tony Kelman",
"type": "Other"
},
{
"name": "Antoine Levitt",
"type": "Other"
},
{
"name": "Iblis Lin",
"type": "Other"
},
{
"name": "Harry Scholes",
"type": "Other"
},
{
"name": "@djsegal",
"type": "Other"
},
{
"name": "Goran Nakerst",
"type": "Other"
},
{
"name": "Felix Hagemann",
"type": "Other"
},
{
"name": "Matthieu Gomez",
"type": "Other"
},
{
"name": "@biggsbiggsby",
"type": "Other"
},
{
"name": "Jonathan Anderson",
"type": "Other"
},
{
"name": "Michael Kraus",
"type": "Other"
},
{
"name": "Carlo Lucibello",
"type": "Other"
},
{
"name": "Robin Deits",
"type": "Other"
},
{
"name": "Misha Mkhasenko",
"type": "Other"
},
{
"name": "Benoît Legat",
"type": "Other"
},
{
"name": "Steven G. Johnson",
"type": "Other"
},
{
"name": "John Verzani",
"type": "Other"
},
{
"name": "Mattias Fält",
"type": "Other"
},
{
"name": "Rashika Karki",
"type": "Other"
},
{
"name": "Morten Piibeleht",
"type": "Other"
},
{
"name": "Filippo Vicentini",
"type": "Other"
},
{
"name": "David Anthoff",
"type": "Other"
},
{
"name": "Leon Wabeke",
"type": "Other"
},
{
"name": "Yusuke Kominami",
"type": "Other"
},
{
"name": "Oscar Dowson",
"type": "Other"
},
{
"name": "Max G",
"type": "Other"
},
{
"name": "Fabian Greimel",
"type": "Other"
},
{
"name": "Jérémy",
"type": "Other"
},
{
"name": "Pearl Li",
"type": "Other"
},
{
"name": "David P. Sanders",
"type": "Other"
},
{
"name": "Asbjørn Nilsen Riseth",
"type": "Other"
},
{
"name": "Jan Weidner",
"type": "Other"
},
{
"name": "@jakkor2",
"type": "Other"
},
{
"name": "Pablo Zubieta",
"type": "Other"
},
{
"name": "Hamza Yusuf Çakır",
"type": "Other"
},
{
"name": "John Rinehart",
"type": "Other"
},
{
"name": "Martin Biel",
"type": "Other"
},
{
"name": "Moritz Schauer",
"type": "Other"
},
{
"name": "Moesè Giodano",
"type": "Other"
},
{
"name": "@olegshtch",
"type": "Other"
},
{
"name": "Leon Shen",
"type": "Other"
},
{
"name": "Jeff Fessler",
"type": "Other"
},
{
"name": "@hustf",
"type": "Other"
},
{
"name": "Asim H Dar",
"type": "Other"
},
{
"name": "@8uurg",
"type": "Other"
},
{
"name": "Abel Siqueira",
"type": "Other"
},
{
"name": "Adrian Dawid",
"type": "Other"
},
{
"name": "Alberto Lusiani",
"type": "Other"
},
{
"name": "Balázs Mezei",
"type": "Other"
},
{
"name": "Ben Ide",
"type": "Other"
},
{
"name": "Benjamin Lungwitz",
"type": "Other"
},
{
"affiliation": "University of Graz",
"name": "Bernd Riederer",
"type": "Other",
"orcid": "0000-0001-8390-0087"
},
{
"name": "Christina Lee",
"type": "Other"
},
{
"name": "Christof Stocker",
"type": "Other"
},
{
"name": "Christoph Finkensiep",
"type": "Other"
},
{
"name": "@Cornelius-G",
"type": "Other"
},
{
"name": "Daniel Høegh",
"type": "Other"
},
{
"name": "Denny Biasiolli",
"type": "Other"
},
{
"name": "Dieter Castel",
"type": "Other"
},
{
"name": "Elliot Saba",
"type": "Other"
},
{
"name": "Fengyang Wang",
"type": "Other"
},
{
"name": "Fons van der Plas",
"type": "Other"
},
{
"name": "Fredrik Bagge Carlson",
"type": "Other"
},
{
"name": "Graham Smith",
"type": "Other"
},
{
"name": "Hayato Ikoma",
"type": "Other"
},
{
"name": "Hessam Mehr",
"type": "Other"
},
{
"name": "@InfiniteChai",
"type": "Other"
},
{
"name": "Jack Dunn",
"type": "Other"
},
{
"name": "Jeff Bezanson",
"type": "Other"
},
{
"name": "Jeff Eldredge",
"type": "Other"
},
{
"name": "Jinay Jain",
"type": "Other"
},
{
"name": "Johan Blåbäck",
"type": "Other"
},
{
"name": "@jmert",
"type": "Other"
},
{
"name": "Lakshya Khatri",
"type": "Other"
},
{
"name": "Lia Siegelmann",
"type": "Other"
},
{
"name": "@marekkukan-tw",
"type": "Other"
},
{
"affiliation": "ETH Zurich",
"name": "Mauro Werder",
"type": "Other",
"orcid": "0000-0003-0137-9377"
},
{
"name": "Maxim Grechkin",
"type": "Other"
},
{
"name": "Michael Cawte",
"type": "Other"
},
{
"name": "@milesfrain",
"type": "Other"
},
{
"name": "Nicholas Bauer",
"type": "Other"
},
{
"name": "Nicolau Leal Werneck",
"type": "Other"
},
{
"name": "@nilshg",
"type": "Other"
},
{
"name": "Oliver Evans",
"type": "Other"
},
{
"name": "Peter Gagarinov",
"type": "Other"
},
{
"name": "Páll Haraldsson",
"type": "Other"
},
{
"name": "Rik Huijzer",
"type": "Other"
},
{
"name": "Romain Franconville",
"type": "Other"
},
{
"name": "Ronan Pigott",
"type": "Other"
},
{
"name": "Roshan Shariff",
"type": "Other"
},
{
"name": "Scott Thomas",
"type": "Other"
},
{
"name": "Sebastian Rollén",
"type": "Other"
},
{
"name": "Seth Bromberger",
"type": "Other"
},
{
"name": "Siva Swaminathan",
"type": "Other"
},
{
"name": "Tim DuBois",
"type": "Other"
},
{
"name": "Travis DePrato",
"type": "Other"
},
{
"name": "Will Thompson",
"type": "Other"
},
{
"name": "Yakir Luc Gagnon",
"type": "Other"
},
{
"name": "Benjamin Chislett",
"type": "Other"
},
{
"name": "@hhaensel",
"type": "Other"
},
{
"name": "@improbable22",
"type": "Other"
},
{
"name": "Johannes Fleck",
"type": "Other"
},
{
"name": "Peter Czaban",
"type": "Other"
},
{
"name": "@innerlee",
"type": "Other"
},
{
"name": "Mats Cronqvist",
"type": "Other"
},
{
"name": "Shi Pengcheng",
"type": "Other"
},
{
"name": "@wg030",
"type": "Other"
},
{
"affiliation": "University of Cambridge",
"name": "Will Tebbutt",
"type": "Other"
},
{
"name": "@t-bltg",
"type": "Other"
}
{
"name": "Fred Callaway",
"type": "Other"
}
],
"upload_type": "software"
}
+18 -22
View File
@@ -1,7 +1,7 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "1.16.5"
version = "1.0.11"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
@@ -10,12 +10,12 @@ 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"
@@ -25,7 +25,6 @@ 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,28 +33,27 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[compat]
Contour = "0.5"
FFMPEG = "0.2, 0.3, 0.4"
FFMPEG = "0.2, 0.3"
FixedPointNumbers = "0.6, 0.7, 0.8"
GR = "0.53, 0.54, 0.55, 0.57"
GeometryBasics = "0.2, 0.3.1"
JSON = "0.21, 1"
Latexify = "0.14, 0.15"
GR = "0.46, 0.47, 0.48"
GeometryTypes = "0.7, 0.8"
JSON = "0.21"
Measures = "0.3"
NaNMath = "0.3"
PlotThemes = "2"
PlotUtils = "1"
PGFPlotsX = "1.2.0"
PlotThemes = "1"
PlotUtils = "0.6.5"
RecipesBase = "1"
RecipesPipeline = "0.3"
Reexport = "0.2, 1.0"
Requires = "1"
Scratch = "1"
Showoff = "0.3.1, 1.0"
RecipesPipeline = "0.1.1"
Reexport = "0.2"
Requires = "0.5, 1"
Showoff = "0.3.1"
StatsBase = "0.32, 0.33"
julia = "1.5"
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"
@@ -63,15 +61,13 @@ Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"
[targets]
test = ["Distributions", "FileIO", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"]
test = ["FileIO", "GeometryTypes", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "HDF5", "Random", "RDatasets", "StaticArrays", "StatsPlots", "Test", "UnicodePlots", "VisualRegressionTests"]
+8 -8
View File
@@ -1,7 +1,10 @@
# 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
[travis-img]: https://img.shields.io/travis/JuliaPlots/Plots.jl?logo=travis
[travis-url]: https://travis-ci.org/JuliaPlots/Plots.jl
[appveyor-img]: https://ci.appveyor.com/api/projects/status/github/juliaplots/plots.jl?branch=master&svg=true
[appveyor-url]: https://ci.appveyor.com/project/mkborregaard/plots-jl
[pkgeval-img]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/P/Plots.svg
[pkgeval-url]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/report.html
@@ -12,16 +15,13 @@
[docs-img]: https://img.shields.io/badge/docs-stable-blue.svg
[docs-url]: http://docs.juliaplots.org/latest/
[![][gh-ci-img]][gh-ci-url]
[![][travis-img]][travis-url]
[![][appveyor-img]][appveyor-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)
[![][gitter-img]][gitter-url]
[![][docs-img]][docs-url]
[![Codecov](https://codecov.io/gh/JuliaPlots/Plots.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaPlots/Plots.jl)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4725317.svg)](https://doi.org/10.5281/zenodo.4725317)
This is the DOI for all Versions, please follow the link to get the DOI for a specific version.
#### Created by Tom Breloff (@tbreloff)
#### Maintained by the [JuliaPlots members](https://github.com/orgs/JuliaPlots/people)
+46
View File
@@ -0,0 +1,46 @@
environment:
matrix:
- julia_version: 1.0
- julia_version: 1
- julia_version: nightly
platform:
- x86 # 32-bit
- x64 # 64-bit
# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
matrix:
allow_failures:
- julia_version: nightly
branches:
only:
- master
- /release-.*/
cache:
- '%USERPROFILE%\.julia\artifacts'
notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false
install:
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
build_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
test_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
-5
View File
@@ -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
-401
View File
@@ -1,401 +0,0 @@
# Use
# @warnpcfail precompile(args...)
# if you want to be warned when a precompile directive fails
macro warnpcfail(ex::Expr)
modl = __module__
file = __source__.file === nothing ? "?" : String(__source__.file)
line = __source__.line
quote
$(esc(ex)) || @warn """precompile directive
$($(Expr(:quote, ex)))
failed. Please report an issue in $($modl) (after checking for duplicates) or remove this directive.""" _file=$file _line=$line
end
end
const __bodyfunction__ = Dict{Method,Any}()
# Find keyword "body functions" (the function that contains the body
# as written by the developer, called after all missing keyword-arguments
# have been assigned values), in a manner that doesn't depend on
# gensymmed names.
# `mnokw` is the method that gets called when you invoke it without
# supplying any keywords.
function __lookup_kwbody__(mnokw::Method)
function getsym(arg)
isa(arg, Symbol) && return arg
@assert isa(arg, GlobalRef)
return arg.name
end
f = get(__bodyfunction__, mnokw, nothing)
if f === nothing
fmod = mnokw.module
# The lowered code for `mnokw` should look like
# %1 = mkw(kwvalues..., #self#, args...)
# return %1
# where `mkw` is the name of the "active" keyword body-function.
ast = Base.uncompressed_ast(mnokw)
if isa(ast, Core.CodeInfo) && length(ast.code) >= 2
callexpr = ast.code[end-1]
if isa(callexpr, Expr) && callexpr.head == :call
fsym = callexpr.args[1]
if isa(fsym, Symbol)
f = getfield(fmod, fsym)
elseif isa(fsym, GlobalRef)
if fsym.mod === Core && fsym.name === :_apply
f = getfield(mnokw.module, getsym(callexpr.args[2]))
elseif fsym.mod === Core && fsym.name === :_apply_iterate
f = getfield(mnokw.module, getsym(callexpr.args[3]))
else
f = getfield(fsym.mod, fsym.name)
end
else
f = missing
end
else
f = missing
end
else
f = missing
end
__bodyfunction__[mnokw] = f
end
return f
end
function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:label, :blank), Tuple{Symbol, Bool}},Type{EmptyLayout}})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:label, :width, :height), Tuple{Symbol, Symbol, Length{:pct, Float64}}},Type{EmptyLayout}})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{GridLayout}},Type{Subplot},GRBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{GridLayout}},Type{Subplot},PlotlyBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{Subplot{GRBackend}}},Type{Subplot},GRBackend})
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{Subplot{PlotlyBackend}}},Type{Subplot},PlotlyBackend})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Int64})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Tuple{Int64, Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Vector{Int64}}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:flip,), Tuple{Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{Symbol}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{typeof(datetimeformatter)}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Float64, Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Float64, Float64}, Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid,), Tuple{Bool}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:gridlinewidth, :grid, :gridalpha, :gridstyle, :foreground_color_grid), Tuple{Int64, Bool, Float64, Symbol, RGBA{Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide,), Tuple{String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide_position, :guidefontvalign, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guidefonthalign, :guide_position, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims, :flip, :ticks, :guide), Tuple{Tuple{Int64, Int64}, Bool, StepRange{Int64, Int64}, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Float64, Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:rotation,), Tuple{Int64}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:scale, :guide), Tuple{Symbol, String}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{Nothing}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{UnitRange{Int64}}},typeof(attr!),Axis})
Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:shape,), Tuple{Symbol}},typeof(default)})
Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:titlefont, :legendfontsize, :guidefont, :tickfont, :guide, :framestyle, :yminorgrid), Tuple{Tuple{Int64, String}, Int64, Tuple{Int64, Symbol}, Tuple{Int64, Symbol}, String, Symbol, Bool}},typeof(default)})
Base.precompile(Tuple{Core.kwftype(typeof(font)),NamedTuple{(:family, :pointsize, :halign, :valign, :rotation, :color), Tuple{String, Int64, Symbol, Symbol, Float64, RGBA{Float64}}},typeof(font)})
Base.precompile(Tuple{Core.kwftype(typeof(font)),NamedTuple{(:family, :pointsize, :valign, :halign, :rotation, :color), Tuple{String, Int64, Symbol, Symbol, Float64, RGBA{Float64}}},typeof(font)})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRange{Int64, Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),Vector{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:halign, :valign, :rotation, :color), Tuple{Symbol, Symbol, Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(hline!)),Any,typeof(hline!),Any})
Base.precompile(Tuple{Core.kwftype(typeof(pie)),Any,typeof(pie),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{GRBackend},Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:annotation,), Tuple{Vector{Tuple{Int64, Float64, PlotText}}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{GRBackend},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{PlotlyBackend},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Function,Float64,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Plot{GRBackend},Function,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{GRBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Vector{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:xgrid,), Tuple{Tuple{Symbol, Symbol, Int64, Symbol, Float64}}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis,), Tuple{Tuple{String, Symbol}}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:annotations, :leg), Tuple{Tuple{Int64, Float64, PlotText}, Bool}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:arrow,), Tuple{Int64}},typeof(plot),Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bins, :weights, :seriestype), Tuple{Symbol, Vector{Int64}, Symbol}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:color, :line, :marker), Tuple{Matrix{Symbol}, Tuple{Symbol, Int64}, Tuple{Matrix{Symbol}, Int64, Float64, Stroke}}},typeof(plot),Vector{Vector{T} where T}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:connections, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vararg{Vector{Int64}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill, :seriestype), Tuple{Bool, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks, :seriestype), Tuple{Matrix{Symbol}, Matrix{String}, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Int64, String, Int64, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Vector{Float64}},Vector{Vector{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:grid, :title), Tuple{Tuple{Symbol, Symbol, Symbol, Int64, Float64}, String}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:lab, :w, :palette, :fill, :α), Tuple{String, Int64, PlotUtils.ContinuousColorGradient, Int64, Float64}},typeof(plot),StepRange{Int64, Int64},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend), Tuple{Matrix{String}, String, String, Int64, Symbol}},typeof(plot),Vector{Function},Float64,Vararg{Float64, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label,), Tuple{Matrix{String}}},typeof(plot),Vector{AbstractVector{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :group, :linetype, :linecolor), Tuple{GridLayout, Vector{String}, Matrix{Symbol}, Symbol}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :palette, :bg_inside), Tuple{Int64, Matrix{PlotUtils.ContinuousColorGradient}, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :t, :leg, :ticks, :border), Tuple{GridLayout, Matrix{Symbol}, Bool, Nothing, Symbol}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :title, :titlelocation, :left_margin, :bottom_margin, :xrotation), Tuple{GridLayout, Matrix{String}, Symbol, Matrix{AbsoluteLength}, AbsoluteLength, Int64}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xguide, :yguide, :xguidefonthalign, :yguidefontvalign, :xguideposition, :yguideposition, :ymirror, :xmirror, :legend, :seriestype), Tuple{Int64, String, String, Matrix{Symbol}, Matrix{Symbol}, Symbol, Matrix{Symbol}, Matrix{Bool}, Matrix{Bool}, Bool, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xlims), Tuple{GridLayout, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Vector{Tuple{Int64, Real}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :lab, :ms), Tuple{Tuple{Matrix{Symbol}, Int64}, Matrix{String}, Int64}},typeof(plot),Vector{Vector{T} where T},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :label, :legendtitle), Tuple{Tuple{Int64, Matrix{Symbol}}, Matrix{String}, String}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :leg, :fill), Tuple{Int64, Bool, Tuple{Int64, Symbol}}},typeof(plot),Function,Function,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :marker, :bg, :fg, :xlim, :ylim, :leg), Tuple{Tuple{Int64, Symbol, Symbol}, Tuple{Shape{Float64, Float64}, Int64, RGBA{Float64}}, Symbol, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Bool}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line_z, :linewidth, :legend), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int64, Bool}},typeof(plot),Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:m, :markersize, :lab, :bg, :xlim, :ylim, :seriestype), Tuple{Matrix{Symbol}, Int64, Matrix{String}, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker,), Tuple{Bool}},typeof(plot),Vector{Union{Missing, Int64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker_z, :color, :legend, :seriestype), Tuple{typeof(+), Symbol, Bool, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :markersize, :marker_z, :line_z, :linewidth), Tuple{Matrix{Symbol}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :seriestype, :label), Tuple{Symbol, Symbol, String}},typeof(plot),UnitRange{Int64},Vector{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :show_empty_bins, :normed, :aspect_ratio, :seriestype), Tuple{Tuple{Int64, Int64}, Bool, Bool, Int64, Symbol}},typeof(plot),Vector{ComplexF64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:proj, :m), Tuple{Symbol, Int64}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:projection, :seriestype), Tuple{Symbol, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},UnitRange{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:quiver, :seriestype), Tuple{Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Vararg{Vector{Float64}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:reg, :fill), Tuple{Bool, Tuple{Int64, Symbol}}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Int64}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Tuple{LinRange{Float64}, LinRange{Float64}}}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{typeof(sqrt)}},typeof(plot),UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color), Tuple{Matrix{Symbol}, Vector{Symbol}, Int64, Vector{Symbol}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{OHLC}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},Vararg{Vector{Float64}, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :l, :seriestype), Tuple{String, Float64, Symbol}},typeof(plot),Vector{String},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{String}},typeof(plot),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{String}},typeof(plot),Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:xaxis, :background_color, :leg), Tuple{Tuple{String, Tuple{Int64, Int64}, StepRange{Int64, Int64}, Symbol}, RGB{Float64}, Bool}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:yflip, :aspect_ratio), Tuple{Bool, Symbol}},typeof(plot),Vector{Float64},Vector{Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:zcolor, :m, :leg, :cbar, :w), Tuple{StepRange{Int64, Int64}, Tuple{Int64, Float64, Symbol, Stroke}, Bool, Bool, Int64}},typeof(plot),Vector{Float64},Vector{Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(portfoliocomposition)),Any,typeof(portfoliocomposition),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(scatter!)),Any,typeof(scatter!),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(scatter!)),Any,typeof(scatter!),Any})
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip,), Tuple{Vector{Int64}}},typeof(test_examples),Symbol})
Base.precompile(Tuple{Type{GridLayout},Int64,Vararg{Int64, N} where N})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},AbstractVector{OHLC}})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},PortfolioComposition})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barbins}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barhist}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bar}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bins2d}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:histogram2d}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hline}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:lens}},AbstractPlot})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:pie}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:quiver}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:spy}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:steppre}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:sticks}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vline}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:xerror}},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Vector{ComplexF64}})
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{GRBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{PlotlyBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{GRBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{PlotlyBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_attributes!),Plot{GRBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{GRBackend},DefaultsDict,Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{GRBackend},Dict{Symbol, Any},Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{PlotlyBackend},DefaultsDict,Symbol,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{PlotlyBackend},Dict{Symbol, Any},Symbol,Any})
Base.precompile(Tuple{typeof(_bin_centers),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Int64},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Nothing},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{PlotUtils.ContinuousColorGradient},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}},String})
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Symbol},String})
Base.precompile(Tuple{typeof(_cycle),Base.OneTo{Int64},Vector{Int64}})
Base.precompile(Tuple{typeof(_cycle),StepRange{Int64, Int64},Vector{Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},StepRange{Int64, Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},UnitRange{Int64}})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
Base.precompile(Tuple{typeof(_heatmap_edges),Vector{Float64},Bool,Bool})
Base.precompile(Tuple{typeof(_plot!),Plot,Any,Any})
Base.precompile(Tuple{typeof(_preprocess_barlike),DefaultsDict,Base.OneTo{Int64},Vector{Float64}})
Base.precompile(Tuple{typeof(_preprocess_binlike),DefaultsDict,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(_update_min_padding!),GridLayout})
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{GRBackend},Subplot{GRBackend},Dict{Symbol, Any},Int64,Bool})
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{PlotlyBackend},Subplot{PlotlyBackend},Dict{Symbol, Any},Int64,Bool})
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{GRBackend},Vector{Any}})
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{PlotlyBackend},Vector{Any}})
Base.precompile(Tuple{typeof(backend),PlotlyBackend})
Base.precompile(Tuple{typeof(bbox),AbsoluteLength,AbsoluteLength,AbsoluteLength,AbsoluteLength})
Base.precompile(Tuple{typeof(bbox),Float64,Float64,Float64,Float64})
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64})
Base.precompile(Tuple{typeof(contour),Any,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(convertLegendValue),Symbol})
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Int64, Float64}})
Base.precompile(Tuple{typeof(create_grid),Expr})
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64},Vararg{Vector{Float64}, N} where N})
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{typeof(error_zipit),Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}})
Base.precompile(Tuple{typeof(expand_extrema!),Axis,Base.OneTo{Int64}})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
Base.precompile(Tuple{typeof(get_ticks),StepRange{Int64, Int64},Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_ticks),UnitRange{Int64},Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(get_xy),OHLC{Float64},Int64,Float64})
Base.precompile(Tuple{typeof(get_xy),Vector{OHLC}})
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Float64, Float64, Float64, Int64, Float64, Float64, Float64, Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_display),Subplot{GRBackend},AbsoluteLength,AbsoluteLength,Vector{Float64}})
Base.precompile(Tuple{typeof(gr_draw_colorbar),GRColorbar,Subplot{GRBackend},Tuple{Float64, Float64},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_draw_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_heatmap),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Float64,Float64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Shape{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Int64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},UnitRange{Int64},Tuple{Vector{Float64}, Vector{Float64}},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRange{Int64, Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Float64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_shapes),Series,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_fill_viewport),Vector{Float64},RGBA{Float64}})
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Float64}, Vector{String}},Int64})
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Int64}, Vector{String}},Int64})
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_label_ticks_3d),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_polaraxes),Int64,Float64,Subplot{GRBackend}})
Base.precompile(Tuple{typeof(gr_polyline),Vector{Float64},Vector{Float64},Function})
Base.precompile(Tuple{typeof(gr_set_gradient),PlotUtils.ContinuousColorGradient})
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}}})
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Float64, Float64, Float64, Int64, Float64, Float64, Float64, Float64}}})
Base.precompile(Tuple{typeof(gr_viewport_from_bbox),Subplot{GRBackend},BoundingBox{Tuple{AbsoluteLength, AbsoluteLength}, Tuple{AbsoluteLength, AbsoluteLength}},AbsoluteLength,AbsoluteLength,Vector{Float64}})
Base.precompile(Tuple{typeof(heatmap_edges),Base.OneTo{Int64},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Symbol,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Symbol,Tuple{Int64, Int64},Bool})
Base.precompile(Tuple{typeof(heatmap_edges),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),UnitRange{Int64},Symbol})
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol,UnitRange{Int64},Symbol,Tuple{Int64, Int64},Bool})
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol,Vector{Float64},Symbol,Tuple{Int64, Int64},Bool})
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol})
Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}})
Base.precompile(Tuple{typeof(layout_args),Int64})
Base.precompile(Tuple{typeof(make_fillrange_side),UnitRange{Int64},LinRange{Float64}})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Function})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Symbol})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Float64},Symbol,Symbol})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Int64},Symbol,Symbol})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),StepRange{Int64, Int64},Tuple{Int64, Int64},Symbol,Symbol})
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),UnitRange{Int64},Tuple{Float64, Float64},Symbol,Symbol})
Base.precompile(Tuple{typeof(partialcircle),Int64,Float64,Int64})
Base.precompile(Tuple{typeof(plot),Any,Any,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(plot),Any})
Base.precompile(Tuple{typeof(processFillArg),Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(processGridArg!),DefaultsDict,Bool,Symbol})
Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Matrix{Symbol}})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Matrix{Symbol}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},RGBA{Float64}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Shape{Float64, Float64}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Stroke})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol})
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}})
Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{Bool},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{Int64},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{PlotUtils.ContinuousColorGradient},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{RGBA{Float64}},Int64})
Base.precompile(Tuple{typeof(slice_arg),Matrix{String},Int64})
Base.precompile(Tuple{typeof(spy),Any})
Base.precompile(Tuple{typeof(straightline_data),Tuple{Float64, Float64},Tuple{Float64, Float64},Vector{Float64},Vector{Float64},Int64})
Base.precompile(Tuple{typeof(stroke),Int64,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(text),String,Int64,Symbol,Vararg{Symbol, N} where N})
Base.precompile(Tuple{typeof(text),String,Symbol,Int64,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(title!),AbstractString})
Base.precompile(Tuple{typeof(unzip),Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{typeof(vline!),Any})
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
Base.precompile(Tuple{typeof(yaxis!),Any,Any})
let fbody = try __lookup_kwbody__(which(gr_polyline, (Vector{Float64},Vector{Float64},typeof(GR.fillarea),))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Symbol,Symbol,typeof(gr_polyline),Vector{Float64},Vector{Float64},typeof(GR.fillarea),))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Any,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Any,))
end
end
let fbody = try __lookup_kwbody__(which(plot!, (Any,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot!),Any,Vararg{Any, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Any,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Any,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Any,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Any,Vararg{Any, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(plot, (Plot,Plot,Vararg{Plot, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(plot),Plot,Plot,Vararg{Plot, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(text, (String,Int64,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(text),String,Int64,Vararg{Any, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(text, (String,Symbol,Vararg{Any, N} where N,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(text),String,Symbol,Vararg{Any, N} where N,))
end
end
let fbody = try __lookup_kwbody__(which(title!, (AbstractString,))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Any,typeof(title!),AbstractString,))
end
end
end
-4
View File
@@ -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
+53
View File
@@ -0,0 +1,53 @@
# To figure out what should be precompiled, run this script, then move
# precompile_Plots.jl in precompiles_path (see below) to src/precompile.jl
# This script works by using SnoopCompile to log compilations that take place
# while running the examples on the GR backend. So SnoopCompile must be
# installed, and StatsPlots, RDatasets, and FileIO are also required for
# certain examples.
# If precompilation fails with an UndefVarError for a module, probably what is
# happening is that the module appears in the precompile statements, but is
# only visible to one of Plots' dependencies, and not Plots itself. Adding the
# module to the blacklist below will remove these precompile statements.
# Anonymous functions may appear in precompile statements as functions with
# hashes in their name. Those of the form "#something##kw" have to do with
# compiling functions with keyword arguments, and are named reproducibly, so
# can be kept. Others generally will not work. Currently, SnoopCompile includes
# some anonymous functions that not reproducible, but SnoopCompile PR #30
# (which looks about to be merged) will ensure that anonymous functions are
# actually defined before attempting to precompile them. Alternatively, we can
# keep only the keyword argument related anonymous functions by changing the
# regex that SnoopCompile uses to detect anonymous functions to
# r"#{1,2}[^\"#]+#{1,2}\d+" (see anonrex in SnoopCompile.jl). To exclude all
# precompile statements involving anonymous functions, "#" can also be added to
# the blacklist below.
using SnoopCompile
project_flag = string("--project=", joinpath(homedir(), ".julia", "dev", "Plots"))
log_path = joinpath(tempdir(), "compiles.log")
precompiles_path = joinpath(tempdir(), "precompile")
# run examples with GR backend, logging what needs to be compiled
SnoopCompile.@snoopc project_flag log_path begin
using Plots
Plots.test_examples(:gr)
Plots.test_examples(:plotly, skip = Plots._backend_skips[:plotly])
end
# precompile calls containing the following strings are dropped
blacklist = [
# functions defined in examples
"PlotExampleModule",
# the following are not visible to Plots, only its dependencies
"CategoricalArrays",
"FixedPointNumbers",
"SparseArrays",
r"#{1,2}[^\"#]+#{1,2}\d+",
]
data = SnoopCompile.read(log_path)
pc = SnoopCompile.parcel(reverse!(data[2]), blacklist=blacklist)
SnoopCompile.write(precompiles_path, pc)
+19 -24
View File
@@ -8,9 +8,9 @@ const _current_plots_version = VersionNumber(split(first(filter(line -> occursin
using Reexport
import GeometryBasics
import GeometryTypes
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random
using SparseArrays
import SparseArrays: findnz
using FFMPEG
@@ -25,6 +25,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 +108,6 @@ export
gif,
mov,
mp4,
webm,
animate,
@animate,
@gif,
@@ -113,11 +123,7 @@ export
center,
BezierCurve,
plotattr,
scalefontsize,
scalefontsizes,
resetfontsizes
plotattr
# ---------------------------------------------------------
@@ -154,12 +160,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
@@ -187,16 +187,11 @@ import RecipesPipeline: SliceIt,
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("colorbars.jl")
include("components.jl")
include("axes.jl")
include("args.jl")
include("components.jl")
include("themes.jl")
include("plot.jl")
include("pipeline.jl")
@@ -212,7 +207,6 @@ include("output.jl")
include("ijulia.jl")
include("fileio.jl")
include("init.jl")
include("legend.jl")
include("backends/plotly.jl")
include("backends/gr.jl")
@@ -230,8 +224,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,
@@ -251,6 +245,7 @@ end
const CURRENT_BACKEND = CurrentBackend(:none)
include("precompile_includer.jl")
include("precompile.jl")
_precompile_()
end # module
+7 -9
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)"
@@ -90,15 +88,15 @@ function buildanimation(anim::Animation, fn::AbstractString,
if variable_palette
# generate a colorpalette for each frame for highest quality, but larger filesize
palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1"
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -lavfi "$palette" -loop $loop -y $fn`)
ffmpeg_exe(`-v $verbose_level -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"`)
# 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 $verbose_level -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 $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
end
show_msg && @info("Saved animation to ", fn)
@@ -112,8 +110,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>"
@@ -137,8 +135,8 @@ end
# -----------------------------------------------
function _animate(forloop::Expr, args...; callgif = false)
if forloop.head (:for, :while)
error("@animate macro expects a for- or while-block. got: $(forloop.head)")
if forloop.head != :for
error("@animate macro expects a for-block. got: $(forloop.head)")
end
# add the call to frame to the end of each iteration
+151 -174
View File
@@ -2,185 +2,162 @@
const _arg_desc = KW(
# series args
:label => "String type. The label for a series, which appears in a legend. If empty, no legend entry is added.",
:seriescolor => "Color Type. The base color for this series. `:auto` (the default) will select a color from the subplot's `color_palette`, based on the order it was added to the subplot",
:seriesalpha => "Number in [0,1]. The alpha/opacity override for the series. `nothing` (the default) means it will take the alpha value of the color.",
:seriestype => "Symbol. This is the identifier of the type of visualization for this series. Choose from $(_allTypes) or any series recipes which are defined.",
:linestyle => "Symbol. Style of the line (for path and bar stroke). Choose from $(_allStyles)",
:linewidth => "Number. Width of the line (in pixels)",
:linecolor => "Color Type. Color of the line (for path and bar stroke). `:match` will take the value from `:seriescolor`, (though histogram/bar types use `:black` as a default).",
:linealpha => "Number in [0,1]. The alpha/opacity override for the line. `nothing` (the default) means it will take the alpha value of linecolor.",
:fillrange => "Number or AbstractVector. Fills area between fillrange and y for line-types, sets the base for bar/stick types, and similar for other types.",
:fillcolor => "Color Type. Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`.",
:fillalpha => "Number in [0,1]. The alpha/opacity override for the fill area. `nothing` (the default) means it will take the alpha value of fillcolor.",
:markershape => "Symbol, Shape, or AbstractVector. Choose from $(_allMarkers).",
:markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.",
:markeralpha => "Number in [0,1]. The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor.",
:markersize => "Number or AbstractVector. Size (radius pixels) of the markers.",
:markerstrokestyle => "Symbol. Style of the marker stroke (border). Choose from $(_allStyles)",
:markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)",
:markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.",
:markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.",
:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `range(minimum(x), stop = maximum(x), length = 25)`",
:smooth => "Bool. Add a regression line?",
:group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.",
:x => "Various. Input data. First Dimension",
:y => "Various. Input data. Second Dimension",
:z => "Various. Input data. Third Dimension. May be wrapped by a `Surface` for surface and heatmap types.",
:marker_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. z-values for each series data point, which correspond to the color to be used from a markercolor gradient.",
:line_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment).",
:fill_z => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.",
:levels => "Integer, NTuple{2,Integer}, or AbstractVector. Levels or number of levels (or x-levels/y-levels) for a contour type.",
:orientation => "Symbol. Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default).",
:bar_position => "Symbol. Choose from `:overlay` (default), `:stack`. (warning: May not be implemented fully)",
:bar_width => "nothing or Number. Width of bars in data coordinates. When nothing, chooses based on x (or y when `orientation = :h`).",
:bar_edges => "Bool. Align bars to edges (true), or centers (the default)?",
:xerror => "AbstractVector or 2-Tuple of Vectors. x (horizontal) error relative to x-value. If 2-tuple of vectors, the first vector corresponds to the left error (and the second to the right)",
:yerror => "AbstractVector or 2-Tuple of Vectors. y (vertical) error relative to y-value. If 2-tuple of vectors, the first vector corresponds to the bottom error (and the second to the top)",
:ribbon => "Number or AbstractVector. Creates a fillrange around the data points.",
:quiver => "AbstractVector or 2-Tuple of vectors. The directional vectors U,V which specify velocity/gradient vectors for a quiver plot.",
:arrow => "nothing (no arrows), Bool (if true, default arrows), Arrow object, or arg(s) that could be style or head length/widths. Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar.",
:normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete Probability Density Function, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes).",
:weights => "AbstractVector. Used in histogram types for weighted counts.",
:show_empty_bins => "Bool. Whether empty bins in a 2D histogram are colored as 0 (true), or transparent (the default).",
:contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.",
:contour_labels => "Bool. Show labels at the contour lines?",
:match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.",
:subplot => "Integer (subplot index) or Subplot object. The subplot that this series belongs to.",
:series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.",
:primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.",
:hover => "nothing or vector of strings. Text to display when hovering over each data point.",
:colorbar_entry => "Bool. Include this series in the color bar? Set to `false` to exclude.",
:label => "String type. The label for a series, which appears in a legend. If empty, no legend entry is added.",
:seriescolor => "Color Type. The base color for this series. `:auto` (the default) will select a color from the subplot's `color_palette`, based on the order it was added to the subplot",
:seriesalpha => "Number in [0,1]. The alpha/opacity override for the series. `nothing` (the default) means it will take the alpha value of the color.",
:seriestype => "Symbol. This is the identifier of the type of visualization for this series. Choose from $(_allTypes) or any series recipes which are defined.",
:linestyle => "Symbol. Style of the line (for path and bar stroke). Choose from $(_allStyles)",
:linewidth => "Number. Width of the line (in pixels)",
:linecolor => "Color Type. Color of the line (for path and bar stroke). `:match` will take the value from `:seriescolor`, (though histogram/bar types use `:black` as a default).",
:linealpha => "Number in [0,1]. The alpha/opacity override for the line. `nothing` (the default) means it will take the alpha value of linecolor.",
:fillrange => "Number or AbstractVector. Fills area between fillrange and y for line-types, sets the base for bar/stick types, and similar for other types.",
:fillcolor => "Color Type. Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`.",
:fillalpha => "Number in [0,1]. The alpha/opacity override for the fill area. `nothing` (the default) means it will take the alpha value of fillcolor.",
:markershape => "Symbol, Shape, or AbstractVector. Choose from $(_allMarkers).",
:markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.",
:markeralpha => "Number in [0,1]. The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor.",
:markersize => "Number or AbstractVector. Size (radius pixels) of the markers.",
:markerstrokestyle => "Symbol. Style of the marker stroke (border). Choose from $(_allStyles)",
:markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)",
:markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.",
:markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.",
:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `range(minimum(x), stop = maximum(x), length = 25)`",
:smooth => "Bool. Add a regression line?",
:group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.",
:x => "Various. Input data. First Dimension",
:y => "Various. Input data. Second Dimension",
:z => "Various. Input data. Third Dimension. May be wrapped by a `Surface` for surface and heatmap types.",
:marker_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. z-values for each series data point, which correspond to the color to be used from a markercolor gradient.",
:line_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment).",
:fill_z => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.",
:levels => "Integer, NTuple{2,Integer}, or AbstractVector. Levels or number of levels (or x-levels/y-levels) for a contour type.",
:orientation => "Symbol. Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default).",
:bar_position => "Symbol. Choose from `:overlay` (default), `:stack`. (warning: May not be implemented fully)",
:bar_width => "nothing or Number. Width of bars in data coordinates. When nothing, chooses based on x (or y when `orientation = :h`).",
:bar_edges => "Bool. Align bars to edges (true), or centers (the default)?",
:xerror => "AbstractVector or 2-Tuple of Vectors. x (horizontal) error relative to x-value. If 2-tuple of vectors, the first vector corresponds to the left error (and the second to the right)",
:yerror => "AbstractVector or 2-Tuple of Vectors. y (vertical) error relative to y-value. If 2-tuple of vectors, the first vector corresponds to the bottom error (and the second to the top)",
:ribbon => "Number or AbstractVector. Creates a fillrange around the data points.",
:quiver => "AbstractVector or 2-Tuple of vectors. The directional vectors U,V which specify velocity/gradient vectors for a quiver plot.",
:arrow => "nothing (no arrows), Bool (if true, default arrows), Arrow object, or arg(s) that could be style or head length/widths. Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar.",
:normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete Probability Density Function, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes).",
:weights => "AbstractVector. Used in histogram types for weighted counts.",
:show_empty_bins => "Bool. Whether empty bins in a 2D histogram are colored as 0 (true), or transparent (the default).",
:contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.",
:contour_labels => "Bool. Show labels at the contour lines?",
:match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.",
:subplot => "Integer (subplot index) or Subplot object. The subplot that this series belongs to.",
:series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.",
:primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.",
:hover => "nothing or vector of strings. Text to display when hovering over each data point.",
:colorbar_entry => "Bool. Include this series in the color bar? Set to `false` to exclude.",
# plot args
:plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)",
:background_color => "Color Type. Base color for all backgrounds.",
:background_color_outside => "Color Type or `:match` (matches `:background_color`). Color outside the plot area(s)",
:foreground_color => "Color Type. Base color for all foregrounds.",
:size => "NTuple{2,Int}. (width_px, height_px) of the whole Plot",
:pos => "NTuple{2,Int}. (left_px, top_px) position of the GUI window (note: currently unimplemented)",
:window_title => "String. Title of the standalone gui-window.",
:show => "Bool. Should this command open/refresh a GUI/display? This allows displaying in scripts or functions without explicitly calling `display`",
:layout => "Integer (number of subplots), NTuple{2,Integer} (grid dimensions), AbstractLayout (for example `grid(2,2)`), or the return from the `@layout` macro. This builds the layout of subplots.",
:link => "Symbol. How/whether to link axis limits between subplots. Values: `:none`, `:x` (x axes are linked by columns), `:y` (y axes are linked by rows), `:both` (x and y are linked), `:all` (every subplot is linked together regardless of layout position).",
:overwrite_figure => "Bool. Should we reuse the same GUI window/figure when plotting (true) or open a new one (false).",
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
:tex_output_standalone => "Bool. When writing tex output, should the source include a preamble for a standalone document class.",
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
:dpi => "Number. Dots Per Inch of output figures",
:thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.",
:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.",
:extra_kwargs => "Either one of (`:plot`, `:subplot`, `:series`) to specify for which element extra keyword args are collected or a KW (Dict{Symbol,Any}) to pass a map of extra keyword args which may be specific to a backend. Default: `:series`.\n Example: `pgfplotsx(); scatter(1:5, extra_kwargs=Dict(:subplot=>Dict(\"axis line shift\" => \"10pt\"))`",
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",
:warn_on_unsupported => "Bool. Warn on unsupported attributes, series types and marker shapes",
:plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)",
:background_color => "Color Type. Base color for all backgrounds.",
:background_color_outside => "Color Type or `:match` (matches `:background_color`). Color outside the plot area(s)",
:foreground_color => "Color Type. Base color for all foregrounds.",
:size => "NTuple{2,Int}. (width_px, height_px) of the whole Plot",
:pos => "NTuple{2,Int}. (left_px, top_px) position of the GUI window (note: currently unimplemented)",
:window_title => "String. Title of the window.",
:show => "Bool. Should this command open/refresh a GUI/display? This allows displaying in scripts or functions without explicitly calling `display`",
:layout => "Integer (number of subplots), NTuple{2,Integer} (grid dimensions), AbstractLayout (for example `grid(2,2)`), or the return from the `@layout` macro. This builds the layout of subplots.",
:link => "Symbol. How/whether to link axis limits between subplots. Values: `:none`, `:x` (x axes are linked by columns), `:y` (y axes are linked by rows), `:both` (x and y are linked), `:all` (every subplot is linked together regardless of layout position).",
:overwrite_figure => "Bool. Should we reuse the same GUI window/figure when plotting (true) or open a new one (false).",
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
:tex_output_standalone => "Bool. When writing tex output, should the source include a preamble for a standalone document class.",
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
:dpi => "Number. Dots Per Inch of output figures",
:thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.",
:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.",
:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.",
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",
# subplot args
:title => "String. Subplot title.",
:titlelocation => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`",
:titlefontfamily => "String or Symbol. Font family of subplot title.",
:titlefontsize => "Integer. Font pointsize of subplot title.",
:titlefonthalign => "Symbol. Font horizontal alignment of subplot title: :hcenter, :left, :right or :center",
:titlefontvalign => "Symbol. Font vertical alignment of subplot title: :vcenter, :top, :bottom or :center",
:titlefontrotation => "Real. Font rotation of subplot title",
:titlefontcolor => "Color Type. Font color of subplot title",
:background_color_subplot => "Color Type or `:match` (matches `:background_color`). Base background color of the subplot.",
:background_color_legend => "Color Type or `:match` (matches `:background_color_subplot`). Background color of the legend.",
:background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).",
:foreground_color_subplot => "Color Type or `:match` (matches `:foreground_color`). Base foreground color of the subplot.",
:foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
:foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.",
:color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.",
:legend => "Bool (show the legend?) or (x,y) tuple or Symbol (legend position) or angle or (angle,inout) tuple. Bottom left corner of legend is placed at (x,y). Symbol values: `:none`; `:best`; `:inline`; `:inside`; `:legend`; any valid combination of `:(outer ?)(top/bottom ?)(right/left ?)`, i.e.: `:top`, `:topright`, `:outerleft`, `:outerbottomright` ... (note: only some may be supported in each backend). Legend is positioned at (angle degrees) (so (90,:outer) is roughly equivalent to :outertop), close to the inside of the axes or the outside if inout=:outer.",
:legendfontfamily => "String or Symbol. Font family of legend entries.",
:legendfontsize => "Integer. Font pointsize of legend entries.",
:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center",
:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center",
:legendfontrotation => "Real. Font rotation of legend entries",
:legendfontcolor => "Color Type. Font color of legend entries",
:legendtitle => "String. Legend title.",
:legendtitlefontfamily => "String or Symbol. Font family of the legend title.",
:legendtitlefontsize => "Integer. Font pointsize the legend title.",
:legendtitlefonthalign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center",
:legendtitlefontvalign => "Symbol. Font vertical alignment of the legend title: :vcenter, :top, :bottom or :center",
:legendtitlefontrotation => "Real. Font rotation of the legend title",
:legendtitlefontcolor => "Color Type. Font color of the legend title",
:colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)",
:clims => "`:auto`, NTuple{2,Number}, or a function that takes series data in and returns NTuple{2,Number}. Fixes the limits of the colorbar.",
:colorbar_fontfamily => "String or Symbol. Font family of colobar entries.",
:colorbar_ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
:colorbar_tickfontfamily => "String or Symbol. Font family of colorbar tick labels.",
:colorbar_tickfontsize => "Integer. Font pointsize of colorbar tick entries.",
:colorbar_tickfontcolor => "Color Type. Font color of colorbar tick entries",
:colorbar_scale => "Symbol. Scale of the colorbar axis: `:none`, `:ln`, `:log2`, `:log10`",
:colorbar_formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.",
:legendfont => "Font. Font of legend items.",
:legendtitlefont => "Font. Font of the legend title.",
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
:annotationfontfamily => "String or Symbol. Font family of annotations.",
:annotationfontsize => "Integer. Font pointsize of annotations.",
:annotationhalign => "Symbol. horizontal alignment of annotations, :hcenter, :left, :right or :center.",
:annotationvalign => "Symbol. Vertical alignment of annotations, :vcenter, :top, :bottom or :center.",
:annotationrotation => "Float. Rotation of annotations in degrees.",
:annotationcolor => "Colorant or :match. Color of annotations.",
:projection => "Symbol or String. '3d' or 'polar'",
:aspect_ratio => "Symbol (:equal or :none) or Number. Plot area is resized so that 1 y-unit is the same size as `aspect_ratio` x-units. With `:none`, images inherit aspect ratio of the plot area.",
:margin => "Measure (multiply by `mm`, `px`, etc). Base for individual margins... not directly used. Specifies the extra padding around subplots.",
:left_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the left of the subplot.",
:top_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the top of the subplot.",
:right_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the right of the subplot.",
:bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.",
:subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.",
:colorbar_title => "String. Title of colorbar.",
:framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)",
:camera => "NTuple{2, Real}. Sets the view angle (azimuthal, elevation) for 3D plots",
:title => "String. Subplot title.",
:title_location => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`",
:titlefontfamily => "String or Symbol. Font family of subplot title.",
:titlefontsize => "Integer. Font pointsize of subplot title.",
:titlefonthalign => "Symbol. Font horizontal alignment of subplot title: :hcenter, :left, :right or :center",
:titlefontvalign => "Symbol. Font vertical alignment of subplot title: :vcenter, :top, :bottom or :center",
:titlefontrotation => "Real. Font rotation of subplot title",
:titlefontcolor => "Color Type. Font color of subplot title",
:background_color_subplot => "Color Type or `:match` (matches `:background_color`). Base background color of the subplot.",
:background_color_legend => "Color Type or `:match` (matches `:background_color_subplot`). Background color of the legend.",
:background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).",
:foreground_color_subplot => "Color Type or `:match` (matches `:foreground_color`). Base foreground color of the subplot.",
:foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
:foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.",
:color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.",
:legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` , `:inline` (note: only some may be supported in each backend)",
:legendfontfamily => "String or Symbol. Font family of legend entries.",
:legendfontsize => "Integer. Font pointsize of legend entries.",
:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center",
:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center",
:legendfontrotation => "Real. Font rotation of legend entries",
:legendfontcolor => "Color Type. Font color of legend entries",
:legendtitlefontfamily => "String or Symbol. Font family of the legend title.",
:legendtitlefontsize => "Integer. Font pointsize the legend title.",
:legendtitlefonthalign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center",
:legendtitlefontvalign => "Symbol. Font vertical alignment of the legend title: :vcenter, :top, :bottom or :center",
:legendtitlefontrotation => "Real. Font rotation of the legend title",
:legendtitlefontcolor => "Color Type. Font color of the legend title",
:colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)",
:clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.",
:legendfont => "Font. Font of legend items.",
:legendtitlefont => "Font. Font of the legend title.",
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
:projection => "Symbol or String. '3d' or 'polar'",
:aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `aspect_ratio` x-units.",
:margin => "Measure (multiply by `mm`, `px`, etc). Base for individual margins... not directly used. Specifies the extra padding around subplots.",
:left_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the left of the subplot.",
:top_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the top of the subplot.",
:right_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the right of the subplot.",
:bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.",
:subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.",
:colorbar_title => "String. Title of colorbar.",
:framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)",
:camera => "NTuple{2, Real}. Sets the view angle (azimuthal, elevation) for 3D plots",
# axis args
:guide => "String. Axis guide (label).",
:guide_position => "Symbol. Position of axis guides: :top, :bottom, :left or :right",
:lims => """
NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example).
`:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]
`:symmetric` sets the limits to be symmetric around zero.
Set widen=true to widen the specified limits (as occurs when lims are not specified).
""",
:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`",
:rotation => "Number. Degrees rotation of tick labels.",
:flip => "Bool. Should we flip (reverse) the axis?",
:formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.",
:tickfontfamily => "String or Symbol. Font family of tick labels.",
:tickfontsize => "Integer. Font pointsize of tick labels.",
:tickfonthalign => "Symbol. Font horizontal alignment of tick labels: :hcenter, :left, :right or :center",
:tickfontvalign => "Symbol. Font vertical alignment of tick labels: :vcenter, :top, :bottom or :center",
:tickfontrotation => "Real. Font rotation of tick labels",
:tickfontcolor => "Color Type. Font color of tick labels",
:guidefontfamily => "String or Symbol. Font family of axes guides.",
:guidefontsize => "Integer. Font pointsize of axes guides.",
:guidefonthalign => "Symbol. Font horizontal alignment of axes guides: :hcenter, :left, :right or :center",
:guidefontvalign => "Symbol. Font vertical alignment of axes guides: :vcenter, :top, :bottom or :center",
:guidefontrotation => "Real. Font rotation of axes guides",
:guidefontcolor => "Color Type. Font color of axes guides",
:foreground_color_axis => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis ticks.",
:foreground_color_border => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of plot area border (spines).",
:foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.",
:foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).",
:mirror => "Bool. Switch the side of the tick labels (right or top).",
:grid => "Bool, Symbol, String or `nothing`. Show the grid lines? `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`",
:foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.",
:gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.",
:gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)",
:gridlinewidth => "Number. Width of the grid lines (in pixels)",
:guide => "String. Axis guide (label).",
:guide_position => "Symbol. Position of axis guides: :top, :bottom, :left or :right",
:lims => "NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example). `:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]",
:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`",
:rotation => "Number. Degrees rotation of tick labels.",
:flip => "Bool. Should we flip (reverse) the axis?",
:formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.",
:tickfontfamily => "String or Symbol. Font family of tick labels.",
:tickfontsize => "Integer. Font pointsize of tick labels.",
:tickfonthalign => "Symbol. Font horizontal alignment of tick labels: :hcenter, :left, :right or :center",
:tickfontvalign => "Symbol. Font vertical alignment of tick labels: :vcenter, :top, :bottom or :center",
:tickfontrotation => "Real. Font rotation of tick labels",
:tickfontcolor => "Color Type. Font color of tick labels",
:guidefontfamily => "String or Symbol. Font family of axes guides.",
:guidefontsize => "Integer. Font pointsize of axes guides.",
:guidefonthalign => "Symbol. Font horizontal alignment of axes guides: :hcenter, :left, :right or :center",
:guidefontvalign => "Symbol. Font vertical alignment of axes guides: :vcenter, :top, :bottom or :center",
:guidefontrotation => "Real. Font rotation of axes guides",
:guidefontcolor => "Color Type. Font color of axes guides",
:foreground_color_axis => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis ticks.",
:foreground_color_border => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of plot area border (spines).",
:foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.",
:foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).",
:mirror => "Bool. Switch the side of the tick labels (right or top).",
:grid => "Bool, Symbol, String or `nothing`. Show the grid lines? `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`",
:foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.",
:gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.",
:gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)",
:gridlinewidth => "Number. Width of the grid lines (in pixels)",
:foreground_color_minor_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of minor grid lines.",
:minorgrid => "Bool. Adds minor grid lines and ticks to the plot. Set minorticks to change number of gridlines",
:minorticks => "Integer. Intervals to divide the gap between major ticks into",
:minorgridalpha => "Number in [0,1]. The alpha/opacity override for the minorgrid lines.",
:minorgridstyle => "Symbol. Style of the minor grid lines. Choose from $(_allStyles)",
:minorgridlinewidth => "Number. Width of the minor grid lines (in pixels)",
:tick_direction => "Symbol. Direction of the ticks. `:in`, `:out` or `:none`",
:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`",
:widen => """
Bool or :auto. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders.
Defaults to `:auto`, which widens unless limits were manually set.
""",
:draw_arrow => "Bool. Draw arrow at the end of the axis.",
:minorgrid => "Bool. Adds minor grid lines and ticks to the plot. Set minorticks to change number of gridlines",
:minorticks => "Integer. Intervals to divide the gap between major ticks into",
:minorgridalpha => "Number in [0,1]. The alpha/opacity override for the minorgrid lines.",
:minorgridstyle => "Symbol. Style of the minor grid lines. Choose from $(_allStyles)",
:minorgridlinewidth => "Number. Width of the minor grid lines (in pixels)",
:tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`",
:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`",
:widen => "Bool. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders. Defaults to `true`.",
:draw_arrow => "Bool. Draw arrow at the end of the axis.",
)
+227 -438
View File
@@ -1,46 +1,26 @@
function makeplural(s::Symbol)
str = string(s)
if last(str) != 's'
return Symbol(string(s,"s"))
end
return s
end
function make_non_underscore(s::Symbol)
str = string(s)
str = replace(str, "_" => "")
return Symbol(str)
end
const _keyAliases = Dict{Symbol,Symbol}()
function add_aliases(sym::Symbol, aliases::Symbol...)
for alias in aliases
if haskey(_keyAliases, alias) || alias === sym
return nothing
if haskey(_keyAliases, alias)
error("Already an alias $alias => $(_keyAliases[alias])... can't also alias $sym")
end
_keyAliases[alias] = sym
end
return nothing
end
function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol})
for (k,v) in aliases
s = string(k)
if '_' in s
aliases[make_non_underscore(k)] = v
aliases[Symbol(replace(s, "_" => ""))] = v
end
end
end
function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol}, args::Vector{Symbol})
for arg in args
s = string(arg)
if '_' in s
aliases[make_non_underscore(arg)] = arg
end
end
end
# ------------------------------------------------------------
const _allAxes = [:auto, :left, :right]
@@ -51,10 +31,10 @@ const _axesAliases = Dict{Symbol,Symbol}(
)
const _3dTypes = [
:path3d, :scatter3d, :surface, :wireframe, :contour3d, :volume, :mesh3d
:path3d, :scatter3d, :surface, :wireframe, :contour3d, :volume
]
const _allTypes = vcat([
:none, :line, :path, :steppre, :stepmid, :steppost, :sticks, :scatter,
:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
:heatmap, :hexbin, :barbins, :barhist, :histogram, :scatterbins,
:scatterhist, :stepbins, :stephist, :bins2d, :histogram2d, :histogram3d,
:density, :bar, :hline, :vline,
@@ -101,7 +81,7 @@ const _typeAliases = Dict{Symbol,Symbol}(
add_non_underscore_aliases!(_typeAliases)
const _histogram_like = [:histogram, :barhist, :barbins]
const _line_like = [:line, :path, :steppre, :stepmid, :steppost]
const _line_like = [:line, :path, :steppre, :steppost]
const _surface_like = [:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image]
like_histogram(seriestype::Symbol) = seriestype in _histogram_like
@@ -124,81 +104,56 @@ const _styleAliases = Dict{Symbol,Symbol}(
:ddd => :dashdotdot,
)
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 _allMarkers = vcat(:none, :auto, _shape_keys) #sort(collect(keys(_shapes))))
const _markerAliases = Dict{Symbol,Symbol}(
:n => :none,
:no => :none,
:a => :auto,
:ellipse => :circle,
:c => :circle,
:circ => :circle,
:square => :rect,
:sq => :rect,
:r => :rect,
:d => :diamond,
:^ => :utriangle,
:ut => :utriangle,
:utri => :utriangle,
:uptri => :utriangle,
:uptriangle => :utriangle,
:v => :dtriangle,
:V => :dtriangle,
:dt => :dtriangle,
:dtri => :dtriangle,
:downtri => :dtriangle,
:downtriangle => :dtriangle,
:> => :rtriangle,
:rt => :rtriangle,
:rtri => :rtriangle,
:n => :none,
:no => :none,
:a => :auto,
:ellipse => :circle,
:c => :circle,
:circ => :circle,
:square => :rect,
:sq => :rect,
:r => :rect,
:d => :diamond,
:^ => :utriangle,
:ut => :utriangle,
:utri => :utriangle,
:uptri => :utriangle,
:uptriangle => :utriangle,
:v => :dtriangle,
:V => :dtriangle,
:dt => :dtriangle,
:dtri => :dtriangle,
:downtri => :dtriangle,
:downtriangle => :dtriangle,
:> => :rtriangle,
:rt => :rtriangle,
:rtri => :rtriangle,
:righttri => :rtriangle,
:righttriangle => :rtriangle,
:< => :ltriangle,
:lt => :ltriangle,
:ltri => :ltriangle,
:< => :ltriangle,
:lt => :ltriangle,
:ltri => :ltriangle,
:lighttri => :ltriangle,
:lighttriangle => :ltriangle,
# :+ => :cross,
:plus => :cross,
# :x => :xcross,
:X => :xcross,
:star => :star5,
:s => :star5,
:star1 => :star5,
:s2 => :star8,
:star2 => :star8,
:p => :pentagon,
:pent => :pentagon,
:h => :hexagon,
:hex => :hexagon,
:hep => :heptagon,
:o => :octagon,
:oct => :octagon,
:spike => :vline,
# :+ => :cross,
:plus => :cross,
# :x => :xcross,
:X => :xcross,
:star => :star5,
:s => :star5,
:star1 => :star5,
:s2 => :star8,
:star2 => :star8,
:p => :pentagon,
:pent => :pentagon,
:h => :hexagon,
:hex => :hexagon,
:hep => :heptagon,
:o => :octagon,
:oct => :octagon,
:spike => :vline,
)
const _positionAliases = Dict{Symbol,Symbol}(
@@ -273,78 +228,71 @@ const _bar_width = 0.8
# -----------------------------------------------------------------------------
const _series_defaults = KW(
:label => :auto,
:colorbar_entry => true,
:seriescolor => :auto,
:seriesalpha => nothing,
:seriestype => :path,
:linestyle => :solid,
:linewidth => :auto,
:linecolor => :auto,
:linealpha => nothing,
:fillrange => nothing, # ribbons, areas, etc
:fillcolor => :match,
:fillalpha => nothing,
:markershape => :none,
:markercolor => :match,
:markeralpha => nothing,
:markersize => 4,
:markerstrokestyle => :solid,
:markerstrokewidth => 1,
:markerstrokecolor => :match,
:markerstrokealpha => nothing,
:bins => :auto, # number of bins for hists
:smooth => false, # regression line?
:group => nothing, # groupby vector
:x => nothing,
:y => nothing,
:z => nothing, # depth for contour, surface, etc
:marker_z => nothing, # value for color scale
:line_z => nothing,
:fill_z => nothing,
:levels => 15,
:orientation => :vertical,
:bar_position => :overlay, # for bar plots and histograms: could also be stack (stack up) or dodge (side by side)
:bar_width => nothing,
:bar_edges => false,
:xerror => nothing,
:yerror => nothing,
:zerror => nothing,
:ribbon => nothing,
:quiver => nothing,
:arrow => nothing, # allows for adding arrows to line/path... call `arrow(args...)`
:normalize => false, # do we want a normalized histogram?
:weights => nothing, # optional weights for histograms (1D and 2D)
:show_empty_bins => false, # should empty bins in 2D histogram be colored as zero (otherwise they are transparent)
:contours => false, # add contours to 3d surface and wireframe plots
:contour_labels => false,
:subplot => :auto, # which subplot(s) does this series belong to?
:label => "AUTO",
:colorbar_entry => true,
:seriescolor => :auto,
:seriesalpha => nothing,
:seriestype => :path,
:linestyle => :solid,
:linewidth => :auto,
:linecolor => :auto,
:linealpha => nothing,
:fillrange => nothing, # ribbons, areas, etc
:fillcolor => :match,
:fillalpha => nothing,
:markershape => :none,
:markercolor => :match,
:markeralpha => nothing,
:markersize => 4,
:markerstrokestyle => :solid,
:markerstrokewidth => 1,
:markerstrokecolor => :match,
:markerstrokealpha => nothing,
:bins => :auto, # number of bins for hists
:smooth => false, # regression line?
:group => nothing, # groupby vector
:x => nothing,
:y => nothing,
:z => nothing, # depth for contour, surface, etc
:marker_z => nothing, # value for color scale
:line_z => nothing,
:fill_z => nothing,
:levels => 15,
:orientation => :vertical,
:bar_position => :overlay, # for bar plots and histograms: could also be stack (stack up) or dodge (side by side)
:bar_width => nothing,
:bar_edges => false,
:xerror => nothing,
:yerror => nothing,
:zerror => nothing,
:ribbon => nothing,
:quiver => nothing,
:arrow => nothing, # allows for adding arrows to line/path... call `arrow(args...)`
:normalize => false, # do we want a normalized histogram?
:weights => nothing, # optional weights for histograms (1D and 2D)
:show_empty_bins => false, # should empty bins in 2D histogram be colored as zero (otherwise they are transparent)
:contours => false, # add contours to 3d surface and wireframe plots
:contour_labels => false,
:match_dimensions => false, # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196
# this ONLY effects whether or not the z-matrix is transposed for a heatmap display!
:subplot => :auto, # which subplot(s) does this series belong to?
:series_annotations => nothing, # a list of annotations which apply to the coordinates of this series
:primary => true, # when true, this "counts" as a series for color selection, etc. the main use is to allow
# one logical series to be broken up (path and markers, for example)
:hover => nothing, # text to display when hovering over the data points
:stride => (1,1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride.
:connections => nothing, # tuple of arrays to specifiy connectivity of a 3d mesh
:extra_kwargs => Dict()
)
const _plot_defaults = KW(
:plot_title => "",
:plot_titlefontsize => 16,
:plot_title_location => :center, # also :left or :right
:plot_titlefontfamily => :match,
:plot_titlefonthalign => :hcenter,
:plot_titlefontvalign => :vcenter,
:plot_titlefontrotation => 0.0,
:plot_titlefontcolor => :match,
:background_color => colorant"white", # default for all backgrounds,
:background_color_outside => :match, # background outside grid,
:foreground_color => :auto, # default for all foregrounds, and title color,
:fontfamily => "sans-serif",
:size => (600,400),
:pos => (0,0),
:window_title => "Plots.jl",
:window_title => "Plots.jl",
:show => false,
:layout => 1,
:link => :none,
@@ -356,128 +304,100 @@ const _plot_defaults = KW(
:dpi => DPI, # dots per inch for images, etc
:thickness_scaling => 1,
:display_type => :auto,
:warn_on_unsupported => true,
:extra_plot_kwargs => Dict(),
:extra_kwargs => :series, # directs collection of extra_kwargs
:extra_kwargs => KW(),
)
const _subplot_defaults = KW(
:title => "",
:titlelocation => :center, # also :left or :right
:fontfamily_subplot => :match,
:titlefontfamily => :match,
:titlefontsize => 14,
:titlefonthalign => :hcenter,
:titlefontvalign => :vcenter,
:titlefontrotation => 0.0,
:titlefontcolor => :match,
:background_color_subplot => :match, # default for other bg colors... match takes plot default
:background_color_legend => :match, # background of legend
:background_color_inside => :match, # background inside grid
:foreground_color_subplot => :match, # default for other fg colors... match takes plot default
:foreground_color_legend => :match, # foreground of legend
:foreground_color_title => :match, # title color
:color_palette => :auto,
:legend => :best,
:legendtitle => nothing,
:colorbar => :legend,
:clims => :auto,
:colorbar_fontfamily => :match,
:colorbar_ticks => :auto,
:colorbar_tickfontfamily => :match,
:colorbar_tickfontsize => 8,
:colorbar_tickfonthalign => :hcenter,
:colorbar_tickfontvalign => :vcenter,
:colorbar_tickfontrotation => 0.0,
:colorbar_tickfontcolor => :match,
:colorbar_scale => :identity,
:colorbar_formatter => :auto,
:colorbar_discrete_values => [],
:colorbar_continuous_values => zeros(0),
:legendfontfamily => :match,
:legendfontsize => 8,
:legendfonthalign => :hcenter,
:legendfontvalign => :vcenter,
:legendfontrotation => 0.0,
:legendfontcolor => :match,
:legendtitlefontfamily => :match,
:legendtitlefontsize => 11,
:legendtitlefonthalign => :hcenter,
:legendtitlefontvalign => :vcenter,
:legendtitlefontrotation => 0.0,
:legendtitlefontcolor => :match,
:annotations => [], # annotation tuples... list of (x,y,annotation)
:annotationfontfamily => :match,
:annotationfontsize => 14,
:annotationhalign => :hcenter,
:annotationvalign => :vcenter,
:annotationrotation => 0.0,
:annotationcolor => :match,
:projection => :none, # can also be :polar or :3d
:aspect_ratio => :auto, # choose from :none or :equal
:margin => 1mm,
:left_margin => :match,
:top_margin => :match,
:right_margin => :match,
:bottom_margin => :match,
:subplot_index => -1,
:colorbar_title => "",
:colorbar_titlefontsize => 10,
:colorbar_title_location => :center, # also :left or :right
:colorbar_titlefontfamily => :match,
:colorbar_titlefonthalign => :hcenter,
:colorbar_titlefontvalign => :vcenter,
:colorbar_titlefontrotation => 0.0,
:colorbar_titlefontcolor => :match,
:framestyle => :axes,
:camera => (30,30),
:extra_kwargs => Dict()
:title => "",
:title_location => :center, # also :left or :right
:fontfamily_subplot => :match,
:titlefontfamily => :match,
:titlefontsize => 14,
:titlefonthalign => :hcenter,
:titlefontvalign => :vcenter,
:titlefontrotation => 0.0,
:titlefontcolor => :match,
:background_color_subplot => :match, # default for other bg colors... match takes plot default
:background_color_legend => :match, # background of legend
:background_color_inside => :match, # background inside grid
:foreground_color_subplot => :match, # default for other fg colors... match takes plot default
:foreground_color_legend => :match, # foreground of legend
:foreground_color_title => :match, # title color
:color_palette => :auto,
:legend => :best,
:legendtitle => nothing,
:colorbar => :legend,
:clims => :auto,
:legendfontfamily => :match,
:legendfontsize => 8,
:legendfonthalign => :hcenter,
:legendfontvalign => :vcenter,
:legendfontrotation => 0.0,
:legendfontcolor => :match,
:legendtitlefontfamily => :match,
:legendtitlefontsize => 11,
:legendtitlefonthalign => :hcenter,
:legendtitlefontvalign => :vcenter,
:legendtitlefontrotation => 0.0,
:legendtitlefontcolor => :match,
:annotations => [], # annotation tuples... list of (x,y,annotation)
:projection => :none, # can also be :polar or :3d
:aspect_ratio => :auto, # choose from :none or :equal
:margin => 1mm,
:left_margin => :match,
:top_margin => :match,
:right_margin => :match,
:bottom_margin => :match,
:subplot_index => -1,
:colorbar_title => "",
:framestyle => :axes,
:camera => (30,30),
)
const _axis_defaults = KW(
:guide => "",
:guide_position => :auto,
:lims => :auto,
:ticks => :auto,
:scale => :identity,
:rotation => 0,
:flip => false,
:link => [],
:tickfontfamily => :match,
:tickfontsize => 8,
:tickfonthalign => :hcenter,
:tickfontvalign => :vcenter,
:tickfontrotation => 0.0,
:tickfontcolor => :match,
:guidefontfamily => :match,
:guidefontsize => 11,
:guidefonthalign => :hcenter,
:guidefontvalign => :vcenter,
:guidefontrotation => 0.0,
:guidefontcolor => :match,
:foreground_color_axis => :match, # axis border/tick colors,
:foreground_color_border => :match, # plot area border/spines,
:foreground_color_text => :match, # tick text color,
:foreground_color_guide => :match, # guide text color,
:discrete_values => [],
:formatter => :auto,
:mirror => false,
:grid => true,
:foreground_color_grid => :match, # grid color
:gridalpha => 0.1,
:gridstyle => :solid,
:gridlinewidth => 0.5,
:guide => "",
:guide_position => :auto,
:lims => :auto,
:ticks => :auto,
:scale => :identity,
:rotation => 0,
:flip => false,
:link => [],
:tickfontfamily => :match,
:tickfontsize => 8,
:tickfonthalign => :hcenter,
:tickfontvalign => :vcenter,
:tickfontrotation => 0.0,
:tickfontcolor => :match,
:guidefontfamily => :match,
:guidefontsize => 11,
:guidefonthalign => :hcenter,
:guidefontvalign => :vcenter,
:guidefontrotation => 0.0,
:guidefontcolor => :match,
:foreground_color_axis => :match, # axis border/tick colors,
:foreground_color_border => :match, # plot area border/spines,
:foreground_color_text => :match, # tick text color,
:foreground_color_guide => :match, # guide text color,
:discrete_values => [],
:formatter => :auto,
:mirror => false,
:grid => true,
:foreground_color_grid => :match, # grid color
:gridalpha => 0.1,
:gridstyle => :solid,
:gridlinewidth => 0.5,
:foreground_color_minor_grid => :match, # grid color
:minorgridalpha => 0.05,
:minorgridstyle => :solid,
:minorgridlinewidth => 0.5,
:tick_direction => :in,
:minorticks => false,
:minorgrid => false,
:showaxis => true,
:widen => :auto,
:draw_arrow => false,
:minorgridalpha => 0.05,
:minorgridstyle => :solid,
:minorgridlinewidth => 0.5,
:tick_direction => :in,
:minorticks => false,
:minorgrid => false,
:showaxis => true,
:widen => true,
:draw_arrow => false,
)
const _suppress_warnings = Set{Symbol}([
@@ -525,7 +445,6 @@ const _initial_axis_defaults = deepcopy(_axis_defaults)
const _initial_fontsizes = Dict(:titlefontsize => _subplot_defaults[:titlefontsize],
:legendfontsize => _subplot_defaults[:legendfontsize],
:legendtitlefontsize => _subplot_defaults[:legendtitlefontsize],
:annotationfontsize => _subplot_defaults[:annotationfontsize],
:tickfontsize => _axis_defaults[:tickfontsize],
:guidefontsize => _axis_defaults[:guidefontsize])
@@ -538,7 +457,7 @@ const _subplot_args = sort(union(collect(keys(_subplot_defaults))))
const _plot_args = sort(union(collect(keys(_plot_defaults))))
const _magic_axis_args = [:axis, :tickfont, :guidefont, :grid, :minorgrid]
const _magic_subplot_args = [:titlefont, :legendfont, :legendtitlefont, :plot_titlefont, :colorbar_titlefont]
const _magic_subplot_args = [:titlefont, :legendfont, :legendtitlefont, ]
const _magic_series_args = [:line, :marker, :fill]
const _all_axis_args = sort(union([_axis_args; _magic_axis_args]))
@@ -547,7 +466,7 @@ const _all_series_args = sort(union([_series_args; _magic_series_args]))
const _all_plot_args = _plot_args
const _all_args =
sort(union([_all_axis_args; _all_subplot_args; _all_series_args; _all_plot_args]))
sort([_all_axis_args; _all_subplot_args; _all_series_args; _all_plot_args])
is_subplot_attr(k) = k in _all_subplot_args
is_series_attr(k) = k in _all_series_args
@@ -558,7 +477,13 @@ RecipesBase.is_key_supported(k::Symbol) = is_attr_supported(k)
is_default_attribute(k) = k in _internal_args || k in _all_args || is_axis_attr_noletter(k)
# -----------------------------------------------------------------------------
autopick_ignore_none_auto(arr::AVec, idx::Integer) = _cycle(setdiff(arr, [:none, :auto]), idx)
makeplural(s::Symbol) = Symbol(string(s,"s"))
autopick(arr::AVec, idx::Integer) = arr[mod1(idx,length(arr))]
autopick(notarr, idx::Integer) = notarr
autopick_ignore_none_auto(arr::AVec, idx::Integer) = autopick(setdiff(arr, [:none, :auto]), idx)
autopick_ignore_none_auto(notarr, idx::Integer) = notarr
function aliasesAndAutopick(plotattributes::AKW, sym::Symbol, aliases::Dict{Symbol,Symbol}, options::AVec, plotIndex::Int)
@@ -576,13 +501,6 @@ end
# -----------------------------------------------------------------------------
# margin
add_aliases(:left_margin , :leftmargin )
add_aliases(:top_margin , :topmargin)
add_aliases(:bottom_margin , :bottommargin)
add_aliases(:right_margin ,:rightmargin)
# colors
add_aliases(:seriescolor, :c, :color, :colour)
add_aliases(:linecolor, :lc, :lcolor, :lcolour, :linecolour)
@@ -664,7 +582,6 @@ add_aliases(:fill_z, :fillz, :fz, :surfacecolor, :surfacecolour, :sc, :surfcolor
add_aliases(:legend, :leg, :key)
add_aliases(:legendtitle, :legend_title, :labeltitle, :label_title, :leg_title, :key_title)
add_aliases(:colorbar, :cb, :cbar, :colorkey)
add_aliases(:colorbar_title, :colorbartitle, :cb_title, :cbtitle, :cbartitle, :cbar_title, :colorkeytitle, :colorkey_title)
add_aliases(:clims, :clim, :cbarlims, :cbar_lims, :climits, :color_limits)
add_aliases(:smooth, :regression, :reg)
add_aliases(:levels, :nlevels, :nlev, :levs)
@@ -680,9 +597,10 @@ add_aliases(:quiver, :velocity, :quiver2d, :gradient, :vectorfield)
add_aliases(:normalize, :norm, :normed, :normalized)
add_aliases(:show_empty_bins, :showemptybins, :showempty, :show_empty)
add_aliases(:aspect_ratio, :aspectratio, :axis_ratio, :axisratio, :ratio)
add_aliases(:match_dimensions, :transpose, :transpose_z)
add_aliases(:subplot, :sp, :subplt, :splt)
add_aliases(:projection, :proj)
add_aliases(:titlelocation, :title_location, :title_loc, :titleloc, :title_position, :title_pos, :titlepos, :titleposition, :title_align, :title_alignment)
add_aliases(:title_location, :title_loc, :titleloc, :title_position, :title_pos, :titlepos, :titleposition, :title_align, :title_alignment)
add_aliases(:series_annotations, :series_ann, :seriesann, :series_anns, :seriesanns, :series_annotation, :text, :txt, :texts, :txts)
add_aliases(:html_output_format, :format, :fmt, :html_format)
add_aliases(:orientation, :direction, :dir)
@@ -696,14 +614,13 @@ add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyl
add_aliases(:tick_direction, :tickdirection, :tick_dir, :tickdir, :tick_orientation, :tickorientation, :tick_or, :tickor)
add_aliases(:camera, :cam, :viewangle, :view_angle)
add_aliases(:contour_labels, :contourlabels, :clabels, :clabs)
add_aliases(:warn_on_unsupported, :warn)
# add all pluralized forms to the _keyAliases dict
for arg in _all_args
add_aliases(arg, makeplural(arg))
for arg in keys(_series_defaults)
_keyAliases[makeplural(arg)] = arg
end
# add all non_underscored forms to the _keyAliases
add_non_underscore_aliases!(_keyAliases)
# -----------------------------------------------------------------------------
@@ -740,7 +657,7 @@ function default(k::Symbol)
return _axis_defaults_byletter[letter][key]
end
k == :letter && return k # for type recipe processing
return missing
k in _suppress_warnings || error("Unknown key: ", k)
end
function default(k::Symbol, v)
@@ -763,10 +680,7 @@ function default(k::Symbol, v)
k in _suppress_warnings || error("Unknown key: ", k)
end
function default(; reset = true, kw...)
if reset && isempty(kw)
reset_defaults()
end
function default(; kw...)
kw = KW(kw)
RecipesPipeline.preprocess_attributes!(kw)
for (k,v) in kw
@@ -1025,9 +939,8 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
replaceAliases!(plotattributes, _keyAliases)
# handle axis args common to all axis
args = wraptuple(RecipesPipeline.pop_kw!(plotattributes, :axis, ()))
showarg = wraptuple(RecipesPipeline.pop_kw!(plotattributes, :showaxis, ()))
for arg in wraptuple((args..., showarg...))
args = RecipesPipeline.pop_kw!(plotattributes, :axis, ())
for arg in wraptuple(args)
for letter in (:x, :y, :z)
process_axis_arg!(plotattributes, arg, letter)
end
@@ -1043,9 +956,9 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end
end
# vline and others accesses the y argument but actually maps it to the x axis.
# vline accesses the y argument but actually maps it to the x axis.
# Hence, we have to swap formatters
if treats_y_as_x(get(plotattributes, :seriestype, :path))
if get(plotattributes, :seriestype, :path) == :vline
xformatter = get(plotattributes, :xformatter, :auto)
yformatter = get(plotattributes, :yformatter, :auto)
plotattributes[:xformatter] = yformatter
@@ -1114,7 +1027,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end
# fonts
for fontname in (:titlefont, :legendfont, :legendtitlefont, :plot_titlefont, :colorbar_titlefont)
for fontname in (:titlefont, :legendfont, :legendtitlefont)
args = RecipesPipeline.pop_kw!(plotattributes, fontname, ())
for arg in wraptuple(args)
processFontArg!(plotattributes, fontname, arg)
@@ -1139,7 +1052,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
RecipesPipeline.reset_kw!(plotattributes, :marker)
if haskey(plotattributes, :markershape)
plotattributes[:markershape] = _replace_markershape(plotattributes[:markershape])
if plotattributes[:markershape] == :none && get(plotattributes, :seriestype, :path) in (:scatter, :scatterbins, :scatterhist, :scatter3d) #the default should be :auto, not :none, so that :none can be set explicitly and would be respected
if plotattributes[:markershape] == :none && plotattributes[:seriestype] in (:scatter, :scatterbins, :scatterhist, :scatter3d) #the default should be :auto, not :none, so that :none can be set explicitly and would be respected
plotattributes[:markershape] = :circle
end
elseif anymarker
@@ -1195,6 +1108,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatsPlots)
@warn("seriestype $st has been moved to StatsPlots. To use: \`Pkg.add(\"StatsPlots\"); using StatsPlots\`")
end
return
end
@@ -1208,26 +1122,20 @@ function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes)
empty!(_to_warn)
bend = backend_name(pkg)
already_warned = get!(_already_warned, bend, Set{Symbol}())
extra_kwargs = Dict{Symbol,Any}()
for k in keys(plotattributes)
is_attr_supported(pkg, k) && continue
k in _suppress_warnings && continue
default_value = default(k)
if ismissing(default_value)
extra_kwargs[k] = pop_kw!(plotattributes, k)
elseif plotattributes[k] != default(k)
if plotattributes[k] != default(k)
k in already_warned || push!(_to_warn, k)
end
end
if !isempty(_to_warn) &&
!get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported])
if !isempty(_to_warn)
for k in sort(collect(_to_warn))
push!(already_warned, k)
@warn("Keyword argument $k not supported with $pkg. Choose from: $(supported_attrs(pkg))")
end
end
return extra_kwargs
end
# _markershape_supported(pkg::AbstractBackend, shape::Symbol) = shape in supported_markers(pkg)
@@ -1235,9 +1143,6 @@ end
# _markershape_supported(pkg::AbstractBackend, shapes::AVec) = all([_markershape_supported(pkg, shape) for shape in shapes])
function warn_on_unsupported(pkg::AbstractBackend, plotattributes)
if !get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported])
return
end
if !is_seriestype_supported(pkg, plotattributes[:seriestype])
@warn("seriestype $(plotattributes[:seriestype]) is unsupported with $pkg. Choose from: $(supported_seriestypes(pkg))")
end
@@ -1250,9 +1155,6 @@ function warn_on_unsupported(pkg::AbstractBackend, plotattributes)
end
function warn_on_unsupported_scales(pkg::AbstractBackend, plotattributes::AKW)
if !get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported])
return
end
for k in (:xscale, :yscale, :zscale, :scale)
if haskey(plotattributes, k)
v = plotattributes[k]
@@ -1280,8 +1182,6 @@ end
convertLegendValue(val::Bool) = val ? :best : :none
convertLegendValue(val::Nothing) = :none
convertLegendValue(v::Tuple{S,T}) where {S<:Real, T<:Real} = v
convertLegendValue(v::Tuple{<:Real,Symbol}) = v
convertLegendValue(v::Real) = v
convertLegendValue(v::AbstractArray) = map(convertLegendValue, v)
# -----------------------------------------------------------------------------
@@ -1347,27 +1247,18 @@ const _match_map = KW(
:background_color_inside => :background_color_subplot,
:foreground_color_legend => :foreground_color_subplot,
:foreground_color_title => :foreground_color_subplot,
:left_margin => :margin,
:top_margin => :margin,
:right_margin => :margin,
:bottom_margin => :margin,
:left_margin => :margin,
:top_margin => :margin,
:right_margin => :margin,
:bottom_margin => :margin,
:titlefontfamily => :fontfamily_subplot,
:titlefontcolor => :foreground_color_subplot,
:legendfontfamily => :fontfamily_subplot,
:legendfontcolor => :foreground_color_subplot,
:legendtitlefontfamily => :fontfamily_subplot,
:titlefontcolor => :foreground_color_subplot,
:legendfontcolor => :foreground_color_subplot,
:legendtitlefontcolor => :foreground_color_subplot,
:colorbar_fontfamily => :fontfamily_subplot,
:colorbar_titlefontfamily => :fontfamily_subplot,
:colorbar_titlefontcolor => :foreground_color_subplot,
:colorbar_tickfontfamily => :fontfamily_subplot,
:colorbar_tickfontcolor => :foreground_color_subplot,
:plot_titlefontfamily => :fontfamily,
:plot_titlefontcolor => :foreground_color,
:tickfontcolor => :foreground_color_text,
:guidefontcolor => :foreground_color_guide,
:annotationfontfamily => :fontfamily_subplot,
:annotationcolor => :foreground_color_subplot,
)
# these can match values from the parent container (axis --> subplot --> plot)
@@ -1505,7 +1396,8 @@ end
function _update_subplot_colors(sp::Subplot)
# background colors
color_or_nothing!(sp.attr, :background_color_subplot)
sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], 30)
bg = plot_color(sp[:background_color_subplot])
sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], bg, 30)
color_or_nothing!(sp.attr, :background_color_legend)
color_or_nothing!(sp.attr, :background_color_inside)
@@ -1591,18 +1483,9 @@ function _update_subplot_args(plt::Plot, sp::Subplot, plotattributes_in, subplot
_update_subplot_periphery(sp, anns)
_update_subplot_colors(sp)
lims_warned = false
for letter in (:x, :y, :z)
_update_axis(plt, sp, plotattributes_in, letter, subplot_index)
lk = Symbol(letter, :lims)
# warn against using `Range` in x,y,z lims
if !lims_warned && haskey(plotattributes_in, lk) && plotattributes_in[lk] isa AbstractRange
@warn("lims should be a Tuple, not $(typeof(plotattributes_in[lk])).")
lims_warned = true
end
end
_update_subplot_colorbars(sp)
end
# -----------------------------------------------------------------------------
@@ -1617,9 +1500,9 @@ end
# and assigns a color automatically
function get_series_color(c, sp::Subplot, n::Int, seriestype)
if c == :auto
c = like_surface(seriestype) ? cgrad() : _cycle(sp[:color_palette], n)
c = like_surface(seriestype) ? cgrad() : autopick(sp[:color_palette], n)
elseif isa(c, Int)
c = _cycle(sp[:color_palette], c)
c = autopick(sp[:color_palette], c)
end
plot_color(c)
end
@@ -1629,13 +1512,7 @@ function get_series_color(c::AbstractArray, sp::Subplot, n::Int, seriestype)
end
function ensure_gradient!(plotattributes::AKW, csym::Symbol, asym::Symbol)
if plotattributes[csym] isa ColorPalette
α = nothing
if !(plotattributes[asym] isa AbstractVector)
α = plotattributes[asym]
end
plotattributes[csym] = cgrad(plotattributes[csym], categorical = true, alpha = α)
elseif !(plotattributes[csym] isa ColorGradient)
if !isa(plotattributes[csym], ColorGradient)
plotattributes[csym] = typeof(plotattributes[asym]) <: AbstractVector ? cgrad() : cgrad(alpha = plotattributes[asym])
end
end
@@ -1654,20 +1531,6 @@ function _slice_series_args!(plotattributes::AKW, plt::Plot, sp::Subplot, comman
return plotattributes
end
label_to_string(label::Bool, series_plotindex) = label ? label_to_string(:auto, series_plotindex) : ""
label_to_string(label::Nothing, series_plotindex) = ""
label_to_string(label::Missing, series_plotindex) = ""
function label_to_string(label::Symbol, series_plotindex)
if label==:auto
return string("y", series_plotindex)
elseif label==:none
return ""
else
throw(ArgumentError("unsupported symbol $(label) passed to `label`"))
end
end
label_to_string(label, series_plotindex) = string(label) # Fallback to string promotion
function _update_series_attributes!(plotattributes::AKW, plt::Plot, sp::Subplot)
pkg = plt.backend
globalIndex = plotattributes[:series_plotindex]
@@ -1736,7 +1599,10 @@ function _update_series_attributes!(plotattributes::AKW, plt::Plot, sp::Subplot)
end
# set label
plotattributes[:label] = label_to_string.(plotattributes[:label], globalIndex)
label = plotattributes[:label]
label = (label == "AUTO" ? "y$globalIndex" : label)
label = label in (:none, nothing, false) ? "" : label
plotattributes[:label] = label
_replace_linewidth(plotattributes)
plotattributes
@@ -1757,80 +1623,3 @@ function _series_index(plotattributes, sp)
end
return idx
end
#--------------------------------------------------
## inspired by Base.@kwdef
macro add_attributes( level, expr )
expr = macroexpand(__module__, expr) # to expand @static
expr isa Expr && expr.head === :struct || error("Invalid usage of @add_attributes")
T = expr.args[2]
if T isa Expr && T.head === :<:
T = T.args[1]
end
key_args = Any[]
value_args = Any[]
_splitdef!(expr.args[3], value_args, key_args)
insert_block = Expr(:block)
for (key, value) in zip(key_args, value_args)
# e.g. _series_defualts[key] = value
exp_key = Symbol(lowercase(string(T)), "_", key)
pl_key = makeplural(exp_key)
push!(insert_block.args, Expr(
:(=), Expr(:ref, Symbol("_", level, "_defaults"), QuoteNode(exp_key)), value
))
push!(insert_block.args, :(
add_aliases($(QuoteNode(exp_key)), $(QuoteNode(pl_key)))
))
push!(insert_block.args, :(
add_aliases($(QuoteNode(exp_key)), $(QuoteNode(make_non_underscore(exp_key))))
))
push!(insert_block.args, :(
add_aliases($(QuoteNode(exp_key)), $(QuoteNode(make_non_underscore(pl_key))))
))
end
return quote
$expr
$insert_block
end |> esc
end
function _splitdef!(blk, value_args, key_args)
for i in eachindex(blk.args)
ei = blk.args[i]
if ei isa Symbol
# var
continue
elseif ei isa Expr
if ei.head === :(=)
lhs = ei.args[1]
if lhs isa Symbol
# var = defexpr
var = lhs
elseif lhs isa Expr && lhs.head === :(::) && lhs.args[1] isa Symbol
# var::T = defexpr
var = lhs.args[1]
else
# something else, e.g. inline inner constructor
# F(...) = ...
continue
end
defexpr = ei.args[2] # defexpr
push!(value_args, defexpr)
push!(key_args, var)
blk.args[i] = lhs
elseif ei.head === :(::) && ei.args[1] isa Symbol
# var::Typ
var = ei.args[1]
push!(value_args, var)
push!(key_args, var)
elseif ei.head === :block
# can arise with use of @static inside type decl
_kwdef!(ei, value_args, key_args)
end
end
end
blk
end
+427 -377
View File
@@ -35,6 +35,7 @@ end
function process_axis_arg!(plotattributes::AKW, arg, letter = "")
T = typeof(arg)
arg = get(_scaleAliases, arg, arg)
if typeof(arg) <: Font
plotattributes[Symbol(letter,:tickfont)] = arg
plotattributes[Symbol(letter,:guidefont)] = arg
@@ -94,12 +95,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
@@ -129,18 +124,11 @@ const _label_func = Dict{Symbol,Function}(
)
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(ticks, alims, scale, formatter)
amin, amax = alims
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)
# If the axis input was a Date or DateTime use a special logic to find
@@ -151,7 +139,7 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
# rather than on the input format
# TODO: maybe: non-trivial scale (:ln, :log2, :log10) for date/datetime
if ticks === nothing && scale == :identity
if formatter == RecipesPipeline.dateformatter
if axis[:formatter] == RecipesPipeline.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,
@@ -162,7 +150,7 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
k_min = 2, k_max = 4)
# Now the ticks are converted back to floats corresponding to Dates.
return ticks / 864e5, labels
elseif formatter == RecipesPipeline.datetimeformatter
elseif axis[:formatter] == RecipesPipeline.datetimeformatter
return optimize_datetime_ticks(amin, amax; k_min = 2, k_max = 4)
end
end
@@ -186,17 +174,24 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
# 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(RecipesPipeline.inverse_scale_func(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)
labels = if any(isfinite, unscaled_ticks)
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))
formatter = axis[:formatter]
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)
@@ -217,114 +212,49 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
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)
dvals = axis[:discrete_values]
ticks = _transform_ticks(axis[:ticks])
axis.plotattributes[:optimized_ticks] = if ticks isa Symbol && ticks !== :none &&
ispolar(sp) && axis[:letter] === :x && !isempty(dvals)
collect(0:pi/4:7pi/4), string.(0:45:315)
function get_ticks(sp::Subplot, axis::Axis)
ticks = _transform_ticks(axis[:ticks])
ticks in (:none, nothing, false) && return nothing
# 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[: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
cvals = axis[:continuous_values]
alims = axis_limits(sp, axis[:letter])
scale = axis[:scale]
formatter = axis[:formatter]
get_ticks(ticks, cvals, dvals, alims, scale, formatter)
# compute optimal ticks and labels
optimal_ticks_and_labels(sp, axis)
end
end
return axis.plotattributes[:optimized_ticks]
end
# Ticks getter functions
for l in (:x, :y, :z)
axis = string(l, "-axis") # "x-axis"
ticks = string(l, "ticks") # "xticks"
f = Symbol(ticks) # :xticks
@eval begin
"""
$($f)(p::Plot)
returns a vector of the $($axis) ticks of the subplots of `p`.
Example use:
```jldoctest
julia> p = plot(1:5, $($ticks)=[1,2])
julia> $($f)(p)
1-element Vector{Tuple{Vector{Float64}, Vector{String}}}:
([1.0, 2.0], ["1", "2"])
```
If `p` consists of a single subplot, you might want to grab
only the first element, via
```jldoctest
julia> $($f)(p)[1]
([1.0, 2.0], ["1", "2"])
```
or you can call $($f) on the first (only) subplot of `p` via
```jldoctest
julia> $($f)(p[1])
([1.0, 2.0], ["1", "2"])
```
"""
$f(p::Plot) = get_ticks(p, $(Meta.quot(l)))
"""
$($f)(sp::Subplot)
returns the $($axis) ticks of the subplot `sp`.
Note that the ticks are returned as tuples of values and labels:
```jldoctest
julia> sp = plot(1:5, $($ticks)=[1,2]).subplots[1]
Subplot{1}
julia> $($f)(sp)
([1.0, 2.0], ["1", "2"])
```
"""
$f(sp::Subplot) = get_ticks(sp, $(Meta.quot(l)))
export $f
end
end
# get_ticks from axis symbol :x, :y, or :z
get_ticks(sp::Subplot, s::Symbol) = get_ticks(sp, sp[Symbol(s, :axis)])
get_ticks(p::Plot, s::Symbol) = [get_ticks(sp, s) for sp in p.subplots]
function get_ticks(ticks::Symbol, cvals::T, dvals, args...) where T
if ticks === :none
return T[], String[]
elseif !isempty(dvals)
n = length(dvals)
if ticks === :all || n < 16
return cvals, string.(dvals)
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
Δ = ceil(Int, n / 10)
rng = Δ:Δ:n
return cvals[rng], string.(dvals[rng])
# 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
return optimal_ticks_and_labels(nothing, args...)
error("Unknown ticks type in get_ticks: $(typeof(ticks))")
end
# @show ticks dvals cv dv
return cv, dv
end
get_ticks(ticks::AVec, cvals, dvals, args...) = optimal_ticks_and_labels(ticks, args...)
function get_ticks(ticks::Int, dvals, cvals, args...)
if !isempty(dvals)
rng = round.(Int, range(1, stop=length(dvals), length=ticks))
cvals[rng], string.(dvals[rng])
else
optimal_ticks_and_labels(ticks, args...)
end
end
get_ticks(ticks::NTuple{2, Any}, args...) = ticks
get_ticks(::Nothing, cvals::T, args...) where T = T[], String[]
get_ticks(ticks::Bool, args...) =
ticks ? get_ticks(:auto, args...) : get_ticks(nothing, args...)
get_ticks(::T, args...) where T = error("Unknown ticks type in get_ticks: $T")
_transform_ticks(ticks) = ticks
_transform_ticks(ticks::AbstractArray{T}) where T <: Dates.TimeType = Dates.value.(ticks)
@@ -501,22 +431,20 @@ function widen(lmin, lmax, scale = :identity)
end
# figure out if widening is a good idea.
const _widen_seriestypes = (:line, :path, :steppre, :stepmid, :steppost, :sticks, :scatter, :barbins, :barhist, :histogram, :scatterbins, :scatterhist, :stepbins, :stephist, :bins2d, :histogram2d, :bar, :shape, :path3d, :scatter3d)
const _widen_seriestypes = (:line, :path, :steppre, :steppost, :sticks, :scatter, :barbins, :barhist, :histogram, :scatterbins, :scatterhist, :stepbins, :stephist, :bins2d, :histogram2d, :bar, :shape, :path3d, :scatter3d)
function default_should_widen(axis::Axis)
if axis[:widen] isa Bool
return axis[:widen]
end
# automatic behavior: widen if limits aren't specified and series type is appropriate
(is_2tuple(axis[:lims]) || axis[:lims] == :round) && return false
for sp in axis.sps
for series in series_list(sp)
if series.plotattributes[:seriestype] in _widen_seriestypes
return true
should_widen = false
if !(is_2tuple(axis[:lims]) || axis[:lims] == :round)
for sp in axis.sps
for series in series_list(sp)
if series.plotattributes[:seriestype] in _widen_seriestypes
should_widen = true
end
end
end
end
false
should_widen
end
function round_limits(amin,amax)
@@ -534,21 +462,13 @@ 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
elseif isfinite(lmin)
amin = lmin
if isfinite(lims[1])
amin = lims[1]
end
if lmax == :auto
elseif isfinite(lmax)
amax = lmax
if isfinite(lims[2])
amax = lims[2]
end
end
if lims == :symmetric
aval = max(abs(amin), abs(amax))
amin = -aval
amax = aval
end
if amax <= amin && isfinite(amin)
amax = amin + 1.0
end
@@ -564,7 +484,7 @@ function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(l
else
amin, amax
end
elseif should_widen
elseif should_widen && axis[:widen]
widen(amin, amax, axis[:scale])
elseif lims == :round
round_limits(amin,amax)
@@ -655,274 +575,404 @@ 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)
# xaxis
y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(ax[:mirror], oax[:flip]) ? (oamax, oamin) : (oamin, oamax)
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
end
if ax[:showaxis]
if xaxis[:showaxis]
if sp[:framestyle] != :grid
push!(segments, reverse_if((amin, oa1), isy), reverse_if((amax, oa1), isy))
push!(xaxis_segs, (xmin, y1), (xmax, y1))
# 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
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
if sp[:framestyle] in (:semi, :box) # top spine
push!(
border_segments,
reverse_if((amin, oa2), isy),
reverse_if((amax, oa2), isy),
)
end
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2), (xmax, y2)) # top spine
end
if !(ax[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(oax[:scale])
invf = RecipesPipeline.inverse_scale_func(oax[:scale])
if ax[:tick_direction] !== :none
if !(xaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(yaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(yaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
(-t, t)
else
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
t = invf(f(y1) + 0.012 * (f(y2) - f(y1)) * ticks_in)
(y1, t)
end
for xtick in xticks[1]
if xaxis[:showaxis]
push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick
end
xaxis[:grid] && push!(xgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid
end
if !(xaxis[:minorticks] in (:none, nothing, false)) || xaxis[:minorgrid]
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(oamax) - f(oamin)))
t = invf(f(0) + 0.006 * (f(ymax) - f(ymin)))
(-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)
t = invf(f(y1) + 0.006 * (f(y2) - f(y1)) * ticks_in)
(y1, t)
end
end
for tick in ticks[1]
if ax[:showaxis] && ax[:tick_direction] !== :none
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)
else
t = invf(f(oa1) + 0.006 * (f(oa2) - f(oa1)) * ticks_in)
(oa1, t)
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),
)
for xtick in xminorticks
if xaxis[:showaxis]
push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick
end
xaxis[:minorgrid] && push!(xminorgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid
end
end
end
end
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
# yaxis
x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 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]))
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax)
end
fa0, fa1 = if sp[:framestyle] in (:origin, :zerolines)
0, 0
else
reverse_if((famin, famax), xor(ax[:mirror], fax[:flip]))
end
if ax[:showaxis]
if yaxis[:showaxis]
if sp[:framestyle] != :grid
push!(
segments,
sort_3d_axes(amin, na0, fa0, letter),
sort_3d_axes(amax, na0, fa0, letter),
)
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 i0 !== 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 = RecipesPipeline.scale_func(xaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(xaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(xmax) - f(xmin)))
(-t, t)
else
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
t = invf(f(x1) + 0.012 * (f(x2) - f(x1)) * ticks_in)
(x1, t)
end
for ytick in yticks[1]
if yaxis[:showaxis]
push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick
end
yaxis[:grid] && push!(ygrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
end
if !(yaxis[:minorticks] in (:none, nothing, false)) || yaxis[:minorgrid]
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.006 * (f(xmax) - f(xmin)))
(-t, t)
else
t = invf(f(x1) + 0.006 * (f(x2) - f(x1)) * ticks_in)
(x1, t)
end
for ytick in yminorticks
if yaxis[:showaxis]
push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick
end
yaxis[:minorgrid] && push!(yminorgrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
end
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])
if ax[:tick_direction] !== :none
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
xticks, yticks, xaxis_segs, yaxis_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xminorgrid_segs, yminorgrid_segs, xborder_segs, yborder_segs
end
function axis_drawing_info_3d(sp::Subplot)
xaxis, yaxis, zaxis = sp[:xaxis], sp[:yaxis], sp[:zaxis]
xmin, xmax = axis_limits(sp, :x)
ymin, ymax = axis_limits(sp, :y)
zmin, zmax = axis_limits(sp, :z)
xticks = get_ticks(sp, xaxis)
yticks = get_ticks(sp, yaxis)
zticks = get_ticks(sp, zaxis)
xminorticks = get_minor_ticks(sp, xaxis, xticks)
yminorticks = get_minor_ticks(sp, yaxis, yticks)
zminorticks = get_minor_ticks(sp, zaxis, zticks)
xaxis_segs = Segments(3)
yaxis_segs = Segments(3)
zaxis_segs = Segments(3)
xtick_segs = Segments(3)
ytick_segs = Segments(3)
ztick_segs = Segments(3)
xgrid_segs = Segments(3)
ygrid_segs = Segments(3)
zgrid_segs = Segments(3)
xminorgrid_segs = Segments(3)
yminorgrid_segs = Segments(3)
zminorgrid_segs = Segments(3)
xborder_segs = Segments(3)
yborder_segs = Segments(3)
zborder_segs = Segments(3)
if sp[:framestyle] != :none
# xaxis
y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
end
z1, z2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(xaxis[:mirror], zaxis[:flip]) ? (zmax, zmin) : (zmin, zmax)
end
if xaxis[:showaxis]
if sp[:framestyle] != :grid
push!(xaxis_segs, (xmin, y1, z1), (xmax, y1, z1))
# don't show the 0 tick label for the origin framestyle
if sp[:framestyle] == :origin && !(xticks in (:none, nothing, false)) && length(xticks) > 1
showticks = xticks[1] .!= 0
xticks = (xticks[1][showticks], xticks[2][showticks])
end
end
ga0, ga1 = sp[:framestyle] in (:origin, :zerolines) ? (namin, namax) : (na0, na1)
for tick in ticks[1]
if ax[:showaxis] && ax[:tick_direction] !== :none
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
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2, z2), (xmax, y2, z2)) # top spine
end
if !(xaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(yaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(yaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
(-t, t)
else
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
t = invf(f(y1) + 0.012 * (f(y2) - f(y1)) * ticks_in)
(y1, t)
end
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)
for xtick in xticks[1]
if xaxis[:showaxis]
push!(xtick_segs, (xtick, tick_start, z1), (xtick, tick_stop, z1)) # bottom tick
end
for tick in minor_ticks
if ax[:showaxis] && ax[:tick_direction] !== :none
push!(
tick_segments,
sort_3d_axes(tick, tick_start, fa0, letter),
sort_3d_axes(tick, tick_stop, fa0, letter),
)
if xaxis[:grid]
if sp[:framestyle] in (:origin, :zerolines)
push!(xgrid_segs, (xtick, ymin, 0.0), (xtick, ymax, 0.0))
push!(xgrid_segs, (xtick, 0.0, zmin), (xtick, 0.0, zmax))
else
push!(xgrid_segs, (xtick, y1, z1), (xtick, y2, z1))
push!(xgrid_segs, (xtick, y2, z1), (xtick, y2, z2))
end
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),
)
end
end
if !(xaxis[:minorticks] in (:none, nothing, false)) || xaxis[:minorgrid]
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.006 * (f(ymax) - f(ymin)))
(-t, t)
else
t = invf(f(y1) + 0.006 * (f(y2) - f(y1)) * ticks_in)
(y1, t)
end
for xtick in xminorticks
if xaxis[:showaxis]
push!(xtick_segs, (xtick, tick_start, z1), (xtick, tick_stop, z1)) # bottom tick
end
if xaxis[:minorgrid]
if sp[:framestyle] in (:origin, :zerolines)
push!(xminorgrid_segs, (xtick, ymin, 0.0), (xtick, ymax, 0.0))
push!(xminorgrid_segs, (xtick, 0.0, zmin), (xtick, 0.0, zmax))
else
push!(xminorgrid_segs, (xtick, y1, z1), (xtick, y2, z1))
push!(xminorgrid_segs, (xtick, y2, z1), (xtick, y2, z2))
end
end
end
end
end
# yaxis
x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(yaxis[:mirror], xaxis[:flip]) ? (xmin, xmax) : (xmax, xmin)
end
z1, z2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(yaxis[:mirror], zaxis[:flip]) ? (zmax, zmin) : (zmin, zmax)
end
if yaxis[:showaxis]
if sp[:framestyle] != :grid
push!(yaxis_segs, (x1, ymin, z1), (x1, ymax, z1))
# don't show the 0 tick label for the origin framestyle
if sp[:framestyle] == :origin && !(yticks in (:none, nothing,false)) && length(yticks) > 1
showticks = yticks[1] .!= 0
yticks = (yticks[1][showticks], yticks[2][showticks])
end
end
sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (x2, ymin, z2), (x2, ymax, z2)) # right spine
end
if !(yaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(xaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(xaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(xmax) - f(xmin)))
(-t, t)
else
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
t = invf(f(x1) + 0.012 * (f(x2) - f(x1)) * ticks_in)
(x1, t)
end
for ytick in yticks[1]
if yaxis[:showaxis]
push!(ytick_segs, (tick_start, ytick, z1), (tick_stop, ytick, z1)) # left tick
end
if yaxis[:grid]
if sp[:framestyle] in (:origin, :zerolines)
push!(ygrid_segs, (xmin, ytick, 0.0), (xmax, ytick, 0.0))
push!(ygrid_segs, (0.0, ytick, zmin), (0.0, ytick, zmax))
else
push!(ygrid_segs, (x1, ytick, z1), (x2, ytick, z1))
push!(ygrid_segs, (x2, ytick, z1), (x2, ytick, z2))
end
end
end
if !(yaxis[:minorticks] in (:none, nothing, false)) || yaxis[:minorgrid]
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.006 * (f(xmax) - f(xmin)))
(-t, t)
else
t = invf(f(x1) + 0.006 * (f(x2) - f(x1)) * ticks_in)
(x1, t)
end
for ytick in yminorticks
if yaxis[:showaxis]
push!(ytick_segs, (tick_start, ytick, z1), (tick_stop, ytick, z1)) # left tick
end
if yaxis[:minorgrid]
if sp[:framestyle] in (:origin, :zerolines)
push!(yminorgrid_segs, (xmin, ytick, 0.0), (xmax, ytick, 0.0))
push!(yminorgrid_segs, (0.0, ytick, zmin), (0.0, ytick, zmax))
else
push!(yminorgrid_segs, (x1, ytick, z1), (x2, ytick, z1))
push!(yminorgrid_segs, (x2, ytick, z1), (x2, ytick, z2))
end
end
end
end
end
# zaxis
x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(zaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax)
end
y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0
else
xor(zaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
end
if zaxis[:showaxis]
if sp[:framestyle] != :grid
push!(zaxis_segs, (x1, y1, zmin), (x1, y1, zmax))
# don't show the 0 tick label for the origin framestyle
if sp[:framestyle] == :origin && !(zticks in (:none, nothing,false)) && length(zticks) > 1
showticks = zticks[1] .!= 0
zticks = (zticks[1][showticks], zticks[2][showticks])
end
end
sp[:framestyle] in (:semi, :box) && push!(zborder_segs, (x2, y2, zmin), (x2, y2, zmax))
end
if !(zaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(xaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(xaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
(-t, t)
else
ticks_in = zaxis[:tick_direction] == :out ? -1 : 1
t = invf(f(y1) + 0.012 * (f(y2) - f(y1)) * ticks_in)
(y1, t)
end
for ztick in zticks[1]
if zaxis[:showaxis]
push!(ztick_segs, (x1, tick_start, ztick), (x1, tick_stop, ztick)) # left tick
end
if zaxis[:grid]
if sp[:framestyle] in (:origin, :zerolines)
push!(zgrid_segs, (xmin, 0.0, ztick), (xmax, 0.0, ztick))
push!(ygrid_segs, (0.0, ymin, ztick), (0.0, ymax, ztick))
else
push!(ygrid_segs, (x1, y1, ztick), (x1, y2, ztick))
push!(ygrid_segs, (x1, y2, ztick), (x2, y2, ztick))
end
end
end
if !(zaxis[:minorticks] in (:none, nothing, false)) || zaxis[:minorgrid]
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.006 * (f(ymax) - f(ymin)))
(-t, t)
else
t = invf(f(y1) + 0.006 * (f(y2) - f(y1)) * ticks_in)
(y1, t)
end
for ztick in zminorticks
if zaxis[:showaxis]
push!(ztick_segs, (x1, tick_start, ztick), (x1, tick_stop, ztick)) # left tick
end
if zaxis[:minorgrid]
if sp[:framestyle] in (:origin, :zerolines)
push!(zminorgrid_segs, (xmin, 0.0, ztick), (xmax, 0.0, ztick))
push!(zminorgrid_segs, (0.0, ymin, ztick), (0.0, ymax, ztick))
else
push!(zminorgrid_segs, (x1, y1, ztick), (x1, y2, ztick))
push!(zminorgrid_segs, (x1, y2, ztick), (x2, y2, ztick))
end
end
end
end
end
end
return (
ticks = ticks,
segments = segments,
tick_segments = tick_segments,
grid_segments = grid_segments,
minorgrid_segments = minorgrid_segments,
border_segments = border_segments
)
xticks, yticks, zticks, xaxis_segs, yaxis_segs, zaxis_segs, xtick_segs, ytick_segs, ztick_segs, xgrid_segs, ygrid_segs, zgrid_segs, xminorgrid_segs, yminorgrid_segs, zminorgrid_segs, xborder_segs, yborder_segs, zborder_segs
end
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])
+38 -98
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))
@@ -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
@@ -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,
@@ -531,10 +514,6 @@ const _pyplot_attr = merge_with_base_supported([
:guidefontfamily, :guidefontsize, :guidefontcolor,
:grid, :gridalpha, :gridstyle, :gridlinewidth,
:legend, :legendtitle, :colorbar, :colorbar_title, :colorbar_entry,
:colorbar_ticks, :colorbar_tickfontfamily, :colorbar_tickfontsize,
:colorbar_tickfonthalign, :colorbar_tickfontvalign,
:colorbar_tickfontrotation, :colorbar_tickfontcolor,
:colorbar_scale,
:marker_z, :line_z, :fill_z,
:levels,
:ribbon, :quiver, :arrow,
@@ -543,6 +522,7 @@ const _pyplot_attr = merge_with_base_supported([
:polar,
:normalize, :weights,
:contours, :aspect_ratio,
:match_dimensions,
:clims,
:inset_subplots,
:dpi,
@@ -553,23 +533,12 @@ const _pyplot_attr = merge_with_base_supported([
:contour_labels,
])
const _pyplot_seriestype = [
:path,
:steppre,
:stepmid,
: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]
@@ -599,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
@@ -616,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,
@@ -629,45 +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,
:stepmid,
: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
@@ -685,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,
@@ -702,6 +646,7 @@ const _inspectdr_attr = merge_with_base_supported([
:polar,
# :normalize, :weights,
# :contours, :aspect_ratio,
:match_dimensions,
# :clims,
# :inset_subplots,
:dpi,
@@ -709,7 +654,7 @@ const _inspectdr_attr = merge_with_base_supported([
])
const _inspectdr_style = [:auto, :solid, :dash, :dot, :dashdot]
const _inspectdr_seriestype = [
:path, :scatter, :shape, :straightline, #, :steppre, :stepmid, :steppost
:path, :scatter, :shape, :straightline, #, :steppre, :steppost
]
#see: _allMarkers, _shape_keys
const _inspectdr_marker = Symbol[
@@ -762,6 +707,7 @@ const _pgfplotsx_attr = merge_with_base_supported([
:ticks,
:scale,
:flip,
:match_dimensions,
:titlefontfamily,
:titlefontsize,
:titlefonthalign,
@@ -824,10 +770,8 @@ const _pgfplotsx_seriestype = [
:surface,
:wireframe,
:heatmap,
:mesh3d,
:contour,
:contour3d,
:quiver,
:shape,
:steppre,
:stepmid,
@@ -848,7 +792,6 @@ const _pgfplotsx_marker = [
:rtriangle,
:cross,
:xcross,
:x,
:star5,
:pentagon,
:hline,
@@ -857,6 +800,3 @@ const _pgfplotsx_marker = [
]
const _pgfplotsx_scale = [:identity, :ln, :log2, :log10]
is_marker_supported(::PGFPlotsXBackend, shape::Shape) = true
# additional constants
const _pgfplotsx_series_ids = KW()
+1169 -1108
View File
File diff suppressed because it is too large Load Diff
+511 -491
View File
File diff suppressed because it is too large Load Diff
+41 -101
View File
@@ -17,6 +17,9 @@ Add in functionality to Plots.jl:
is_marker_supported(::InspectDRBackend, shape::Shape) = true
_inspectdr_to_pixels(bb::BoundingBox) =
InspectDR.BoundingBox(to_pixels(left(bb)), to_pixels(right(bb)), to_pixels(top(bb)), to_pixels(bottom(bb)))
#Do we avoid Map to avoid possible pre-comile issues?
function _inspectdr_mapglyph(s::Symbol)
s == :rect && return :square
@@ -76,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
@@ -216,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
@@ -287,7 +237,7 @@ For st in :shape:
color = linecolor, fillcolor = fillcolor
)
end
elseif st in (:path, :scatter, :straightline) #, :steppre, :stepmid, :steppost)
elseif st in (:path, :scatter, :straightline) #, :steppre, :steppost)
#NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think).
linewidth = series[:linewidth]
#More efficient & allows some support for markerstrokewidth:
@@ -306,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
@@ -338,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)
@@ -352,48 +302,38 @@ 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]]
#Modify base layout of new object:
l = plot.layout.defaults = deepcopy(InspectDR.defaults.plotlayout)
#IMPORTANT: Must deepcopy to ensure we don't change layouts of other plots.
#Works because plot uses defaults (not user-overwritten `layout.values`)
l.frame_canvas.fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
l.frame_data.fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
l.frame_data.line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
l.font_title = InspectDR.Font(sp[:titlefontfamily],
l = plot.layout
l[:frame_canvas].fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
l[:frame_data].fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
l[:frame_data].line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
l[:font_title] = InspectDR.Font(sp[:titlefontfamily],
_inspectdr_mapptsize(sp[:titlefontsize]),
color = _inspectdr_mapcolor(sp[:titlefontcolor])
)
#Cannot independently control fonts of axes with InspectDR:
l.font_axislabel = InspectDR.Font(xaxis[:guidefontfamily],
l[:font_axislabel] = InspectDR.Font(xaxis[:guidefontfamily],
_inspectdr_mapptsize(xaxis[:guidefontsize]),
color = _inspectdr_mapcolor(xaxis[:guidefontcolor])
)
l.font_ticklabel = InspectDR.Font(xaxis[:tickfontfamily],
l[:font_ticklabel] = InspectDR.Font(xaxis[:tickfontfamily],
_inspectdr_mapptsize(xaxis[:tickfontsize]),
color = _inspectdr_mapcolor(xaxis[:tickfontcolor])
)
l.enable_legend = (sp[:legend] != :none)
#l.halloc_legend = 150 #TODO: compute???
l.font_legend = InspectDR.Font(sp[:legendfontfamily],
l[:enable_legend] = (sp[:legend] != :none)
#l[:halloc_legend] = 150 #TODO: compute???
l[:font_legend] = InspectDR.Font(sp[:legendfontfamily],
_inspectdr_mapptsize(sp[:legendfontsize]),
color = _inspectdr_mapcolor(sp[:legendfontcolor])
)
l.frame_legend.fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
#_round!() ensures values use integer spacings (looks better on screen):
InspectDR._round!(InspectDR.autofit2font!(l, legend_width=10.0)) #10 "em"s wide
return
l[:frame_legend].fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
end
# called just before updating layout bounding boxes... in case you need to prep
@@ -407,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)
@@ -473,16 +412,11 @@ end
function _update_plot_object(plt::Plot{InspectDRBackend})
mplot = _inspectdr_getmplot(plt.o)
if nothing == mplot; return; end
mplot.bblist = InspectDR.BoundingBox[]
for (i, sp) in enumerate(plt.subplots)
figw, figh = sp.plt[:size]
pcts = bbox_to_pcts(sp.bbox, figw*px, figh*px)
_left, _bottom, _width, _height = pcts
ymax = 1.0-_bottom
ymin = ymax - _height
bb = InspectDR.BoundingBox(_left, _left+_width, ymin, ymax)
push!(mplot.bblist, bb)
graphbb = _inspectdr_to_pixels(plotarea(sp))
plot = mplot.subplots[i]
plot.plotbb = InspectDR.plotbounds(plot.layout.values, graphbb)
end
gplot = _inspectdr_getgui(plt.o)
@@ -495,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
+427 -642
View File
File diff suppressed because it is too large Load Diff
+149 -267
View File
@@ -1,33 +1,46 @@
# 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)
@warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was chosen instead.")
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
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(
@@ -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(
@@ -143,16 +155,20 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
:zerolinecolor => rgba_string(axis[:foreground_color_axis]),
:showline => framestyle in (:box, :axes) && axis[:showaxis],
:linecolor => rgba_string(plot_color(axis[:foreground_color_axis])),
:ticks => axis[:tick_direction] === :out ? "outside" :
axis[:tick_direction] === :in ? "inside" : "",
:ticks => axis[:tick_direction] == :out ? "outside" : "inside",
: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 RecipesPipeline.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]
@@ -229,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
@@ -247,42 +263,46 @@ function plotly_layout(plt::Plot)
# set to supported framestyle
sp[:framestyle] = _plotly_framestyle(sp[:framestyle])
if ispolar(sp)
# if any(RecipesPipeline.is3d, seriesargs)
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[: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]
@@ -322,132 +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")
plotly_legend_pos(theta::Real) = plotly_legend_pos((theta, :inner))
function plotly_legend_pos(v::Tuple{S,Symbol}) where S<:Real
(s,c) = sincosd(v[1])
xanchors = ["left", "center", "right"]
yanchors = ["bottom", "middle", "top"]
if v[2] === :inner
rect = (0.07,0.5,1.0,0.07,0.52,1.0)
xanchor = xanchors[legend_anchor_index(c)]
yanchor = yanchors[legend_anchor_index(s)]
else
rect = (-0.15,0.5,1.05,-0.15,0.52,1.1)
xanchor = xanchors[4-legend_anchor_index(c)]
yanchor = yanchors[4-legend_anchor_index(s)]
end
return (coords=legend_pos_from_angle(v[1],rect...), xanchor=xanchor, yanchor=yanchor)
end
function plotly_layout_json(plt::Plot)
JSON.json(plotly_layout(plt), 4)
end
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
@@ -482,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
@@ -493,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)
@@ -533,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
@@ -593,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
@@ -608,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()
@@ -645,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))),
@@ -663,7 +568,7 @@ function plotly_series(plt::Plot, series::Series)
end
function plotly_series_shapes(plt::Plot, series::Series, clims)
segments = series_segments(series)
segments = iter_segments(series)
plotattributes_outs = Vector{KW}(undef, length(segments))
# TODO: create a plotattributes_out for each polygon
@@ -682,8 +587,7 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
for (letter, data) in zip((:x, :y), shape_data(series, 100))
)
for (k, segment) in enumerate(segments)
i, rng = segment.attr_index, segment.range
for (i,rng) in enumerate(segments)
length(rng) < 2 && continue
# to draw polygons, we actually draw lines with fill
@@ -702,10 +606,10 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
:dash => string(get_linestyle(series, i)),
)
end
plotattributes_out[:showlegend] = k==1 ? should_add_to_legend(series) : false
plotattributes_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
plotly_polar!(plotattributes_out, series)
plotly_hover!(plotattributes_out, _cycle(series[:hover], i))
plotattributes_outs[k] = plotattributes_out
plotattributes_outs[i] = plotattributes_out
end
if series[:fill_z] !== nothing
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill))
@@ -726,16 +630,12 @@ 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 = collect(series_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 (k, segment) in enumerate(segments)
i, rng = segment.attr_index, segment.range
for (i,rng) in enumerate(segments)
plotattributes_out = deepcopy(plotattributes_base)
plotattributes_out[:showlegend] = k==1 ? should_add_to_legend(series) : false
plotattributes_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
plotattributes_out[:legendgroup] = series[:label]
# set the type
@@ -769,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),
),
)
@@ -790,8 +688,6 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
:width => get_linewidth(series, i),
:shape => if st == :steppre
"vh"
elseif st == :stepmid
"hvh"
elseif st == :steppost
"hv"
else
@@ -824,15 +720,16 @@ 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)
end
plotattributes_outs[(2k-1):(2k)] = [plotattributes_out_fillrange, plotattributes_out]
plotattributes_outs[(2 * i - 1):(2 * i)] = [plotattributes_out_fillrange, plotattributes_out]
else
plotattributes_outs[k] = plotattributes_out
plotattributes_outs[i] = plotattributes_out
end
end
@@ -860,8 +757,8 @@ function plotly_colorbar_hack(series::Series, plotattributes_base::KW, sym::Symb
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,
@@ -908,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)
@@ -928,33 +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)
$(js_body(plt, uuid))
$(requirejs_suffix)
PLOT = document.getElementById('$(uuid)');
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
</script>
"""
html
@@ -962,7 +844,7 @@ end
function js_body(plt::Plot, uuid)
js = """
var PLOT = document.getElementById('$(uuid)');
PLOT = document.getElementById('$(uuid)');
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
"""
end
@@ -986,7 +868,7 @@ end
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
write(io, embeddable_html(plt))
write(io, standalone_html(plt))
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
+9 -4
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
@@ -34,12 +36,15 @@ _show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBack
html_head(plt::Plot{PlotlyJSBackend}) = plotly_html_head(plt)
html_body(plt::Plot{PlotlyJSBackend}) = plotly_html_body(plt)
_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, embeddable_html(plt))
_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, standalone_html(plt))
_display(plt::Plot{PlotlyJSBackend}) = display(plotlyjs_syncplot(plt))
function PlotlyJS.WebIO.render(plt::Plot{PlotlyJSBackend})
return PlotlyJS.WebIO.render(plotlyjs_syncplot(plt))
@require WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" begin
function WebIO.render(plt::Plot{PlotlyJSBackend})
plt_html = sprint(show, MIME("text/html"), plt)
return WebIO.render(WebIO.dom"div"(innerHTML=plt_html))
end
end
function closeall(::PlotlyJSBackend)
+345 -415
View File
File diff suppressed because it is too large Load Diff
+9 -7
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
+1 -5
View File
@@ -19,10 +19,6 @@ function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr
"""
end
function embeddable_html(plt::AbstractPlot)
html_head(plt) * html_body(plt)
end
function open_browser_window(filename::AbstractString)
@static if Sys.isapple()
return run(`open $(filename)`)
@@ -49,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
-90
View File
@@ -1,90 +0,0 @@
# These functions return an operator for use in `get_clims(::Seres, op)`
process_clims(lims::Tuple{<:Number,<:Number}) = (zlims -> ifelse.(isfinite.(lims), lims, zlims)) ignorenan_extrema
process_clims(s::Union{Symbol,Nothing,Missing}) = ignorenan_extrema
# don't specialize on ::Function otherwise python functions won't work
process_clims(f) = f
function get_clims(sp::Subplot, op=process_clims(sp[:clims]))
zmin, zmax = Inf, -Inf
for series in series_list(sp)
if series[:colorbar_entry]
zmin, zmax = _update_clims(zmin, zmax, get_clims(series, op)...)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(sp::Subplot, series::Series, op=process_clims(sp[:clims]))
zmin, zmax = if series[:colorbar_entry]
get_clims(sp, op)
else
get_clims(series, op)
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
"""
get_clims(::Series, op=Plots.ignorenan_extrema)
Finds the limits for the colorbar by taking the "z-values" for the series and passing them into `op`,
which must return the tuple `(zmin, zmax)`. The default op is the extrema of the finite
values of the input.
"""
function get_clims(series::Series, op=ignorenan_extrema)
zmin, zmax = Inf, -Inf
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface, :hexbin)
for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z])
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, op(vals.surf)...)
elseif (vals !== nothing) && (eltype(vals) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, op(vals)...)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
_update_clims(zmin, zmax, emin, emax) = NaNMath.min(zmin, emin), NaNMath.max(zmax, emax)
@enum ColorbarStyle cbar_gradient cbar_fill cbar_lines
function colorbar_style(series::Series)
colorbar_entry = series[:colorbar_entry]
if !(colorbar_entry isa Bool)
@warn "Non-boolean colorbar_entry ignored."
colorbar_entry = true
end
if !colorbar_entry
nothing
elseif isfilledcontour(series)
cbar_fill
elseif iscontour(series)
cbar_lines
elseif series[:seriestype] (:heatmap,:surface) ||
any(series[z] !== nothing for z [:marker_z,:line_z,:fill_z])
cbar_gradient
else
nothing
end
end
hascolorbar(series::Series) = colorbar_style(series) !== nothing
hascolorbar(sp::Subplot) = sp[:colorbar] != :none && any(hascolorbar(s) for s in series_list(sp))
function get_colorbar_ticks(sp::Subplot; update = true)
if update || !haskey(sp.attr, :colorbar_optimized_ticks)
ticks = _transform_ticks(sp[:colorbar_ticks])
cvals = sp[:colorbar_continuous_values]
dvals = sp[:colorbar_discrete_values]
clims = get_clims(sp)
scale = sp[:colorbar_scale]
formatter = sp[:colorbar_formatter]
sp.attr[:colorbar_optimized_ticks] =
get_ticks(ticks, cvals, dvals, clims, scale, formatter)
end
return sp.attr[:colorbar_optimized_ticks]
end
function _update_subplot_colorbars(sp::Subplot)
# Dynamic callback from the pipeline if needed
end
+63 -74
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))
@@ -9,9 +11,9 @@ compute_angle(v::P2) = (angle = atan(v[2], v[1]); angle < 0 ? 2π - angle : angl
# -------------------------------------------------------------
struct Shape{X<:Number, Y<:Number}
x::Vector{X}
y::Vector{Y}
struct Shape
x::Vector{Float64}
y::Vector{Float64}
# function Shape(x::AVec, y::AVec)
# # if x[1] != x[end] || y[1] != y[end]
# # new(vcat(x, x[1]), vcat(y, y[1]))
@@ -42,17 +44,21 @@ function coords(shape::Shape)
shape.x, shape.y
end
#coords(shapes::AVec{Shape}) = unzip(map(coords, shapes))
function coords(shapes::AVec{<:Shape})
c = map(coords, shapes)
x = [q[1] for q in c]
y = [q[2] for q in c]
function coords(shapes::AVec{Shape})
length(shapes) == 0 && return zeros(0), zeros(0)
xs = map(get_xs, shapes)
ys = map(get_ys, shapes)
x, y = map(copy, coords(shapes[1]))
for shape in shapes[2:end]
nanappend!(x, shape.x)
nanappend!(y, shape.y)
end
x, y
end
"get an array of tuples of points on a circle with radius `r`"
function partialcircle(start_θ, end_θ, n = 20, r=1)
[(r*cos(u), r*sin(u)) for u in range(start_θ, stop=end_θ, length=n)]
Tuple{Float64,Float64}[(r*cos(u),r*sin(u)) for u in range(start_θ, stop=end_θ, length=n)]
end
"interleave 2 vectors into each other (like a zipper's teeth)"
@@ -71,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 * π
@@ -86,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
@@ -95,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)
@@ -103,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),
@@ -205,12 +239,9 @@ function rotate!(shape::Shape, Θ::Real, c = center(shape))
end
"rotate an object in space"
function rotate(shape::Shape, θ::Real, c = center(shape))
x, y = coords(shape)
cx, cy = c
x_new = rotate_x.(x, y, θ, cx, cy)
y_new = rotate_y.(x, y, θ, cx, cy)
Shape(x_new, y_new)
function rotate(shape::Shape, Θ::Real, c = center(shape))
shapecopy = deepcopy(shape)
rotate!(shapecopy, Θ, c)
end
# -----------------------------------------------------------------------
@@ -288,7 +319,7 @@ function font(args...;kw...)
for symbol in keys(kw)
if symbol == :family
family = string(kw[:family])
family = kw[:family]
elseif symbol == :pointsize
pointsize = kw[:pointsize]
elseif symbol == :halign
@@ -327,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
"""
@@ -344,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
@@ -575,21 +588,11 @@ annotations(sa::SeriesAnnotations) = sa
# Expand arrays of coordinates, positions and labels into induvidual annotations
# and make sure labels are of type PlotText
function process_annotation(sp::Subplot, xs, ys, labs, font = nothing)
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)
if isnothing(font)
font = Plots.font(;
family=sp[:annotationfontfamily],
pointsize=sp[:annotationfontsize],
halign=sp[:annotationhalign],
valign=sp[:annotationvalign],
rotation=sp[:annotationrotation],
color=sp[:annotationcolor],
)
end
for i in 1:max(xlength, ylength, length(labs))
x, y, lab = _cycle(xs, i), _cycle(ys, i), _cycle(labs, i)
x = typeof(x) <: TimeType ? Dates.value(x) : x
@@ -598,24 +601,14 @@ function process_annotation(sp::Subplot, xs, ys, labs, font = nothing)
alphabet = "abcdefghijklmnopqrstuvwxyz"
push!(anns, (x, y, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
else
push!(anns, (x, y, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab[1], font, lab[2:end]...) : text(lab, font)))
push!(anns, (x, y, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab...) : text(lab, font)))
end
end
anns
end
function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, labs, font = nothing)
function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, labs, font = font())
anns = []
positions, labs = makevec(positions), makevec(labs)
if isnothing(font)
font = Plots.font(;
family=sp[:annotationfontfamily],
pointsize=sp[:annotationfontsize],
halign=sp[:annotationhalign],
valign=sp[:annotationvalign],
rotation=sp[:annotationrotation],
color=sp[:annotationcolor],
)
end
for i in 1:max(length(positions), length(labs))
pos, lab = _cycle(positions, i), _cycle(labs, i)
pos = get(_positionAliases, pos, pos)
@@ -623,15 +616,12 @@ function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol},
alphabet = "abcdefghijklmnopqrstuvwxyz"
push!(anns, (pos, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
else
push!(anns, (pos, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab[1], font, lab[2:end]...) : text(lab, font)))
push!(anns, (pos, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab...) : text(lab, font)))
end
end
anns
end
function process_any_label(lab, font=Font())
lab isa Tuple ? text(lab...) : text( lab, font )
end
# Give each annotation coordinates based on specified position
function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText)
position_multiplier = Dict{Symbol, Tuple{Float64,Float64}}(
@@ -648,7 +638,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)"
@@ -748,7 +737,7 @@ end
# -----------------------------------------------------------------------
"create a BezierCurve for plotting"
mutable struct BezierCurve{T <: GeometryBasics.Point}
mutable struct BezierCurve{T <: GeometryTypes.Point}
control_points::Vector{T}
end
@@ -763,7 +752,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]
+81 -258
View File
@@ -7,9 +7,9 @@ mutable struct PlotExample
exprs::Vector{Expr}
end
# the _examples we'll run for each backend
# the _examples we'll run for each
const _examples = PlotExample[
PlotExample( # 1
PlotExample(
"Lines",
"A simple line plot of the columns.",
[:(
@@ -18,7 +18,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 2
PlotExample(
"Functions, adding data, and animations",
"""
Plot multiple functions. You can also put the function first, or use the form `plot(f,
@@ -30,16 +30,16 @@ const _examples = PlotExample[
""",
[:(
begin
p = plot([sin, cos], zeros(0), leg = false, xlims = (0, 2π), ylims = (-1, 1))
p = plot([sin, cos], zeros(0), leg = false)
anim = Animation()
for x in range(0, stop = 2π, length = 20)
for x in range(0, stop = 10π, length = 100)
push!(p, x, Float64[sin(x), cos(x)])
frame(anim)
end
end
)],
),
PlotExample( # 3
PlotExample(
"Parametric plots",
"Plot function pair (x(u), y(u)).",
[
@@ -58,7 +58,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 4
PlotExample(
"Colors",
"""
Access predefined palettes (or build your own with the `colorscheme` method).
@@ -74,7 +74,7 @@ const _examples = PlotExample[
rand(11, 4),
lab = "lines",
w = 3,
palette = cgrad(:grays),
palette = :grays,
fill = 0,
α = 0.6,
)
@@ -89,7 +89,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 5
PlotExample(
"Global",
"""
Change the guides/background/limits/ticks. Convenience args `xaxis` and `yaxis` allow
@@ -121,7 +121,13 @@ const _examples = PlotExample[
],
),
PlotExample( # 6
# PlotExample("Two-axis",
# "Use the `axis` arguments.",
# [
# :(plot(Vector[randn(100), randn(100)*100], axis = [:l :r], ylabel="LEFT", yrightlabel="RIGHT", xlabel="X", title="TITLE"))
# ]),
PlotExample(
"Images",
"Plot an image. y-axis is set to flipped",
[
@@ -136,7 +142,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 7
PlotExample(
"Arguments",
"""
Plot multiple series with different numbers of points. Mix arguments that apply to all
@@ -160,7 +166,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 8
PlotExample(
"Build plot in pieces",
"Start with a base plot...",
[:(
@@ -169,7 +175,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 9
PlotExample(
"",
"and add to it later.",
[:(
@@ -178,7 +184,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 10
PlotExample(
"Histogram2D",
"",
[:(
@@ -187,7 +193,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 11
PlotExample(
"Line types",
"",
[
@@ -208,7 +214,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 12
PlotExample(
"Line styles",
"",
[
@@ -231,7 +237,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 13
PlotExample(
"Marker types",
"",
[
@@ -241,15 +247,14 @@ const _examples = PlotExample[
m -> m in Plots.supported_markers(),
Plots._shape_keys,
)
markers = permutedims(markers)
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 = markers,
markersize = 8,
m = (8, :auto),
lab = map(string, markers),
bg = :linen,
xlim = (0, 10),
@@ -259,7 +264,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 14
PlotExample(
"Bar",
"`x` is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)",
[:(
@@ -268,7 +273,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 15
PlotExample(
"Histogram",
"",
[
@@ -283,7 +288,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 16
PlotExample(
"Subplots",
"""
Use the `layout` keyword, and optionally the convenient `@layout` macro to generate
@@ -305,7 +310,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 17
PlotExample(
"Adding to subplots",
"""
Note here the automatic grid layout, as well as the order in which new series are added
@@ -317,27 +322,21 @@ const _examples = PlotExample[
plot(
Plots.fakedata(100, 10),
layout = 4,
palette = cgrad.([:grays :blues :heat :lightrainbow]),
palette = [:grays :blues :heat :lightrainbow],
bg_inside = [:orange :pink :darkblue :black],
)
end
),
],
),
PlotExample( # 18
"",
"",
[
:(
begin
using Random
Random.seed!(111)
plot!(Plots.fakedata(100, 10))
end
)
]
),
PlotExample( # 19
PlotExample("", "", [:(
begin
using Random
Random.seed!(111)
plot!(Plots.fakedata(100, 10))
end
)]),
PlotExample(
"Open/High/Low/Close",
"""
Create an OHLC chart. Pass in a list of (open,high,low,close) tuples as your `y`
@@ -366,7 +365,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 20
PlotExample(
"Annotations",
"""
The `annotations` keyword is used for text annotations in data-coordinates. Pass in a
@@ -409,7 +408,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 21
PlotExample(
"Custom Markers",
"""A `Plots.Shape` is a light wrapper around vertices of a polygon. For supported
backends, pass arbitrary polygons as the marker shapes. Note: The center is (0,0) and
@@ -455,7 +454,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 22
PlotExample(
"Contours",
"""
Any value for fill works here. We first build a filled contour from a function, then an
@@ -475,7 +474,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 23
PlotExample(
"Pie",
"",
[:(
@@ -486,7 +485,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 24
PlotExample(
"3D",
"",
[
@@ -512,7 +511,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 25
PlotExample(
"DataFrames",
"Plot using DataFrame column symbols.",
[
@@ -535,7 +534,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 26
PlotExample(
"Groups and Subplots",
"",
[
@@ -553,7 +552,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 27
PlotExample(
"Polar Plots",
"",
[:(
@@ -564,7 +563,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 28
PlotExample(
"Heatmap, categorical axes, and aspect_ratio",
"",
[:(
@@ -576,7 +575,7 @@ const _examples = PlotExample[
end
)],
),
PlotExample( # 29
PlotExample(
"Layouts, margins, label rotation, title location",
"",
[
@@ -587,7 +586,7 @@ const _examples = PlotExample[
rand(100, 6),
layout = @layout([a b; c]),
title = ["A" "B" "C"],
titlelocation = :left,
title_location = :left,
left_margin = [20mm 0mm],
bottom_margin = 10px,
xrotation = 60,
@@ -596,7 +595,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 30
PlotExample(
"Boxplot and Violin series recipes",
"",
[
@@ -621,7 +620,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 31
PlotExample(
"Animation with subplots",
"The `layout` macro can be used to create an animation with subplots.",
[
@@ -629,15 +628,14 @@ const _examples = PlotExample[
begin
l = @layout([[a; b] c])
p = plot(
plot([sin, cos], 1, ylims = (-1, 1), leg = false),
scatter([atan, cos], 1, ylims = (-1, 1.5), leg = false),
plot(log, 1, ylims = (0, 2), leg = false),
plot([sin, cos], 1, leg = false),
scatter([atan, cos], 1, leg = false),
plot(log, 1, xlims = (1, 10π), ylims = (0, 5), leg = false),
layout = l,
xlims = (1, 2π),
)
anim = Animation()
for x in range(1, stop = 2π, length = 20)
for x in range(1, stop = 10π, length = 100)
plot(push!(
p,
x,
@@ -649,7 +647,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 32
PlotExample(
"Spy",
"""
For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has
@@ -683,7 +681,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 33
PlotExample(
"Magic grid argument",
"""
The grid lines can be modified individually for each axis with the magic `grid` argument.
@@ -713,7 +711,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 34
PlotExample(
"Framestyle",
"""
The style of the frame/axes of a (sub)plot can be changed with the `framestyle`
@@ -737,7 +735,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 35
PlotExample(
"Lines and markers with varying colors",
"""
You can use the `line_z` and `marker_z` properties to associate a color with
@@ -763,7 +761,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 36
PlotExample(
"Portfolio Composition maps",
"""
see: http://stackoverflow.com/a/37732384/5075246
@@ -789,7 +787,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 37
PlotExample(
"Ribbons",
"""
Ribbons can be added to lines via the `ribbon` keyword;
@@ -812,7 +810,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 38
PlotExample(
"Histogram2D (complex values)",
"",
[
@@ -831,7 +829,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 39
PlotExample(
"Unconnected lines using `missing` or `NaN`",
"""
Missing values and non-finite values, including `NaN`, are not plotted.
@@ -855,7 +853,7 @@ const _examples = PlotExample[
),
],
),
PlotExample( # 40
PlotExample(
"Lens",
"A lens lets you easily magnify a region of a plot. x and y coordinates refer to the to be magnified region and the via the `inset` keyword the subplot index and the bounding box (in relative coordinates) of the inset plot with the magnified plot can be specified. Additional attributes count for the inset plot.",
[
@@ -877,7 +875,7 @@ const _examples = PlotExample[
end,
],
),
PlotExample( # 41
PlotExample(
"Array Types",
"Plots supports different `Array` types that follow the `AbstractArray` interface, like `StaticArrays` and `OffsetArrays.`",
[
@@ -887,12 +885,11 @@ const _examples = PlotExample[
sv = SVector{10}(rand(10))
ov = OffsetVector(rand(10), -2)
plot([sv, ov], label = ["StaticArray" "OffsetArray"])
plot!(3ov, ribbon=ov, label="OffsetArray ribbon")
end
end,
],
),
PlotExample( # 42
PlotExample(
"Setting defaults and font arguments",
"",
[
@@ -922,7 +919,7 @@ const _examples = PlotExample[
end,
],
),
PlotExample( # 43
PlotExample(
"Heatmap with DateTime axis",
"",
[
@@ -937,7 +934,7 @@ const _examples = PlotExample[
end,
],
),
PlotExample( # 44
PlotExample(
"Linked axes",
"",
[
@@ -949,7 +946,7 @@ const _examples = PlotExample[
end,
],
),
PlotExample( # 45
PlotExample(
"Error bars and array type recipes",
"",
[
@@ -976,8 +973,8 @@ const _examples = PlotExample[
surf = Measurement.((1:10) .* (1:10)', rand(10,10))
plot(
scatter(x, [x y]),
scatter(x, y, z),
scatter(x, [x y], msw = 0),
scatter(x, y, z, msw = 0),
heatmap(x, y, surf),
wireframe(x, y, surf),
legend = :topleft
@@ -986,201 +983,27 @@ const _examples = PlotExample[
end,
],
),
PlotExample( # 46
"Tuples and `Point`s as data",
"",
[quote
using GeometryBasics
using Distributions
d = MvNormal([1.0 0.75; 0.75 2.0])
plot([(1,2),(3,2),(2,1),(2,3)])
scatter!(Point2.(eachcol(rand(d,1000))), alpha=0.25)
end]
),
PlotExample( # 47
"Mesh3d",
"""
Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically.
You can also specify the connections using the connections keyword.
The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle,
such that elements at the same position of these vectors form a triangle.
""",
[
:(
begin
# specify the vertices
x=[0, 1, 2, 0]
y=[0, 0, 1, 2]
z=[0, 2, 0, 1]
# specify the triangles
# every column is one triangle,
# where the values denote the indices of the vertices of the triangle
i=[0, 0, 0, 1]
j=[1, 2, 3, 2]
k=[2, 3, 1, 3]
# the four triangles gives above give a tetrahedron
mesh3d(x,y,z;connections=(i,j,k))
end
),
],
),
PlotExample( # 48
"Vectors of markershapes and segments",
"",
[quote
using Base.Iterators: cycle, take
yv = ones(9)
ys = [1; 1; NaN; ones(6)]
y = 5 .- [yv 2ys 3yv 4ys]
plt_color_rows = plot(
y,
seriestype = [:path :path :scatter :scatter],
markershape = collect(take(cycle((:utriangle, :rect)), 9)),
markersize = 8,
color = collect(take(cycle((:red, :black)), 9))
)
plt_z_cols = plot(
y,
markershape = [:utriangle :x :circle :square],
markersize = [5 10 10 5],
marker_z = [5 4 3 2],
line_z = [1 3 3 1],
linewidth = [1 10 5 1]
)
plot(plt_color_rows, plt_z_cols)
end]
),
PlotExample( # 49
"Polar heatmaps",
"",
[quote
x = range(0, 2π, length=9)
y = 0:4
z = (1:4) .+ (1:8)'
heatmap(x, y, z, projection = :polar)
end]
),
PlotExample( # 50
"3D surface with axis guides",
"",
[quote
f(x,a) = 1/x + a*x^2
xs = collect(0.1:0.05:2.0);
as = collect(0.2:0.1:2.0);
x_grid = [x for x in xs for y in as];
a_grid = [y for x in xs for y in as];
plot(x_grid, a_grid, f.(x_grid,a_grid),
st = :surface,
xlabel = "longer xlabel",
ylabel = "longer ylabel",
zlabel = "longer zlabel",
)
end]
),
PlotExample( # 51
"Images with custom axes",
"",
[quote
using Plots
using TestImages
img = testimage("lighthouse")
# plot the image reversing the first dimension and setting yflip = false
plot([-π, π], [-1, 1], reverse(img, dims=1), yflip=false, aspect_ratio=:none)
# plot other data
plot!(sin, -π, π, lw=3, color=:red)
end]
),
PlotExample(
"3d quiver",
"",
[quote
using Plots
ϕs = range(-π, π, length=50)
θs = range(0, π, length=25)
θqs = range(1, π-1, length=25)
x = vec([sin(θ) * cos(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θs)])
y = vec([sin(θ) * sin(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θs)])
z = vec([cos(θ) for (ϕ, θ) in Iterators.product(ϕs, θs)])
u = 0.1 * vec([sin(θ) * cos(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θqs)])
v = 0.1 * vec([sin(θ) * sin(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θqs)])
w = 0.1 * vec([cos(θ) for (ϕ, θ) in Iterators.product(ϕs, θqs)])
quiver(x,y,z, quiver=(u,v,w))
end]
),
PlotExample( # 53
"Step Types",
"A comparison of the various step-like `seriestype`s",
[
:(
begin
x = 1:5
y = [1, 2, 3, 2, 1]
default(shape=:circle)
plot(
plot(x, y, markershape=:circle, seriestype=:steppre, label="steppre"),
plot(x, y, markershape=:circle, seriestype=:stepmid, label="stepmid"),
plot(x, y, markershape=:circle, seriestype=:steppost, label="steppost"),
layout=(3,1)
)
end
),
],
),
PlotExample( # 54
"Guide positions and alignment",
"",
[
:(
begin
plot(
rand(10, 4),
layout=4,
xguide="x guide",
yguide="y guide",
xguidefonthalign=[:left :right :right :left],
yguidefontvalign=[:top :bottom :bottom :top],
xguideposition=:top,
yguideposition=[:right :left :right :left],
ymirror=[false true true false],
xmirror=[false false true true],
legend=false,
seriestype=[:bar :scatter :path :stepmid]
)
end
),
],
),
]
# Some constants for PlotDocs and PlotReferenceImages
_animation_examples = [2, 31]
_backend_skips = Dict(
:gr => [25, 30, 47],
:pyplot => [2, 25, 30, 31, 47, 49],
:plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51],
:plotly => [2, 21, 24, 25, 30, 31, 49, 50, 51],
:gr => [25, 30],
:pyplot => [2, 25, 30, 31],
:plotlyjs => [2, 21, 24, 25, 30, 31],
:plotly => [2, 21, 24, 25, 30, 31],
:pgfplots => [2, 5, 6, 10, 16, 20, 22, 23, 25, 28, 30, 31, 34, 37, 38, 39],
:pgfplotsx => [
2, # animation
6, # images
10, # histogram2d
16, # pgfplots thinks the upper panel is too small
30, # @df
22, # contourf
23, # pie
31, # animation
32, # spy
49, # polar heatmap
51, # image with custom axes
38, # histogram2d
45, # wireframe
],
)
+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
+20 -17
View File
@@ -1,7 +1,4 @@
using REPL
using Scratch
const plotly_local_file_path = Ref{Union{Nothing, String}}(nothing)
function _plots_defaults()
@@ -16,10 +13,9 @@ end
function __init__()
user_defaults = _plots_defaults()
if haskey(user_defaults, :theme)
theme(pop!(user_defaults, :theme); user_defaults...)
else
default(; user_defaults...)
theme(pop!(user_defaults, :theme))
end
default(; user_defaults...)
insert!(Base.Multimedia.displays, findlast(x -> x isa Base.TextDisplay || x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, PlotsDisplay())
@@ -33,41 +29,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 +82,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)
+37 -15
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
@@ -775,17 +805,9 @@ end
"Adds a new, empty subplot overlayed on top of `sp`, with a mirrored y-axis and linked x-axis."
function twinx(sp::Subplot)
plot!(sp.plt,
inset = (sp[:subplot_index], bbox(0,0,1,1)),
right_margin = sp[:right_margin],
left_margin = sp[:left_margin],
top_margin = sp[:top_margin],
bottom_margin = sp[:bottom_margin],
)
sp[:right_margin] = max(sp[:right_margin], 30px)
plot!(sp.plt, inset = (sp[:subplot_index], bbox(0,0,1,1)))
twinsp = sp.plt.subplots[end]
twinsp[:xaxis][:grid] = false
twinsp[:yaxis][:grid] = false
twinsp[:xaxis][:showaxis] = false
twinsp[:yaxis][:mirror] = true
twinsp[:background_color_inside] = RGBA{Float64}(0,0,0,0)
link_axes!(sp[:xaxis], twinsp[:xaxis])
-59
View File
@@ -1,59 +0,0 @@
"""
```julia
legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax, inout)
```
Return `(x,y)` at an angle `theta` degrees from
`(xcenter,ycenter)` on a rectangle defined by (`xmin`,
`xmax`, `ymin`, `ymax`).
"""
function legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax)
(s,c) = sincosd(theta)
x = c < 0 ? (xmin-xcenter)/c : (xmax-xcenter)/c
y = s < 0 ? (ymin-ycenter)/s : (ymax-ycenter)/s
A = min(x,y)
return (xcenter + A*c, ycenter + A*s)
end
"""
Split continuous range `[-1,1]` evenly into an integer `[1,2,3]`
"""
function legend_anchor_index(x)
x<-1//3 && return 1
x<1//3 && return 2
return 3
end
"""
Turn legend argument into a (theta, :inner) or (theta, :outer) tuple.
For backends where legend position is given in normal coordinates (0,0) -- (1,1),
so :topleft exactly corresponds to (45, :inner) etc.
If `leg` is a (::Real,::Real) tuple, keep it as is.
"""
legend_angle(leg::Real) = (leg,:inner)
legend_angle(leg::Tuple{S,T}) where {S<:Real,T<:Real} = leg
legend_angle(leg::Tuple{S,Symbol}) where S<:Real = leg
legend_angle(leg::Symbol) = get(
(
topleft = (135,:inner),
top = (90, :inner),
topright = (45, :inner),
left = (180,:inner),
right = (0, :inner),
bottomleft = (225,:inner),
bottom = (270,:inner),
bottomright = (315,:inner),
outertopleft = (135,:outer),
outertop = (90, :outer),
outertopright = (45, :outer),
outerleft = (180,:outer),
outerright = (0, :outer),
outerbottomleft = (225,:outer),
outerbottom = (270,:outer),
outerbottomright = (315,:outer),
),
leg,
(45, :inner)
)
+99 -88
View File
@@ -1,51 +1,54 @@
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)
@@ -66,39 +69,48 @@ end
html(fn::AbstractString) = html(current(), fn)
function txt(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "txt")
io = open(fn, "w")
show(io, MIME("text/plain"), plt)
close(io)
fn = addExtension(fn, "txt")
io = open(fn, "w")
show(io, MIME("text/plain"), plt)
close(io)
end
txt(fn::AbstractString) = txt(current(), fn)
# ----------------------------------------------------------------
const _savemap = Dict(
"png" => png,
"svg" => svg,
"pdf" => pdf,
"ps" => ps,
"ps" => ps,
"eps" => eps,
"tex" => tex,
"json" => json,
"html" => html,
"tikz" => tex,
"txt" => txt,
)
)
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 +121,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 +164,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 +184,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 +196,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 +204,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,26 +249,34 @@ 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
+34 -62
View File
@@ -4,31 +4,43 @@
function RecipesPipeline.warn_on_recipe_aliases!(
plt::Plot,
plotattributes::AKW,
recipe_type::Symbol,
@nospecialize(args)
plotattributes,
recipe_type,
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`"))
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`."
@warn "Attribute alias `$k` detected in the $recipe_type recipe defined for the signature $(_signature_string(Val{recipe_type}, args...)). To ensure expected behavior it is recommended to use the default attribute `$dk`."
end
plotattributes[dk] = RecipesPipeline.pop_kw!(plotattributes, k)
end
end
end
function RecipesPipeline.warn_on_recipe_aliases!(
plt::Plot,
v::AbstractVector,
recipe_type,
args...,
)
foreach(x -> RecipesPipeline.warn_on_recipe_aliases!(plt, x, recipe_type, args...), v)
end
function RecipesPipeline.warn_on_recipe_aliases!(
plt::Plot,
rd::RecipeData,
recipe_type,
args...,
)
RecipesPipeline.warn_on_recipe_aliases!(plt, rd.plotattributes, recipe_type, args...)
end
function _signature_string(::Type{Val{:user}}, args...)
return string("(::", join(string.(typeof.(args)), ", ::"), ")")
end
_signature_string(::Type{Val{:type}}, T) = "(::Type{$T}, ::$T)"
_signature_string(::Type{Val{:plot}}, st) = "(::Type{Val{:$st}}, ::AbstractPlot)"
_signature_string(::Type{Val{:series}}, st) = "(::Type{Val{:$st}}, x, y, z)"
## Grouping
@@ -37,23 +49,12 @@ 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)
split_strs = _RecipesPipeline.split_attribute(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)
end
RecipesPipeline.preprocess_attributes!(plt::Plot, plotattributes) =
RecipesPipeline.preprocess_attributes!(plotattributes) # in src/args.jl
@@ -141,7 +142,7 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::AKW)
end
RecipesPipeline.get_axis_limits(plt::Plot, letter) = axis_limits(plt[1], letter)
RecipesPipeline.get_axis_limits(plt::Plot, f, letter) = axis_limits(plt[1], letter)
## Plot recipes
@@ -154,23 +155,8 @@ RecipesPipeline.type_alias(plt::Plot) = get(_typeAliases, st, st)
function RecipesPipeline.plot_setup!(plt::Plot, plotattributes, kw_list)
_plot_setup(plt, plotattributes, kw_list)
_subplot_setup(plt, plotattributes, kw_list)
return nothing
end
function RecipesPipeline.process_sliced_series_attributes!(plt::Plots.Plot, kw_list)
# swap errors
err_inds = findall(kw -> get(kw, :seriestype, :path) in (:xerror, :yerror, :zerror), kw_list)
for ind in err_inds
if get(kw_list[ind-1],:seriestype,:path) == :scatter
tmp = copy(kw_list[ind])
kw_list[ind] = copy(kw_list[ind-1])
kw_list[ind-1] = tmp
end
end
return nothing
end
# TODO: Should some of this logic be moved to RecipesPipeline?
function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
# merge in anything meant for the Plot
@@ -288,7 +274,6 @@ function RecipesPipeline.slice_series_attributes!(plt::Plot, kw_list, kw)
# 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
@@ -313,7 +298,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) || (st == :quiver && plotattributes[:z] !== nothing)
if RecipesPipeline.needs_3d_axes(st)
sp.attr[:projection] = "3d"
end
@@ -327,9 +312,9 @@ end
function _override_seriestype_check(plotattributes::AKW, st::Symbol)
# do we want to override the series type?
if !RecipesPipeline.is3d(st) && !(st in (:contour, :contour3d, :quiver))
if !RecipesPipeline.is3d(st) && !(st in (:contour, :contour3d))
z = plotattributes[:z]
if z !== nothing &&
if !isa(z, Nothing) &&
(size(plotattributes[:x]) == size(plotattributes[:y]) == size(z))
st = (st == :scatter ? :scatter3d : :path3d)
plotattributes[:seriestype] = st
@@ -345,7 +330,7 @@ function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
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,20 +341,7 @@ 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_args(plt.backend, plotattributes)
warn_on_unsupported(plt.backend, plotattributes)
series = Series(plotattributes)
push!(plt.series_list, series)
+3 -10
View File
@@ -43,11 +43,10 @@ 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)
@@ -61,7 +60,6 @@ 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)
@@ -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,7 +152,6 @@ 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)
# merge!(plt.user_attr, plotattributes)
@@ -168,7 +164,6 @@ end
# 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)
current(plt)
_do_plot_show(plt, plt[:show])
@@ -210,12 +205,10 @@ 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
+740
View File
@@ -0,0 +1,740 @@
function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
isdefined(Plots, Symbol("#@layout")) && precompile(Tuple{getfield(Plots, Symbol("#@layout")), LineNumberNode, Module, Expr})
isdefined(Plots, Symbol("#_make_hist##kw")) && precompile(Tuple{getfield(Plots, Symbol("#_make_hist##kw")), NamedTuple{(:normed, :weights), Tuple{Bool, Array{Int64, 1}}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}}, Symbol})
isdefined(Plots, Symbol("#_make_hist##kw")) && precompile(Tuple{getfield(Plots, Symbol("#_make_hist##kw")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
isdefined(Plots, Symbol("#_make_hist##kw")) && precompile(Tuple{getfield(Plots, Symbol("#_make_hist##kw")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Tuple{Int64, Int64}})
isdefined(Plots, Symbol("#_make_hist##kw")) && precompile(Tuple{getfield(Plots, Symbol("#_make_hist##kw")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}}, Symbol})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:formatter,), Tuple{Symbol}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:formatter,), Tuple{typeof(RecipesPipeline.datetimeformatter)}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Int64, Int64}, Bool}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :ticks), Tuple{Bool, Nothing}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:gridlinewidth, :grid, :gridalpha, :gridstyle, :foreground_color_grid), Tuple{Int64, Bool, Float64, Symbol, ColorTypes.RGBA{Float64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:guide,), Tuple{String}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:lims, :flip, :ticks, :guide), Tuple{Tuple{Int64, Int64}, Bool, Base.StepRange{Int64, Int64}, String}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:lims,), Tuple{Tuple{Float64, Float64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:rotation,), Tuple{Int64}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:scale, :guide), Tuple{Symbol, String}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:ticks,), Tuple{Base.UnitRange{Int64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:ticks,), Tuple{Nothing}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#contour##kw")) && precompile(Tuple{getfield(Plots, Symbol("#contour##kw")), NamedTuple{(:fill,), Tuple{Bool}}, typeof(Plots.contour), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
isdefined(Plots, Symbol("#default##kw")) && precompile(Tuple{getfield(Plots, Symbol("#default##kw")), NamedTuple{(:titlefont, :legendfontsize, :guidefont, :tickfont, :guide, :framestyle, :yminorgrid), Tuple{Tuple{Int64, String}, Int64, Tuple{Int64, Symbol}, Tuple{Int64, Symbol}, String, Symbol, Bool}}, typeof(Plots.default)})
isdefined(Plots, Symbol("#gr_polyline##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_polyline##kw")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}})
isdefined(Plots, Symbol("#gr_polyline##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_polyline##kw")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Array{Int64, 1}, Array{Float64, 1}})
isdefined(Plots, Symbol("#gr_polyline##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_polyline##kw")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}})
isdefined(Plots, Symbol("#gr_polyline##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_polyline##kw")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Base.StepRange{Int64, Int64}, Array{Float64, 1}})
isdefined(Plots, Symbol("#gr_polyline##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_polyline##kw")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Base.UnitRange{Int64}, Array{Float64, 1}})
isdefined(Plots, Symbol("#gr_polyline##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_polyline##kw")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Base.UnitRange{Int64}, Base.UnitRange{Int64}})
isdefined(Plots, Symbol("#gr_set_font##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_set_font##kw")), NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}}, typeof(Plots.gr_set_font), Plots.Font})
isdefined(Plots, Symbol("#heatmap##kw")) && precompile(Tuple{getfield(Plots, Symbol("#heatmap##kw")), NamedTuple{(:aspect_ratio,), Tuple{Int64}}, typeof(Plots.heatmap), Array{String, 1}, Int})
isdefined(Plots, Symbol("#histogram##kw")) && precompile(Tuple{getfield(Plots, Symbol("#histogram##kw")), NamedTuple{(:bins, :weights), Tuple{Symbol, Array{Int64, 1}}}, typeof(Plots.histogram), Array{Float64, 1}})
isdefined(Plots, Symbol("#histogram2d##kw")) && precompile(Tuple{getfield(Plots, Symbol("#histogram2d##kw")), NamedTuple{(:nbins, :show_empty_bins, :normed, :aspect_ratio), Tuple{Tuple{Int64, Int64}, Bool, Bool, Int64}}, typeof(Plots.histogram2d), Array{Base.Complex{Float64}, 1}})
isdefined(Plots, Symbol("#histogram2d##kw")) && precompile(Tuple{getfield(Plots, Symbol("#histogram2d##kw")), NamedTuple{(:nbins,), Tuple{Int64}}, typeof(Plots.histogram2d), Array{Float64, 1}, Array{Float64, 1}})
isdefined(Plots, Symbol("#hline!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#hline!##kw")), NamedTuple{(:line,), Tuple{Tuple{Int64, Symbol, Float64, Array{Symbol, 2}}}}, typeof(Plots.hline!), Array{Float64, 2}})
isdefined(Plots, Symbol("#lens!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#lens!##kw")), NamedTuple{(:inset,), Tuple{Tuple{Int64, Measures.BoundingBox{Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}, Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}}}}}, typeof(Plots.lens!), Array{Int64, 1}, Int})
isdefined(Plots, Symbol("#pie##kw")) && precompile(Tuple{getfield(Plots, Symbol("#pie##kw")), NamedTuple{(:title, :l), Tuple{String, Float64}}, typeof(Plots.pie), Array{String, 1}, Int})
isdefined(Plots, Symbol("#plotly_annotation_dict##kw")) && precompile(Tuple{getfield(Plots, Symbol("#plotly_annotation_dict##kw")), NamedTuple{(:xref, :yref), Tuple{String, String}}, typeof(Plots.plotly_annotation_dict), Float64, Float64, String})
isdefined(Plots, Symbol("#portfoliocomposition##kw")) && precompile(Tuple{getfield(Plots, Symbol("#portfoliocomposition##kw")), NamedTuple{(:labels,), Tuple{Array{String, 2}}}, typeof(Plots.portfoliocomposition), Array{Float64, 2}, Int})
isdefined(Plots, Symbol("#scatter!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter!##kw")), NamedTuple{(:marker, :series_annotations), Tuple{Tuple{Int64, Float64, Symbol}, Array{Any, 1}}}, typeof(Plots.scatter!), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
isdefined(Plots, Symbol("#scatter!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter!##kw")), NamedTuple{(:markersize, :c), Tuple{Int64, Symbol}}, typeof(Plots.scatter!), Array{Float64, 1}})
isdefined(Plots, Symbol("#scatter!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter!##kw")), 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("#scatter##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter##kw")), NamedTuple{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks), Tuple{Array{Symbol, 2}, Array{String, 2}, Base.ReshapedArray{Int64, 2, Base.UnitRange{Int64}, Tuple{}}, Int64, String, Int64, Base.UnitRange{Int64}}}, typeof(Plots.scatter), Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
isdefined(Plots, Symbol("#scatter##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter##kw")), NamedTuple{(:m, :lab, :bg, :xlim, :ylim), Tuple{Tuple{Int64, Symbol}, Array{String, 2}, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}}}, typeof(Plots.scatter), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
isdefined(Plots, Symbol("#scatter##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter##kw")), NamedTuple{(:marker_z, :color, :legend), Tuple{typeof(Base.:+), Symbol, Bool}}, typeof(Plots.scatter), Array{Float64, 1}, Array{Float64, 1}})
isdefined(Plots, Symbol("#standalone_html##kw")) && precompile(Tuple{getfield(Plots, Symbol("#standalone_html##kw")), NamedTuple{(:title,), Tuple{String}}, typeof(Plots.standalone_html), Plots.Plot{Plots.PlotlyBackend}})
isdefined(Plots, Symbol("#test_examples##kw")) && precompile(Tuple{getfield(Plots, Symbol("#test_examples##kw")), NamedTuple{(:skip,), Tuple{Array{Int64, 1}}}, typeof(Plots.test_examples), Symbol})
precompile(Tuple{typeof(Plots.__init__)})
precompile(Tuple{typeof(Plots._add_errorbar_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._add_markershape), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._add_smooth_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._backend_instance), Symbol})
precompile(Tuple{typeof(Plots._bin_centers), Array{Float64, 1}})
precompile(Tuple{typeof(Plots._binbarlike_baseline), Float64, Symbol})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Int64, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Nothing, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{PlotUtils.ColorGradient, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Symbol, 1}, String})
precompile(Tuple{typeof(Plots._create_backend_figure), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._create_backend_figure), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._cycle), Array{Any, 1}, Int64})
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots._cycle), Array{Float64, 1}, Int64})
precompile(Tuple{typeof(Plots._cycle), Array{Plots.Subplot{T} where T<:RecipesBase.AbstractBackend, 1}, Int64})
precompile(Tuple{typeof(Plots._cycle), Array{String, 1}, Int64})
precompile(Tuple{typeof(Plots._cycle), Base.OneTo{Int64}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots._cycle), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int64})
precompile(Tuple{typeof(Plots._cycle), Base.StepRange{Int64, Int64}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots._cycle), Base.StepRange{Int64, Int64}, Int64})
precompile(Tuple{typeof(Plots._cycle), ColorTypes.RGBA{Float64}, Int64})
precompile(Tuple{typeof(Plots._cycle), Float64, Int64})
precompile(Tuple{typeof(Plots._cycle), Int64, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots._cycle), Int64, Int64})
precompile(Tuple{typeof(Plots._cycle), Nothing, Array{Int64, 1}})
precompile(Tuple{typeof(Plots._cycle), Nothing, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots._cycle), Nothing, Int64})
precompile(Tuple{typeof(Plots._cycle), Plots.Shape, Int64})
precompile(Tuple{typeof(Plots._cycle), Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots._cycle), Plots.Subplot{Plots.PlotlyBackend}, Int64})
precompile(Tuple{typeof(Plots._cycle), Symbol, Int64})
precompile(Tuple{typeof(Plots._display), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Bool})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.PlotlyBackend}, Bool})
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._heatmap_edges), Array{Float64, 1}, Bool})
precompile(Tuple{typeof(Plots._hist_edge), Tuple{Array{Float64, 1}}, Int64, Symbol})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}}, Symbol})
precompile(Tuple{typeof(Plots._initialize_backend), Plots.PlotlyBackend})
precompile(Tuple{typeof(Plots._override_seriestype_check), RecipesPipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._pick_default_backend)})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, 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.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots._plot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._plot_setup), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._plotly_framestyle), Symbol})
precompile(Tuple{typeof(Plots._plots_defaults)})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._preprocess_barlike), RecipesPipeline.DefaultsDict, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_barlike), RecipesPipeline.DefaultsDict, Array{Int64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_barlike), RecipesPipeline.DefaultsDict, Base.OneTo{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_binlike), RecipesPipeline.DefaultsDict, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_userrecipe), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._replace_linewidth), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._replace_markershape), Array{Symbol, 2}})
precompile(Tuple{typeof(Plots._replace_markershape), Plots.Shape})
precompile(Tuple{typeof(Plots._scale_adjusted_values), Type{Float64}, Array{Float64, 1}, Symbol})
precompile(Tuple{typeof(Plots._series_index), RecipesPipeline.DefaultsDict, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._series_index), RecipesPipeline.DefaultsDict, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._show), Base.IOStream, Base.Multimedia.MIME{Symbol("image/png")}, Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._slice_series_args!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots._slice_series_args!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Int64})
precompile(Tuple{typeof(Plots._slice_series_args!), RecipesPipeline.DefaultsDict, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots._slice_series_args!), RecipesPipeline.DefaultsDict, Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, 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._subplot_setup), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._transform_ticks), Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots._transform_ticks), Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots._transform_ticks), Nothing})
precompile(Tuple{typeof(Plots._transform_ticks), Symbol})
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, RecipesPipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis_colors), Plots.Axis})
precompile(Tuple{typeof(Plots._update_axis_links), Plots.Plot{Plots.GRBackend}, Plots.Axis, Symbol})
precompile(Tuple{typeof(Plots._update_axis_links), Plots.Plot{Plots.PlotlyBackend}, Plots.Axis, Symbol})
precompile(Tuple{typeof(Plots._update_clims), Float64, Float64, Float64, Float64})
precompile(Tuple{typeof(Plots._update_clims), Float64, Float64, Int64, Int64})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.GridLayout})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._update_series_attributes!), RecipesPipeline.DefaultsDict, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._update_series_attributes!), RecipesPipeline.DefaultsDict, Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._update_subplot_periphery), Plots.Subplot{Plots.GRBackend}, Array{Any, 1}})
precompile(Tuple{typeof(Plots._update_subplot_periphery), Plots.Subplot{Plots.PlotlyBackend}, Array{Any, 1}})
precompile(Tuple{typeof(Plots.addExtension), String, String})
precompile(Tuple{typeof(Plots.add_layout_pct!), Base.Dict{Symbol, Any}, Expr, Int64, Int64})
precompile(Tuple{typeof(Plots.aliasesAndAutopick), RecipesPipeline.DefaultsDict, Symbol, Base.Dict{Symbol, Symbol}, Array{Symbol, 1}, Int64})
precompile(Tuple{typeof(Plots.allAlphas), Int64})
precompile(Tuple{typeof(Plots.allStyles), Int64})
precompile(Tuple{typeof(Plots.allStyles), Symbol})
precompile(Tuple{typeof(Plots.annotate!), Array{Tuple{Int64, Float64, Plots.PlotText}, 1}})
precompile(Tuple{typeof(Plots.arrow), Int64})
precompile(Tuple{typeof(Plots.attr), Plots.EmptyLayout, Symbol, Symbol})
precompile(Tuple{typeof(Plots.attr), Plots.EmptyLayout, Symbol})
precompile(Tuple{typeof(Plots.autopick), Array{ColorTypes.RGBA{Float64}, 1}, Int64})
precompile(Tuple{typeof(Plots.autopick_ignore_none_auto), Array{Symbol, 1}, Int64})
precompile(Tuple{typeof(Plots.axis_drawing_info), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.axis_drawing_info_3d), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol, Bool, Bool})
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.PlotlyBackend}, Symbol, Bool, Bool})
precompile(Tuple{typeof(Plots.axis_limits), Plots.Subplot{Plots.PlotlyBackend}, Symbol})
precompile(Tuple{typeof(Plots.backend), Plots.GRBackend})
precompile(Tuple{typeof(Plots.backend), Plots.PlotlyBackend})
precompile(Tuple{typeof(Plots.backend), Symbol})
precompile(Tuple{typeof(Plots.backend)})
precompile(Tuple{typeof(Plots.bar), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.bbox!), Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.bbox!), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.bbox!), Plots.Subplot{Plots.PlotlyBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.bbox), Float64, Float64, Float64, Float64})
precompile(Tuple{typeof(Plots.bbox), Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}})
precompile(Tuple{typeof(Plots.bbox_to_pcts), 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}, Bool})
precompile(Tuple{typeof(Plots.bbox_to_pcts), 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}})
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.bottom), Measures.BoundingBox{Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}, Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}}})
precompile(Tuple{typeof(Plots.bottompad), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.bottompad), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64, Array{Plots.Plot{T} where T<:RecipesBase.AbstractBackend, 1}})
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64})
precompile(Tuple{typeof(Plots.build_layout), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.calc_num_subplots), Plots.EmptyLayout})
precompile(Tuple{typeof(Plots.calc_num_subplots), Plots.GridLayout})
precompile(Tuple{typeof(Plots.color_or_nothing!), RecipesPipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots.colorbar_style), Plots.Series})
precompile(Tuple{typeof(Plots.compute_gridsize), Int64, Int64, Int64})
precompile(Tuple{typeof(Plots.concatenate_fillrange), Base.UnitRange{Int64}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.contour), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.contour_levels), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.convertLegendValue), Bool})
precompile(Tuple{typeof(Plots.convertLegendValue), Symbol})
precompile(Tuple{typeof(Plots.convert_sci_unicode), String})
precompile(Tuple{typeof(Plots.convert_to_polar), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}, Tuple{Int64, Float64}})
precompile(Tuple{typeof(Plots.copy_series!), Plots.Series, Symbol})
precompile(Tuple{typeof(Plots.create_grid), Expr})
precompile(Tuple{typeof(Plots.create_grid), Symbol})
precompile(Tuple{typeof(Plots.create_grid_curly), Expr})
precompile(Tuple{typeof(Plots.create_grid_vcat), Expr})
precompile(Tuple{typeof(Plots.default), Symbol, Bool})
precompile(Tuple{typeof(Plots.default), Symbol, Int64})
precompile(Tuple{typeof(Plots.default), Symbol, String})
precompile(Tuple{typeof(Plots.default), Symbol, Symbol})
precompile(Tuple{typeof(Plots.default), Symbol})
precompile(Tuple{typeof(Plots.default_should_widen), Plots.Axis})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Array{String, 1}})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Array{Union{Base.Missing, Float64}, 1}})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Base.Missing})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Char})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, String})
precompile(Tuple{typeof(Plots.ensure_gradient!), RecipesPipeline.DefaultsDict, Symbol, Symbol})
precompile(Tuple{typeof(Plots.error_coords), Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.error_coords), Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.error_style!), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.error_zipit), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.OneTo{Int64}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Float64})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Int64})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, RecipesPipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.extend_by_data!), Array{Float64, 1}, Float64})
precompile(Tuple{typeof(Plots.extend_series_data!), Plots.Series, Float64, Symbol})
precompile(Tuple{typeof(Plots.fakedata), Int64, Int64})
precompile(Tuple{typeof(Plots.fg_color), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.font), Int64, Int})
precompile(Tuple{typeof(Plots.font), String, Int})
precompile(Tuple{typeof(Plots.font), Symbol, Int})
precompile(Tuple{typeof(Plots.frame), Plots.Animation, Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.frame), Plots.Animation})
precompile(Tuple{typeof(Plots.get_aspect_ratio), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.get_aspect_ratio), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.get_axis), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.get_axis), Plots.Subplot{Plots.PlotlyBackend}, Symbol})
precompile(Tuple{typeof(Plots.get_clims), Plots.Series})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.PlotlyBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.get_fillalpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_fillalpha), Plots.Series})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.get_linealpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_linealpha), Plots.Series})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.get_linestyle), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_linestyle), Plots.Series})
precompile(Tuple{typeof(Plots.get_linewidth), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_linewidth), Plots.Series})
precompile(Tuple{typeof(Plots.get_markeralpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_markercolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots.get_markerstrokealpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_markerstrokecolor), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_markerstrokewidth), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{Any, 1}}})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{String, 1}}})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Int64, 1}, Array{String, 1}}})
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), Int64, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), Int64, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ColorGradient, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ColorGradient, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_subplot), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.get_subplot), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.get_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.get_ticks), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.get_xy), Array{Plots.OHLC{T} where T<:Real, 1}, Base.OneTo{Int64}})
precompile(Tuple{typeof(Plots.get_xy), Plots.OHLC{Float64}, Int64, Float64})
precompile(Tuple{typeof(Plots.gr_axis_height), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.gr_axis_width), Plots.Subplot{Plots.GRBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.gr_color), ColorTypes.RGBA{Float64}, Type{ColorTypes.RGB{Float64}}})
precompile(Tuple{typeof(Plots.gr_colorbar_colors), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_contour_levels), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_display), Plots.Plot{Plots.GRBackend}, String})
precompile(Tuple{typeof(Plots.gr_display), Plots.Subplot{Plots.GRBackend}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_draw_colorbar), Plots.GRColorbar, Plots.Subplot{Plots.GRBackend}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64, Int64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Float64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Float64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Int64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Int64, Tuple{Float64, Float64}, Int64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Int64, Tuple{Float64, Float64}, Int64, Int64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_fill_viewport), Array{Float64, 1}, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_get_color), Plots.Series})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{Any, 1}}, Int64})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{String, 1}}, Int64})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Int64, 1}, Array{String, 1}}, Int64})
precompile(Tuple{typeof(Plots.gr_inqtext), Int64, Int64, String})
precompile(Tuple{typeof(Plots.gr_legend_pos), Plots.Subplot{Plots.GRBackend}, Float64, Float64})
precompile(Tuple{typeof(Plots.gr_polaraxes), Int64, Float64, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}, typeof(identity)})
precompile(Tuple{typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_set_bordercolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_fill), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_fillcolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_font), Plots.Font})
precompile(Tuple{typeof(Plots.gr_set_gradient), PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots.gr_set_gradient), Plots.Series})
precompile(Tuple{typeof(Plots.gr_set_line), Float64, Symbol, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots.gr_set_linecolor), PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots.gr_set_markercolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_textcolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Float64})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Nothing})
precompile(Tuple{typeof(Plots.gr_set_transparency), Float64})
precompile(Tuple{typeof(Plots.gr_set_viewport_cmap), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_set_viewport_polar)})
precompile(Tuple{typeof(Plots.gr_set_xticks_font), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_set_yticks_font), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_text), Float64, Float64, String})
precompile(Tuple{typeof(Plots.gr_text_size), String, Int64})
precompile(Tuple{typeof(Plots.gr_text_size), String})
precompile(Tuple{typeof(Plots.gr_tick_label), Plots.Axis, String})
precompile(Tuple{typeof(Plots.gr_update_colorbar!), Plots.GRColorbar, Plots.Series})
precompile(Tuple{typeof(Plots.gr_viewport_from_bbox), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_w3tondc), Float64, Float64, Float64})
precompile(Tuple{typeof(Plots.gr_w3tondc), Int64, Float64, Float64})
precompile(Tuple{typeof(Plots.gui), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gui), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.guide_padding), Plots.Axis})
precompile(Tuple{typeof(Plots.guidefont), Plots.Axis})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Array{Symbol, 2}, Symbol})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, ColorTypes.RGBA{Float64}, Symbol})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Plots.Shape, Symbol})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.has_attribute_segments), Plots.Series})
precompile(Tuple{typeof(Plots.hascolorbar), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.hascolorbar), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.hasgrid), Symbol, Symbol})
precompile(Tuple{typeof(Plots.heatmap), Array{Dates.DateTime, 1}, Int})
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Array{Float64, 1}, Symbol, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Base.UnitRange{Int64}, Symbol, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol, Bool})
precompile(Tuple{typeof(Plots.heatmap_edges), Array{Float64, 1}, Symbol})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol, Bool})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Symbol})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.UnitRange{Int64}, Symbol, Bool})
precompile(Tuple{typeof(Plots.heatmap_edges), Base.UnitRange{Int64}, Symbol})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Array{Float64, 2}})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.ignorenan_extrema), Plots.Axis})
precompile(Tuple{typeof(Plots.ignorenan_maximum), Base.OneTo{Int64}})
precompile(Tuple{typeof(Plots.ignorenan_minimum), Array{Int64, 1}})
precompile(Tuple{typeof(Plots.ignorenan_minimum), Base.OneTo{Int64}})
precompile(Tuple{typeof(Plots.inline), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.inline), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.intersection_point), Float64, Float64, Float64, Float64, Float64, Float64})
precompile(Tuple{typeof(Plots.is_2tuple), Int64})
precompile(Tuple{typeof(Plots.is_2tuple), Symbol})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Float64}})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Measures.BoundingBox{Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}, Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}}}})
precompile(Tuple{typeof(Plots.is_axis_attr), Symbol})
precompile(Tuple{typeof(Plots.is_axis_attr_noletter), Symbol})
precompile(Tuple{typeof(Plots.is_default_attribute), Symbol})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.PlotlyBackend, Symbol})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.Shape})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.Stroke})
precompile(Tuple{typeof(Plots.is_marker_supported), Symbol})
precompile(Tuple{typeof(Plots.is_scale_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.is_scale_supported), Plots.PlotlyBackend, Symbol})
precompile(Tuple{typeof(Plots.is_series_attr), Symbol})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Plots.PlotlyBackend, Symbol})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Symbol})
precompile(Tuple{typeof(Plots.is_style_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.is_style_supported), Plots.PlotlyBackend, Symbol})
precompile(Tuple{typeof(Plots.is_subplot_attr), Symbol})
precompile(Tuple{typeof(Plots.is_uniformly_spaced), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iscontour), Plots.Series})
precompile(Tuple{typeof(Plots.isijulia)})
precompile(Tuple{typeof(Plots.ispolar), Plots.Series})
precompile(Tuple{typeof(Plots.ispolar), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.ispolar), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.isvertical), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.isvertical), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.iter_segments), Array{Float64, 1}, Array{Float64, 1}, Int})
precompile(Tuple{typeof(Plots.iter_segments), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Array{Int64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Base.OneTo{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Base.OneTo{Int64}, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.iter_segments), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Base.StepRange{Int64, Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Base.UnitRange{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Plots.Series})
precompile(Tuple{typeof(Plots.labelfunc), Symbol, Plots.GRBackend})
precompile(Tuple{typeof(Plots.labelfunc), Symbol, Plots.PlotlyBackend})
precompile(Tuple{typeof(Plots.layout_args), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.layout_args), Int64, Int64})
precompile(Tuple{typeof(Plots.layout_args), Int64, Plots.GridLayout})
precompile(Tuple{typeof(Plots.layout_args), Int64, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.layout_args), Int64})
precompile(Tuple{typeof(Plots.layout_args), Plots.GridLayout})
precompile(Tuple{typeof(Plots.layout_args), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.left), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.left), Measures.BoundingBox{Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}, Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}}})
precompile(Tuple{typeof(Plots.leftpad), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.leftpad), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.legendfont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.legendfont), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.legendtitlefont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.like_histogram), Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Array{RecipesBase.AbstractLayout, 1}, Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Axis, Plots.Axis})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Axis})
precompile(Tuple{typeof(Plots.link_axes!), Plots.GridLayout, Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Subplot{Plots.PlotlyBackend}, Symbol})
precompile(Tuple{typeof(Plots.link_subplots), Array{RecipesBase.AbstractLayout, 1}, Symbol})
precompile(Tuple{typeof(Plots.locate_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText})
precompile(Tuple{typeof(Plots.make_fillrange_from_ribbon), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.make_fillrange_side), Base.UnitRange{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.make_fillrange_side), Base.UnitRange{Int64}, Base.LinRange{Float64}})
precompile(Tuple{typeof(Plots.make_fillrange_side), Base.UnitRange{Int64}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.make_fillrange_side), Base.UnitRange{Int64}, Int64})
precompile(Tuple{typeof(Plots.make_steps), Array{Float64, 1}, Symbol})
precompile(Tuple{typeof(Plots.make_steps), Array{Int64, 1}, Symbol})
precompile(Tuple{typeof(Plots.make_steps), Base.OneTo{Int64}, Symbol})
precompile(Tuple{typeof(Plots.make_steps), Nothing, Symbol})
precompile(Tuple{typeof(Plots.nanappend!), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.ohlc), Array{Plots.OHLC{T} where T<:Real, 1}})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Nothing})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis, Nothing})
precompile(Tuple{typeof(Plots.parse_axis_kw), Symbol})
precompile(Tuple{typeof(Plots.pie_labels), Plots.Subplot{Plots.GRBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.pie_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.plotarea!), Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.plotarea!), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.plotarea!), Plots.Subplot{Plots.PlotlyBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.plotarea), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.plotarea), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.plotly_annotation_dict), Float64, Float64, Plots.PlotText})
precompile(Tuple{typeof(Plots.plotly_apply_aspect_ratio), Plots.Subplot{Plots.PlotlyBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotly_axis), Plots.Plot{Plots.PlotlyBackend}, Plots.Axis, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.plotly_colorbar_hack), Plots.Series, Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.plotly_colorscale), PlotUtils.ColorGradient, Nothing})
precompile(Tuple{typeof(Plots.plotly_data), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Array{Int64, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Array{String, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{String, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.OneTo{Int64}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Nothing})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, RecipesPipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.plotly_domain), Plots.Subplot{Plots.PlotlyBackend}, Symbol})
precompile(Tuple{typeof(Plots.plotly_font), Plots.Font, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.plotly_font), Plots.Font})
precompile(Tuple{typeof(Plots.plotly_hover!), Base.Dict{Symbol, Any}, Array{Nothing, 1}})
precompile(Tuple{typeof(Plots.plotly_hover!), Base.Dict{Symbol, Any}, Nothing})
precompile(Tuple{typeof(Plots.plotly_html_body), Plots.Plot{Plots.PlotlyBackend}, Nothing})
precompile(Tuple{typeof(Plots.plotly_html_head), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.plotly_layout), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.plotly_legend_pos), Symbol})
precompile(Tuple{typeof(Plots.plotly_link_indicies), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Float64, 2}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{String, 1}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.OneTo{Int64}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, RecipesPipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.plotly_polar!), Base.Dict{Symbol, Any}, Plots.Series})
precompile(Tuple{typeof(Plots.plotly_polaraxis), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.plotly_series), Plots.Plot{Plots.PlotlyBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.plotly_series), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Array{Float64, 1}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Array{Int64, 1}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Array{Int64, 1}, Array{Int64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Base.OneTo{Int64}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Base.OneTo{Int64}, Base.UnitRange{Int64}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Base.StepRange{Int64, Int64}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Base.UnitRange{Int64}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Nothing, Nothing, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_shapes), Plots.Plot{Plots.PlotlyBackend}, Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_surface_data), Plots.Series, RecipesPipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.png), Plots.Plot{Plots.GRBackend}, String})
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Bool})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.processFontArg!), Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots.processFontArg!), Base.Dict{Symbol, Any}, Symbol, String})
precompile(Tuple{typeof(Plots.processFontArg!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Bool, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Float64, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Int64, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), RecipesPipeline.DefaultsDict, Bool, Symbol})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Float64})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Bool})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Float64})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Plots.Shape})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Plots.Stroke})
precompile(Tuple{typeof(Plots.processMarkerArg), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.processMinorGridArg!), Base.Dict{Symbol, Any}, Bool, Symbol})
precompile(Tuple{typeof(Plots.process_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText, Plots.Font})
precompile(Tuple{typeof(Plots.process_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText})
precompile(Tuple{typeof(Plots.process_annotation), Plots.Subplot{Plots.PlotlyBackend}, Int64, Float64, Plots.PlotText, Plots.Font})
precompile(Tuple{typeof(Plots.process_annotation), Plots.Subplot{Plots.PlotlyBackend}, Int64, Float64, Plots.PlotText})
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Base.StepRange{Int64, Int64}, Symbol})
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, String, Symbol})
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Tuple{Int64, Int64}, Symbol})
precompile(Tuple{typeof(Plots.recompute_lengths), Array{Measures.Measure, 1}})
precompile(Tuple{typeof(Plots.replaceAlias!), Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.replaceAlias!), RecipesPipeline.DefaultsDict, Symbol, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.replaceAliases!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.replaceAliases!), RecipesPipeline.DefaultsDict, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.reset_axis_defaults_byletter!)})
precompile(Tuple{typeof(Plots.right), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.rightpad), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.rightpad), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.rowsize), Expr})
precompile(Tuple{typeof(Plots.rowsize), Symbol})
precompile(Tuple{typeof(Plots.series_annotations), Array{Any, 1}})
precompile(Tuple{typeof(Plots.series_annotations), Plots.SeriesAnnotations})
precompile(Tuple{typeof(Plots.series_annotations_shapes!), Plots.Series, Symbol})
precompile(Tuple{typeof(Plots.series_idx), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.shape_data), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.should_add_to_legend), Plots.Series})
precompile(Tuple{typeof(Plots.showaxis), Symbol, Symbol})
precompile(Tuple{typeof(Plots.shrink_by), Float64, Float64, Float64})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, RecipesPipeline.DefaultsDict, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg!), RecipesPipeline.DefaultsDict, RecipesPipeline.DefaultsDict, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg), Array{ColorTypes.RGBA{Float64}, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{Float64, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{Measures.Length{:mm, Float64}, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{String, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{Symbol, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Base.ReshapedArray{Int64, 2, Base.UnitRange{Int64}, Tuple{}}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Base.StepRange{Int64, Int64}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Base.UnitRange{Int64}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Bool, Int64})
precompile(Tuple{typeof(Plots.slice_arg), ColorTypes.RGBA{Float64}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Float64, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Int64, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Nothing, Int64})
precompile(Tuple{typeof(Plots.slice_arg), String, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Symbol, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Tuple{Int64, Float64}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Tuple{Int64, Int64}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), typeof(identity), Int64})
precompile(Tuple{typeof(Plots.straightline_data), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.straightline_data), Tuple{Int64, Int64}, Tuple{Float64, Float64}, Array{Float64, 1}, Array{Float64, 1}, Int64})
precompile(Tuple{typeof(Plots.stroke), Int64, Int})
precompile(Tuple{typeof(Plots.supported_markers), Plots.GRBackend})
precompile(Tuple{typeof(Plots.supported_markers), Plots.PlotlyBackend})
precompile(Tuple{typeof(Plots.supported_markers)})
precompile(Tuple{typeof(Plots.supported_styles), Plots.GRBackend})
precompile(Tuple{typeof(Plots.supported_styles), Plots.PlotlyBackend})
precompile(Tuple{typeof(Plots.supported_styles)})
precompile(Tuple{typeof(Plots.test_examples), Symbol})
precompile(Tuple{typeof(Plots.text), String, Int64, Symbol, Symbol})
precompile(Tuple{typeof(Plots.text), String, Plots.Font})
precompile(Tuple{typeof(Plots.text), String, Symbol, Int64, Int})
precompile(Tuple{typeof(Plots.text), String, Symbol})
precompile(Tuple{typeof(Plots.text_size), Int64, Int64, Int64})
precompile(Tuple{typeof(Plots.tick_padding), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.tickfont), Plots.Axis})
precompile(Tuple{typeof(Plots.title!), String})
precompile(Tuple{typeof(Plots.title_padding), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.titlefont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.titlefont), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.top), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.toppad), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.toppad), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.transpose_z), Plots.Series, Array{Float64, 2}, Bool})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout, Array{Measures.Length{:mm, Float64}, 1}})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.GridLayout})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.Subplot{Plots.GRBackend}, Array{Measures.Length{:mm, Float64}, 1}})
precompile(Tuple{typeof(Plots.update_child_bboxes!), Plots.Subplot{Plots.PlotlyBackend}, Array{Measures.Length{:mm, Float64}, 1}})
precompile(Tuple{typeof(Plots.update_inset_bboxes!), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.update_inset_bboxes!), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.vline!), Array{Int64, 1}})
precompile(Tuple{typeof(Plots.wand_edges), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.warn_on_unsupported), Plots.GRBackend, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported), Plots.PlotlyBackend, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported_args), Plots.GRBackend, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported_args), Plots.PlotlyBackend, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported_scales), Plots.GRBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.warn_on_unsupported_scales), Plots.PlotlyBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.widen), Float64, Float64, Symbol})
precompile(Tuple{typeof(Plots.wraptuple), Array{Any, 1}})
precompile(Tuple{typeof(Plots.wraptuple), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.wraptuple), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.wraptuple), Bool})
precompile(Tuple{typeof(Plots.wraptuple), Float64})
precompile(Tuple{typeof(Plots.wraptuple), Int64})
precompile(Tuple{typeof(Plots.wraptuple), Nothing})
precompile(Tuple{typeof(Plots.wraptuple), Plots.SeriesAnnotations})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Array{Symbol, 2}, Int64, Float64, Plots.Stroke}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Array{Symbol, 2}, Int64}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Base.LinRange{Float64}, Base.LinRange{Float64}}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Array{Symbol, 2}}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Float64, Symbol, Plots.Stroke}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Float64, Symbol}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, String}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol, Float64, Array{Symbol, 2}}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol, Symbol}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Int64, Symbol}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Plots.Shape, Int64, ColorTypes.RGBA{Float64}}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{String, Symbol}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{String, Tuple{Int64, Int64}, Base.StepRange{Int64, Int64}, Symbol}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Float64, Plots.Stroke}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Int64}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Symbol, Int64, Symbol, Float64}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{Symbol, Symbol, Symbol, Int64, Float64}})
precompile(Tuple{typeof(Plots.wraptuple), Tuple{}})
precompile(Tuple{typeof(Plots.write_temp_html), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.xgrid!), Plots.Plot{Plots.GRBackend}, Symbol, Int})
precompile(Tuple{typeof(Plots.xgrid!), Plots.Plot{Plots.PlotlyBackend}, Symbol, Int})
precompile(Tuple{typeof(Plots.xlims), Int64})
precompile(Tuple{typeof(Plots.xlims), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.xlims), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.xy_mm_to_pcts), Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}})
precompile(Tuple{typeof(Plots.yaxis!), String, Symbol})
precompile(Tuple{typeof(Plots.ylims), Int64})
precompile(Tuple{typeof(Plots.ylims), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.ylims), Plots.Subplot{Plots.PlotlyBackend}})
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
+123 -305
View File
@@ -71,15 +71,12 @@ const POTENTIAL_VECTOR_ARGUMENTS = [
:marker_z,
:markerstrokecolor,
:markerstrokealpha,
:xerror,
:yerror,
:zerror,
:yerror,
:series_annotations,
:fillrange,
]
@nospecialize
@recipe function f(::Type{Val{:line}}, x, y, z)
indices = sortperm(x)
x := x[indices]
@@ -114,7 +111,7 @@ end
@recipe function f(::Type{Val{:hline}}, x, y, z)
n = length(y)
newx = repeat(Float64[1, 2, NaN], n)
newx = repeat(Float64[-1, 1, NaN], n)
newy = vec(Float64[yi for i = 1:3, yi in y])
x := newx
y := newy
@@ -126,8 +123,9 @@ end
@recipe function f(::Type{Val{:vline}}, x, y, z)
n = length(y)
newx = vec(Float64[yi for i = 1:3, yi in y])
newy = repeat(Float64[-1, 1, NaN], n)
x := newx
y := repeat(Float64[1, 2, NaN], n)
y := newy
seriestype := :straightline
()
end
@@ -165,81 +163,45 @@ end
x := x
y := y
seriestype := :scatter
@series begin
()
end
@series begin
seriestype := :path
label := ""
primary := false
()
end
primary := false
()
end
@deps scatterpath path scatter
# ---------------------------------------------------------------------------
# regression line and scatter
# plots line corresponding to linear regression of y on a constant and x
@recipe function f(::Type{Val{:linearfit}}, x, y, z)
x := x
y := y
seriestype := :scatter
@series begin
()
end
@series begin
y := mean(y) .+ cov(x, y) / var(x) .* (x .- mean(x))
seriestype := :path
label := ""
primary := false
()
end
primary := false
()
end
@specialize
# ---------------------------------------------------------------------------
# steps
make_steps(x, st, even) = x
function make_steps(x::AbstractArray, st, even)
make_steps(x, st) = x
function make_steps(x::AbstractArray, st)
n = length(x)
n == 0 && return zeros(0)
newx = zeros(2n - (even ? 0 : 1))
newx[1] = x[1]
for i = 2:n
newx = zeros(2n - 1)
for i = 1:n
idx = 2i - 1
if st == :mid
newx[idx] = newx[idx-1] = (x[i] + x[i-1]) / 2
else
newx[idx] = x[i]
newx[idx] = x[i]
if i > 1
newx[idx - 1] = x[st == :pre ? i : i - 1]
end
end
even && (newx[end] = x[end])
return newx
end
make_steps(t::Tuple, st, even) = Tuple(make_steps(ti, st, even) for ti in t)
make_steps(t::Tuple, st) = Tuple(make_steps(ti, st) for ti in t)
@nospecialize
# create a path from steps
@recipe function f(::Type{Val{:steppre}}, x, y, z)
plotattributes[:x] = make_steps(x, :post, false)
plotattributes[:y] = make_steps(y, :pre, false)
plotattributes[:x] = make_steps(x, :post)
plotattributes[:y] = make_steps(y, :pre)
seriestype := :path
# handle fillrange
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :pre, false)
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :pre)
# create a secondary series for the markers
if plotattributes[:markershape] != :none
@@ -257,39 +219,14 @@ make_steps(t::Tuple, st, even) = Tuple(make_steps(ti, st, even) for ti in t)
end
@deps steppre path scatter
# create a path from steps
@recipe function f(::Type{Val{:stepmid}}, x, y, z)
plotattributes[:x] = make_steps(x, :mid, true)
plotattributes[:y] = make_steps(y, :post, true)
seriestype := :path
# handle fillrange
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post, true)
# create a secondary series for the markers
if plotattributes[:markershape] != :none
@series begin
seriestype := :scatter
x := x
y := y
label := ""
primary := false
()
end
markershape := :none
end
()
end
@deps stepmid path scatter
# create a path from steps
@recipe function f(::Type{Val{:steppost}}, x, y, z)
plotattributes[:x] = make_steps(x, :pre, false)
plotattributes[:y] = make_steps(y, :post, false)
plotattributes[:x] = make_steps(x, :pre)
plotattributes[:y] = make_steps(y, :post)
seriestype := :path
# handle fillrange
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post, false)
plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post)
# create a secondary series for the markers
if plotattributes[:markershape] != :none
@@ -325,39 +262,24 @@ end
end
end
newx, newy = zeros(3n), zeros(3n)
newz = z !== nothing ? zeros(3n) : nothing
for (i, (xi, yi, zi)) = enumerate(zip(x, y, z !== nothing ? z : 1:n))
for i = 1:n
rng = (3i - 2):(3i)
newx[rng] = [xi, xi, NaN]
if z !== nothing
newy[rng] = [yi, yi, NaN]
newz[rng] = [_cycle(fr, i), zi, NaN]
else
newy[rng] = [_cycle(fr, i), yi, NaN]
end
newx[rng] = [x[i], x[i], NaN]
newy[rng] = [_cycle(fr, i), y[i], NaN]
end
x := newx
y := newy
if z !== nothing
z := newz
end
fillrange := nothing
seriestype := :path
if plotattributes[:linecolor] == :auto && plotattributes[:marker_z] !== nothing && plotattributes[:line_z] === nothing
line_z := plotattributes[:marker_z]
end
# create a primary series for the markers
# create a secondary series for the markers
if plotattributes[:markershape] != :none
primary := false
@series begin
seriestype := :scatter
x := x
y := y
if z !== nothing
z := z
end
primary := true
label := ""
primary := false
()
end
markershape := :none
@@ -366,8 +288,6 @@ end
end
@deps sticks path scatter
@specialize
# ---------------------------------------------------------------------------
# bezier curves
@@ -382,8 +302,6 @@ function bezier_value(pts::AVec, t::Real)
val
end
@nospecialize
# create segmented bezier curves in place of line segments
@recipe function f(::Type{Val{:curves}}, x, y, z; npoints = 30)
args = z !== nothing ? (x, y, z) : (x, y)
@@ -455,7 +373,7 @@ end
bw = plotattributes[:bar_width]
hw = if bw === nothing
if nx > 1
0.5 * _bar_width * ignorenan_minimum(filter(x -> x > 0, diff(sort(procx))))
0.5 * _bar_width * ignorenan_minimum(filter(x -> x > 0, diff(procx)))
else
0.5 * _bar_width
end
@@ -472,15 +390,6 @@ end
fillto = map(x -> _is_positive(x) ? typeof(baseline)(x) : baseline, fillto)
end
if !isnothing(plotattributes[:series_annotations])
if isvertical(plotattributes)
annotations := (x,y,plotattributes[:series_annotations].strs,:bottom)
else
annotations := (y,x,plotattributes[:series_annotations].strs,:left)
end
series_annotations := nothing
end
# create the bar shapes by adding x/y segments
xseg, yseg = Segments(), Segments()
for i = 1:ny
@@ -548,12 +457,9 @@ end
()
end
@deps plots_heatmap shape
@specialize
is_3d(::Type{Val{:plots_heatmap}}) = true
RecipesPipeline.is_surface(::Type{Val{:plots_heatmap}}) = true
RecipesPipeline.is_surface(::Type{Val{:hexbin}}) = true
# ---------------------------------------------------------------------------
# Histograms
@@ -614,8 +520,6 @@ function _preprocess_binlike(plotattributes, x, y)
end
@nospecialize
@recipe function f(::Type{Val{:barbins}}, x, y, z)
edge, weights, xscale, yscale, baseline =
_preprocess_binlike(plotattributes, x, y)
@@ -633,21 +537,14 @@ end
@recipe function f(::Type{Val{:scatterbins}}, x, y, z)
edge, weights, xscale, yscale, baseline =
_preprocess_binlike(plotattributes, x, y)
@series begin
x := _bin_centers(edge)
xerror := diff(edge) / 2
primary := false
seriestype := :xerror
()
end
xerror := diff(edge) / 2
x := _bin_centers(edge)
y := weights
seriestype := :scatter
()
end
@deps scatterbins xerror scatter
@deps scatterbins scatter
@specialize
function _stepbins_path(
edge,
@@ -715,8 +612,8 @@ function _stepbins_path(
(x, y)
end
@recipe function f(::Type{Val{:stepbins}}, x, y, z)
@nospecialize
axis =
plotattributes[:subplot][Plots.isvertical(plotattributes) ? :xaxis : :yaxis]
@@ -853,7 +750,6 @@ function _make_hist(
normalize!(h, mode = _hist_norm_mode(normed))
end
@nospecialize
@recipe function f(::Type{Val{:histogram}}, x, y, z)
seriestype := length(y) > 1e6 ? :stephist : :barhist
@@ -863,7 +759,7 @@ end
@recipe function f(::Type{Val{:barhist}}, x, y, z)
h = _make_hist(
tuple(y),
(y,),
plotattributes[:bins],
normed = plotattributes[:normalize],
weights = plotattributes[:weights],
@@ -877,7 +773,7 @@ end
@recipe function f(::Type{Val{:stephist}}, x, y, z)
h = _make_hist(
tuple(y),
(y,),
plotattributes[:bins],
normed = plotattributes[:normalize],
weights = plotattributes[:weights],
@@ -891,7 +787,7 @@ end
@recipe function f(::Type{Val{:scatterhist}}, x, y, z)
h = _make_hist(
tuple(y),
(y,),
plotattributes[:bins],
normed = plotattributes[:normalize],
weights = plotattributes[:weights],
@@ -958,7 +854,9 @@ end
x := Plots._bin_centers(edge_x)
y := Plots._bin_centers(edge_y)
z := Surface(permutedims(float_weights))
z := Surface(float_weights)
match_dimensions := true
seriestype := :heatmap
()
end
@@ -987,41 +885,6 @@ end
end
# ---------------------------------------------------------------------------
# pie
@recipe function f(::Type{Val{:pie}}, x, y, z)
framestyle --> :none
aspect_ratio --> true
s = sum(y)
θ = 0
for i in eachindex(y)
θ_new = θ + 2π * y[i] / s
coords = [(0.0, 0.0); partialcircle(θ, θ_new, 50)]
@series begin
seriestype := :shape
label --> string(x[i])
x := first.(coords)
y := last.(coords)
end
θ = θ_new
end
end
@deps pie shape
# ---------------------------------------------------------------------------
# mesh 3d replacement for non-plotly backends
@recipe function f(::Type{Val{:mesh3d}}, x, y, z)
# As long as no i,j,k are supplied this should work with PyPlot and GR
seriestype := :surface
if plotattributes[:connections] !== nothing
throw(ArgumentError("Giving triangles using the connections argument is only supported on Plotly backend."))
end
()
end
# ---------------------------------------------------------------------------
# scatter 3d
@@ -1037,6 +900,7 @@ end
# note: don't add dependencies because this really isn't a drop-in replacement
# ---------------------------------------------------------------------------
# lens! - magnify a region of a plot
lens!(args...;kwargs...) = plot!(args...; seriestype=:lens, kwargs...)
@@ -1058,12 +922,8 @@ export lens!
lens_index = last(plt.subplots)[:subplot_index] + 1
x1, x2 = plotattributes[:x]
y1, y2 = plotattributes[:y]
backup = copy(plotattributes)
empty!(plotattributes)
series_plotindex := backup[:series_plotindex]
seriestype := :path
primary := false
label := ""
linecolor := :lightgray
bbx_mag = (x1 + x2) / 2
bby_mag = (y1 + y2) / 2
@@ -1073,7 +933,6 @@ export lens!
if xl1 < xi_lens < xl2 &&
yl1 < yi_lens < yl2
@series begin
primary := false
subplot := sp_index
x := [xi_mag, xi_lens]
y := [yi_mag, yi_lens]
@@ -1082,7 +941,6 @@ export lens!
end
# add magnification shape
@series begin
primary := false
subplot := sp_index
x := [x1, x1, x2, x2, x1]
y := [y1, y2, y2, y1, y1]
@@ -1091,19 +949,20 @@ export lens!
# add subplot
for series in sp.series_list
@series begin
plotattributes = merge(backup, copy(series.plotattributes))
plotattributes = merge(plotattributes, copy(series.plotattributes))
subplot := lens_index
primary := false
label := ""
xlims := (x1, x2)
ylims := (y1, y2)
()
end
end
nothing
backup = copy(plotattributes)
empty!(plotattributes)
seriestype := :path
series_plotindex := backup[:series_plotindex]
end
@specialize
function intersection_point(xA, yA, xB, yB, h, w)
s = (yA - yB) / (xA - xB)
hh = h / 2
@@ -1131,7 +990,6 @@ end
# contourf - filled contours
@recipe function f(::Type{Val{:contourf}}, x, y, z)
@nospecialize
fillrange := true
seriestype := :contour
()
@@ -1141,24 +999,8 @@ end
# Error Bars
function error_style!(plotattributes::AKW)
msc = plotattributes[:markerstrokecolor]
msc = if msc === :match
plotattributes[:subplot][:foreground_color_subplot]
elseif msc === :auto
get_series_color(
plotattributes[:linecolor],
plotattributes[:subplot],
plotattributes[:series_plotindex],
plotattributes[:seriestype],
)
else
msc
end
plotattributes[:seriestype] = :path
plotattributes[:markerstrokecolor] = msc
plotattributes[:markercolor] = msc
plotattributes[:linecolor] = msc
plotattributes[:linecolor] = plotattributes[:markerstrokecolor]
plotattributes[:linewidth] = plotattributes[:markerstrokewidth]
plotattributes[:label] = ""
end
@@ -1177,7 +1019,7 @@ error_tuple(x::Tuple) = x
function error_coords(errorbar, errordata, otherdata...)
ed = Vector{float_extended_type(errordata)}(undef, 0)
od = [Vector{float_extended_type(odi)}(undef, 0) for odi in otherdata]
od = [Float64[] for _ in otherdata]
for (i, edi) in enumerate(errordata)
for (j, odj) in enumerate(otherdata)
odi = _cycle(odj, i)
@@ -1189,17 +1031,9 @@ function error_coords(errorbar, errordata, otherdata...)
return (ed, od...)
end
# clamp non-NaN values in an array to Base.eps(Float64) for log-scale plots
function clamp_to_eps!(ary)
replace!(x -> x <= 0.0 ? Base.eps(Float64) : x, ary)
nothing
end
# we will create a series of path segments, where each point represents one
# side of an errorbar
@nospecialize
@recipe function f(::Type{Val{:xerror}}, x, y, z)
error_style!(plotattributes)
markershape := :vline
@@ -1210,9 +1044,6 @@ end
plotattributes[:x], plotattributes[:y], plotattributes[:z] =
error_coords(xerr, x, y, z)
end
if :xscale keys(plotattributes) && plotattributes[:xscale] == :log10
clamp_to_eps!(plotattributes[:x])
end
()
end
@deps xerror path
@@ -1227,9 +1058,6 @@ end
plotattributes[:y], plotattributes[:x], plotattributes[:z] =
error_coords(yerr, y, x, z)
end
if :yscale keys(plotattributes) && plotattributes[:yscale] == :log10
clamp_to_eps!(plotattributes[:y])
end
()
end
@deps yerror path
@@ -1242,14 +1070,10 @@ end
plotattributes[:z], plotattributes[:x], plotattributes[:y] =
error_coords(zerr, z, x, y)
end
if :zscale keys(plotattributes) && plotattributes[:zscale] == :log10
clamp_to_eps!(plotattributes[:z])
end
()
end
@deps zerror path
@deps xerror path
@specialize
# TODO: move quiver to PlotRecipes
@@ -1263,51 +1087,35 @@ function quiver_using_arrows(plotattributes::AKW)
if !isa(plotattributes[:arrow], Arrow)
plotattributes[:arrow] = arrow()
end
is_3d = haskey(plotattributes,:z) && !isnothing(plotattributes[:z])
velocity = error_zipit(plotattributes[:quiver])
xorig, yorig = plotattributes[:x], plotattributes[:y]
zorig = is_3d ? plotattributes[:z] : []
# for each point, we create an arrow of velocity vi, translated to the x/y coordinates
x, y = zeros(0), zeros(0)
is_3d && ( z = zeros(0))
for i = 1:max(length(xorig), length(yorig), is_3d ? 0 : length(zorig))
for i = 1:max(length(xorig), length(yorig))
# get the starting position
xi = _cycle(xorig, i)
yi = _cycle(yorig, i)
zi = is_3d ? _cycle(zorig, i) : 0
# get the velocity
vi = _cycle(velocity, i)
if is_3d
vx, vy, vz = if istuple(vi)
vi[1], vi[2], vi[3]
elseif isscalar(vi)
vi, vi, vi
elseif isa(vi, Function)
vi(xi, yi, zi)
else
error("unexpected vi type $(typeof(vi)) for quiver: $vi")
end
else # 2D quiver
vx, vy = if istuple(vi)
first(vi), last(vi)
elseif isscalar(vi)
vi, vi
elseif isa(vi, Function)
vi(xi, yi)
else
error("unexpected vi type $(typeof(vi)) for quiver: $vi")
end
vx, vy = if istuple(vi)
first(vi), last(vi)
elseif isscalar(vi)
vi, vi
elseif isa(vi, Function)
vi(xi, yi)
else
error("unexpected vi type $(typeof(vi)) for quiver: $vi")
end
# add the points
nanappend!(x, [xi, xi + vx, NaN])
nanappend!(y, [yi, yi + vy, NaN])
is_3d && nanappend!(z, [zi, zi + vz, NaN])
end
plotattributes[:x], plotattributes[:y] = x, y
if is_3d
plotattributes[:z] = z
end
# KW[plotattributes]
end
@@ -1362,7 +1170,6 @@ end
# function apply_series_recipe(plotattributes::AKW, ::Type{Val{:quiver}})
@recipe function f(::Type{Val{:quiver}}, x, y, z)
@nospecialize
if :arrow in supported_attrs()
quiver_using_arrows(plotattributes)
else
@@ -1395,14 +1202,12 @@ end
else
seriestype := :heatmap
yflip --> true
colorbar --> false
fillcolor --> cgrad([:black, :white])
cbar --> false
fillcolor --> ColorGradient([:black, :white])
SliceIt, m, n, Surface(clamp!(convert(Matrix{Float64}, mat), 0.0, 1.0))
end
end
@nospecialize
# images - colors
@recipe function f(mat::AMat{T}) where {T <: Colorant}
n, m = axes(mat)
@@ -1414,7 +1219,7 @@ end
else
seriestype := :heatmap
yflip --> true
colorbar --> false
cbar --> false
aspect_ratio --> :equal
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, m, n, Surface(z)
@@ -1428,22 +1233,12 @@ end
coords(shape)
end
@recipe function f(shapes::AVec{<:Shape})
@recipe function f(shapes::AVec{Shape})
seriestype --> :shape
# For backwards compatibility, column vectors of segmenting attributes are
# interpreted as having one element per shape
for attr in union(_segmenting_array_attributes, _segmenting_vector_attributes)
v = get(plotattributes, attr, nothing)
if v isa AVec || v isa AMat && size(v,2) == 1
@warn "Column vector attribute `$attr` reinterpreted as row vector (one value per shape).\n" *
"Pass a row vector instead (e.g. using `permutedims`) to suppress this warning."
plotattributes[attr] = permutedims(v)
end
end
coords(shapes)
end
@recipe function f(shapes::AMat{<:Shape})
@recipe function f(shapes::AMat{Shape})
seriestype --> :shape
for j in axes(shapes, 2)
@series coords(vec(shapes[:, j]))
@@ -1464,8 +1259,8 @@ end
else
seriestype := :heatmap
yflip --> true
colorbar --> false
fillcolor --> cgrad([:black, :white])
cbar --> false
fillcolor --> ColorGradient([:black, :white])
SliceIt, x, y, Surface(convert(Matrix{Float64}, mat))
end
end
@@ -1479,24 +1274,23 @@ end
else
seriestype := :heatmap
yflip --> true
colorbar --> false
cbar --> false
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, x, y, Surface(z)
end
end
# --------------------------------------------------------------------
# Lists of tuples and GeometryBasics.Points
# Lists of tuples and GeometryTypes.Points
# --------------------------------------------------------------------
@recipe f(v::AVec{<:GeometryBasics.Point}) = RecipesPipeline.unzip(v)
@recipe f(p::GeometryBasics.Point) = [p]
@recipe f(v::AVec{<:GeometryTypes.Point}) = RecipesPipeline.unzip(v)
@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] :
RecipesPipeline.unzip(xyuv)
@specialize
# -------------------------------------------------
@@ -1536,8 +1330,6 @@ end
# TODO: when I allow `@recipe f(::Type{T}, v::T) = ...` definitions to replace convertToAnyVector,
# then I should replace these with one definition to convert to a vector of 4-tuples
@nospecialize
# to squash ambiguity warnings...
@recipe f(x::AVec{Function}, v::AVec{OHLC}) = error()
@recipe f(
@@ -1595,17 +1387,17 @@ end
@recipe function f(::Type{Val{:spy}}, x, y, z)
yflip := true
aspect_ratio := 1
rs, cs, zs = Plots.findnz(z.surf)
xlims := widen(ignorenan_extrema(cs)..., get(plotattributes, :xscale, :identity))
ylims := widen(ignorenan_extrema(rs)..., get(plotattributes, :yscale, :identity))
markershape --> :circle
markersize --> 1
markerstrokewidth := 0
if length(unique(zs)) == 1
seriescolor --> :black
else
marker_z := zs
rs, cs, zs = findnz(z.surf)
xlims := ignorenan_extrema(cs)
ylims := ignorenan_extrema(rs)
if plotattributes[:markershape] == :none
markershape := :circle
end
if plotattributes[:markersize] == default(:markersize)
markersize := 1
end
markerstrokewidth := 0
marker_z := zs
label := ""
x := cs
y := rs
@@ -1615,24 +1407,8 @@ end
()
end
@specialize
Plots.findnz(A::AbstractSparseMatrix) = SparseArrays.findnz(A)
# fallback function for finding non-zero elements of non-sparse matrices
function Plots.findnz(A::AbstractMatrix)
keysnz = findall(!iszero, A)
rs = [k[1] for k in keysnz]
cs = [k[2] for k in keysnz]
zs = A[keysnz]
rs, cs, zs
end
# -------------------------------------------------
@nospecialize
"Adds ax+b... straight line over the current plot, without changing the axis limits"
abline!(plt::Plot, a, b; kw...) =
plot!(plt, [0, 1], [b, b + a]; seriestype = :straightline, kw...)
@@ -1658,6 +1434,50 @@ end
end
# --------------------------------------------------
# Color Gradients
@userplot ShowLibrary
@recipe function f(cl::ShowLibrary)
if !(length(cl.args) == 1 && isa(cl.args[1], Symbol))
error("showlibrary takes the name of a color library as a Symbol")
end
library = PlotUtils.color_libraries[cl.args[1]]
z = sqrt.((1:15) * reshape(1:20, 1, :))
seriestype := :heatmap
ticks := nothing
legend := false
layout --> length(library.lib)
i = 0
for grad in sort(collect(keys(library.lib)))
@series begin
seriescolor := cgrad(grad, cl.args[1])
title := string(grad)
subplot := i += 1
z
end
end
end
@userplot ShowGradient
@recipe function f(grad::ShowGradient)
if !(length(grad.args) == 1 && isa(grad.args[1], Symbol))
error("showgradient takes the name of a color gradient as a Symbol")
end
z = sqrt.((1:15) * reshape(1:20, 1, :))
seriestype := :heatmap
ticks := nothing
legend := false
seriescolor := grad.args[1]
title := string(grad.args[1])
z
end
# Moved in from PlotRecipes - see: http://stackoverflow.com/a/37732384/5075246
@userplot PortfolioComposition
@@ -1702,5 +1522,3 @@ julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], f
end
end
end
@specialize
+12 -38
View File
@@ -1,5 +1,3 @@
@nospecialize
"""
scatter(x,y)
scatter!(x,y)
@@ -57,7 +55,6 @@ Plot a histogram.
# Example
```julia-repl
julia> histogram([1,2,1,1,4,3,8],bins=0:8)
julia> histogram([1,2,1,1,4,3,8],bins=0:8,weights=weights([4,7,3,9,12,2,6]))
```
"""
@shorthands histogram
@@ -72,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`.
@@ -254,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)
```
"""
@@ -275,7 +272,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])))
```
"""
@@ -321,27 +318,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)
@@ -405,7 +381,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)
@@ -421,13 +398,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...)
@@ -435,10 +412,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...)
@@ -461,9 +438,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 = collect(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...)
@@ -478,5 +454,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
+6 -18
View File
@@ -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
# ----------------------------------------------------------------------
+19 -9
View File
@@ -14,15 +14,25 @@ function _theme(s::Symbol, defaults::AKW; kw...)
# 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
+200 -231
View File
@@ -1,10 +1,8 @@
function treats_y_as_x(seriestype)
return seriestype in (:vline, :vspan, :histogram, :barhist, :stephist, :scatterhist)
end
function replace_image_with_heatmap(z::Array{T}) where T<:Colorant
n, m = size(z)
colors = palette(vec(z))
newz = reshape(1:n*m, n, m)
colors = ColorGradient(vec(z))
newz = reshape(range(0, stop=1, length=n*m), n, m)
newz, colors
end
@@ -53,16 +51,10 @@ function Base.push!(segments::Segments{T}, vs::AVec) where T
end
struct SeriesSegment
# indexes of this segement in series data vectors
range::UnitRange
# index into vector-valued attributes corresponding to this segment
attr_index::Int
end
# -----------------------------------------------------
# helper to manage NaN-separated segments
struct NaNSegmentsIterator
mutable struct SegmentsIterator
args::Tuple
n1::Int
n2::Int
@@ -72,50 +64,26 @@ function iter_segments(args...)
tup = Plots.wraptuple(args)
n1 = minimum(map(firstindex, tup))
n2 = maximum(map(lastindex, tup))
NaNSegmentsIterator(tup, n1, n2)
SegmentsIterator(tup, n1, n2)
end
function series_segments(series::Series, seriestype::Symbol = :path)
function iter_segments(series::Series)
x, y, z = series[:x], series[:y], series[:z]
(x === nothing || isempty(x)) && return UnitRange{Int}[]
args = RecipesPipeline.is3d(series) ? (x, y, z) : (x, y)
nan_segments = collect(iter_segments(args...))
segments = if has_attribute_segments(series)
Iterators.flatten(map(nan_segments) do r
if seriestype in (:scatter, :scatter3d)
(SeriesSegment(i:i, i) for i in r)
else
(SeriesSegment(i:i+1, i) for i in first(r):last(r)-1)
end
end)
else
(SeriesSegment(r, 1) for r in nan_segments)
end
warn_on_attr_dim_mismatch(series, x, y, z, segments)
return segments
end
function warn_on_attr_dim_mismatch(series, x, y, z, segments)
isempty(segments) && return
seg_range = UnitRange(minimum(first(seg.range) for seg in segments),
maximum(last(seg.range) for seg in segments))
for attr in _segmenting_vector_attributes
v = get(series, attr, nothing)
if v isa AVec && eachindex(v) != seg_range
@warn "Indices $(eachindex(v)) of attribute `$attr` does not match data indices $seg_range."
if any(v -> !isnothing(v) && any(isnan, v), (x,y,z))
@info """Data contains NaNs or missing values, and indices of `$attr` vector do not match data indices.
If you intend elements of `$attr` to apply to individual NaN-separated segements in the data,
pass each segment in a separate vector instead, and use a row vector for `$attr`. Legend entries
may be suppressed by passing an empty label.
For example,
plot([1:2,1:3], [[4,5],[3,4,5]], label=["y" ""], $attr=[1 2])
"""
end
if x === nothing
return UnitRange{Int}[]
elseif has_attribute_segments(series)
if series[:seriestype] in (:scatter, :scatter3d)
return [[i] for i in eachindex(y)]
else
return [i:(i + 1) for i in firstindex(y):lastindex(y)-1]
end
else
segs = UnitRange{Int}[]
args = RecipesPipeline.is3d(series) ? (x, y, z) : (x, y)
for seg in iter_segments(args...)
push!(segs, seg)
end
return segs
end
end
@@ -125,7 +93,7 @@ anynan(args::Tuple) = i -> anynan(i,args)
anynan(istart::Int, iend::Int, args::Tuple) = any(anynan(args), istart:iend)
allnan(istart::Int, iend::Int, args::Tuple) = all(anynan(args), istart:iend)
function Base.iterate(itr::NaNSegmentsIterator, nextidx::Int = itr.n1)
function Base.iterate(itr::SegmentsIterator, nextidx::Int = itr.n1)
i = findfirst(!anynan(itr.args), nextidx:itr.n2)
i === nothing && return nothing
nextval = nextidx + i - 1
@@ -135,7 +103,6 @@ function Base.iterate(itr::NaNSegmentsIterator, nextidx::Int = itr.n1)
nextval:nextnan-1, nextnan
end
Base.IteratorSize(::NaNSegmentsIterator) = Base.SizeUnknown()
# Find minimal type that can contain NaN and x
# To allow use of NaN separated segments with categorical x axis
@@ -155,21 +122,19 @@ isnothing(x) = false
_cycle(wrapper::InputWrapper, idx::Int) = wrapper.obj
_cycle(wrapper::InputWrapper, idx::AVec{Int}) = wrapper.obj
_cycle(v::AVec, idx::Int) = v[mod(idx, axes(v,1))]
_cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[end, mod(idx, axes(v,2))] : v[:, mod(idx, axes(v,2))]
_cycle(v::AVec, idx::Int) = v[mod1(idx, length(v))]
_cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))]
_cycle(v, idx::Int) = v
_cycle(v::AVec, indices::AVec{Int}) = map(i -> _cycle(v,i), indices)
_cycle(v::AMat, indices::AVec{Int}) = map(i -> _cycle(v,i), indices)
_cycle(v, indices::AVec{Int}) = fill(v, length(indices))
_cycle(cl::PlotUtils.AbstractColorList, idx::Int) = cl[mod1(idx, end)]
_cycle(cl::PlotUtils.AbstractColorList, idx::AVec{Int}) = cl[mod1.(idx, end)]
_cycle(grad::ColorGradient, idx::Int) = _cycle(grad.colors, idx)
_cycle(grad::ColorGradient, indices::AVec{Int}) = _cycle(grad.colors, indices)
_as_gradient(grad) = grad
_as_gradient(v::AbstractVector{<:Colorant}) = cgrad(v)
_as_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
_as_gradient(c::Colorant) = cgrad([c, c])
_as_gradient(grad::ColorGradient) = grad
_as_gradient(c::Colorant) = ColorGradient([c,c])
makevec(v::AVec) = v
makevec(v::T) where {T} = T[v]
@@ -180,18 +145,15 @@ maketuple(x::Tuple{T,S}) where {T,S} = x
for i in 2:4
@eval begin
RecipesPipeline.unzip(
v::Union{AVec{<:Tuple{Vararg{T,$i} where T}}, AVec{<:GeometryBasics.Point{$i}}},
) = $(Expr(:tuple, (:([t[$j] for t in v]) for j=1:i)...))
RecipesPipeline.unzip(v::Union{AVec{<:Tuple{Vararg{T,$i} where T}},
AVec{<:GeometryTypes.Point{$i}}}) = $(Expr(:tuple, (:([t[$j] for t in v]) for j=1:i)...))
end
end
RecipesPipeline.unzip(
::Union{AVec{<:GeometryBasics.Point{N}}, AVec{<:Tuple{Vararg{T,N} where T}}}
) where N = error("$N-dimensional unzip not implemented.")
RecipesPipeline.unzip(::Union{AVec{<:GeometryBasics.Point}, AVec{<:Tuple}}) = error(
"Can't unzip points of different dimensions."
)
RecipesPipeline.unzip(v::Union{AVec{<:GeometryTypes.Point{N}},
AVec{<:Tuple{Vararg{T,N} where T}}}) where N = error("$N-dimensional unzip not implemented.")
RecipesPipeline.unzip(v::Union{AVec{<:GeometryTypes.Point},
AVec{<:Tuple}}) = error("Can't unzip points of different dimensions.")
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
function _expand_limits(lims, x)
@@ -238,27 +200,37 @@ end
createSegments(z) = collect(repeat(reshape(z,1,:),2,1))[2:end]
Base.first(c::Colorant) = c
Base.first(x::Symbol) = x
sortedkeys(plotattributes::Dict) = sort(collect(keys(plotattributes)))
function _heatmap_edges(v::AVec, isedges::Bool = false, ispolar::Bool = false)
length(v) == 1 && return v[1] .+ [ispolar ? max(-v[1], -0.5) : -0.5, 0.5]
const _scale_base = Dict{Symbol, Real}(
:log10 => 10,
:log2 => 2,
:ln => ,
)
function _heatmap_edges(v::AVec, isedges::Bool = false)
length(v) == 1 && return v[1] .+ [-0.5, 0.5]
if isedges return v end
# `isedges = true` means that v is a vector which already describes edges
# and does not need to be extended.
vmin, vmax = ignorenan_extrema(v)
extra_min = ispolar ? min(v[1], (v[2] - v[1]) / 2) : (v[2] - v[1]) / 2
extra_min = (v[2] - v[1]) / 2
extra_max = (v[end] - v[end - 1]) / 2
vcat(vmin-extra_min, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra_max)
end
"create an (n+1) list of the outsides of heatmap rectangles"
function heatmap_edges(v::AVec, scale::Symbol = :identity, isedges::Bool = false, ispolar::Bool = false)
function heatmap_edges(v::AVec, scale::Symbol = :identity, isedges::Bool = false)
f, invf = RecipesPipeline.scale_func(scale), RecipesPipeline.inverse_scale_func(scale)
map(invf, _heatmap_edges(map(f,v), isedges, ispolar))
map(invf, _heatmap_edges(map(f,v), isedges))
end
function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size::Tuple{Int, Int}, ispolar::Bool = false)
function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size::Tuple{Int, Int})
nx, ny = length(x), length(y)
# ismidpoints = z_size == (ny, nx) # This fails some tests, but would actually be
# the correct check, since (4, 3) != (3, 4) and a missleading plot is produced.
@@ -270,7 +242,7 @@ function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size:
or `size(z) == (length(y)+1, length(x)+1))` (x & y define edges).""")
end
x, y = heatmap_edges(x, xscale, isedges),
heatmap_edges(y, yscale, isedges, ispolar) # special handle for `r` in polar plots
heatmap_edges(y, yscale, isedges)
return x, y
end
@@ -323,11 +295,13 @@ limsType(lims::Tuple{T,S}) where {T<:Real,S<:Real} = :limits
limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
limsType(lims) = :invalid
# axis_Symbol(letter, postfix) = Symbol(letter * postfix)
# axis_symbols(letter, postfix...) = map(s -> axis_Symbol(letter, s), postfix)
# recursively merge kw-dicts, e.g. for merging extra_kwargs / extra_plot_kwargs in plotly)
recursive_merge(x::AbstractDict...) = merge(recursive_merge, x...)
# if values are not AbstractDicts, take the last definition (as does merge)
recursive_merge(x...) = x[end]
Base.convert(::Type{Vector{T}}, rng::AbstractRange{T}) where {T<:Real} = T[x for x in rng]
Base.convert(::Type{Vector{T}}, rng::AbstractRange{S}) where {T<:Real,S<:Real} = T[x for x in rng]
Base.merge(a::AbstractVector, b::AbstractVector) = sort(unique(vcat(a,b)))
nanpush!(a::AbstractVector, b) = (push!(a, NaN); push!(a, b))
nanappend!(a::AbstractVector, b) = (push!(a, NaN); append!(a, b))
@@ -365,8 +339,17 @@ function indices_and_unique_values(z::AbstractArray)
newz, vals
end
handle_surface(z) = z
handle_surface(z::Surface) = permutedims(z.surf)
# this is a helper function to determine whether we need to transpose a surface matrix.
# it depends on whether the backend matches rows to x (transpose_on_match == true) or vice versa
# for example: PyPlot sends rows to y, so transpose_on_match should be true
function transpose_z(plotattributes, z, transpose_on_match::Bool = true)
if plotattributes[:match_dimensions] == transpose_on_match
# z'
permutedims(z, [2,1])
else
z
end
end
function ok(x::Number, y::Number, z::Number = 0)
isfinite(x) && isfinite(y) && isfinite(z)
@@ -374,10 +357,10 @@ end
ok(tup::Tuple) = ok(tup...)
# compute one side of a fill range from a ribbon
function make_fillrange_side(y::AVec, rib)
frs = zeros(axes(y))
for (i, yi) in pairs(y)
frs[i] = yi + _cycle(rib,i)
function make_fillrange_side(y, rib)
frs = zeros(length(y))
for (i, (yi, ri)) in enumerate(zip(y, Base.Iterators.cycle(rib)))
frs[i] = yi + ri
end
frs
end
@@ -432,7 +415,78 @@ xlims(sp_idx::Int = 1) = xlims(current(), sp_idx)
ylims(sp_idx::Int = 1) = ylims(current(), sp_idx)
zlims(sp_idx::Int = 1) = zlims(current(), sp_idx)
iscontour(series::Series) = series[:seriestype] in (:contour, :contour3d)
function get_clims(sp::Subplot)
zmin, zmax = Inf, -Inf
for series in series_list(sp)
if series[:colorbar_entry]
zmin, zmax = _update_clims(zmin, zmax, get_clims(series)...)
end
end
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(sp::Subplot, series::Series)
zmin, zmax = if series[:colorbar_entry]
get_clims(sp)
else
get_clims(series)
end
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(series::Series)
zmin, zmax = Inf, -Inf
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface)
for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z])
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...)
elseif (vals !== nothing) && (eltype(vals) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals)...)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
_update_clims(zmin, zmax, emin, emax) = NaNMath.min(zmin, emin), NaNMath.max(zmax, emax)
@enum ColorbarStyle cbar_gradient cbar_fill cbar_lines
function colorbar_style(series::Series)
colorbar_entry = series[:colorbar_entry]
if !(colorbar_entry isa Bool)
@warn "Non-boolean colorbar_entry ignored."
colorbar_entry = true
end
if !colorbar_entry
nothing
elseif isfilledcontour(series)
cbar_fill
elseif iscontour(series)
cbar_lines
elseif series[:seriestype] (:heatmap,:surface) ||
any(series[z] !== nothing for z [:marker_z,:line_z,:fill_z])
cbar_gradient
else
nothing
end
end
hascolorbar(series::Series) = colorbar_style(series) !== nothing
hascolorbar(sp::Subplot) = sp[:colorbar] != :none && any(hascolorbar(s) for s in series_list(sp))
iscontour(series::Series) = series[:seriestype] == :contour
isfilledcontour(series::Series) = iscontour(series) && series[:fillrange] !== nothing
function contour_levels(series::Series, clims)
@@ -467,7 +521,8 @@ for comp in (:line, :fill, :marker)
if z === nothing
isa(c, ColorGradient) ? c : plot_color(_cycle(c, i))
else
get(get_gradient(c), z[i], (cmin, cmax))
grad = isa(c, ColorGradient) ? c : cgrad()
grad[clamp((_cycle(z, i) - cmin) / (cmax - cmin), 0, 1)]
end
end
@@ -485,28 +540,9 @@ for comp in (:line, :fill, :marker)
end
end
function get_colorgradient(series::Series)
st = series[:seriestype]
if st in (:surface, :heatmap) || isfilledcontour(series)
series[:fillcolor]
elseif st in (:contour, :wireframe)
series[:linecolor]
elseif series[:marker_z] !== nothing
series[:markercolor]
elseif series[:line_z] !== nothing
series[:linecolor]
elseif series[:fill_z] !== nothing
series[:fillcolor]
end
end
single_color(c, v = 0.5) = c
single_color(grad::ColorGradient, v = 0.5) = grad[v]
get_gradient(c) = cgrad()
get_gradient(cg::ColorGradient) = cg
get_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
function get_linewidth(series, i::Int = 1)
_cycle(series[:linewidth], i)
end
@@ -528,34 +564,17 @@ function get_markerstrokewidth(series, i::Int = 1)
_cycle(series[:markerstrokewidth], i)
end
const _segmenting_vector_attributes = (
:seriescolor,
:seriesalpha,
:linecolor,
:linealpha,
:linewidth,
:linestyle,
:fillcolor,
:fillalpha,
:markercolor,
:markeralpha,
:markersize,
:markerstrokecolor,
:markerstrokealpha,
:markerstrokewidth,
:markershape,
)
const _segmenting_array_attributes = (:line_z, :fill_z, :marker_z)
function has_attribute_segments(series::Series)
# we want to check if a series needs to be split into segments just because
# of its attributes
for letter in (:x, :y, :z)
# If we have NaNs in the data they define the segments and
# SegmentsIterator is used
series[letter] !== nothing && NaN in collect(series[letter]) && return false
end
series[:seriestype] == :shape && return false
# check relevant attributes if they have multiple inputs
return any(series[attr] isa AbstractVector && length(series[attr]) > 1
for attr in _segmenting_vector_attributes
) || any(series[attr] isa AbstractArray for attr in _segmenting_array_attributes)
# ... else we check relevant attributes if they have multiple inputs
return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :linestyle, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray for attr in (:line_z, :fill_z, :marker_z))
end
function get_aspect_ratio(sp)
@@ -571,17 +590,6 @@ function get_aspect_ratio(sp)
return aspect_ratio
end
get_size(kw) = get(kw, :size, default(:size))
get_size(plt::Plot) = get_size(plt.attr)
get_size(sp::Subplot) = get_size(sp.plt)
get_size(series::Series) = get_size(series.plotattributes[:subplot])
get_thickness_scaling(kw) = get(kw, :thickness_scaling, default(:thickness_scaling))
get_thickness_scaling(plt::Plot) = get_thickness_scaling(plt.attr)
get_thickness_scaling(sp::Subplot) = get_thickness_scaling(sp.plt)
get_thickness_scaling(series::Series) =
get_thickness_scaling(series.plotattributes[:subplot])
# ---------------------------------------------------------------
makekw(; kw...) = KW(kw)
@@ -924,7 +932,7 @@ px2inch(px::Real) = float(px / PX_PER_INCH)
inch2mm(inches::Real) = float(inches * MM_PER_INCH)
mm2inch(mm::Real) = float(mm / MM_PER_INCH)
px2mm(px::Real) = float(px * MM_PER_PX)
mm2px(mm::Real) = float(mm / MM_PER_PX)
mm2px(mm::Real) = float(px / MM_PER_PX)
"Smallest x in plot"
@@ -939,72 +947,54 @@ ignorenan_extrema(plt::Plot) = (xmin(plt), xmax(plt))
# ---------------------------------------------------------------
# get fonts from objects:
plottitlefont(p::Plot) = font(;
family = p[:plot_titlefontfamily],
pointsize = p[:plot_titlefontsize],
valign = p[:plot_titlefontvalign],
halign = p[:plot_titlefonthalign],
rotation = p[:plot_titlefontrotation],
color = p[:plot_titlefontcolor],
titlefont(sp::Subplot) = font(
sp[:titlefontfamily],
sp[:titlefontsize],
sp[:titlefontvalign],
sp[:titlefonthalign],
sp[:titlefontrotation],
sp[:titlefontcolor],
)
colorbartitlefont(sp::Subplot) = font(;
family = sp[:colorbar_titlefontfamily],
pointsize = sp[:colorbar_titlefontsize],
valign = sp[:colorbar_titlefontvalign],
halign = sp[:colorbar_titlefonthalign],
rotation = sp[:colorbar_titlefontrotation],
color = sp[:colorbar_titlefontcolor],
legendfont(sp::Subplot) = font(
sp[:legendfontfamily],
sp[:legendfontsize],
sp[:legendfontvalign],
sp[:legendfonthalign],
sp[:legendfontrotation],
sp[:legendfontcolor],
)
titlefont(sp::Subplot) = font(;
family = sp[:titlefontfamily],
pointsize = sp[:titlefontsize],
valign = sp[:titlefontvalign],
halign = sp[:titlefonthalign],
rotation = sp[:titlefontrotation],
color = sp[:titlefontcolor],
legendtitlefont(sp::Subplot) = font(
sp[:legendtitlefontfamily],
sp[:legendtitlefontsize],
sp[:legendtitlefontvalign],
sp[:legendtitlefonthalign],
sp[:legendtitlefontrotation],
sp[:legendtitlefontcolor],
)
legendfont(sp::Subplot) = font(;
family = sp[:legendfontfamily],
pointsize = sp[:legendfontsize],
valign = sp[:legendfontvalign],
halign = sp[:legendfonthalign],
rotation = sp[:legendfontrotation],
color = sp[:legendfontcolor],
tickfont(ax::Axis) = font(
ax[:tickfontfamily],
ax[:tickfontsize],
ax[:tickfontvalign],
ax[:tickfonthalign],
ax[:tickfontrotation],
ax[:tickfontcolor],
)
legendtitlefont(sp::Subplot) = font(;
family = sp[:legendtitlefontfamily],
pointsize = sp[:legendtitlefontsize],
valign = sp[:legendtitlefontvalign],
halign = sp[:legendtitlefonthalign],
rotation = sp[:legendtitlefontrotation],
color = sp[:legendtitlefontcolor],
)
tickfont(ax::Axis) = font(;
family = ax[:tickfontfamily],
pointsize = ax[:tickfontsize],
valign = ax[:tickfontvalign],
halign = ax[:tickfonthalign],
rotation = ax[:tickfontrotation],
color = ax[:tickfontcolor],
)
guidefont(ax::Axis) = font(;
family = ax[:guidefontfamily],
pointsize = ax[:guidefontsize],
valign = ax[:guidefontvalign],
halign = ax[:guidefonthalign],
rotation = ax[:guidefontrotation],
color = ax[:guidefontcolor],
guidefont(ax::Axis) = font(
ax[:guidefontfamily],
ax[:guidefontsize],
ax[:guidefontvalign],
ax[:guidefonthalign],
ax[:guidefontrotation],
ax[:guidefontcolor],
)
# ---------------------------------------------------------------
# converts unicode scientific notation, as returned by Showoff,
# to a tex-like format (supported by gr, pyplot, and pgfplots).
# converts unicode scientific notation unsupported by pgfplots and gr
# into a format that works
function convert_sci_unicode(label::AbstractString)
unicode_dict = Dict(
@@ -1033,21 +1023,10 @@ end
function straightline_data(series, expansion_factor = 1)
sp = series[:subplot]
xl, yl = isvertical(series) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp))
# handle axes scales
xscale = sp[:xaxis][:scale]
xf = RecipesPipeline.scale_func(xscale)
xinvf = RecipesPipeline.inverse_scale_func(xscale)
yscale = sp[:yaxis][:scale]
yf = RecipesPipeline.scale_func(yscale)
yinvf = RecipesPipeline.inverse_scale_func(yscale)
xl, yl = xf.(xl), yf.(yl)
x, y = xf.(series[:x]), yf.(series[:y])
x, y = series[:x], series[:y]
n = length(x)
xdata, ydata = if n == 2
straightline_data(xl, yl, x, y, expansion_factor)
if n == 2
return straightline_data(xl, yl, x, y, expansion_factor)
else
k, r = divrem(n, 3)
if r == 0
@@ -1056,13 +1035,11 @@ function straightline_data(series, expansion_factor = 1)
inds = (3 * i - 2):(3 * i - 1)
xdata[inds], ydata[inds] = straightline_data(xl, yl, x[inds], y[inds], expansion_factor)
end
xdata, ydata
return xdata, ydata
else
error("Misformed data. `straightline_data` either accepts vectors of length 2 or 3k. The provided series has length $n")
end
end
return xinvf.(xdata), yinvf.(ydata)
end
function straightline_data(xl, yl, x, y, expansion_factor = 1)
@@ -1094,28 +1071,20 @@ end
function shape_data(series, expansion_factor = 1)
sp = series[:subplot]
xl, yl = isvertical(series) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp))
# handle axes scales
xscale = sp[:xaxis][:scale]
xf = RecipesPipeline.scale_func(xscale)
xinvf = RecipesPipeline.inverse_scale_func(xscale)
yscale = sp[:yaxis][:scale]
yf = RecipesPipeline.scale_func(yscale)
yinvf = RecipesPipeline.inverse_scale_func(yscale)
x, y = copy(series[:x]), copy(series[:y])
factor = 100
for i in eachindex(x)
if x[i] == -Inf
x[i] = xinvf(xf(xl[1]) - expansion_factor * (xf(xl[2]) - xf(xl[1])))
x[i] = xl[1] - expansion_factor * (xl[2] - xl[1])
elseif x[i] == Inf
x[i] = xinvf(xf(xl[2]) + expansion_factor * (xf(xl[2]) - xf(xl[1])))
x[i] = xl[2] + expansion_factor * (xl[2] - xl[1])
end
end
for i in eachindex(y)
if y[i] == -Inf
y[i] = yinvf(yf(yl[1]) - expansion_factor * (yf(yl[2]) - yf(yl[1])))
y[i] = yl[1] - expansion_factor * (yl[2] - yl[1])
elseif y[i] == Inf
y[i] = yinvf(yf(yl[2]) + expansion_factor * (yf(yl[2]) - yf(yl[1])))
y[i] = yl[2] + expansion_factor * (yl[2] - yl[1])
end
end
return x, y
+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
+49 -100
View File
@@ -1,41 +1,14 @@
using Plots: guidefont
import ImageMagick
using VisualRegressionTests
using Plots
using Random
using StableRNGs
using Test
using TestImages
using FileIO
using Gtk
using LibGit2
import GeometryBasics
using GeometryTypes
using Dates
using RecipesBase
@testset "Plotly standalone" begin
@test_nowarn Plots._init_ijulia_plotting()
@test Plots.plotly_local_file_path[] === nothing
temp = Plots.use_local_dependencies[]
withenv("PLOTS_HOST_DEPENDENCY_LOCAL" => true) do
Plots.__init__()
@test Plots.plotly_local_file_path[] isa String
@test isfile(Plots.plotly_local_file_path[])
@test Plots.use_local_dependencies[] = true
@test_nowarn Plots._init_ijulia_plotting()
end
Plots.plotly_local_file_path[] = nothing
Plots.use_local_dependencies[] = temp
end # testset
include("test_defaults.jl")
include("test_axes.jl")
include("test_axis_letter.jl")
include("test_components.jl")
include("test_shorthands.jl")
include("integration_dates.jl")
include("test_recipes.jl")
include("test_hdf5plots.jl")
include("test_pgfplotsx.jl")
@@ -44,7 +17,7 @@ reference_dir(args...) = joinpath(homedir(), ".julia", "dev", "PlotReferenceImag
function reference_file(backend, i, version)
refdir = reference_dir("Plots", string(backend))
fn = "ref$i.png"
versions = sort(VersionNumber.(readdir(refdir)), rev=true)
versions = sort(VersionNumber.(readdir(refdir)), rev = true)
reffn = joinpath(refdir, string(version), fn)
for v in versions
@@ -70,31 +43,30 @@ 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
img_tol = is_ci() ? 1e-2 : Sys.islinux() ? 1e-3 : 0.1
## 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
#=
@testset "GR" begin
image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
end
# 10 Histogram2D
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
=#
##
@testset "Backends" begin
@@ -108,7 +80,7 @@ const IMG_TOL = VERSION < v"1.4" && Sys.iswindows() ? 1e-1 : is_ci() ? 1e-2 : 1e
@static if haskey(ENV, "APPVEYOR")
@info "Skipping GR image comparison tests on AppVeyor"
else
image_comparison_facts(:gr, tol=IMG_TOL, skip=Plots._backend_skips[:gr])
image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
end
end
@@ -134,21 +106,12 @@ const IMG_TOL = VERSION < v"1.4" && Sys.iswindows() ? 1e-1 : is_ci() ? 1e-2 : 1e
@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)])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
hline!(p, [3.1])
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
end
@testset "PlotlyJS" begin
@test plotlyjs() == Plots.PlotlyJSBackend()
@test backend() == Plots.PlotlyJSBackend()
p = plot(rand(10))
@test isa(p, Plots.Plot) == true
@test_broken isa(display(p), Nothing) == true
end
end
@testset "Axes" begin
@@ -157,42 +120,27 @@ end
@test typeof(axis) == Plots.Axis
@test Plots.discrete_value!(axis, "HI") == (0.5, 1)
@test Plots.discrete_value!(axis, :yo) == (1.5, 2)
@test Plots.ignorenan_extrema(axis) == (0.5, 1.5)
@test Plots.ignorenan_extrema(axis) == (0.5,1.5)
@test axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1)
Plots.discrete_value!(axis, ["x$i" for i = 1:5])
Plots.discrete_value!(axis, ["x$i" for i = 0:2])
Plots.discrete_value!(axis, ["x$i" for i=1:5])
Plots.discrete_value!(axis, ["x$i" for i=0:2])
@test Plots.ignorenan_extrema(axis) == (0.5, 7.5)
end
@testset "NoFail" begin
#ensure backend with tested display
@test unicodeplots() == Plots.UnicodePlotsBackend()
@test backend() == Plots.UnicodePlotsBackend()
@testset "Plot" begin
plots = [histogram([1, 0, 0, 0, 0, 0]),
plot([missing]),
plot([missing, missing]),
plot(fill(missing, 10)),
plot([missing; 1:4]),
plot([fill(missing, 10); 1:4]),
plot([1 1; 1 missing]),
plot(["a" "b"; missing "d"], [1 2; 3 4])]
for plt in plots
display(plt)
end
@test_nowarn plot(x -> x^2, 0, 2)
end
@testset "Bar" begin
p = bar([3,2,1], [1,2,3]);
@test isa(p, Plots.Plot)
@test isa(display(p), Nothing) == true
plots = [histogram([1, 0, 0, 0, 0, 0]),
plot([missing]),
plot([missing; 1:4]),
plot([fill(missing,10); 1:4]),
plot([1 1; 1 missing]),
plot(["a" "b"; missing "d"], [1 2; 3 4])]
for plt in plots
display(plt)
end
@test_nowarn plot(x->x^2,0,2)
end
@testset "EmptyAnim" begin
anim = @animate for i in []
end
@@ -200,10 +148,16 @@ end
@test_throws ArgumentError gif(anim)
end
@testset "NaN-separated Segments" begin
segments(args...) = collect(iter_segments(args...))
@testset "Segments" begin
function segments(args...)
segs = UnitRange{Int}[]
for seg in iter_segments(args...)
push!(segs,seg)
end
segs
end
nan10 = fill(NaN, 10)
nan10 = fill(NaN,10)
@test segments(11:20) == [1:10]
@test segments([NaN]) == []
@test segments(nan10) == []
@@ -215,17 +169,12 @@ end
end
@testset "Utils" begin
zipped = ([(1, 2)], [("a", "b")], [(1, "a"),(2, "b")],
[(1, 2),(3, 4)], [(1, 2, 3),(3, 4, 5)], [(1, 2, 3, 4),(3, 4, 5, 6)],
[(1, 2.0),(missing, missing)], [(1, missing),(missing, "a")],
[(missing, missing)], [(missing, missing, missing),("a", "b", "c")])
zipped = ([(1,2)], [("a","b")], [(1,"a"),(2,"b")],
[(1,2),(3,4)], [(1,2,3),(3,4,5)], [(1,2,3,4),(3,4,5,6)],
[(1,2.0),(missing,missing)], [(1,missing),(missing,"a")],
[(missing,missing)], [(missing,missing,missing),("a","b","c")])
for z in zipped
@test isequal(collect(zip(Plots.unzip(z)...)), z)
@test isequal(collect(zip(Plots.unzip(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
-65
View File
@@ -1,65 +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
@testset "Ticks getter functions" begin
ticks1 = ([1,2,3], ("a","b","c"))
ticks2 = ([4,5], ("e","f"))
p1 = plot(1:5, 1:5, 1:5, xticks=ticks1, yticks=ticks1, zticks=ticks1)
p2 = plot(1:5, 1:5, 1:5, xticks=ticks2, yticks=ticks2, zticks=ticks2)
p = plot(p1, p2)
@test xticks(p) == yticks(p) == zticks(p) == [ticks1, ticks2]
@test xticks(p[1]) == yticks(p[1]) == zticks(p[1]) == ticks1
end
@testset "Axis limits" begin
pl = plot(1:5, xlims=:symmetric, widen = false)
@test Plots.xlims(pl) == (-5, 5)
pl = plot(1:3)
@test Plots.xlims(pl) == Plots.widen(1,3)
pl = plot([1.05,2.0,2.95], ylims=:round)
@test Plots.ylims(pl) == (1, 3)
pl = plot(1:3, xlims=(1,5))
@test Plots.xlims(pl) == (1, 5)
pl = plot(1:3, xlims=(1,5), widen=true)
@test Plots.xlims(pl) == Plots.widen(1, 5)
end
@testset "3D Axis" begin
ql = quiver([1, 2], [2, 1], [3, 4], quiver = ([1, -1], [0, 0], [1, -0.5]), arrow=true)
@test ql[1][:projection] == "3d"
end
@testset "twinx" begin
pl = plot(1:10, margin = 2Plots.cm)
twpl = twinx(pl)
pl! = plot!(twinx(), -(1:10))
@test twpl[:right_margin] == 2Plots.cm
@test twpl[:left_margin] == 2Plots.cm
@test twpl[:top_margin] == 2Plots.cm
@test twpl[:bottom_margin] == 2Plots.cm
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
-127
View File
@@ -1,127 +0,0 @@
using Plots, Test
@testset "Shapes" begin
@testset "Type" begin
square = Shape([(0,0.0),(1,0.0),(1,1.0),(0,1.0)])
@test isa(square, Shape{Int64, Float64})
@test coords(square) isa Tuple{Vector{S}, Vector{T}} where {T,S}
end
@testset "Copy" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
square2 = Shape(square)
@test square2.x == square.x
@test square2.y == square.y
end
@testset "Center" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
@test Plots.center(square) == (0.5,0.5)
end
@testset "Translate" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
squareUp = Shape([(0,1),(1,1),(1,2),(0,2)])
squareUpRight = Shape([(1,1),(2,1),(2,2),(1,2)])
@test Plots.translate(square,0,1).x == squareUp.x
@test Plots.translate(square,0,1).y == squareUp.y
@test Plots.center(translate!(square,1)) == (1.5,1.5)
end
@testset "Rotate" begin
# 2 radians rotation matrix
R2 = [cos(2) sin(2); -sin(2) cos(2)]
coords = [0 0; 1 0; 1 1; 0 1]'
coordsRotated2 = R2*(coords.-0.5).+0.5
square = Shape([(0,0),(1,0),(1,1),(0,1)])
# make a new, rotated square
square2 = Plots.rotate(square, -2)
@test square2.x coordsRotated2[1,:]
@test square2.y coordsRotated2[2,:]
# unrotate the new square in place
rotate!(square2, 2)
@test square2.x coords[1,:]
@test square2.y coords[2,:]
end
@testset "Plot" begin
ang = range(0, 2π, length = 60)
ellipse(x, y, w, h) = Shape(w*sin.(ang).+x, h*cos.(ang).+y)
myshapes = [ellipse(x,rand(),rand(),rand()) for x = 1:4]
@test coords(myshapes) isa Tuple{Vector{Vector{S}}, Vector{Vector{T}}} where {T,S}
local p
@test_nowarn p = plot(myshapes)
@test p[1][1][:seriestype] == :shape
end
end
@testset "Brush" begin
@testset "Colors" begin
baseline = brush(1, RGB(0,0,0))
@test brush(:black) == baseline
@test brush("black") == baseline
end
@testset "Weight" begin
@test brush(10).size == 10
@test brush(0.1).size == 1
end
@testset "Alpha" begin
@test brush(0.4).alpha == 0.4
@test brush(20).alpha == nothing
end
@testset "Bad Argument" begin
# using test_logs because test_warn seems to not work anymore
@test_logs (:warn,"Unused brush arg: nothing (Nothing)") begin
brush(nothing)
end
end
end
@testset "Fonts" begin
@testset "Scaling" begin
sizesToCheck = [:titlefontsize, :legendfontsize, :legendtitlefontsize,
:xtickfontsize, :ytickfontsize, :ztickfontsize,
:xguidefontsize, :yguidefontsize, :zguidefontsize,]
# get inital font sizes
initialSizes = [Plots.default(s) for s in sizesToCheck ]
#scale up font sizes
scalefontsizes(2)
# get inital font sizes
doubledSizes = [Plots.default(s) for s in sizesToCheck ]
@test doubledSizes == initialSizes*2
# reset font sizes
resetfontsizes()
finalSizes = [Plots.default(s) for s in sizesToCheck ]
@test finalSizes == initialSizes
end
end
@testset "Series Annotations" begin
square = Shape([(0,0),(1,0),(1,1),(0,1)])
@test_logs (:warn,"Unused SeriesAnnotations arg: triangle (Symbol)") begin
p = plot([1,2,3],
series_annotations=(["a"],
2, # pass a scale factor
(1,4), # pass two scale factors (overwrites first one)
square, # pass a shape
font(:courier), # pass an annotation font
:triangle # pass an incorrect argument
))
sa = p.series_list[1].plotattributes[:series_annotations]
@test sa.strs == ["a"]
@test sa.font.family == "courier"
@test sa.baseshape == square
@test sa.scalefactor == (1,4)
end
end
-13
View File
@@ -1,13 +0,0 @@
using Plots, Test
const PLOTS_DEFAULTS = Dict(:theme => :wong2, :fontfamily => :palantino)
Plots.__init__()
@testset "Loading theme" begin
pl = plot(1:5)
@test pl[1][1][:seriescolor] == RGBA(colorant"black")
@test guidefont(pl[1][:xaxis]).family == "palantino"
end
empty!(PLOTS_DEFAULTS)
Plots.__init__()
+21 -114
View File
@@ -21,12 +21,12 @@ end
@test !haskey(axis.contents[1].options.dict, "fill")
@testset "Legends" begin
legends_plot = plot(rand(5, 2), lab = ["1" ""])
scatter!(legends_plot, rand(5))
legends_plot = plot( rand(5,2), lab = ["1" ""] )
scatter!(legends_plot, rand(5) )
Plots._update_plot_object(legends_plot)
axis_contents = Plots.pgfx_axes(legends_plot.o)[1].contents
leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents)
series = filter(x -> x isa PGFPlotsX.Plot, axis_contents)
leg_entries = filter( x -> x isa PGFPlotsX.LegendEntry, axis_contents )
series = filter( x -> x isa PGFPlotsX.Plot, axis_contents )
@test length(leg_entries) == 2
@test !haskey(series[1].options.dict, "forget plot")
@test haskey(series[2].options.dict, "forget plot")
@@ -71,7 +71,7 @@ end
pl = scatter!(
y,
zcolor = abs.(y .- 0.5),
m = (:hot, 0.8, Plots.stroke(1, :green)),
m = (:heat, 0.8, Plots.stroke(1, :green)),
ms = 10 * abs.(y .- 0.5) .+ 4,
lab = ["grad", "", "ient"],
)
@@ -91,8 +91,8 @@ end
scatter!(pic, rand(100), markersize = 6, c = :orange)
Plots._update_plot_object(pic)
axis_contents = Plots.pgfx_axes(pic.o)[1].contents
leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents)
series = filter(x -> x isa PGFPlotsX.Plot, axis_contents)
leg_entries = filter( x -> x isa PGFPlotsX.LegendEntry, axis_contents )
series = filter( x -> x isa PGFPlotsX.Plot, axis_contents )
@test length(leg_entries) == 2
@test length(series) == 4
@test haskey(series[1].options.dict, "forget plot")
@@ -106,7 +106,7 @@ end
end), Plots._shape_keys)
markers = reshape(markers, 1, length(markers))
n = length(markers)
x = (range(0, stop = 10, length = n + 2))[2:(end-1)]
x = (range(0, stop = 10, length = n + 2))[2:(end - 1)]
y = repeat(reshape(reverse(x), 1, :), n, 1)
scatter(
x,
@@ -122,7 +122,7 @@ end
plot(
Plots.fakedata(100, 10),
layout = 4,
palette = [:grays :blues :hot :rainbow],
palette = [:grays :blues :heat :lightrainbow],
bg_inside = [:orange :pink :darkblue :black],
)
end # testset
@@ -211,7 +211,7 @@ end
marker_z = ((x, y) -> begin
x + y
end),
color = :bwr,
color = :bluesreds,
legend = false,
)
plot(p1, p2)
@@ -231,7 +231,7 @@ end
# TODO: support :semi
end # testset
@testset "Quiver" begin
x = (-2pi):0.2:(2*pi)
x = (-2pi):0.2:(2 * pi)
y = sin.(x)
u = ones(length(x))
@@ -255,7 +255,7 @@ end
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 1
mktempdir() do path
file_path = joinpath(path, "annotations.tex")
file_path =joinpath(path,"annotations.tex")
@test_nowarn savefig(pgfx_plot, file_path)
open(file_path) do io
lines = readlines(io)
@@ -271,7 +271,7 @@ end
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 3
mktempdir() do path
file_path = joinpath(path, "annotations.tex")
file_path =joinpath(path,"annotations.tex")
@test_nowarn savefig(pgfx_plot, file_path)
open(file_path) do io
lines = readlines(io)
@@ -296,17 +296,12 @@ end
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 9
mktempdir() do path
file_path = joinpath(path, "annotations.tex")
file_path =joinpath(path,"annotations.tex")
@test_nowarn savefig(annotation_plot, file_path)
open(file_path) do io
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 9
end
# test .tikz extension
file_path = joinpath(path, "annotations.tikz")
@test_nowarn savefig(annotation_plot, file_path)
@test_nowarn open(file_path) do io
end
end
end # testset
@testset "Ribbon" begin
@@ -319,103 +314,15 @@ end
Plots._update_plot_object(ribbon_plot)
axis = Plots.pgfx_axes(ribbon_plot.o)[1]
plots = filter(x -> x isa PGFPlotsX.Plot, axis.contents)
@test length(plots) == 3
@test haskey(plots[1].options.dict, "fill")
@test haskey(plots[2].options.dict, "fill")
@test length(plots) == 4
@test !haskey(plots[1].options.dict, "fill")
@test !haskey(plots[2].options.dict, "fill")
@test !haskey(plots[3].options.dict, "fill")
@test haskey(plots[4].options.dict, "fill")
@test ribbon_plot.o !== nothing
@test ribbon_plot.o.the_plot !== nothing
# mktempdir() do path
# @test_nowarn savefig(ribbon_plot, path*"ribbon.svg")
# end
end # testset
@testset "Markers and Paths" begin
pl = plot(
5 .- ones(9),
markershape = [:utriangle, :rect],
markersize = 8,
color = [:red, :black],
)
Plots._update_plot_object(pl)
axis = Plots.pgfx_axes(pl.o)[1]
plots = filter(x -> x isa PGFPlotsX.Plot, axis.contents)
@test length(plots) == 9
end # testset
@testset "Groups and Subplots" begin
group = rand(map((i->begin
"group $(i)"
end), 1:4), 100)
pl = plot(rand(100), layout = @layout([a b; c]), group = group, linetype = [:bar :scatter :steppre], linecolor = :match)
Plots._update_plot_object(pl)
axis = Plots.pgfx_axes(pl.o)[1]
legend_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis.contents)
@test length(legend_entries) == 2
end
end # testset
@testset "Extra kwargs" begin
pl = plot(1:5, test = "me")
@test pl[1][1].plotattributes[:extra_kwargs][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :subplot)
@test pl[1].attr[:extra_kwargs][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :plot)
@test pl.attr[:extra_plot_kwargs][:test] == "me"
pl = plot(
1:5,
extra_kwargs = Dict(
:plot => Dict(:test => "me"),
:series => Dict(:and => "me too"),
),
)
@test pl.attr[:extra_plot_kwargs][:test] == "me"
@test pl[1][1].plotattributes[:extra_kwargs][:and] == "me too"
pl = plot(
plot(1:5, title = "Line"),
scatter(
1:5,
title = "Scatter",
extra_kwargs = Dict(:subplot => Dict("axis line shift" => "10pt")),
),
)
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test !haskey(axes[1].options.dict, "axis line shift")
@test haskey(axes[2].options.dict, "axis line shift")
pl = plot(
x -> x,
-1:1;
add = raw"\node at (0,0.5) {\huge hi};",
extra_kwargs = :subplot,
)
@test pl[1][:extra_kwargs] == Dict(:add => raw"\node at (0,0.5) {\huge hi};")
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test filter(x -> x isa String, axes[1].contents)[1] ==
raw"\node at (0,0.5) {\huge hi};"
plot!(pl)
@test pl[1][:extra_kwargs] == Dict(:add => raw"\node at (0,0.5) {\huge hi};")
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test filter(x -> x isa String, axes[1].contents)[1] ==
raw"\node at (0,0.5) {\huge hi};"
end # testset
@testset "Titlefonts" begin
pl = plot(1:5, title = "Test me", titlefont = (2, :left))
@test pl[1][:title] == "Test me"
@test pl[1][:titlefontsize] == 2
@test pl[1][:titlefonthalign] == :left
Plots._update_plot_object(pl)
ax_opt = Plots.pgfx_axes(pl.o)[1].options
@test ax_opt["title"] == "Test me"
@test(haskey(ax_opt.dict, "title style")) isa Test.Pass
pl = plot(1:5, plot_title = "Test me", plot_titlefont = (2, :left))
@test pl[:plot_title] == "Test me"
@test pl[:plot_titlefontsize] == 2
@test pl[:plot_titlefonthalign] == :left
pl = heatmap(
rand(3, 3),
colorbar_title = "Test me",
colorbar_titlefont = (12, :right),
)
@test pl[1][:colorbar_title] == "Test me"
@test pl[1][:colorbar_titlefontsize] == 12
@test pl[1][:colorbar_titlefonthalign] == :right
end # testset
-49
View File
@@ -1,49 +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
@testset "framestyle axes" begin
pl = plot(-1:1, -1:1, -1:1)
sp = pl.subplots[1]
defaultret = Plots.axis_drawing_info_3d(sp, :x)
for letter in [:x, :y, :z]
for fr in [:box :semi :origin :zerolines :grid :none]
prevha = UInt64(0)
push!(sp.attr, :framestyle => fr)
ret = Plots.axis_drawing_info_3d(sp, letter)
ha = hash(string(ret))
@test ha != prevha
prevha = ha
end
end
end
-48
View File
@@ -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