Compare commits
4 Commits
master
...
compathelp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3894f95072 | ||
|
|
1c9336b453 | ||
|
|
58a0ef11e0 | ||
|
|
b6f542b573 |
@ -1,12 +0,0 @@
|
||||
always_for_in = true
|
||||
import_to_using = false
|
||||
align_pair_arrow = true
|
||||
align_assignment = true
|
||||
align_conditional = true
|
||||
always_use_return = false
|
||||
conditional_to_if = false
|
||||
whitespace_in_kwargs = true
|
||||
remove_extra_newlines = true
|
||||
whitespace_ops_in_indices = true
|
||||
short_to_long_function_def = false
|
||||
annotate_untyped_fields_with_any = false
|
||||
5
.github/ISSUE_TEMPLATE/bug.md
vendored
5
.github/ISSUE_TEMPLATE/bug.md
vendored
@ -20,14 +20,13 @@ Backend | yes | no | untested
|
||||
-------------|-----|-----|---------
|
||||
gr (default) | | |
|
||||
pyplot | | |
|
||||
plotly | | |
|
||||
plotlyjs | | |
|
||||
pgfplotsx | | |
|
||||
unicodeplots | | |
|
||||
inspectdr | | |
|
||||
gaston | | |
|
||||
|
||||
### Versions
|
||||
|
||||
Plots.jl version:
|
||||
Backend version (`]st -m <backend(s)>`):
|
||||
Backend version (`]st -m`):
|
||||
Output of `versioninfo()`:
|
||||
|
||||
41
.github/workflows/SnoopCompile.yml
vendored
41
.github/workflows/SnoopCompile.yml
vendored
@ -1,11 +1,9 @@
|
||||
# NOTE: this file should be named 'SnoopCompile.yml', cf github.com/aminya/CompileBot.jl/blob/master/src/CompileBot.jl#L57
|
||||
|
||||
name: SnoopCompile
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master # NOTE: to run the bot only on pushes to master
|
||||
# - 'master' # NOTE: to run the bot only on pushes to master
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@ -16,19 +14,14 @@ jobs:
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
env:
|
||||
GKS_ENCODING: "utf8"
|
||||
GKSwstype: "nul"
|
||||
GKSwstype: "100"
|
||||
PLOTS_TEST: "true"
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.version == '~1.8.0-0' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: # NOTE: the versions below should match those in your botconfig
|
||||
- '1.6' # ⎤
|
||||
- '1.7' # |
|
||||
- '~1.8.0-0' # |
|
||||
# - 'nightly' # ⎦ <<< keep these versions in sync with deps/SnoopCompile/snoop_bot_config.jl
|
||||
# ^^^^^^^^^ for 'nightly', see github.com/JuliaPlots/Plots.jl/issues/4079
|
||||
- '1'
|
||||
os: # NOTE: should match the os setting of your botconfig
|
||||
- ubuntu-latest
|
||||
arch:
|
||||
@ -40,20 +33,11 @@ jobs:
|
||||
with:
|
||||
version: ${{ matrix.version }}
|
||||
|
||||
- name: Set Swap Space
|
||||
uses: pierotofy/set-swap-space@master
|
||||
with:
|
||||
swap-size-gb: 10 # required (not enough memory on github actions virtual machine)
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cat /proc/cpuinfo
|
||||
cat /proc/meminfo
|
||||
cat /proc/swaps
|
||||
free
|
||||
df -h
|
||||
julia --project -e 'using Pkg; Pkg.instantiate()'
|
||||
julia -e 'using Pkg; Pkg.add(PackageSpec(name="CompileBot", version="1")); Pkg.develop(PackageSpec(; path=pwd())); using CompileBot; CompileBot.addtestdep()'
|
||||
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
|
||||
@ -85,21 +69,18 @@ jobs:
|
||||
uses: actions/download-artifact@v2
|
||||
|
||||
- name: CompileBot postprocess
|
||||
run: |
|
||||
if ! grep -m1 -q 'format: off' artifact/src/precompile_includer.jl; then sed -i '1 i\#! format: off' artifact/src/precompile_includer.jl; fi
|
||||
julia -e 'using Pkg; Pkg.add(PackageSpec(name="CompileBot", version="1")); using CompileBot; CompileBot.postprocess()'
|
||||
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 [skip ci]
|
||||
title: "[AUTO] Update precompiles [skip ci]"
|
||||
labels: |
|
||||
SnoopCompile
|
||||
no changelog
|
||||
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
|
||||
|
||||
1
.github/workflows/TagBot.yml
vendored
1
.github/workflows/TagBot.yml
vendored
@ -12,4 +12,3 @@ jobs:
|
||||
- uses: JuliaRegistries/TagBot@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
ssh: ${{ secrets.TAGBOT_KEY }}
|
||||
|
||||
9
.github/workflows/benchmark.yml
vendored
9
.github/workflows/benchmark.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: benchmarks
|
||||
name: Run benchmarks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@ -6,14 +6,17 @@ on:
|
||||
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.7'
|
||||
version: 1
|
||||
|
||||
# Setup
|
||||
## Setup
|
||||
- name: Ubuntu TESTCMD
|
||||
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
|
||||
- name: Install Plots dependencies
|
||||
|
||||
41
.github/workflows/ci.yml
vendored
41
.github/workflows/ci.yml
vendored
@ -2,8 +2,6 @@ name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
defaults:
|
||||
@ -15,7 +13,7 @@ jobs:
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
env:
|
||||
GKS_ENCODING: "utf8"
|
||||
GKSwstype: "nul"
|
||||
GKSwstype: "100"
|
||||
|
||||
name: Julia ${{ matrix.version }} - ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
@ -24,8 +22,8 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version:
|
||||
- '1.6' # LTS
|
||||
- '1.7' # latest stable
|
||||
- '1'
|
||||
- 'nightly'
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
@ -33,11 +31,9 @@ jobs:
|
||||
arch:
|
||||
- x64
|
||||
# - x86
|
||||
include:
|
||||
- version: 'nightly'
|
||||
os: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
# Setup environment
|
||||
- uses: actions/checkout@v2
|
||||
- uses: julia-actions/setup-julia@latest
|
||||
@ -55,16 +51,19 @@ jobs:
|
||||
${{ 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
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install gnuplot poppler-utils texlive-{latex-base,latex-extra,luatex}
|
||||
sudo fc-cache -vr
|
||||
run: echo "TESTCMD=xvfb-run --auto-servernum julia" >> $GITHUB_ENV
|
||||
|
||||
# Julia Dependencies
|
||||
- name: Install Julia dependencies
|
||||
@ -72,18 +71,12 @@ jobs:
|
||||
|
||||
# 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")'
|
||||
run: $TESTCMD --project -e 'using Pkg; Pkg.test(coverage=true);'
|
||||
|
||||
# Codecov
|
||||
- uses: julia-actions/julia-processcoverage@v1
|
||||
if: startsWith(matrix.os,'ubuntu')
|
||||
- uses: codecov/codecov-action@v2
|
||||
if: startsWith(matrix.os,'ubuntu')
|
||||
with:
|
||||
file: lcov.info
|
||||
- name: Codecov
|
||||
uses: julia-actions/julia-uploadcodecov@latest
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
Skip:
|
||||
if: "contains(github.event.head_commit.message, '[skip ci]')"
|
||||
|
||||
34
.github/workflows/docs.yml
vendored
34
.github/workflows/docs.yml
vendored
@ -1,34 +0,0 @@
|
||||
name: docs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags: '*'
|
||||
|
||||
jobs:
|
||||
Build_docs:
|
||||
runs-on: ubuntu-latest
|
||||
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: Build documentation
|
||||
env:
|
||||
PYTHON: ""
|
||||
DOCUMENTER_KEY: ${{secrets.DOCUMENTER_KEY}}
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
run: bash docs/ci_build.sh
|
||||
54
.github/workflows/format_check.yml
vendored
54
.github/workflows/format_check.yml
vendored
@ -1,54 +0,0 @@
|
||||
name: format
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
code-style:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: julia-actions/setup-julia@v1
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
using Pkg
|
||||
Pkg.add([
|
||||
PackageSpec("JuliaFormatter"),
|
||||
PackageSpec(url = "https://github.com/tkf/JuliaProjectFormatter.jl.git"),
|
||||
])
|
||||
shell: julia --color=yes {0}
|
||||
|
||||
- name: Format Julia files
|
||||
run: |
|
||||
using JuliaFormatter
|
||||
format(["src", "test"])
|
||||
shell: julia --color=yes --compile=min -O0 {0}
|
||||
- name: suggester / JuliaFormatter
|
||||
uses: reviewdog/action-suggester@v1
|
||||
with:
|
||||
tool_name: JuliaFormatter
|
||||
fail_on_error: true
|
||||
|
||||
# reviewdog/action-suggester not using `cleanup` flag?
|
||||
- name: Cleanup
|
||||
if: success() || failure()
|
||||
run: |
|
||||
git checkout -- .
|
||||
git clean --force
|
||||
shell: bash
|
||||
|
||||
- name: Format Julia project files
|
||||
if: success() || failure()
|
||||
run: |
|
||||
using JuliaProjectFormatter
|
||||
format_projects()
|
||||
shell: julia --color=yes --compile=min -O0 {0}
|
||||
- name: suggester / JuliaProjectFormatter
|
||||
if: success() || failure()
|
||||
uses: reviewdog/action-suggester@v1
|
||||
with:
|
||||
tool_name: JuliaProjectFormatter
|
||||
fail_on_error: true
|
||||
35
.github/workflows/format_pr.yml
vendored
35
.github/workflows/format_pr.yml
vendored
@ -1,35 +0,0 @@
|
||||
name: format
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 1 * *'
|
||||
|
||||
jobs:
|
||||
pr:
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install JuliaFormatter and format
|
||||
run: |
|
||||
julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter"))'
|
||||
julia -e 'using JuliaFormatter; [format(["src", "test"]) for _ in 1:2]'
|
||||
git diff --exit-code
|
||||
|
||||
- name: Create Pull Request
|
||||
if: ${{ failure() }}
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: "Format .jl files [skip ci]"
|
||||
title: 'Automatic JuliaFormatter.jl run'
|
||||
branch: auto-juliaformatter-pr
|
||||
delete-branch: true
|
||||
labels: formatting, automated pr, no changelog
|
||||
|
||||
- name: Check outputs
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
||||
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,4 +12,3 @@ dev/
|
||||
test/tmpplotsave.hdf5
|
||||
/.benchmarkci
|
||||
/benchmark/*.json
|
||||
.vscode/
|
||||
|
||||
722
.zenodo.json
722
.zenodo.json
@ -1,722 +0,0 @@
|
||||
{
|
||||
"title": "Plots.jl",
|
||||
"license": "MIT",
|
||||
"creators": [
|
||||
{
|
||||
"affiliation": "Headlands Technologies",
|
||||
"name": "Tom Breloff"
|
||||
}
|
||||
],
|
||||
"contributors":[
|
||||
{
|
||||
"affiliation": "TU Wien",
|
||||
"name": "Daniel Schwabeneder",
|
||||
"orcid": "0000-0002-0412-0777",
|
||||
"type": "ProjectLeader"
|
||||
},
|
||||
{
|
||||
"affiliation": "GLOBE Institute, University of Copenhagen",
|
||||
"name": "Michael Krabbe Borregaard",
|
||||
"orcid": "0000-0002-8146-8435",
|
||||
"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",
|
||||
"affiliation": "Columbia University",
|
||||
"orcid": "0000-0001-6055-1291",
|
||||
"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": "Mosè 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"
|
||||
},
|
||||
{
|
||||
"name": "Jan Thorben Schneider",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"orcid": "0000-0003-4102-2460",
|
||||
"affiliation": "Alogus Research Corporation",
|
||||
"name": "Lee Phillips",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Tom Gillam",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Steve Leung",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Xu Zhi-Yuan",
|
||||
"type": "Other"
|
||||
}
|
||||
],
|
||||
"upload_type": "software"
|
||||
}
|
||||
2
NEWS.md
2
NEWS.md
@ -3,7 +3,7 @@
|
||||
|
||||
#### notes on release changes, ongoing development, and future planned work
|
||||
|
||||
## NOTE: this file is deprecated, see the [TagBot](https://github.com/marketplace/actions/julia-tagbot) auto-generated changelogs instead
|
||||
## (current master)
|
||||
|
||||
## 0.28.3
|
||||
- support generalized array interface
|
||||
|
||||
42
Project.toml
42
Project.toml
@ -1,13 +1,12 @@
|
||||
name = "Plots"
|
||||
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
author = ["Tom Breloff (@tbreloff)"]
|
||||
version = "1.29.0"
|
||||
version = "1.11.2"
|
||||
|
||||
[deps]
|
||||
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||
Contour = "d38c429a-6771-53c6-b99e-75d170b6e991"
|
||||
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||
Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
|
||||
FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
|
||||
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
|
||||
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
|
||||
@ -17,7 +16,6 @@ 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"
|
||||
@ -33,53 +31,39 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
||||
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
||||
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
|
||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1"
|
||||
Unzip = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d"
|
||||
|
||||
[compat]
|
||||
Contour = "0.5"
|
||||
FFMPEG = "0.2 - 0.4"
|
||||
FixedPointNumbers = "0.6 - 0.8"
|
||||
GR = "0.64"
|
||||
GeometryBasics = "0.2, 0.3.1, 0.4"
|
||||
FFMPEG = "0.2, 0.3, 0.4"
|
||||
FixedPointNumbers = "0.6, 0.7, 0.8"
|
||||
GR = "0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.57"
|
||||
GeometryBasics = "0.2, 0.3.1"
|
||||
JSON = "0.21, 1"
|
||||
Latexify = "0.14 - 0.15"
|
||||
Latexify = "0.14, 0.15"
|
||||
Measures = "0.3"
|
||||
NaNMath = "0.3, 1"
|
||||
PGFPlotsX = "1"
|
||||
PlotThemes = "2, 3"
|
||||
NaNMath = "0.3"
|
||||
PlotThemes = "2"
|
||||
PlotUtils = "1"
|
||||
PlotlyBase = "0.7"
|
||||
PlotlyJS = "0.18"
|
||||
PyPlot = "2"
|
||||
RecipesBase = "1.2"
|
||||
RecipesPipeline = "0.5"
|
||||
RecipesBase = "1"
|
||||
RecipesPipeline = "0.3"
|
||||
Reexport = "0.2, 1.0"
|
||||
Requires = "1"
|
||||
Scratch = "1"
|
||||
Showoff = "0.3.1, 1.0"
|
||||
StatsBase = "0.32 - 0.33"
|
||||
UnicodeFun = "0.4"
|
||||
UnicodePlots = "2.10"
|
||||
Unzip = "0.1"
|
||||
julia = "1.6"
|
||||
StatsBase = "0.32, 0.33"
|
||||
julia = "1.5"
|
||||
|
||||
[extras]
|
||||
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
|
||||
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
|
||||
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
|
||||
Gaston = "4b11ee91-296f-5714-9832-002c20994614"
|
||||
Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44"
|
||||
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
|
||||
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
|
||||
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
|
||||
InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d"
|
||||
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
||||
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
|
||||
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
|
||||
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
|
||||
PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a"
|
||||
PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee"
|
||||
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
|
||||
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
|
||||
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||
@ -90,4 +74,4 @@ UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
|
||||
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"
|
||||
|
||||
[targets]
|
||||
test = ["Colors", "Distributions", "FileIO", "Gaston", "Gtk", "ImageMagick", "Images", "InspectDR", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "PlotlyBase", "PyPlot", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"]
|
||||
test = ["Distributions", "FileIO", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "HDF5", "RDatasets", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "VisualRegressionTests"]
|
||||
|
||||
@ -10,17 +10,13 @@
|
||||
[gitter-url]: https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||
|
||||
[docs-img]: https://img.shields.io/badge/docs-stable-blue.svg
|
||||
[docs-url]: https://docs.juliaplots.org/stable/
|
||||
[docs-url]: http://docs.juliaplots.org/latest/
|
||||
|
||||
[![][gh-ci-img]][gh-ci-url]
|
||||
[![][pkgeval-img]][pkgeval-url]
|
||||
[](https://julialang.zulipchat.com/#narrow/stream/236493-plots)
|
||||
[![][docs-img]][docs-url]
|
||||
[](https://codecov.io/gh/JuliaPlots/Plots.jl)
|
||||
[](https://pkgs.genieframework.com?packages=Plots)
|
||||
|
||||
[](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)
|
||||
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
github_checks:
|
||||
annotations: false
|
||||
|
||||
ignore:
|
||||
- "src/backends/inspectdr.jl"
|
||||
- "src/backends/orca.jl"
|
||||
|
||||
487
deps/SnoopCompile/precompile/1.7/precompile_Plots.jl
vendored
487
deps/SnoopCompile/precompile/1.7/precompile_Plots.jl
vendored
@ -1,487 +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{(:parent,), Tuple{GridLayout}},Type{Subplot},GRBackend})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{GridLayout}},Type{Subplot},PlotlyBackend})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{Subplot{GRBackend}}},Type{Subplot},GRBackend})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:parent,), Tuple{Subplot{PlotlyBackend}}},Type{Subplot},PlotlyBackend})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Int64})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Tuple{Int64, Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Vector{Int64}}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(areaplot)),Any,typeof(areaplot),Any,Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:flip,), Tuple{Bool}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:foreground_color_grid, :grid, :gridalpha, :gridstyle, :gridlinewidth), Tuple{RGBA{Float64}, Bool, Float64, Symbol, Int64}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{Symbol}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{typeof(datetimeformatter)}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :flip, :minorgrid, :guide), Tuple{Bool, Bool, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Float64, Float64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Float64, Float64}, Bool}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :guide), Tuple{Bool, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :mirror, :guide), Tuple{Bool, Bool, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid,), Tuple{Bool}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide,), Tuple{String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide_position, :guidefontvalign, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guidefonthalign, :guide_position, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims, :flip, :ticks, :guide), Tuple{Tuple{Int64, Int64}, Bool, StepRange{Int64, Int64}, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Float64, Float64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:minorgrid, :scale, :guide), Tuple{Bool, Symbol, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:minorgrid,), Tuple{Bool}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:rotation,), Tuple{Int64}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{Nothing}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{UnitRange{Int64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:shape,), Tuple{Symbol}},typeof(default)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:titlefont, :legendfontsize, :guidefont, :tickfont, :guide, :framestyle, :yminorgrid), Tuple{Tuple{Int64, String}, Int64, Tuple{Int64, Symbol}, Tuple{Int64, Symbol}, String, Symbol, Bool}},typeof(default)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(font)),NamedTuple{(:family, :pointsize, :halign, :valign, :rotation, :color), Tuple{String, Int64, Symbol, Symbol, Float64, RGBA{Float64}}},typeof(font)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(font)),NamedTuple{(:family, :pointsize, :valign, :halign, :rotation, :color), Tuple{String, Int64, Symbol, Symbol, Float64, RGBA{Float64}}},typeof(font)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRange{Int64, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}},typeof(gr_set_font),Font,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:rotation, :color), Tuple{Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(lens!)),Any,typeof(lens!),Any,Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{GRBackend},Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:annotation,), Tuple{Vector{Tuple{Int64, Float64, Tuple{String, Any, Any, Any}}}}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:layout, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{GRBackend},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{PlotlyBackend},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Function,Float64,Irrational{:π}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Plot{GRBackend},Function,Float64,Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{GRBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},Vector{Float64},Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:xgrid,), Tuple{Tuple{Symbol, Symbol, Int64, Symbol, Float64}}},typeof(plot!),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:annotations, :leg), Tuple{Tuple{Int64, Float64, PlotText}, Bool}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:arrow,), Tuple{Int64}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bar_width, :alpha, :color, :fillto, :label, :seriestype), Tuple{Float64, Float64, Vector{Symbol}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, String, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bins, :weights, :seriestype), Tuple{Symbol, Vector{Int64}, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:color, :line, :marker), Tuple{Matrix{Symbol}, Tuple{Symbol, Int64}, Tuple{Matrix{Symbol}, Int64, Float64, Stroke}}},typeof(plot),Vector{Vector}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:connections, :title, :xlabel, :ylabel, :zlabel, :legend, :margin, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, String, String, String, String, Symbol, AbsoluteLength, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill, :seriestype), Tuple{Bool, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill_z, :alpha, :label, :bar_width, :seriestype), Tuple{StepRange{Int64, Int64}, Vector{Float64}, String, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks, :seriestype), Tuple{Matrix{Symbol}, Matrix{String}, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Int64, String, Int64, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Vector{Float64}},Vector{Vector{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:grid, :title), Tuple{Tuple{Symbol, Symbol, Symbol, Int64, Float64}, String}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:lab, :w, :palette, :fill, :α), Tuple{String, Int64, PlotUtils.ContinuousColorGradient, Int64, Float64}},typeof(plot),StepRange{Int64, Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :legend, :seriestype), Tuple{String, Symbol, Symbol}},typeof(plot),Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend), Tuple{Matrix{String}, String, String, Int64, Symbol}},typeof(plot),Vector{Function},Float64,Float64})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label,), Tuple{Matrix{String}}},typeof(plot),Vector{AbstractVector{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:labels,), Tuple{Matrix{String}}},typeof(plot),PortfolioComposition})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :group, :linetype, :linecolor), Tuple{Matrix{Any}, Vector{String}, Matrix{Symbol}, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :palette, :bg_inside), Tuple{Int64, Matrix{PlotUtils.ContinuousColorGradient}, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :t, :leg, :ticks, :border), Tuple{Matrix{Any}, Matrix{Symbol}, Bool, Nothing, Symbol}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :title, :titlelocation, :left_margin, :bottom_margin, :xrotation), Tuple{Matrix{Any}, Matrix{String}, Symbol, Matrix{AbsoluteLength}, AbsoluteLength, Int64}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xguide, :yguide, :xguidefonthalign, :yguidefontvalign, :xguideposition, :yguideposition, :ymirror, :xmirror, :legend, :seriestype), Tuple{Int64, String, String, Matrix{Symbol}, Matrix{Symbol}, Symbol, Matrix{Symbol}, Matrix{Bool}, Matrix{Bool}, Bool, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xlims), Tuple{Matrix{Any}, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Vector{Tuple{Int64, Real}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :lab, :ms), Tuple{Tuple{Matrix{Symbol}, Int64}, Matrix{String}, Int64}},typeof(plot),Vector{Vector},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :label, :legendtitle), Tuple{Tuple{Int64, Matrix{Symbol}}, Matrix{String}, String}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :leg, :fill), Tuple{Int64, Bool, Tuple{Int64, Symbol}}},typeof(plot),Function,Function,Int64,Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :marker, :bg, :fg, :xlim, :ylim, :leg), Tuple{Tuple{Int64, Symbol, Symbol}, Tuple{Shape{Float64, Float64}, Int64, RGBA{Float64}}, Symbol, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Bool}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line_z, :linewidth, :legend), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Int64, Bool}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:m, :markersize, :lab, :bg, :xlim, :ylim, :seriestype), Tuple{Matrix{Symbol}, Int64, Matrix{String}, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker,), Tuple{Bool}},typeof(plot),Vector{Union{Missing, Int64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker_z, :color, :legend, :seriestype), Tuple{typeof(+), Symbol, Bool, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :markersize, :marker_z, :line_z, :linewidth), Tuple{Matrix{Symbol}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :seriestype, :label), Tuple{Symbol, Symbol, String}},typeof(plot),UnitRange{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :show_empty_bins, :normed, :aspect_ratio, :seriestype), Tuple{Tuple{Int64, Int64}, Bool, Bool, Int64, Symbol}},typeof(plot),Vector{ComplexF64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:proj, :m), Tuple{Symbol, Int64}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:projection, :seriestype), Tuple{Symbol, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},UnitRange{Int64},Matrix{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:quiver, :seriestype), Tuple{Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:reg, :fill), Tuple{Bool, Tuple{Int64, Symbol}}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Int64}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Tuple{LinRange{Float64, Int64}, LinRange{Float64, Int64}}}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{typeof(sqrt)}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriescolor, :fillalpha), Tuple{Matrix{Symbol}, Matrix{Float64}}},typeof(plot),AreaPlot})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color), Tuple{Matrix{Symbol}, Vector{Symbol}, Int64, Vector{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{OHLC}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :l, :seriestype), Tuple{String, Float64, Symbol}},typeof(plot),Vector{String},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :xflip, :yflip, :zflip, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :xmirror, :ymirror, :zmirror, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:xaxis, :background_color, :leg), Tuple{Tuple{String, Tuple{Int64, Int64}, StepRange{Int64, Int64}, Symbol}, RGB{Float64}, Bool}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:zcolor, :m, :leg, :cbar, :w), Tuple{StepRange{Int64, Int64}, Tuple{Int64, Float64, Symbol, Stroke}, Bool, Bool, Int64}},typeof(plot),Vector{Float64},Vector{Float64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(portfoliocomposition)),Any,typeof(portfoliocomposition),Any,Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(scatter!)),Any,typeof(scatter!),Any})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip, :disp), Tuple{Vector{Int64}, Bool}},typeof(test_examples),Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip,), Tuple{Vector{Int64}}},typeof(test_examples),Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(yaxis!)),Any,typeof(yaxis!),Any,Any})
|
||||
Base.precompile(Tuple{Type{GridLayout},Int64,Vararg{Int64}})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},AbstractVector{<:GeometryBasics.Point}})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},AbstractVector{OHLC}})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},PortfolioComposition})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barbins}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barhist}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bar}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bins2d}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:histogram2d}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hline}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hspan}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:lens}},AbstractPlot})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:pie}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:quiver}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:spy}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:steppre}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:sticks}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vline}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vspan}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:xerror}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Vector{ComplexF64}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{GRBackend},DefaultsDict})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{PlotlyBackend},DefaultsDict})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{GRBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{PlotlyBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_attributes!),Plot{GRBackend},DefaultsDict})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_axis_args!),Plot{GRBackend},Dict{Symbol, Any},Symbol})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_axis_args!),Plot{PlotlyBackend},Dict{Symbol, Any},Symbol})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{GRBackend},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.unzip),Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{typeof(_bin_centers),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Float64},String})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Int64},String})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Nothing},String})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{PlotUtils.ContinuousColorGradient},String})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}},String})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Symbol},String})
|
||||
Base.precompile(Tuple{typeof(_cycle),Base.OneTo{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),StepRange{Int64, Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),UnitRange{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},StepRange{Int64, Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Int64},StepRange{Int64, Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Int64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
|
||||
Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},Bool})
|
||||
Base.precompile(Tuple{typeof(_heatmap_edges),Vector{Float64},Bool,Bool})
|
||||
Base.precompile(Tuple{typeof(_plot!),Plot,Any,Any})
|
||||
Base.precompile(Tuple{typeof(_preprocess_barlike),DefaultsDict,Base.OneTo{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(_preprocess_binlike),DefaultsDict,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(_replace_markershape),Vector{Symbol}})
|
||||
Base.precompile(Tuple{typeof(_update_min_padding!),GridLayout})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{GRBackend},Subplot{GRBackend},Dict{Symbol, Any},Int64,Bool})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{PlotlyBackend},Subplot{PlotlyBackend},Dict{Symbol, Any},Int64,Bool})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{GRBackend},Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{PlotlyBackend},Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(annotate!),AbstractVector{<:Tuple}})
|
||||
Base.precompile(Tuple{typeof(axis_limits),Subplot{GRBackend},Symbol,Bool,Bool})
|
||||
Base.precompile(Tuple{typeof(axis_limits),Subplot{PlotlyBackend},Symbol,Bool,Bool})
|
||||
Base.precompile(Tuple{typeof(backend),PlotlyBackend})
|
||||
Base.precompile(Tuple{typeof(bbox),AbsoluteLength,AbsoluteLength,AbsoluteLength,AbsoluteLength})
|
||||
Base.precompile(Tuple{typeof(bbox),Float64,Float64,Float64,Float64})
|
||||
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64,Vector{Plot}})
|
||||
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64},Tuple{Int64, Float64}})
|
||||
Base.precompile(Tuple{typeof(discrete_value!),Axis,Vector{Union{Missing, Float64}}})
|
||||
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64},Vararg{Vector{Float64}}})
|
||||
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(error_zipit),Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}})
|
||||
Base.precompile(Tuple{typeof(fakedata),Int64,Int64})
|
||||
Base.precompile(Tuple{typeof(fakedata),TaskLocalRNG,Int64,Vararg{Int64}})
|
||||
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(get_series_color),SubArray{Symbol, 1, Vector{Symbol}, Tuple{UnitRange{Int64}}, true},Subplot{GRBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{PlotlyBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_ticks),StepRange{Int64, Int64},Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Float64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_ticks),UnitRange{Int64},Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_xy),Vector{OHLC}})
|
||||
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_display),Subplot{GRBackend},AbsoluteLength,AbsoluteLength,Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_heatmap),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Float64,Float64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Shape{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Int64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64},Int64,Int64})
|
||||
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_markers),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_markers),Series,UnitRange{Int64},Vector{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},UnitRange{Int64},Tuple{Vector{Float64}, Vector{Float64}},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Vector{Float64},Nothing,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64},Nothing,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRange{Int64, Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,UnitRange{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,UnitRange{Int64},Vector{Float64},Nothing,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,UnitRange{Int64},Vector{Float64},Vector{Int64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Float64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Float64},Vector{Float64},Nothing,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Int64},Vector{Int64},Nothing,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Vector{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_fill_viewport),Vector{Float64},RGBA{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_get_3d_axis_angle),Vector{Float64},Float64,Float64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Float64}, Vector{String}},Int64})
|
||||
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Int64}, Vector{String}},Int64})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Int64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks_3d),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_polaraxes),Int64,Float64,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(gr_polyline),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{typeof(gr_set_gradient),PlotUtils.ContinuousColorGradient})
|
||||
Base.precompile(Tuple{typeof(gr_text),Float64,Float64,String})
|
||||
Base.precompile(Tuple{typeof(gr_text_size),String})
|
||||
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}}})
|
||||
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}}})
|
||||
Base.precompile(Tuple{typeof(gr_viewport_from_bbox),Subplot{GRBackend},BoundingBox{Tuple{AbsoluteLength, AbsoluteLength}, Tuple{AbsoluteLength, AbsoluteLength}},AbsoluteLength,AbsoluteLength,Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(heatmap_edges),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Symbol})
|
||||
Base.precompile(Tuple{typeof(heatmap_edges),UnitRange{Int64},Symbol})
|
||||
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol})
|
||||
Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(layout_args),Matrix{Any}})
|
||||
Base.precompile(Tuple{typeof(layout_args),NamedTuple{(:label, :blank), Tuple{Symbol, Bool}}})
|
||||
Base.precompile(Tuple{typeof(layout_args),NamedTuple{(:label, :width, :height), Tuple{Symbol, Symbol, Float64}}})
|
||||
Base.precompile(Tuple{typeof(make_fillrange_side),UnitRange{Int64},LinRange{Float64, Int64}})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Function})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Float64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Int64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),StepRange{Int64, Int64},Tuple{Int64, Int64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),UnitRange{Int64},Tuple{Float64, Float64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(partialcircle),Float64,Float64,Int64})
|
||||
Base.precompile(Tuple{typeof(partialcircle),Int64,Float64,Int64})
|
||||
Base.precompile(Tuple{typeof(plot!),Any})
|
||||
Base.precompile(Tuple{typeof(plot!),Plot,Plot,Plot,Vararg{Plot}})
|
||||
Base.precompile(Tuple{typeof(plot),Any,Any})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Matrix{Symbol}})
|
||||
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Symbol})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Bool})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Matrix{Symbol}})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},RGBA{Float64}})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Shape{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Stroke})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Symbol})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
|
||||
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol})
|
||||
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(quiver_using_arrows),DefaultsDict})
|
||||
Base.precompile(Tuple{typeof(resetfontsizes)})
|
||||
Base.precompile(Tuple{typeof(scalefontsizes),Float64})
|
||||
Base.precompile(Tuple{typeof(series_annotations),Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{AbsoluteLength},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{Bool},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{Int64},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{PlotUtils.ContinuousColorGradient},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{RGBA{Float64}},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{String},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{Symbol},Int64})
|
||||
Base.precompile(Tuple{typeof(spy),Any})
|
||||
Base.precompile(Tuple{typeof(straightline_data),Tuple{Float64, Float64},Tuple{Float64, Float64},Vector{Float64},Vector{Float64},Int64})
|
||||
Base.precompile(Tuple{typeof(stroke),Int64,Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(text),String,Symbol})
|
||||
Base.precompile(Tuple{typeof(title!),AbstractString})
|
||||
Base.precompile(Tuple{typeof(vline!),Any})
|
||||
Base.precompile(Tuple{typeof(warn_on_attr_dim_mismatch),Series,Vector{Float64},Vector{Float64},Nothing,Base.Iterators.Flatten{Vector{Tuple{SeriesSegment}}}})
|
||||
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(xgrid!),Plot{PlotlyBackend},Symbol,Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
|
||||
isdefined(Plots, Symbol("#168#169")) && Base.precompile(Tuple{getfield(Plots, Symbol("#168#169")),Any})
|
||||
isdefined(Plots, Symbol("#170#171")) && Base.precompile(Tuple{getfield(Plots, Symbol("#170#171")),Any})
|
||||
isdefined(Plots, Symbol("#2#6")) && Base.precompile(Tuple{getfield(Plots, Symbol("#2#6")),UnitRange{Int64}})
|
||||
isdefined(Plots, Symbol("#301#337")) && Base.precompile(Tuple{getfield(Plots, Symbol("#301#337"))})
|
||||
isdefined(Plots, Symbol("#322#358")) && Base.precompile(Tuple{getfield(Plots, Symbol("#322#358"))})
|
||||
isdefined(Plots, Symbol("#add_major_or_minor_segments#102")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#102")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64}},Float64,Bool})
|
||||
isdefined(Plots, Symbol("#add_major_or_minor_segments#103")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#103")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64, Float64}},Float64,Bool})
|
||||
let fbody = try __lookup_kwbody__(which(annotate!, (AbstractVector{<:Tuple},))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(annotate!),AbstractVector{<:Tuple},))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(font, (Font,Vararg{Any},))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(font),Font,Vararg{Any},))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(gr_polyline, (Vector{Float64},Vector{Float64},typeof(GR.fillarea),))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Symbol,Symbol,typeof(gr_polyline),Vector{Float64},Vector{Float64},typeof(GR.fillarea),))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(gr_set_font, (Font,Subplot{GRBackend},))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Symbol,Symbol,RGBA{Float64},Float64,typeof(gr_set_font),Font,Subplot{GRBackend},))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Any,Vararg{Any},))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot!),Any,Vararg{Any},))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot!),Plot,Plot,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,Plot,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot!),Plot,Plot,Plot,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,Plot,Vararg{Plot},))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot!),Plot,Plot,Plot,Vararg{Plot},))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot, (Any,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot),Any,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot, (Any,Vararg{Any},))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(plot),Any,Vararg{Any},))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(title!, (AbstractString,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(title!),AbstractString,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(yaxis!, (Any,Vararg{Any},))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Pairs{Symbol, V, Tuple{Vararg{Symbol, N}}, NamedTuple{names, T}} where {V, N, names, T<:Tuple{Vararg{Any, N}}},typeof(yaxis!),Any,Vararg{Any},))
|
||||
end
|
||||
end
|
||||
end
|
||||
282
deps/SnoopCompile/precompile/1.8/precompile_Plots.jl
vendored
282
deps/SnoopCompile/precompile/1.8/precompile_Plots.jl
vendored
@ -1,282 +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
|
||||
|
||||
|
||||
function _precompile_()
|
||||
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Int64})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Vector{Int64}}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{typeof(datetimeformatter)}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide,), Tuple{String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:guide_position, :guidefontvalign, :mirror, :guide), Tuple{Symbol, Symbol, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:ticks,), Tuple{Nothing}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(default)),NamedTuple{(:titlefont, :legendfontsize, :guidefont, :tickfont, :guide, :framestyle, :yminorgrid), Tuple{Tuple{Int64, String}, Int64, Tuple{Int64, Symbol}, Tuple{Int64, Symbol}, String, Symbol, Bool}},typeof(default)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),StepRange{Int64, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}},typeof(gr_set_font),Font,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:rotation, :color), Tuple{Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{GRBackend},Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:annotation,), Tuple{Vector{Tuple{Int64, Float64, Tuple{String, Any, Any, Any}}}}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:layout, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{GRBackend},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{PlotlyBackend},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Function,Float64,Irrational{:π}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Plot{GRBackend},Function,Float64,Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{GRBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot!),Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},Vector{Float64},Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:annotations, :leg), Tuple{Tuple{Int64, Float64, PlotText}, Bool}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bar_width, :alpha, :color, :fillto, :label, :seriestype), Tuple{Float64, Float64, Vector{Symbol}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, String, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bins, :weights, :seriestype), Tuple{Symbol, Vector{Int64}, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:color, :line, :marker), Tuple{Matrix{Symbol}, Tuple{Symbol, Int64}, Tuple{Matrix{Symbol}, Int64, Float64, Stroke}}},typeof(plot),Vector{Vector}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:connections, :title, :xlabel, :ylabel, :zlabel, :legend, :margin, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, String, String, String, String, Symbol, AbsoluteLength, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill, :seriestype), Tuple{Bool, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill_z, :alpha, :label, :bar_width, :seriestype), Tuple{StepRange{Int64, Int64}, Vector{Float64}, String, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks, :seriestype), Tuple{Matrix{Symbol}, Matrix{String}, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Int64, String, Int64, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Vector{Float64}},Vector{Vector{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:grid, :title), Tuple{Tuple{Symbol, Symbol, Symbol, Int64, Float64}, String}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:lab, :w, :palette, :fill, :α), Tuple{String, Int64, PlotUtils.ContinuousColorGradient, Int64, Float64}},typeof(plot),StepRange{Int64, Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :legend, :seriestype), Tuple{String, Symbol, Symbol}},typeof(plot),Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend), Tuple{Matrix{String}, String, String, Int64, Symbol}},typeof(plot),Vector{Function},Float64,Float64})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label,), Tuple{Matrix{String}}},typeof(plot),Vector{AbstractVector{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :group, :linetype, :linecolor), Tuple{Matrix{Any}, Vector{String}, Matrix{Symbol}, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :link), Tuple{Int64, Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :palette, :bg_inside), Tuple{Int64, Matrix{PlotUtils.ContinuousColorGradient}, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :t, :leg, :ticks, :border), Tuple{Matrix{Any}, Matrix{Symbol}, Bool, Nothing, Symbol}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :title, :titlelocation, :left_margin, :bottom_margin, :xrotation), Tuple{Matrix{Any}, Matrix{String}, Symbol, Matrix{AbsoluteLength}, AbsoluteLength, Int64}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xguide, :yguide, :xguidefonthalign, :yguidefontvalign, :xguideposition, :yguideposition, :ymirror, :xmirror, :legend, :seriestype), Tuple{Int64, String, String, Matrix{Symbol}, Matrix{Symbol}, Symbol, Matrix{Symbol}, Matrix{Bool}, Matrix{Bool}, Bool, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xlims), Tuple{Matrix{Any}, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Vector{Tuple{Int64, Real}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :lab, :ms), Tuple{Tuple{Matrix{Symbol}, Int64}, Matrix{String}, Int64}},typeof(plot),Vector{Vector},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :label, :legendtitle), Tuple{Tuple{Int64, Matrix{Symbol}}, Matrix{String}, String}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :leg, :fill), Tuple{Int64, Bool, Tuple{Int64, Symbol}}},typeof(plot),Function,Function,Int64,Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :marker, :bg, :fg, :xlim, :ylim, :leg), Tuple{Tuple{Int64, Symbol, Symbol}, Tuple{Shape{Float64, Float64}, Int64, RGBA{Float64}}, Symbol, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Bool}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line_z, :linewidth, :legend), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Int64, Bool}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:m, :markersize, :lab, :bg, :xlim, :ylim, :seriestype), Tuple{Matrix{Symbol}, Int64, Matrix{String}, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker,), Tuple{Bool}},typeof(plot),Vector{Union{Missing, Int64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker_z, :color, :legend, :seriestype), Tuple{typeof(+), Symbol, Bool, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :markersize, :marker_z, :line_z, :linewidth), Tuple{Matrix{Symbol}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :seriestype, :label), Tuple{Symbol, Symbol, String}},typeof(plot),UnitRange{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:nbins, :show_empty_bins, :normed, :aspect_ratio, :seriestype), Tuple{Tuple{Int64, Int64}, Bool, Bool, Int64, Symbol}},typeof(plot),Vector{ComplexF64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:proj, :m), Tuple{Symbol, Int64}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:projection, :seriestype), Tuple{Symbol, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},UnitRange{Int64},Matrix{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:quiver, :seriestype), Tuple{Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:reg, :fill), Tuple{Bool, Tuple{Int64, Symbol}}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Tuple{LinRange{Float64, Int64}, LinRange{Float64, Int64}}}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{typeof(sqrt)}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color), Tuple{Matrix{Symbol}, Vector{Symbol}, Int64, Vector{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{OHLC}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :l, :seriestype), Tuple{String, Float64, Symbol}},typeof(plot),Vector{String},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :xflip, :yflip, :zflip, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :xmirror, :ymirror, :zmirror, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:xaxis, :background_color, :leg), Tuple{Tuple{String, Tuple{Int64, Int64}, StepRange{Int64, Int64}, Symbol}, RGB{Float64}, Bool}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:zcolor, :m, :leg, :cbar, :w), Tuple{StepRange{Int64, Int64}, Tuple{Int64, Float64, Symbol, Stroke}, Bool, Bool, Int64}},typeof(plot),Vector{Float64},Vector{Float64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(portfoliocomposition)),Any,typeof(portfoliocomposition),Any,Vararg{Any}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip, :disp), Tuple{Vector{Int64}, Bool}},typeof(test_examples),Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip,), Tuple{Vector{Int64}}},typeof(test_examples),Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(yaxis!)),Any,typeof(yaxis!),Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},AbstractVector{OHLC}})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},PortfolioComposition})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:barhist}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bar}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bins2d}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:histogram2d}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hline}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hspan}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:lens}},AbstractPlot})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:pie}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:quiver}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:sticks}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vline}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vspan}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:xerror}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Vector{ComplexF64}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{GRBackend},DefaultsDict})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{PlotlyBackend},DefaultsDict})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{GRBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{PlotlyBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_attributes!),Plot{GRBackend},DefaultsDict})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{GRBackend},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.unzip),Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{typeof(_bin_centers),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{PlotUtils.ContinuousColorGradient},String})
|
||||
Base.precompile(Tuple{typeof(_cycle),StepRange{Int64, Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},StepRange{Int64, Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
|
||||
Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},Bool})
|
||||
Base.precompile(Tuple{typeof(_preprocess_barlike),DefaultsDict,Base.OneTo{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(_preprocess_binlike),DefaultsDict,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(_update_min_padding!),GridLayout})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{GRBackend},Subplot{GRBackend},Dict{Symbol, Any},Int64,Bool})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{PlotlyBackend},Subplot{PlotlyBackend},Dict{Symbol, Any},Int64,Bool})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{GRBackend},Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{PlotlyBackend},Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(annotate!),AbstractVector{<:Tuple}})
|
||||
Base.precompile(Tuple{typeof(axis_limits),Subplot{GRBackend},Symbol,Bool,Bool})
|
||||
Base.precompile(Tuple{typeof(axis_limits),Subplot{PlotlyBackend},Symbol,Bool,Bool})
|
||||
Base.precompile(Tuple{typeof(backend),PlotlyBackend})
|
||||
Base.precompile(Tuple{typeof(bbox),AbsoluteLength,AbsoluteLength,AbsoluteLength,AbsoluteLength})
|
||||
Base.precompile(Tuple{typeof(bbox),Float64,Float64,Float64,Float64})
|
||||
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64,Vector{Plot}})
|
||||
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Vector{Float64},Tuple{Int64, Float64}})
|
||||
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64},Vararg{Vector{Float64}}})
|
||||
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(error_zipit),Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}})
|
||||
Base.precompile(Tuple{typeof(fakedata),Int64,Int64})
|
||||
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(get_series_color),SubArray{Symbol, 1, Vector{Symbol}, Tuple{UnitRange{Int64}}, true},Subplot{GRBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{PlotlyBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_ticks),StepRange{Int64, Int64},Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Float64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_ticks),UnitRange{Int64},Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(get_xy),Vector{OHLC}})
|
||||
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_display),Subplot{GRBackend},AbsoluteLength,AbsoluteLength,Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_heatmap),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Float64,Float64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Shape{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Int64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},UnitRange{Int64},Tuple{Vector{Float64}, Vector{Float64}},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRange{Int64, Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Float64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Vector{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_fill_viewport),Vector{Float64},RGBA{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Float64}, Vector{String}},Int64})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Int64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks_3d),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_polaraxes),Int64,Float64,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(gr_set_gradient),PlotUtils.ContinuousColorGradient})
|
||||
Base.precompile(Tuple{typeof(gr_text),Float64,Float64,String})
|
||||
Base.precompile(Tuple{typeof(gr_text_size),String})
|
||||
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}}})
|
||||
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}}})
|
||||
Base.precompile(Tuple{typeof(gr_viewport_from_bbox),Subplot{GRBackend},BoundingBox{Tuple{AbsoluteLength, AbsoluteLength}, Tuple{AbsoluteLength, AbsoluteLength}},AbsoluteLength,AbsoluteLength,Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(heatmap_edges),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64},Symbol})
|
||||
Base.precompile(Tuple{typeof(heatmap_edges),UnitRange{Int64},Symbol})
|
||||
Base.precompile(Tuple{typeof(heatmap_edges),Vector{Float64},Symbol})
|
||||
Base.precompile(Tuple{typeof(ignorenan_minimum),Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(is_marker_supported),GRBackend,Vector{Symbol}})
|
||||
Base.precompile(Tuple{typeof(layout_args),Matrix{Any}})
|
||||
Base.precompile(Tuple{typeof(link_axes!),GridLayout,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Function})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Float64, Float64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Float64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),Nothing,Tuple{Int64, Int64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),StepRange{Int64, Int64},Tuple{Int64, Int64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(optimal_ticks_and_labels),UnitRange{Int64},Tuple{Float64, Float64},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(partialcircle),Int64,Float64,Int64})
|
||||
Base.precompile(Tuple{typeof(plot!),Plot,Plot,Plot,Vararg{Plot}})
|
||||
Base.precompile(Tuple{typeof(plot),Any,Any})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Matrix{Symbol}})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Matrix{Symbol}})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},RGBA{Float64}})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Shape{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText,Font})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol},Font})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String},Font})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText,Font})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol},Font})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Symbol, Int64, String},Font})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
|
||||
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol})
|
||||
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(push!),Segments{Tuple{Float64, Float64, Float64}},Tuple{Float64, Int64, Int64},Tuple{Float64, Int64, Int64}})
|
||||
Base.precompile(Tuple{typeof(resetfontsizes)})
|
||||
Base.precompile(Tuple{typeof(scalefontsizes),Float64})
|
||||
Base.precompile(Tuple{typeof(series_annotations),Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{AbsoluteLength},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{Bool},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{Int64},Int64})
|
||||
Base.precompile(Tuple{typeof(spy),Any})
|
||||
Base.precompile(Tuple{typeof(straightline_data),Tuple{Float64, Float64},Tuple{Float64, Float64},Vector{Float64},Vector{Float64},Int64})
|
||||
Base.precompile(Tuple{typeof(title!),AbstractString})
|
||||
Base.precompile(Tuple{typeof(update_child_bboxes!),GridLayout})
|
||||
Base.precompile(Tuple{typeof(update_clims),Float64,Float64,SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true},typeof(ignorenan_extrema)})
|
||||
Base.precompile(Tuple{typeof(warn_on_attr_dim_mismatch),Series,Vector{Float64},Vector{Float64},Nothing,Base.Iterators.Flatten{Vector{Tuple{SeriesSegment}}}})
|
||||
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(xgrid!),Plot{PlotlyBackend},Symbol,Vararg{Any}})
|
||||
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
|
||||
isdefined(Plots, Symbol("#2#6")) && Base.precompile(Tuple{getfield(Plots, Symbol("#2#6")),UnitRange{Int64}})
|
||||
isdefined(Plots, Symbol("#322#358")) && Base.precompile(Tuple{getfield(Plots, Symbol("#322#358"))})
|
||||
isdefined(Plots, Symbol("#add_major_or_minor_segments#102")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#102")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64}},Float64,Bool})
|
||||
isdefined(Plots, Symbol("#add_major_or_minor_segments#103")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#103")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64, Float64}},Float64,Bool})
|
||||
end
|
||||
@ -66,19 +66,23 @@ 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(areaplot)),Any,typeof(areaplot),Any,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:foreground_color_grid, :grid, :gridalpha, :gridstyle, :gridlinewidth), Tuple{RGBA{Float64}, Bool, Float64, Symbol, Int64}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(: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, :flip, :minorgrid, :guide), Tuple{Bool, Bool, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Float64, Float64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Float64, Float64}, Bool}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :guide), Tuple{Bool, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :minorgrid, :mirror, :guide), Tuple{Bool, Bool, Bool, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid,), Tuple{Bool}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(: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})
|
||||
@ -86,46 +90,36 @@ function _precompile_()
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Float64, Float64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Float64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:lims,), Tuple{Tuple{Int64, Int64}}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:minorgrid, :scale, :guide), Tuple{Bool, Symbol, String}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(: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), Tuple{Symbol, Symbol, Int64}},typeof(gr_set_font),Font,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:rotation, :color), Tuple{Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :label, :seriestype), Tuple{Float64, String, Symbol}},typeof(plot!),Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(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(histogram2d)),Any,typeof(histogram2d),Any,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(hline!)),Any,typeof(hline!),Any})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{GRBackend},Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:annotation,), Tuple{Vector{Tuple{Int64, Float64, Tuple{String, Any, Any, Any}}}}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:c, :lw, :label), Tuple{Symbol, Int64, String}},typeof(plot!),Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:layout, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot!),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
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,Irrational{:π}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Plot{GRBackend},Function,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{GRBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{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},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),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}})
|
||||
@ -133,51 +127,48 @@ function _precompile_()
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!),Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},Vector{Float64},Vararg{Any, N} where N})
|
||||
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, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!),Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis,), 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{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bar_width, :alpha, :color, :fillto, :label, :seriestype), Tuple{Float64, Float64, Vector{Symbol}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, String, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(: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, :title, :xlabel, :ylabel, :zlabel, :legend, :margin, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, String, String, String, String, Symbol, AbsoluteLength, Symbol}},typeof(plot),Vector{Int64},Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill, :seriestype), Tuple{Bool, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:fill_z, :alpha, :label, :bar_width, :seriestype), Tuple{StepRange{Int64, Int64}, Vector{Float64}, String, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(: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, :legend, :seriestype), Tuple{String, Symbol, Symbol}},typeof(plot),Vector{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend), Tuple{Matrix{String}, String, String, Int64, Symbol}},typeof(plot),Vector{Function},Float64,Float64})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend), Tuple{Matrix{String}, String, String, Int64, Symbol}},typeof(plot),Vector{Function},Float64,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{Matrix{Any}, Vector{String}, Matrix{Symbol}, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :label, :fillrange, :fillalpha), Tuple{Tuple{Int64, Int64}, String, Int64, Float64}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:labels,), Tuple{Matrix{String}}},typeof(plot),PortfolioComposition})
|
||||
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, :margin), Tuple{Matrix{Any}, AbsoluteLength}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :palette, :bg_inside), Tuple{Int64, Matrix{PlotUtils.ContinuousColorGradient}, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :t, :leg, :ticks, :border), Tuple{Matrix{Any}, Matrix{Symbol}, Bool, Nothing, Symbol}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :title, :titlelocation, :left_margin, :bottom_margin, :xrotation), Tuple{Matrix{Any}, Matrix{String}, Symbol, Matrix{AbsoluteLength}, AbsoluteLength, Int64}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :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{Matrix{Any}, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
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,Int64,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, :leg, :fill), Tuple{Int64, Bool, Tuple{Int64, Symbol}}},typeof(plot),Function,Function,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :marker, :bg, :fg, :xlim, :ylim, :leg), Tuple{Tuple{Int64, Symbol, Symbol}, Tuple{Shape, Int64, RGBA{Float64}}, Symbol, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Bool}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},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{(:m, :lab, :bg, :xlim, :ylim, :seriestype), Tuple{Tuple{Int64, Symbol}, 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}})
|
||||
@ -185,31 +176,29 @@ function _precompile_()
|
||||
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},Matrix{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:quiver, :seriestype), Tuple{Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(: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{(:seriescolor, :fillalpha), Tuple{Matrix{Symbol}, Matrix{Float64}}},typeof(plot),AreaPlot})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color), Tuple{Matrix{Symbol}, Vector{Symbol}, Int64, Vector{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},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},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},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, :xflip, :yflip, :zflip, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :xmirror, :ymirror, :zmirror, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, Bool, Bool, Bool, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :zlabel, :grid, :ylabel, :minorgrid, :xlabel, :seriestype), Tuple{String, String, Bool, String, Bool, String, Symbol}},typeof(plot),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{Matrix{String}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(: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{(:zcolor, :m, :leg, :cbar, :w), Tuple{StepRange{Int64, Int64}, Tuple{Int64, Float64, Symbol, Stroke}, Bool, Bool, Int64}},typeof(plot),Vector{Float64},Vector{Float64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(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, :disp), Tuple{Vector{Int64}, Bool}},typeof(test_examples),Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(test_examples)),NamedTuple{(:skip,), Tuple{Vector{Int64}}},typeof(test_examples),Symbol})
|
||||
Base.precompile(Tuple{Type{GridLayout},Int64,Vararg{Int64, N} where N})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},AbstractVector{OHLC}})
|
||||
@ -220,14 +209,12 @@ function _precompile_()
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:bins2d}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:histogram2d}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hline}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:hspan}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:lens}},AbstractPlot})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:pie}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:quiver}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:steppre}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:sticks}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vline}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:vspan}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Type{Val{:xerror}},Any,Any,Any})
|
||||
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol, Any},Vector{ComplexF64}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.add_series!),Plot{GRBackend},DefaultsDict})
|
||||
@ -235,50 +222,49 @@ function _precompile_()
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{GRBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{PlotlyBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_attributes!),Plot{GRBackend},DefaultsDict})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{GRBackend},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_sliced_series_attributes!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
|
||||
Base.precompile(Tuple{typeof(RecipesPipeline.unzip),Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{typeof(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(_bin_centers),Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Float64},String})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Int64},String})
|
||||
Base.precompile(Tuple{typeof(_cbar_unique),Vector{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),UnitRange{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Base.OneTo{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),ColorPalette,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{Int64},StepRange{Int64, Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Int64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
|
||||
Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},Bool})
|
||||
Base.precompile(Tuple{typeof(_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(_replace_markershape),Vector{Symbol}})
|
||||
Base.precompile(Tuple{typeof(_update_min_padding!),GridLayout})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{GRBackend},Subplot{GRBackend},Dict{Symbol, Any},Int64,Bool})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_args),Plot{PlotlyBackend},Subplot{PlotlyBackend},Dict{Symbol, Any},Int64,Bool})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{GRBackend},Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(_update_subplot_periphery),Subplot{PlotlyBackend},Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(axis_limits),Subplot{GRBackend},Symbol,Bool,Bool})
|
||||
Base.precompile(Tuple{typeof(axis_limits),Subplot{PlotlyBackend},Symbol,Bool,Bool})
|
||||
Base.precompile(Tuple{typeof(backend),PlotlyBackend})
|
||||
Base.precompile(Tuple{typeof(bbox),AbsoluteLength,AbsoluteLength,AbsoluteLength,AbsoluteLength})
|
||||
Base.precompile(Tuple{typeof(bbox),Float64,Float64,Float64,Float64})
|
||||
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64,Vector{Plot}})
|
||||
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64})
|
||||
Base.precompile(Tuple{typeof(contour),Any,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Int64, Float64}})
|
||||
Base.precompile(Tuple{typeof(default),Symbol,Bool})
|
||||
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(fakedata),Int64,Int64})
|
||||
Base.precompile(Tuple{typeof(fakedata),MersenneTwister,Int64,Vararg{Int64, N} where N})
|
||||
Base.precompile(Tuple{typeof(fakedata),Int64,Vararg{Int64, N} where N})
|
||||
Base.precompile(Tuple{typeof(font),String,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(get_series_color),SubArray{Symbol, 1, Vector{Symbol}, Tuple{UnitRange{Int64}}, true},Subplot{GRBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{PlotlyBackend},Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(get_ticks),StepRange{Int64, Int64},Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any, N} where N})
|
||||
@ -288,116 +274,85 @@ function _precompile_()
|
||||
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),Vector{OHLC}})
|
||||
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_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,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Int64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64}})
|
||||
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,UnitRange{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,UnitRange{Int64},Vector{Float64},Vector{Int64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Float64},Vector{Float64},Int64,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Int64},Vector{Float64},Nothing,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_3d_axis_angle),Vector{Float64},Float64,Float64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Float64}, Vector{String}},Int64})
|
||||
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Int64}, Vector{String}},Int64})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Int64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks_3d),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_polaraxes),Int64,Float64,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(gr_polyline),Vector{Float64},Vector{Float64},Function})
|
||||
Base.precompile(Tuple{typeof(gr_set_gradient),PlotUtils.ContinuousColorGradient})
|
||||
Base.precompile(Tuple{typeof(gr_text),Float64,Float64,String})
|
||||
Base.precompile(Tuple{typeof(gr_text_size),String})
|
||||
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}}})
|
||||
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}}})
|
||||
Base.precompile(Tuple{typeof(gr_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,UnitRange{Int64},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),NamedTuple{(:label, :blank), Tuple{Symbol, Bool}}})
|
||||
Base.precompile(Tuple{typeof(layout_args),NamedTuple{(:label, :width, :height), Tuple{Symbol, Symbol, Float64}}})
|
||||
Base.precompile(Tuple{typeof(isvertical),Dict{Symbol, Any}})
|
||||
Base.precompile(Tuple{typeof(layout_args),Int64})
|
||||
Base.precompile(Tuple{typeof(make_fillrange_side),UnitRange{Int64},LinRange{Float64}})
|
||||
Base.precompile(Tuple{typeof(make_steps),UnitRange{Int64},Symbol,Bool})
|
||||
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})
|
||||
Base.precompile(Tuple{typeof(plot!),Plot,Plot,Plot,Vararg{Plot, N} where N})
|
||||
Base.precompile(Tuple{typeof(plot),Any,Any})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{typeof(plot),Any,Any,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(plot),Any})
|
||||
Base.precompile(Tuple{typeof(processGridArg!),DefaultsDict,Bool,Symbol})
|
||||
Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},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},Shape})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Stroke})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Symbol})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
|
||||
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol})
|
||||
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(push!),Segments{Tuple{Float64, Float64, Float64}},Tuple{Int64, Int64, Float64},Tuple{Int64, Int64, Float64}})
|
||||
Base.precompile(Tuple{typeof(resetfontsizes)})
|
||||
Base.precompile(Tuple{typeof(scalefontsizes),Float64})
|
||||
Base.precompile(Tuple{typeof(series_annotations),Vector{Any}})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{AbsoluteLength},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{Bool},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{Int64},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{PlotUtils.ContinuousColorGradient},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{RGBA{Float64}},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{String},Int64})
|
||||
Base.precompile(Tuple{typeof(slice_arg),Matrix{Symbol},Int64})
|
||||
Base.precompile(Tuple{typeof(spy),Any})
|
||||
Base.precompile(Tuple{typeof(straightline_data),Tuple{Float64, Float64},Tuple{Float64, Float64},Vector{Float64},Vector{Float64},Int64})
|
||||
Base.precompile(Tuple{typeof(stroke),Int64,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(text),String,Int64,Symbol,Vararg{Symbol, N} where N})
|
||||
Base.precompile(Tuple{typeof(text),String,Symbol,Int64,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(text),String,Symbol})
|
||||
Base.precompile(Tuple{typeof(title!),AbstractString})
|
||||
Base.precompile(Tuple{typeof(unzip),Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{typeof(vline!),Any})
|
||||
Base.precompile(Tuple{typeof(warn_on_attr_dim_mismatch),Series,Vector{Float64},Vector{Float64},Nothing,Base.Iterators.Flatten{Vector{Tuple{SeriesSegment}}}})
|
||||
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
|
||||
isdefined(Plots, Symbol("#166#167")) && Base.precompile(Tuple{getfield(Plots, Symbol("#166#167")),Any})
|
||||
isdefined(Plots, Symbol("#2#6")) && Base.precompile(Tuple{getfield(Plots, Symbol("#2#6")),UnitRange{Int64}})
|
||||
isdefined(Plots, Symbol("#295#331")) && Base.precompile(Tuple{getfield(Plots, Symbol("#295#331"))})
|
||||
isdefined(Plots, Symbol("#316#352")) && Base.precompile(Tuple{getfield(Plots, Symbol("#316#352"))})
|
||||
isdefined(Plots, Symbol("#add_major_or_minor_segments#100")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#100")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64}},Float64,Bool})
|
||||
isdefined(Plots, Symbol("#add_major_or_minor_segments#101")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#101")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64, Float64}},Float64,Bool})
|
||||
let fbody = try __lookup_kwbody__(which(font, (Font,Vararg{Any, N} where N,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(font),Font,Vararg{Any, N} where N,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(gr_polyline, (Vector{Float64},Vector{Float64},typeof(GR.fillarea),))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Symbol,Symbol,typeof(gr_polyline),Vector{Float64},Vector{Float64},typeof(GR.fillarea),))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(gr_set_font, (Font,Subplot{GRBackend},))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Symbol,Symbol,RGBA{Float64},Float64,typeof(gr_set_font),Font,Subplot{GRBackend},))
|
||||
end
|
||||
end
|
||||
Base.precompile(Tuple{typeof(yaxis!),Any,Any})
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Any,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(plot!),Any,))
|
||||
@ -407,26 +362,6 @@ end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(plot!),Any,Vararg{Any, N} where N,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Plot,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(plot!),Plot,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(plot!),Plot,Plot,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,Plot,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(plot!),Plot,Plot,Plot,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Plot,Plot,Plot,Vararg{Plot, N} where N,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(plot!),Plot,Plot,Plot,Vararg{Plot, N} where N,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot, (Any,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
@ -438,9 +373,19 @@ end
|
||||
precompile(fbody, (Any,typeof(plot),Any,Vararg{Any, N} where N,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(scatter, (Any,Vararg{Any, N} where N,))) catch missing 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(scatter),Any,Vararg{Any, N} where N,))
|
||||
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
|
||||
@ -448,4 +393,9 @@ end
|
||||
precompile(fbody, (Any,typeof(title!),AbstractString,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(yaxis!, (Any,Vararg{Any, N} where N,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(yaxis!),Any,Vararg{Any, N} where N,))
|
||||
end
|
||||
end
|
||||
end
|
||||
6
deps/SnoopCompile/snoop_bench.jl
vendored
6
deps/SnoopCompile/snoop_bench.jl
vendored
@ -1,6 +1,8 @@
|
||||
include("snoop_bot_config.jl")
|
||||
using CompileBot
|
||||
|
||||
snoop_bench(
|
||||
botconfig,
|
||||
BotConfig(
|
||||
"Plots",
|
||||
),
|
||||
joinpath(@__DIR__, "precompile_script.jl"),
|
||||
)
|
||||
|
||||
6
deps/SnoopCompile/snoop_bot.jl
vendored
6
deps/SnoopCompile/snoop_bot.jl
vendored
@ -1,6 +1,8 @@
|
||||
include("snoop_bot_config.jl")
|
||||
using CompileBot
|
||||
|
||||
snoop_bot(
|
||||
botconfig,
|
||||
BotConfig(
|
||||
"Plots",
|
||||
),
|
||||
joinpath(@__DIR__, "precompile_script.jl"),
|
||||
)
|
||||
|
||||
7
deps/SnoopCompile/snoop_bot_config.jl
vendored
7
deps/SnoopCompile/snoop_bot_config.jl
vendored
@ -1,7 +0,0 @@
|
||||
using CompileBot
|
||||
|
||||
botconfig = BotConfig(
|
||||
"Plots",
|
||||
version = ["1.6", "1.7", "1.8", "nightly"], # <<< keep these versions in sync with .github/workflows/SnoopCompile.yml
|
||||
# else_version = "nightly",
|
||||
)
|
||||
60
src/Plots.jl
60
src/Plots.jl
@ -1,61 +1,35 @@
|
||||
module Plots
|
||||
|
||||
using Pkg
|
||||
|
||||
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optlevel"))
|
||||
@eval Base.Experimental.@optlevel 1
|
||||
end
|
||||
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@max_methods"))
|
||||
@eval Base.Experimental.@max_methods 1
|
||||
end
|
||||
|
||||
const _plots_project = Pkg.Types.read_project(normpath(@__DIR__, "..", "Project.toml"))
|
||||
const _current_plots_version = _plots_project.version
|
||||
const _plots_compats = _plots_project.compat
|
||||
function _check_compat(sim::Module)
|
||||
sim_str = string(sim)
|
||||
if !haskey(_plots_compats, sim_str)
|
||||
return nothing
|
||||
end
|
||||
be_v = Pkg.Types.read_project(joinpath(Base.pkgdir(sim), "Project.toml")).version
|
||||
be_c = _plots_compats[sim_str]
|
||||
if be_c isa String # julia 1.6
|
||||
if !(be_v in Pkg.Types.semver_spec(be_c))
|
||||
@warn "$sim $be_v is not compatible with this version of Plots. The declared compatibility is $(be_c)."
|
||||
end
|
||||
else
|
||||
if isempty(intersect(be_v, be_c.val))
|
||||
@warn "$sim $be_v is not compatible with this version of Plots. The declared compatibility is $(be_c.str)."
|
||||
end
|
||||
end
|
||||
end
|
||||
const _current_plots_version = VersionNumber(split(first(filter(line -> occursin("version", line), readlines(normpath(@__DIR__, "..", "Project.toml")))), "\"")[2])
|
||||
|
||||
using Reexport
|
||||
|
||||
import GeometryBasics
|
||||
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random, Unzip
|
||||
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random
|
||||
using SparseArrays
|
||||
|
||||
using FFMPEG
|
||||
|
||||
@reexport using RecipesBase
|
||||
import RecipesBase: plot, plot!, animate, is_explicit, grid
|
||||
import RecipesBase: plot, plot!, animate, is_explicit
|
||||
using Base.Meta
|
||||
@reexport using PlotUtils
|
||||
@reexport using PlotThemes
|
||||
import UnicodeFun
|
||||
import StatsBase
|
||||
import Downloads
|
||||
import Showoff
|
||||
import StatsBase
|
||||
import JSON
|
||||
|
||||
using Requires
|
||||
|
||||
#! format: off
|
||||
export
|
||||
grid,
|
||||
bbox,
|
||||
plotarea,
|
||||
@layout,
|
||||
KW,
|
||||
|
||||
wrap,
|
||||
@ -143,7 +117,8 @@ export
|
||||
scalefontsize,
|
||||
scalefontsizes,
|
||||
resetfontsizes
|
||||
#! format: on
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
import NaNMath # define functions that ignores NaNs. To overcome the destructive effects of https://github.com/JuliaLang/julia/pull/12563
|
||||
@ -162,6 +137,7 @@ ignorenan_extrema(x) = Base.extrema(x)
|
||||
# This makes it impossible to create row vectors of String and Symbol with the transpose operator.
|
||||
# This solves this issue, internally in Plots at least.
|
||||
|
||||
|
||||
# commented out on the insistence of the METADATA maintainers
|
||||
|
||||
#Base.transpose(x::Symbol) = x
|
||||
@ -172,16 +148,13 @@ ignorenan_extrema(x) = Base.extrema(x)
|
||||
import Measures
|
||||
module PlotMeasures
|
||||
import Measures
|
||||
import Measures:
|
||||
Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h
|
||||
import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h
|
||||
const BBox = Measures.Absolute2DBox
|
||||
|
||||
# allow pixels and percentages
|
||||
const px = AbsoluteLength(0.254)
|
||||
const pct = Length{:pct, Float64}(1.0)
|
||||
|
||||
Base.convert(::Type{<:Measure}, x::Float64) = x * pct
|
||||
|
||||
Base.:*(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * m2.value)
|
||||
Base.:*(m1::Length{:pct}, m2::AbsoluteLength) = AbsoluteLength(m2.value * m1.value)
|
||||
Base.:/(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value / m2.value)
|
||||
@ -195,8 +168,7 @@ import .PlotMeasures: Length, AbsoluteLength, Measure, width, height
|
||||
# ---------------------------------------------------------
|
||||
|
||||
import RecipesPipeline
|
||||
import RecipesPipeline:
|
||||
SliceIt,
|
||||
import RecipesPipeline: SliceIt,
|
||||
DefaultsDict,
|
||||
Formatted,
|
||||
AbstractSurface,
|
||||
@ -210,13 +182,14 @@ import RecipesPipeline:
|
||||
pop_kw!,
|
||||
scale_func,
|
||||
inverse_scale_func,
|
||||
unzip,
|
||||
dateformatter,
|
||||
datetimeformatter,
|
||||
timeformatter
|
||||
|
||||
# Use fixed version of Plotly instead of the latest one for stable dependency
|
||||
# Ref: https://github.com/JuliaPlots/Plots.jl/pull/2779
|
||||
const _plotly_min_js_filename = "plotly-2.6.3.min.js"
|
||||
const _plotly_min_js_filename = "plotly-1.57.1.min.js"
|
||||
|
||||
include("types.jl")
|
||||
include("utils.jl")
|
||||
@ -224,7 +197,6 @@ include("colorbars.jl")
|
||||
include("axes.jl")
|
||||
include("args.jl")
|
||||
include("components.jl")
|
||||
include("consts.jl")
|
||||
include("themes.jl")
|
||||
include("plot.jl")
|
||||
include("pipeline.jl")
|
||||
@ -260,8 +232,10 @@ let PlotOrSubplot = Union{Plot,Subplot}
|
||||
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::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; xticks = (ticks, labels), kw...)
|
||||
global yticks!(plt::PlotOrSubplot, ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; yticks = (ticks, labels), 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,
|
||||
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; yticks = (ticks,labels), kw...)
|
||||
global xgrid!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; xgrid = args, kw...)
|
||||
global ygrid!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; ygrid = args, kw...)
|
||||
global annotate!(plt::PlotOrSubplot, anns...; kw...) = plot!(plt; annotation = anns, kw...)
|
||||
@ -272,10 +246,10 @@ let PlotOrSubplot = Union{Plot,Subplot}
|
||||
global yaxis!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; yaxis = args, kw...)
|
||||
end
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
const CURRENT_BACKEND = CurrentBackend(:none)
|
||||
const PLOTS_SEED = 1234
|
||||
|
||||
include("precompile_includer.jl")
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ end
|
||||
|
||||
Add a plot (the current plot if not specified) to an existing animation
|
||||
"""
|
||||
function frame(anim::Animation, plt::P = current()) where {P<:AbstractPlot}
|
||||
function frame(anim::Animation, plt::P=current()) where P<:AbstractPlot
|
||||
i = length(anim.frames) + 1
|
||||
filename = @sprintf("%06d.png", i)
|
||||
png(plt, joinpath(anim.dir, filename))
|
||||
@ -69,16 +69,12 @@ webm(anim::Animation, fn = webmfn(); kw...) = buildanimation(anim, fn, false; kw
|
||||
ffmpeg_framerate(fps) = "$fps"
|
||||
ffmpeg_framerate(fps::Rational) = "$(fps.num)/$(fps.den)"
|
||||
|
||||
function buildanimation(
|
||||
anim::Animation,
|
||||
fn::AbstractString,
|
||||
function buildanimation(anim::Animation, fn::AbstractString,
|
||||
is_animated_gif::Bool=true;
|
||||
fps::Real = 20,
|
||||
loop::Integer = 0,
|
||||
fps::Real = 20, loop::Integer = 0,
|
||||
variable_palette::Bool=false,
|
||||
verbose=false,
|
||||
show_msg::Bool = true,
|
||||
)
|
||||
show_msg::Bool=true)
|
||||
if length(anim.frames) == 0
|
||||
throw(ArgumentError("Cannot build empty animations"))
|
||||
end
|
||||
@ -86,47 +82,39 @@ function buildanimation(
|
||||
fn = abspath(expanduser(fn))
|
||||
animdir = anim.dir
|
||||
framerate = ffmpeg_framerate(fps)
|
||||
verbose_level = (verbose isa Int ? verbose : verbose ? 32 : 16) # "error"
|
||||
verbose_level = (verbose isa Int ? verbose :
|
||||
verbose ? 32 # "info"
|
||||
: 16) # "error"
|
||||
|
||||
if is_animated_gif
|
||||
if variable_palette
|
||||
# generate a colorpalette for each frame for highest quality, but larger filesize
|
||||
palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1"
|
||||
ffmpeg_exe(
|
||||
`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -lavfi "$palette" -loop $loop -y $fn`,
|
||||
)
|
||||
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -lavfi "$palette" -loop $loop -y $fn`)
|
||||
else
|
||||
# generate a colorpalette first so ffmpeg does not have to guess it
|
||||
ffmpeg_exe(
|
||||
`-v $verbose_level -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`,
|
||||
)
|
||||
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 -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -loop $loop -y $fn`)
|
||||
end
|
||||
else
|
||||
ffmpeg_exe(
|
||||
`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -vf format=yuv420p -loop $loop -y $fn`,
|
||||
)
|
||||
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -vf format=yuv420p -loop $loop -y $fn`)
|
||||
end
|
||||
|
||||
show_msg && @info("Saved animation to ", fn)
|
||||
AnimatedGif(fn)
|
||||
end
|
||||
|
||||
|
||||
|
||||
# write out html to view the gif
|
||||
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)) *
|
||||
"\" />"
|
||||
html = "<img src=\"data:image/gif;base64," * base64encode(read(agif.filename)) * "\" />"
|
||||
elseif ext in ("mov", "mp4","webm")
|
||||
mimetype = ext == "mov" ? "video/quicktime" : "video/$ext"
|
||||
html =
|
||||
"<video controls><source src=\"data:$mimetype;base64," *
|
||||
html = "<video controls><source src=\"data:$mimetype;base64," *
|
||||
base64encode(read(agif.filename)) *
|
||||
"\" type = \"$mimetype\"></video>"
|
||||
else
|
||||
@ -137,6 +125,7 @@ function Base.show(io::IO, ::MIME"text/html", agif::AnimatedGif)
|
||||
return nothing
|
||||
end
|
||||
|
||||
|
||||
# Only gifs can be shown via image/gif
|
||||
Base.showable(::MIME"image/gif", agif::AnimatedGif) = file_extension(agif.filename) == "gif"
|
||||
|
||||
@ -144,11 +133,12 @@ function Base.show(io::IO, ::MIME"image/gif", agif::AnimatedGif)
|
||||
open(fio-> write(io, fio), agif.filename)
|
||||
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
|
||||
@ -179,12 +169,8 @@ function _animate(forloop::Expr, args...; callgif = false)
|
||||
error("Unsupported animate filter: $args")
|
||||
end
|
||||
|
||||
push!(block.args, :(
|
||||
if $filterexpr
|
||||
Plots.frame($animsym)
|
||||
end
|
||||
))
|
||||
push!(block.args, :($countersym += 1))
|
||||
push!(block.args, :(if $filterexpr; Plots.frame($animsym); end))
|
||||
push!(block.args, :(global $countersym += 1))
|
||||
|
||||
# add a final call to `gif(anim)`?
|
||||
retval = callgif ? :(Plots.gif($animsym)) : animsym
|
||||
@ -193,9 +179,8 @@ function _animate(forloop::Expr, args...; callgif = false)
|
||||
esc(quote
|
||||
$freqassert # if filtering, check frequency is an Integer > 0
|
||||
$animsym = Plots.Animation() # init animation object
|
||||
let $countersym = 1 # init iteration counter
|
||||
global $countersym = 1 # init iteration counter
|
||||
$forloop # for loop, saving a frame after each iteration
|
||||
end
|
||||
$retval # return the animation object, or the gif
|
||||
end)
|
||||
end
|
||||
|
||||
@ -14,26 +14,24 @@ const _arg_desc = KW(
|
||||
: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).",
|
||||
:fillstyle => "Symbol. Style of the fill area. `nothing` (the default) means solid fill. Choose from :/, :\\, :|, :-, :+, :x",
|
||||
:markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.",
|
||||
:markeralpha => "Number in [0,1]. The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor.",
|
||||
:markersize => "Number or AbstractVector. Size (radius pixels) of the markers",
|
||||
:markersize => "Number or AbstractVector. Size (radius pixels) of the markers.",
|
||||
:markerstrokestyle => "Symbol. Style of the marker stroke (border). Choose from $(_allStyles)",
|
||||
:markerstrokewidth => "Number. Width of the marker stroke (border) in pixels",
|
||||
: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`",
|
||||
: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 (number of contours) or AbstractVector (contour values). Determines contour levels for a contour type.",
|
||||
:permute => "Tuple{Symbol,Symbol}. Permutes data and axis properties of the axes given in the tuple. E.g. (:x, :y).",
|
||||
:orientation => "Symbol. (deprecated) Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default).",
|
||||
: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)?",
|
||||
@ -44,7 +42,7 @@ const _arg_desc = KW(
|
||||
: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)",
|
||||
: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`.",
|
||||
@ -53,11 +51,9 @@ const _arg_desc = KW(
|
||||
:primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.",
|
||||
: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.",
|
||||
:z_order => "Symbol or Integer. :front (default), :back or index of position where 1 is farest in the background.",
|
||||
|
||||
# plot args
|
||||
:plot_title => "String. Title for the whole plot (not the subplots)",
|
||||
:plot_titlevspan => "Number in [0,1]. Vertical span of the whole plot title (fraction of the plot height)",
|
||||
: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.",
|
||||
@ -88,28 +84,26 @@ const _arg_desc = KW(
|
||||
: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.",
|
||||
:legend_background_color => "Color Type or `:match` (matches `:background_color_subplot`). Background color of the legend.",
|
||||
: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.",
|
||||
:legend_foreground_color => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
|
||||
: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_position => "Bool (show the legend?) or (x,y) tuple or Symbol (legend position) or angle or (angle,inout) tuple. Bottom left corner of legend is placed at (x,y). Symbol values: `:none`; `:best`; `:inline`; `:inside`; `:legend`; any valid combination of `:(outer ?)(top/bottom ?)(right/left ?)`, i.e.: `:top`, `:topright`, `:outerleft`, `:outerbottomright` ... (note: only some may be supported in each backend)",
|
||||
:legend_column => "Integer. Number of columns in the legend. `-1` stands for maximum number of colums (horizontal legend).",
|
||||
:legend_title_font => "Font. Font of the legend title.",
|
||||
:legend_font_family => "String or Symbol. Font family of legend entries.",
|
||||
:legend_font_pointsize => "Integer. Font pointsize of legend entries.",
|
||||
:legend_font_halign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center",
|
||||
:legend_font_valign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center",
|
||||
:legend_font_rotation => "Real. Font rotation of legend entries",
|
||||
:legend_font_color => "Color Type. Font color of legend entries",
|
||||
:legend_title => "String. Legend title.",
|
||||
:legend_title_font_family => "String or Symbol. Font family of the legend title.",
|
||||
:legend_title_font_pointsize => "Integer. Font pointsize the legend title.",
|
||||
:legend_title_font_halign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center",
|
||||
:legend_title_font_valign => "Symbol. Font vertical alignment of the legend title: :vcenter, :top, :bottom or :center",
|
||||
:legend_title_font_rotation => "Real. Font rotation of the legend title",
|
||||
:legend_title_font_color => "Color Type. Font color of the legend title",
|
||||
: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.",
|
||||
@ -119,15 +113,9 @@ const _arg_desc = KW(
|
||||
: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.",
|
||||
:legend_font => "Font. Font of legend items.",
|
||||
:legend_titlefont => "Font. Font of the legend title.",
|
||||
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String, PlotText (created with `text(args...)`), or a tuple of arguments to `text` (e.g., `(\"Label\", 8, :red, :top)`). Add one-off text annotations at the x,y coordinates.",
|
||||
: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.",
|
||||
:legendfont => "Font. Font of legend items.",
|
||||
:legendtitlefont => "Font. Font of the legend title.",
|
||||
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
|
||||
:projection => "Symbol or String. '3d' or 'polar'",
|
||||
:aspect_ratio => "Symbol (:equal or :none) or Number. Plot area is resized so that 1 y-unit is the same size as `aspect_ratio` x-units. With `:none`, images inherit aspect ratio of the plot area.",
|
||||
:margin => "Measure (multiply by `mm`, `px`, etc). Base for individual margins... not directly used. Specifies the extra padding around subplots.",
|
||||
@ -143,12 +131,7 @@ const _arg_desc = KW(
|
||||
# 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).
|
||||
""",
|
||||
: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.",
|
||||
@ -182,11 +165,8 @@ const _arg_desc = KW(
|
||||
: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`",
|
||||
: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 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.
|
||||
""",
|
||||
: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.",
|
||||
)
|
||||
|
||||
1149
src/args.jl
1149
src/args.jl
File diff suppressed because it is too large
Load Diff
471
src/axes.jl
471
src/axes.jl
@ -1,4 +1,5 @@
|
||||
|
||||
|
||||
# xaxis(args...; kw...) = Axis(:x, args...; kw...)
|
||||
# yaxis(args...; kw...) = Axis(:y, args...; kw...)
|
||||
# zaxis(args...; kw...) = Axis(:z, args...; kw...)
|
||||
@ -23,7 +24,7 @@ function Axis(sp::Subplot, letter::Symbol, args...; kw...)
|
||||
end
|
||||
|
||||
function get_axis(sp::Subplot, letter::Symbol)
|
||||
axissym = get_attr_symbol(letter, :axis)
|
||||
axissym = Symbol(letter, :axis)
|
||||
if haskey(sp.attr, axissym)
|
||||
sp.attr[axissym]
|
||||
else
|
||||
@ -35,45 +36,42 @@ function process_axis_arg!(plotattributes::AKW, arg, letter = "")
|
||||
T = typeof(arg)
|
||||
arg = get(_scaleAliases, arg, arg)
|
||||
if typeof(arg) <: Font
|
||||
plotattributes[get_attr_symbol(letter, :tickfont)] = arg
|
||||
plotattributes[get_attr_symbol(letter, :guidefont)] = arg
|
||||
plotattributes[Symbol(letter,:tickfont)] = arg
|
||||
plotattributes[Symbol(letter,:guidefont)] = arg
|
||||
|
||||
elseif arg in _allScales
|
||||
plotattributes[get_attr_symbol(letter, :scale)] = arg
|
||||
plotattributes[Symbol(letter,:scale)] = arg
|
||||
|
||||
elseif arg in (:flip, :invert, :inverted)
|
||||
plotattributes[get_attr_symbol(letter, :flip)] = true
|
||||
plotattributes[Symbol(letter,:flip)] = true
|
||||
|
||||
elseif T <: AbstractString
|
||||
plotattributes[get_attr_symbol(letter, :guide)] = arg
|
||||
plotattributes[Symbol(letter,:guide)] = arg
|
||||
|
||||
# xlims/ylims
|
||||
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
|
||||
sym = typeof(arg[1]) <: Number ? :lims : :ticks
|
||||
plotattributes[get_attr_symbol(letter, sym)] = arg
|
||||
plotattributes[Symbol(letter,sym)] = arg
|
||||
|
||||
# xticks/yticks
|
||||
elseif T <: AVec
|
||||
plotattributes[get_attr_symbol(letter, :ticks)] = arg
|
||||
plotattributes[Symbol(letter,:ticks)] = arg
|
||||
|
||||
elseif arg === nothing
|
||||
plotattributes[get_attr_symbol(letter, :ticks)] = []
|
||||
plotattributes[Symbol(letter,:ticks)] = []
|
||||
|
||||
elseif T <: Bool || arg in _allShowaxisArgs
|
||||
plotattributes[get_attr_symbol(letter, :showaxis)] = showaxis(arg, letter)
|
||||
plotattributes[Symbol(letter,:showaxis)] = showaxis(arg, letter)
|
||||
|
||||
elseif typeof(arg) <: Number
|
||||
plotattributes[get_attr_symbol(letter, :rotation)] = arg
|
||||
plotattributes[Symbol(letter,:rotation)] = arg
|
||||
|
||||
elseif typeof(arg) <: Function
|
||||
plotattributes[get_attr_symbol(letter, :formatter)] = arg
|
||||
plotattributes[Symbol(letter,:formatter)] = arg
|
||||
|
||||
elseif !handleColors!(
|
||||
plotattributes,
|
||||
arg,
|
||||
get_attr_symbol(letter, :foreground_color_axis),
|
||||
)
|
||||
elseif !handleColors!(plotattributes, arg, Symbol(letter, :foreground_color_axis))
|
||||
@warn("Skipped $(letter)axis arg $arg")
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@ -124,8 +122,11 @@ Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.plotattributes, v,
|
||||
Base.haskey(axis::Axis, k::Symbol) = haskey(axis.plotattributes, k)
|
||||
ignorenan_extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax))
|
||||
|
||||
const _label_func =
|
||||
Dict{Symbol,Function}(:log10 => x -> "10^$x", :log2 => x -> "2^$x", :ln => x -> "e^$x")
|
||||
const _label_func = Dict{Symbol,Function}(
|
||||
:log10 => x -> "10^$x",
|
||||
:log2 => x -> "2^$x",
|
||||
:ln => x -> "e^$x",
|
||||
)
|
||||
labelfunc(scale::Symbol, backend::AbstractBackend) = get(_label_func, scale, string)
|
||||
|
||||
const _label_func_tex = Dict{Symbol,Function}(
|
||||
@ -135,6 +136,7 @@ const _label_func_tex = Dict{Symbol,Function}(
|
||||
)
|
||||
labelfunc_tex(scale::Symbol) = get(_label_func_tex, scale, convert_sci_unicode)
|
||||
|
||||
|
||||
function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
||||
amin, amax = alims
|
||||
|
||||
@ -156,8 +158,8 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
||||
# are converted to 'DateTime integers' (actually floats) before
|
||||
# being passed to optimize_datetime_ticks.
|
||||
# (convert(Int, convert(DateTime, convert(Date, i))) == 87600000*i)
|
||||
ticks, labels =
|
||||
optimize_datetime_ticks(864e5 * amin, 864e5 * amax; k_min = 2, k_max = 4)
|
||||
ticks, labels = optimize_datetime_ticks(864e5 * amin, 864e5 * amax;
|
||||
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
|
||||
@ -170,9 +172,8 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
||||
scaled_ticks = optimize_ticks(
|
||||
sf(amin),
|
||||
sf(amax);
|
||||
k_min = scale ∈ _logScales ? 2 : 4, # minimum number of ticks
|
||||
k_min = 4, # minimum number of ticks
|
||||
k_max = 8, # maximum number of ticks
|
||||
scale = scale,
|
||||
)[1]
|
||||
elseif typeof(ticks) <: Int
|
||||
scaled_ticks, viewmin, viewmax = optimize_ticks(
|
||||
@ -184,7 +185,6 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
||||
# `strict_span = false` rewards cases where the span of the
|
||||
# chosen ticks is not too much bigger than amin - amax:
|
||||
strict_span = false,
|
||||
scale = scale,
|
||||
)
|
||||
# axis[:lims] = map(RecipesPipeline.inverse_scale_func(scale), (viewmin, viewmax))
|
||||
else
|
||||
@ -196,10 +196,7 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
||||
if formatter in (:auto, :plain, :scientific, :engineering)
|
||||
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, formatter))
|
||||
elseif formatter == :latex
|
||||
map(
|
||||
x -> string("\$", replace(convert_sci_unicode(x), '×' => "\\times"), "\$"),
|
||||
Showoff.showoff(unscaled_ticks, :auto),
|
||||
)
|
||||
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)
|
||||
@ -224,15 +221,9 @@ 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)
|
||||
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)
|
||||
else
|
||||
cvals = axis[:continuous_values]
|
||||
alims = axis_limits(sp, axis[:letter])
|
||||
@ -244,67 +235,7 @@ function get_ticks(sp::Subplot, axis::Axis; update = true)
|
||||
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[get_attr_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}
|
||||
function get_ticks(ticks::Symbol, cvals::T, dvals, args...) where T
|
||||
if ticks === :none
|
||||
return T[], String[]
|
||||
elseif !isempty(dvals)
|
||||
@ -330,64 +261,40 @@ function get_ticks(ticks::Int, dvals, cvals, args...)
|
||||
end
|
||||
end
|
||||
get_ticks(ticks::NTuple{2, Any}, args...) = ticks
|
||||
get_ticks(::Nothing, cvals::T, args...) where {T} = T[], String[]
|
||||
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")
|
||||
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)
|
||||
_transform_ticks(ticks::AbstractArray{T}) where T <: Dates.TimeType = Dates.value.(ticks)
|
||||
_transform_ticks(ticks::NTuple{2, Any}) = (_transform_ticks(ticks[1]), ticks[2])
|
||||
|
||||
function get_minor_ticks(sp, axis, ticks)
|
||||
axis[:minorticks] ∈ (:none, nothing, false) && !axis[:minorgrid] && return nothing
|
||||
axis[:minorticks] in (:none, nothing, false) && !axis[:minorgrid] && return nothing
|
||||
ticks = ticks[1]
|
||||
length(ticks) < 2 && return nothing
|
||||
|
||||
amin, amax = axis_limits(sp, axis[:letter])
|
||||
scale = axis[:scale]
|
||||
log_scaled = scale ∈ _logScales
|
||||
base = get(_logScaleBases, scale, nothing)
|
||||
|
||||
# add one phantom tick either side of the ticks to ensure minor ticks extend to the axis limits
|
||||
if log_scaled
|
||||
sub = round(Int, log(base, ticks[2] / ticks[1]))
|
||||
ticks = [ticks[1] / base; ticks; ticks[end] * base]
|
||||
#Add one phantom tick either side of the ticks to ensure minor ticks extend to the axis limits
|
||||
if length(ticks) > 2
|
||||
ratio = (ticks[3] - ticks[2])/(ticks[2] - ticks[1])
|
||||
elseif axis[:scale] in (:none, :identity)
|
||||
ratio = 1
|
||||
else
|
||||
sub = 1 # unused
|
||||
ratio = length(ticks) > 2 ? (ticks[3] - ticks[2]) / (ticks[2] - ticks[1]) : 1
|
||||
return nothing
|
||||
end
|
||||
first_step = ticks[2] - ticks[1]
|
||||
last_step = ticks[end] - ticks[end-1]
|
||||
ticks = [ticks[1] - first_step/ratio; ticks; ticks[end] + last_step*ratio]
|
||||
end
|
||||
|
||||
# default to 9 intervals between major ticks for log10 scale and 5 intervals otherwise
|
||||
n_default = (scale == :log10) ? 9 : 5
|
||||
n =
|
||||
typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 ? axis[:minorticks] :
|
||||
n_default
|
||||
|
||||
#Default to 5 intervals between major ticks
|
||||
n = typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 ? axis[:minorticks] : 5
|
||||
minorticks = typeof(ticks[1])[]
|
||||
for (i,hi) in enumerate(ticks[2:end])
|
||||
lo = ticks[i]
|
||||
if isfinite(lo) && isfinite(hi) && hi > lo
|
||||
if log_scaled
|
||||
for e in 1:sub
|
||||
lo_ = lo * base^(e - 1)
|
||||
hi_ = lo_ * base
|
||||
step = (hi_ - lo_) / n
|
||||
append!(
|
||||
minorticks,
|
||||
collect(
|
||||
(lo_ + (e > 1 ? 0 : step)):step:(hi_ - (e < sub ? 0 :
|
||||
step / 2)),
|
||||
),
|
||||
)
|
||||
end
|
||||
else
|
||||
step = (hi - lo) / n
|
||||
append!(minorticks, collect((lo + step):step:(hi - step / 2)))
|
||||
end
|
||||
append!(minorticks,collect(lo + (hi-lo)/n :(hi-lo)/n: hi - (hi-lo)/2n))
|
||||
end
|
||||
end
|
||||
minorticks[amin .<= minorticks .<= amax]
|
||||
@ -395,15 +302,17 @@ end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
function reset_extrema!(sp::Subplot)
|
||||
for asym in (:x,:y,:z)
|
||||
sp[get_attr_symbol(asym, :axis)][:extrema] = Extrema()
|
||||
sp[Symbol(asym,:axis)][:extrema] = Extrema()
|
||||
end
|
||||
for series in sp.series_list
|
||||
expand_extrema!(sp, series.plotattributes)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function expand_extrema!(ex::Extrema, v::Number)
|
||||
ex.emin = isfinite(v) ? min(v, ex.emin) : ex.emin
|
||||
ex.emax = isfinite(v) ? max(v, ex.emax) : ex.emax
|
||||
@ -418,13 +327,14 @@ end
|
||||
expand_extrema!(axis::Axis, ::Nothing) = axis[:extrema]
|
||||
expand_extrema!(axis::Axis, ::Bool) = axis[:extrema]
|
||||
|
||||
|
||||
function expand_extrema!(axis::Axis, v::Tuple{MIN,MAX}) where {MIN<:Number,MAX<:Number}
|
||||
ex = axis[:extrema]
|
||||
ex.emin = isfinite(v[1]) ? min(v[1], ex.emin) : ex.emin
|
||||
ex.emax = isfinite(v[2]) ? max(v[2], ex.emax) : ex.emax
|
||||
ex
|
||||
end
|
||||
function expand_extrema!(axis::Axis, v::AVec{N}) where {N<:Number}
|
||||
function expand_extrema!(axis::Axis, v::AVec{N}) where N<:Number
|
||||
ex = axis[:extrema]
|
||||
for vi in v
|
||||
expand_extrema!(ex, vi)
|
||||
@ -432,6 +342,7 @@ function expand_extrema!(axis::Axis, v::AVec{N}) where {N<:Number}
|
||||
ex
|
||||
end
|
||||
|
||||
|
||||
function expand_extrema!(sp::Subplot, plotattributes::AKW)
|
||||
vert = isvertical(plotattributes)
|
||||
|
||||
@ -442,22 +353,16 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
|
||||
else
|
||||
letter == :x ? :y : letter == :y ? :x : :z
|
||||
end]
|
||||
if (
|
||||
letter != :z &&
|
||||
plotattributes[:seriestype] == :straightline &&
|
||||
any(series[:seriestype] != :straightline for series in series_list(sp)) &&
|
||||
data[1] != data[2]
|
||||
)
|
||||
if letter != :z && plotattributes[:seriestype] == :straightline && any(series[:seriestype] != :straightline for series in series_list(sp)) && data[1] != data[2]
|
||||
data = [NaN]
|
||||
end
|
||||
axis = sp[get_attr_symbol(letter, :axis)]
|
||||
axis = sp[Symbol(letter, "axis")]
|
||||
|
||||
if isa(data, Volume)
|
||||
expand_extrema!(sp[:xaxis], data.x_extents)
|
||||
expand_extrema!(sp[:yaxis], data.y_extents)
|
||||
expand_extrema!(sp[:zaxis], data.z_extents)
|
||||
elseif eltype(data) <: Number ||
|
||||
(isa(data, Surface) && all(di -> isa(di, Number), data.surf))
|
||||
elseif eltype(data) <: Number || (isa(data, Surface) && all(di -> isa(di, Number), data.surf))
|
||||
if !(eltype(data) <: Number)
|
||||
# huh... must have been a mis-typed surface? lets swap it out
|
||||
data = plotattributes[letter] = Surface(Matrix{Float64}(data.surf))
|
||||
@ -467,9 +372,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
|
||||
# TODO: need more here... gotta track the discrete reference value
|
||||
# as well as any coord offset (think of boxplot shape coords... they all
|
||||
# correspond to the same x-value)
|
||||
plotattributes[letter],
|
||||
plotattributes[get_attr_symbol(letter, :(_discrete_indices))] =
|
||||
discrete_value!(axis, data)
|
||||
plotattributes[letter], plotattributes[Symbol(letter,"_discrete_indices")] = discrete_value!(axis, data)
|
||||
expand_extrema!(axis, plotattributes[letter])
|
||||
end
|
||||
end
|
||||
@ -503,11 +406,9 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
|
||||
|
||||
bw = plotattributes[:bar_width]
|
||||
if bw === nothing
|
||||
bw =
|
||||
plotattributes[:bar_width] =
|
||||
_bar_width * ignorenan_minimum(filter(x -> x > 0, diff(sort(data))))
|
||||
bw = plotattributes[:bar_width] = _bar_width * ignorenan_minimum(filter(x->x>0,diff(sort(data))))
|
||||
end
|
||||
axis = sp.attr[get_attr_symbol(dsym, :axis)]
|
||||
axis = sp.attr[Symbol(dsym, :axis)]
|
||||
expand_extrema!(axis, ignorenan_maximum(data) + 0.5maximum(bw))
|
||||
expand_extrema!(axis, ignorenan_minimum(data) - 0.5minimum(bw))
|
||||
end
|
||||
@ -516,8 +417,8 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
|
||||
if plotattributes[:seriestype] == :heatmap
|
||||
for letter in (:x, :y)
|
||||
data = plotattributes[letter]
|
||||
axis = sp[get_attr_symbol(letter, :axis)]
|
||||
scale = get(plotattributes, get_attr_symbol(letter, :scale), :identity)
|
||||
axis = sp[Symbol(letter, "axis")]
|
||||
scale = get(plotattributes, Symbol(letter, "scale"), :identity)
|
||||
expand_extrema!(axis, heatmap_edges(data, scale))
|
||||
end
|
||||
end
|
||||
@ -540,81 +441,45 @@ 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, :stepmid, :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
|
||||
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
|
||||
return true
|
||||
should_widen = true
|
||||
end
|
||||
end
|
||||
end
|
||||
false
|
||||
end
|
||||
should_widen
|
||||
end
|
||||
|
||||
function round_limits(amin, amax, scale)
|
||||
base = get(_logScaleBases, scale, 10.0)
|
||||
factor = base^(1 - round(log(base, amax - amin)))
|
||||
amin = floor(amin * factor) / factor
|
||||
amax = ceil(amax * factor) / factor
|
||||
function round_limits(amin,amax)
|
||||
scale = 10^(1-round(log10(amax - amin)))
|
||||
amin = floor(amin*scale)/scale
|
||||
amax = ceil(amax*scale)/scale
|
||||
amin, amax
|
||||
end
|
||||
|
||||
# using the axis extrema and limit overrides, return the min/max value for this axis
|
||||
function axis_limits(
|
||||
sp,
|
||||
letter,
|
||||
should_widen = default_should_widen(sp[get_attr_symbol(letter, :axis)]),
|
||||
consider_aspect = true,
|
||||
)
|
||||
axis = sp[get_attr_symbol(letter, :axis)]
|
||||
function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(letter, :axis)]), consider_aspect = true)
|
||||
axis = sp[Symbol(letter, :axis)]
|
||||
ex = axis[:extrema]
|
||||
amin, amax = ex.emin, ex.emax
|
||||
lims = axis[:lims]
|
||||
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)
|
||||
if lmin != :auto && isfinite(lmin)
|
||||
amin = lmin
|
||||
end
|
||||
if lmax == :auto
|
||||
elseif isfinite(lmax)
|
||||
if lmax != :auto && isfinite(lmax)
|
||||
amax = lmax
|
||||
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
|
||||
@ -630,20 +495,15 @@ function axis_limits(
|
||||
else
|
||||
amin, amax
|
||||
end
|
||||
elseif should_widen
|
||||
elseif should_widen && axis[:widen]
|
||||
widen(amin, amax, axis[:scale])
|
||||
elseif lims == :round
|
||||
round_limits(amin, amax, axis[:scale])
|
||||
round_limits(amin,amax)
|
||||
else
|
||||
amin, amax
|
||||
end
|
||||
|
||||
if (
|
||||
!has_user_lims &&
|
||||
consider_aspect &&
|
||||
letter in (:x, :y) &&
|
||||
!(sp[:aspect_ratio] in (:none, :auto) || RecipesPipeline.is3d(:sp))
|
||||
)
|
||||
if !has_user_lims && consider_aspect && letter in (:x, :y) && !(sp[:aspect_ratio] in (:none, :auto) || RecipesPipeline.is3d(:sp))
|
||||
aspect_ratio = isa(sp[:aspect_ratio], Number) ? sp[:aspect_ratio] : 1
|
||||
plot_ratio = height(plotarea(sp)) / width(plotarea(sp))
|
||||
dist = amax - amin
|
||||
@ -675,17 +535,9 @@ end
|
||||
# these methods track the discrete (categorical) values which correspond to axis continuous values (cv)
|
||||
# whenever we have discrete values, we automatically set the ticks to match.
|
||||
# we return (continuous_value, discrete_index)
|
||||
function discrete_value!(plotattributes, letter::Symbol, dv)
|
||||
l = if plotattributes[:permute] !== :none
|
||||
only(filter(!=(letter), plotattributes[:permute]))
|
||||
else
|
||||
letter
|
||||
end
|
||||
discrete_value!(plotattributes[:subplot][get_attr_symbol(l, :axis)], dv)
|
||||
end
|
||||
|
||||
function discrete_value!(axis::Axis, dv)
|
||||
cv_idx = get(axis[:discrete_map], dv, -1)
|
||||
# @show axis[:discrete_map], axis[:discrete_values], dv
|
||||
if cv_idx == -1
|
||||
ex = axis[:extrema]
|
||||
cv = NaNMath.max(0.5, ex.emax + 1.0)
|
||||
@ -737,10 +589,10 @@ 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 = get_attr_symbol(letter, :axis)
|
||||
asym = Symbol(letter, :axis)
|
||||
isy = letter === :y
|
||||
oletter = isy ? :x : :y
|
||||
oasym = get_attr_symbol(oletter, :axis)
|
||||
oasym = Symbol(oletter, :axis)
|
||||
|
||||
# get axis objects, ticks and minor ticks
|
||||
ax, oax = sp[asym], sp[oasym]
|
||||
@ -766,11 +618,7 @@ function axis_drawing_info(sp, letter)
|
||||
if sp[:framestyle] != :grid
|
||||
push!(segments, reverse_if((amin, oa1), isy), reverse_if((amax, oa1), isy))
|
||||
# don't show the 0 tick label for the origin framestyle
|
||||
if (
|
||||
sp[:framestyle] == :origin &&
|
||||
!(ticks in (:none, nothing, false)) &&
|
||||
length(ticks) > 1
|
||||
)
|
||||
if sp[:framestyle] == :origin && !(ticks in (:none, nothing, false)) && length(ticks) > 1
|
||||
i = findfirst(==(0), ticks[1])
|
||||
if i !== nothing
|
||||
deleteat!(ticks[1], i)
|
||||
@ -786,64 +634,62 @@ function axis_drawing_info(sp, letter)
|
||||
)
|
||||
end
|
||||
end
|
||||
if ax[:ticks] ∉ (:none, nothing, false)
|
||||
if !(ax[:ticks] in (:none, nothing, false))
|
||||
f = RecipesPipeline.scale_func(oax[:scale])
|
||||
invf = RecipesPipeline.inverse_scale_func(oax[:scale])
|
||||
|
||||
add_major_or_minor_segments(ticks, grid, segments, factor, cond) = begin
|
||||
ticks === nothing && return
|
||||
if cond
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + factor * (f(oamax) - f(oamin)))
|
||||
t = invf(f(0) + 0.012 * (f(oamax) - f(oamin)))
|
||||
(-t, t)
|
||||
else
|
||||
ticks_in = ax[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(oa1) + factor * (f(oa2) - f(oa1)) * ticks_in)
|
||||
t = invf(f(oa1) + 0.012 * (f(oa2) - f(oa1)) * ticks_in)
|
||||
(oa1, t)
|
||||
end
|
||||
end
|
||||
|
||||
for tick in ticks
|
||||
if ax[:showaxis] && cond
|
||||
for tick in ticks[1]
|
||||
if ax[:showaxis]
|
||||
push!(
|
||||
tick_segments,
|
||||
reverse_if((tick, tick_start), isy),
|
||||
reverse_if((tick, tick_stop), isy),
|
||||
)
|
||||
end
|
||||
if grid
|
||||
if ax[:grid]
|
||||
push!(
|
||||
segments,
|
||||
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
|
||||
|
||||
ax_length = letter === :x ? height(sp.plotarea).value : width(sp.plotarea).value
|
||||
|
||||
# add major grid segments
|
||||
add_major_or_minor_segments(
|
||||
ticks[1],
|
||||
ax[:grid],
|
||||
grid_segments,
|
||||
1.2 / ax_length,
|
||||
ax[:tick_direction] !== :none,
|
||||
for tick in minor_ticks
|
||||
if ax[:showaxis]
|
||||
push!(
|
||||
tick_segments,
|
||||
reverse_if((tick, tick_start), isy),
|
||||
reverse_if((tick, tick_stop), isy),
|
||||
)
|
||||
|
||||
# add minor grid segments
|
||||
if ax[:minorticks] ∉ (:none, nothing, false) || ax[:minorgrid]
|
||||
add_major_or_minor_segments(
|
||||
minor_ticks,
|
||||
ax[:minorgrid],
|
||||
end
|
||||
if ax[:minorgrid]
|
||||
push!(
|
||||
minorgrid_segments,
|
||||
0.6 / ax_length,
|
||||
true,
|
||||
reverse_if((tick, oamin), isy),
|
||||
reverse_if((tick, oamax), isy),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return (
|
||||
ticks = ticks,
|
||||
@ -851,7 +697,7 @@ function axis_drawing_info(sp, letter)
|
||||
tick_segments = tick_segments,
|
||||
grid_segments = grid_segments,
|
||||
minorgrid_segments = minorgrid_segments,
|
||||
border_segments = border_segments,
|
||||
border_segments = border_segments
|
||||
)
|
||||
end
|
||||
|
||||
@ -869,9 +715,9 @@ 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[get_attr_symbol(letter, :axis)]
|
||||
nax = sp[get_attr_symbol(near_letter, :axis)]
|
||||
fax = sp[get_attr_symbol(far_letter, :axis)]
|
||||
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)
|
||||
@ -887,6 +733,7 @@ function axis_drawing_info_3d(sp, letter)
|
||||
minorgrid_segments = Segments(3)
|
||||
border_segments = Segments(3)
|
||||
|
||||
|
||||
if sp[:framestyle] != :none# && letter === :x
|
||||
na0, na1 = if sp[:framestyle] in (:origin, :zerolines)
|
||||
0, 0
|
||||
@ -907,11 +754,7 @@ function axis_drawing_info_3d(sp, letter)
|
||||
sort_3d_axes(amax, na0, fa0, letter),
|
||||
)
|
||||
# don't show the 0 tick label for the origin framestyle
|
||||
if (
|
||||
sp[:framestyle] == :origin &&
|
||||
!(ticks in (:none, nothing, false)) &&
|
||||
length(ticks) > 1
|
||||
)
|
||||
if sp[:framestyle] == :origin && !(ticks in (:none, nothing, false)) && length(ticks) > 1
|
||||
i0 = findfirst(==(0), ticks[1])
|
||||
if i0 !== nothing
|
||||
deleteat!(ticks[1], i0)
|
||||
@ -927,70 +770,72 @@ function axis_drawing_info_3d(sp, letter)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
if ax[:ticks] ∉ (:none, nothing, false)
|
||||
# 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])
|
||||
ga0, ga1 =
|
||||
sp[:framestyle] in (:origin, :zerolines) ? (namin, namax) : (na0, na1)
|
||||
|
||||
add_major_or_minor_segments(ticks, grid, segments, factor, cond) = begin
|
||||
ticks === nothing && return
|
||||
if cond
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + factor * (f(namax) - f(namin)))
|
||||
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) + factor * (f(na1) - f(na0)) * ticks_in)
|
||||
t = invf(f(na0) + 0.012 * (f(na1) - f(na0)) * ticks_in)
|
||||
(na0, t)
|
||||
end
|
||||
end
|
||||
|
||||
for tick in ticks
|
||||
if ax[:showaxis] && cond
|
||||
ga0, ga1 = sp[:framestyle] in (:origin, :zerolines) ? (namin, namax) : (na0, na1)
|
||||
for tick in ticks[1]
|
||||
if ax[:showaxis]
|
||||
push!(
|
||||
tick_segments,
|
||||
sort_3d_axes(tick, tick_start, fa0, letter),
|
||||
sort_3d_axes(tick, tick_stop, fa0, letter),
|
||||
)
|
||||
end
|
||||
if grid
|
||||
fa0_, fa1_ = reverse_if((fa0, fa1), ax[:mirror])
|
||||
ga0_, ga1_ = reverse_if((ga0, ga1), ax[:mirror])
|
||||
if ax[:grid]
|
||||
push!(
|
||||
segments,
|
||||
sort_3d_axes(tick, ga0_, fa0_, letter),
|
||||
sort_3d_axes(tick, ga1_, fa0_, letter),
|
||||
)
|
||||
push!(
|
||||
segments,
|
||||
sort_3d_axes(tick, ga1_, fa0_, letter),
|
||||
sort_3d_axes(tick, ga1_, fa1_, letter),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# add major grid segments
|
||||
add_major_or_minor_segments(
|
||||
ticks[1],
|
||||
ax[:grid],
|
||||
grid_segments,
|
||||
0.012,
|
||||
ax[:tick_direction] !== :none,
|
||||
sort_3d_axes(tick, ga0, fa0, letter),
|
||||
sort_3d_axes(tick, ga1, fa0, letter),
|
||||
)
|
||||
push!(
|
||||
grid_segments,
|
||||
sort_3d_axes(tick, ga1, fa0, letter),
|
||||
sort_3d_axes(tick, ga1, fa1, letter),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# add minor grid segments
|
||||
if ax[:minorticks] ∉ (:none, nothing, false) || ax[:minorgrid]
|
||||
add_major_or_minor_segments(
|
||||
minor_ticks,
|
||||
ax[:minorgrid],
|
||||
minorgrid_segments,
|
||||
0.006,
|
||||
true,
|
||||
if !(ax[:minorticks] in (:none, nothing, false)) || ax[:minorgrid]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.006 * (f(namax) - f(namin)))
|
||||
(-t, t)
|
||||
else
|
||||
t = invf(f(na0) + 0.006 * (f(na1) - f(na0)) * ticks_in)
|
||||
(na0, t)
|
||||
end
|
||||
for tick in minor_ticks
|
||||
if ax[:showaxis]
|
||||
push!(
|
||||
tick_segments,
|
||||
sort_3d_axes(tick, tick_start, fa0, letter),
|
||||
sort_3d_axes(tick, tick_stop, fa0, letter),
|
||||
)
|
||||
end
|
||||
if ax[:minorgrid]
|
||||
push!(
|
||||
minorgrid_segments,
|
||||
sort_3d_axes(tick, ga0, fa0, letter),
|
||||
sort_3d_axes(tick, ga1, fa0, letter),
|
||||
)
|
||||
push!(
|
||||
minorgrid_segments,
|
||||
sort_3d_axes(tick, ga1, fa0, letter),
|
||||
sort_3d_axes(tick, ga1, fa1, letter),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1000,7 +845,7 @@ function axis_drawing_info_3d(sp, letter)
|
||||
tick_segments = tick_segments,
|
||||
grid_segments = grid_segments,
|
||||
minorgrid_segments = minorgrid_segments,
|
||||
border_segments = border_segments,
|
||||
border_segments = border_segments
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
825
src/backends.jl
825
src/backends.jl
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
# significant contributions by: @pkofod
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
# COV_EXCL_START
|
||||
|
||||
const _pgfplots_linestyles = KW(
|
||||
:solid => "solid",
|
||||
:dash => "dashed",
|
||||
@ -27,7 +27,7 @@ const _pgfplots_markers = KW(
|
||||
:diamond => "diamond*",
|
||||
:pentagon => "pentagon*",
|
||||
:hline => "-",
|
||||
:vline => "|",
|
||||
:vline => "|"
|
||||
)
|
||||
|
||||
const _pgfplots_legend_pos = KW(
|
||||
@ -38,6 +38,7 @@ const _pgfplots_legend_pos = KW(
|
||||
:outertopright => "outer north east",
|
||||
)
|
||||
|
||||
|
||||
const _pgf_series_extrastyle = KW(
|
||||
:steppre => "const plot mark right",
|
||||
:stepmid => "const plot mark mid",
|
||||
@ -49,7 +50,11 @@ const _pgf_series_extrastyle = KW(
|
||||
|
||||
# PGFPlots uses the anchors to define orientations for example to align left
|
||||
# one needs to use the right edge as anchor
|
||||
const _pgf_annotation_halign = KW(:center => "", :left => "right", :right => "left")
|
||||
const _pgf_annotation_halign = KW(
|
||||
:center => "",
|
||||
:left => "right",
|
||||
:right => "left"
|
||||
)
|
||||
|
||||
const _pgf_framestyles = [:box, :axes, :origin, :zerolines, :grid, :none]
|
||||
const _pgf_framestyle_defaults = Dict(:semi => :box)
|
||||
@ -58,9 +63,7 @@ function pgf_framestyle(style::Symbol)
|
||||
return style
|
||||
else
|
||||
default_style = get(_pgf_framestyle_defaults, style, :axes)
|
||||
@warn(
|
||||
"Framestyle :$style is not (yet) supported by the PGFPlots backend. :$default_style was cosen instead."
|
||||
)
|
||||
@warn("Framestyle :$style is not (yet) supported by the PGFPlots backend. :$default_style was cosen instead.")
|
||||
default_style
|
||||
end
|
||||
end
|
||||
@ -123,15 +126,8 @@ end
|
||||
|
||||
function pgf_marker(plotattributes, i = 1)
|
||||
shape = _cycle(plotattributes[:markershape], i)
|
||||
cstr, a = pgf_color(
|
||||
plot_color(get_markercolor(plotattributes, i), get_markeralpha(plotattributes, i)),
|
||||
)
|
||||
cstr_stroke, a_stroke = pgf_color(
|
||||
plot_color(
|
||||
get_markerstrokecolor(plotattributes, i),
|
||||
get_markerstrokealpha(plotattributes, i),
|
||||
),
|
||||
)
|
||||
cstr, a = pgf_color(plot_color(get_markercolor(plotattributes, i), get_markeralpha(plotattributes, i)))
|
||||
cstr_stroke, a_stroke = pgf_color(plot_color(get_markerstrokecolor(plotattributes, i), get_markerstrokealpha(plotattributes, i)))
|
||||
return string(
|
||||
"mark = $(get(_pgfplots_markers, shape, "*")),\n",
|
||||
"mark size = $(pgf_thickness_scaling(plotattributes) * 0.5 * _cycle(plotattributes[:markersize], i)),\n",
|
||||
@ -142,7 +138,7 @@ function pgf_marker(plotattributes, i = 1)
|
||||
line width = $(pgf_thickness_scaling(plotattributes) * _cycle(plotattributes[:markerstrokewidth], i)),
|
||||
rotate = $(shape == :dtriangle ? 180 : 0),
|
||||
$(get(_pgfplots_linestyles, _cycle(plotattributes[:markerstrokestyle], i), "solid"))
|
||||
}",
|
||||
}"
|
||||
)
|
||||
end
|
||||
|
||||
@ -150,20 +146,14 @@ function pgf_add_annotation!(o, x, y, val, thickness_scaling = 1)
|
||||
# Construct the style string.
|
||||
# Currently supports color and orientation
|
||||
cstr,a = pgf_color(val.font.color)
|
||||
push!(
|
||||
o,
|
||||
PGFPlots.Plots.Node(
|
||||
val.str, # Annotation Text
|
||||
x,
|
||||
y,
|
||||
push!(o, PGFPlots.Plots.Node(val.str, # Annotation Text
|
||||
x, y,
|
||||
style="""
|
||||
$(get(_pgf_annotation_halign,val.font.halign,"")),
|
||||
color=$cstr, draw opacity=$(convert(Float16,a)),
|
||||
rotate=$(val.font.rotation),
|
||||
font=$(pgf_font(val.font.pointsize, thickness_scaling))
|
||||
""",
|
||||
),
|
||||
)
|
||||
"""))
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
@ -227,7 +217,7 @@ function pgf_series(sp::Subplot, series::Series)
|
||||
end
|
||||
|
||||
# add to legend?
|
||||
if i == 1 && sp[:legend_position] != :none && should_add_to_legend(series)
|
||||
if i == 1 && sp[:legend] != :none && should_add_to_legend(series)
|
||||
if plotattributes[:fillrange] !== nothing
|
||||
push!(style, "forget plot")
|
||||
push!(series_collection, pgf_fill_legend_hack(plotattributes, args))
|
||||
@ -251,15 +241,7 @@ function pgf_series(sp::Subplot, series::Series)
|
||||
|
||||
# add fillrange
|
||||
if series[:fillrange] !== nothing && st != :shape
|
||||
push!(
|
||||
series_collection,
|
||||
pgf_fillrange_series(
|
||||
series,
|
||||
i,
|
||||
_cycle(series[:fillrange], rng),
|
||||
seg_args...,
|
||||
),
|
||||
)
|
||||
push!(series_collection, pgf_fillrange_series(series, i, _cycle(series[:fillrange], rng), seg_args...))
|
||||
end
|
||||
|
||||
# build/return the series object
|
||||
@ -331,7 +313,7 @@ end
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function pgf_axis(sp::Subplot, letter)
|
||||
axis = sp[get_attr_symbol(letter, :axis)]
|
||||
axis = sp[Symbol(letter,:axis)]
|
||||
style = []
|
||||
kw = KW()
|
||||
|
||||
@ -342,7 +324,7 @@ function pgf_axis(sp::Subplot, letter)
|
||||
framestyle = pgf_framestyle(sp[:framestyle])
|
||||
|
||||
# axis guide
|
||||
kw[get_attr_symbol(letter, :label)] = axis[:guide]
|
||||
kw[Symbol(letter,:label)] = axis[:guide]
|
||||
|
||||
# axis label position
|
||||
labelpos = ""
|
||||
@ -354,23 +336,7 @@ function pgf_axis(sp::Subplot, letter)
|
||||
|
||||
# Add label font
|
||||
cstr, α = pgf_color(plot_color(axis[:guidefontcolor]))
|
||||
push!(
|
||||
style,
|
||||
string(
|
||||
letter,
|
||||
"label style = {",
|
||||
labelpos,
|
||||
"font = ",
|
||||
pgf_font(axis[:guidefontsize], pgf_thickness_scaling(sp)),
|
||||
", color = ",
|
||||
cstr,
|
||||
", draw opacity = ",
|
||||
α,
|
||||
", rotate = ",
|
||||
axis[:guidefontrotation],
|
||||
"}",
|
||||
),
|
||||
)
|
||||
push!(style, string(letter, "label style = {", labelpos ,"font = ", pgf_font(axis[:guidefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", axis[:guidefontrotation], "}"))
|
||||
|
||||
# flip/reverse?
|
||||
axis[:flip] && push!(style, "$letter dir=reverse")
|
||||
@ -378,7 +344,7 @@ function pgf_axis(sp::Subplot, letter)
|
||||
# scale
|
||||
scale = axis[:scale]
|
||||
if scale in (:log2, :ln, :log10)
|
||||
kw[get_attr_symbol(letter, :mode)] = "log"
|
||||
kw[Symbol(letter,:mode)] = "log"
|
||||
scale == :ln || push!(style, "log basis $letter=$(scale == :log2 ? 2 : 10)")
|
||||
end
|
||||
|
||||
@ -397,19 +363,15 @@ function pgf_axis(sp::Subplot, letter)
|
||||
# limits
|
||||
# TODO: support zlims
|
||||
if letter != :z
|
||||
lims =
|
||||
ispolar(sp) && letter == :x ? rad2deg.(axis_limits(sp, :x)) :
|
||||
axis_limits(sp, letter)
|
||||
kw[get_attr_symbol(letter, :min)] = lims[1]
|
||||
kw[get_attr_symbol(letter, :max)] = lims[2]
|
||||
lims = ispolar(sp) && letter == :x ? rad2deg.(axis_limits(sp, :x)) : axis_limits(sp, letter)
|
||||
kw[Symbol(letter,:min)] = lims[1]
|
||||
kw[Symbol(letter,:max)] = lims[2]
|
||||
end
|
||||
|
||||
if !(axis[:ticks] in (nothing, false, :none, :native)) && framestyle != :none
|
||||
ticks = get_ticks(sp, axis)
|
||||
#pgf plot ignores ticks with angle below 90 when xmin = 90 so shift values
|
||||
tick_values =
|
||||
ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] :
|
||||
ticks[1]
|
||||
tick_values = ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] : ticks[1]
|
||||
push!(style, string(letter, "tick = {", join(tick_values,","), "}"))
|
||||
if axis[:showaxis] && axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto
|
||||
# wrap the power part of label with }
|
||||
@ -419,13 +381,9 @@ function pgf_axis(sp::Subplot, letter)
|
||||
power = string("{", power, "}")
|
||||
tick_labels[i] = string(base, "^", power)
|
||||
end
|
||||
push!(
|
||||
style,
|
||||
string(letter, "ticklabels = {\$", join(tick_labels, "\$,\$"), "\$}"),
|
||||
)
|
||||
push!(style, string(letter, "ticklabels = {\$", join(tick_labels,"\$,\$"), "\$}"))
|
||||
elseif axis[:showaxis]
|
||||
tick_labels =
|
||||
ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2]
|
||||
tick_labels = ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2]
|
||||
if axis[:formatter] in (:scientific, :auto)
|
||||
tick_labels = string.("\$", convert_sci_unicode.(tick_labels), "\$")
|
||||
tick_labels = replace.(tick_labels, Ref("×" => "\\times"))
|
||||
@ -434,44 +392,10 @@ function pgf_axis(sp::Subplot, letter)
|
||||
else
|
||||
push!(style, string(letter, "ticklabels = {}"))
|
||||
end
|
||||
push!(
|
||||
style,
|
||||
string(
|
||||
letter,
|
||||
"tick align = ",
|
||||
(axis[:tick_direction] == :out ? "outside" : "inside"),
|
||||
),
|
||||
)
|
||||
push!(style, string(letter, "tick align = ", (axis[:tick_direction] == :out ? "outside" : "inside")))
|
||||
cstr, α = pgf_color(plot_color(axis[:tickfontcolor]))
|
||||
push!(
|
||||
style,
|
||||
string(
|
||||
letter,
|
||||
"ticklabel style = {font = ",
|
||||
pgf_font(axis[:tickfontsize], pgf_thickness_scaling(sp)),
|
||||
", color = ",
|
||||
cstr,
|
||||
", draw opacity = ",
|
||||
α,
|
||||
", rotate = ",
|
||||
axis[:tickfontrotation],
|
||||
"}",
|
||||
),
|
||||
)
|
||||
push!(
|
||||
style,
|
||||
string(
|
||||
letter,
|
||||
" grid style = {",
|
||||
pgf_linestyle(
|
||||
pgf_thickness_scaling(sp) * axis[:gridlinewidth],
|
||||
axis[:foreground_color_grid],
|
||||
axis[:gridalpha],
|
||||
axis[:gridstyle],
|
||||
),
|
||||
"}",
|
||||
),
|
||||
)
|
||||
push!(style, string(letter, "ticklabel style = {font = ", pgf_font(axis[:tickfontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", axis[:tickfontrotation], "}"))
|
||||
push!(style, string(letter, " grid style = {", pgf_linestyle(pgf_thickness_scaling(sp) * axis[:gridlinewidth], axis[:foreground_color_grid], axis[:gridalpha], axis[:gridstyle]), "}"))
|
||||
end
|
||||
|
||||
# framestyle
|
||||
@ -488,20 +412,7 @@ function pgf_axis(sp::Subplot, letter)
|
||||
if framestyle == :zerolines
|
||||
push!(style, string("extra ", letter, " ticks = 0"))
|
||||
push!(style, string("extra ", letter, " tick labels = "))
|
||||
push!(
|
||||
style,
|
||||
string(
|
||||
"extra ",
|
||||
letter,
|
||||
" tick style = {grid = major, major grid style = {",
|
||||
pgf_linestyle(
|
||||
pgf_thickness_scaling(sp),
|
||||
axis[:foreground_color_border],
|
||||
1.0,
|
||||
),
|
||||
"}}",
|
||||
),
|
||||
)
|
||||
push!(style, string("extra ", letter, " tick style = {grid = major, major grid style = {", pgf_linestyle(pgf_thickness_scaling(sp), axis[:foreground_color_border], 1.0), "}}"))
|
||||
end
|
||||
|
||||
if !axis[:showaxis]
|
||||
@ -510,19 +421,7 @@ function pgf_axis(sp::Subplot, letter)
|
||||
if !axis[:showaxis] || framestyle in (:zerolines, :grid, :none)
|
||||
push!(style, string(letter, " axis line style = {draw opacity = 0}"))
|
||||
else
|
||||
push!(
|
||||
style,
|
||||
string(
|
||||
letter,
|
||||
" axis line style = {",
|
||||
pgf_linestyle(
|
||||
pgf_thickness_scaling(sp),
|
||||
axis[:foreground_color_border],
|
||||
1.0,
|
||||
),
|
||||
"}",
|
||||
),
|
||||
)
|
||||
push!(style, string(letter, " axis line style = {", pgf_linestyle(pgf_thickness_scaling(sp), axis[:foreground_color_border], 1.0), "}"))
|
||||
end
|
||||
|
||||
# return the style list and KW args
|
||||
@ -531,6 +430,7 @@ end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
|
||||
function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
||||
plt.o = PGFPlots.Axis[]
|
||||
# Obtain the total height of the plot by extracting the maximal bottom
|
||||
@ -556,66 +456,40 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
||||
# A round on 2 decimal places should be enough precision for 300 dpi
|
||||
# plots.
|
||||
bb = bbox(sp)
|
||||
push!(
|
||||
style,
|
||||
"""
|
||||
push!(style, """
|
||||
xshift = $(left(bb).value)mm,
|
||||
yshift = $(round((total_height - (bottom(bb))).value, digits=2))mm,
|
||||
axis background/.style={fill=$(pgf_color(sp[:background_color_inside])[1])}
|
||||
""",
|
||||
)
|
||||
""")
|
||||
kw[:width] = "$(width(bb).value)mm"
|
||||
kw[:height] = "$(height(bb).value)mm"
|
||||
|
||||
if sp[:title] != ""
|
||||
kw[:title] = "$(sp[:title])"
|
||||
cstr, α = pgf_color(plot_color(sp[:titlefontcolor]))
|
||||
push!(
|
||||
style,
|
||||
string(
|
||||
"title style = {font = ",
|
||||
pgf_font(sp[:titlefontsize], pgf_thickness_scaling(sp)),
|
||||
", color = ",
|
||||
cstr,
|
||||
", draw opacity = ",
|
||||
α,
|
||||
", rotate = ",
|
||||
sp[:titlefontrotation],
|
||||
"}",
|
||||
),
|
||||
)
|
||||
push!(style, string("title style = {font = ", pgf_font(sp[:titlefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", sp[:titlefontrotation], "}"))
|
||||
end
|
||||
|
||||
if get_aspect_ratio(sp) in (1, :equal)
|
||||
kw[:axisEqual] = "true"
|
||||
end
|
||||
|
||||
legpos = sp[:legend_position]
|
||||
legpos = sp[:legend]
|
||||
if haskey(_pgfplots_legend_pos, legpos)
|
||||
kw[:legendPos] = _pgfplots_legend_pos[legpos]
|
||||
end
|
||||
cstr, bg_alpha = pgf_color(plot_color(sp[:legend_background_color]))
|
||||
fg_alpha = alpha(plot_color(sp[:legend_foreground_color]))
|
||||
cstr, bg_alpha = pgf_color(plot_color(sp[:background_color_legend]))
|
||||
fg_alpha = alpha(plot_color(sp[:foreground_color_legend]))
|
||||
|
||||
push!(
|
||||
style,
|
||||
string(
|
||||
push!(style, string(
|
||||
"legend style = {",
|
||||
pgf_linestyle(
|
||||
pgf_thickness_scaling(sp),
|
||||
sp[:legend_foreground_color],
|
||||
fg_alpha,
|
||||
"solid",
|
||||
),
|
||||
",",
|
||||
pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], fg_alpha, "solid", ), ",",
|
||||
"fill = $cstr,",
|
||||
"fill opacity = $bg_alpha,",
|
||||
"text opacity = $(alpha(plot_color(sp[:legend_font_color]))),",
|
||||
"font = ",
|
||||
pgf_font(sp[:legend_font_pointsize], pgf_thickness_scaling(sp)),
|
||||
"text opacity = $(alpha(plot_color(sp[:legendfontcolor]))),",
|
||||
"font = ", pgf_font(sp[:legendfontsize], pgf_thickness_scaling(sp)),
|
||||
"}",
|
||||
),
|
||||
)
|
||||
))
|
||||
|
||||
if any(s[:seriestype] == :contour for s in series_list(sp))
|
||||
kw[:view] = "{0}{90}"
|
||||
@ -646,10 +520,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
||||
for series in series_list(sp)
|
||||
for col in (:markercolor, :fillcolor, :linecolor)
|
||||
if typeof(series.plotattributes[col]) == ColorGradient
|
||||
push!(
|
||||
style,
|
||||
"colormap={plots}{$(pgf_colormap(series.plotattributes[col]))}",
|
||||
)
|
||||
push!(style,"colormap={plots}{$(pgf_colormap(series.plotattributes[col]))}")
|
||||
|
||||
if sp[:colorbar] == :none
|
||||
kw[:colorbar] = "false"
|
||||
@ -673,25 +544,16 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
||||
# add series annotations
|
||||
anns = series[:series_annotations]
|
||||
for (xi,yi,str,fnt) in EachAnn(anns, series[:x], series[:y])
|
||||
pgf_add_annotation!(
|
||||
o,
|
||||
xi,
|
||||
yi,
|
||||
PlotText(str, fnt),
|
||||
pgf_thickness_scaling(series),
|
||||
)
|
||||
pgf_add_annotation!(o, xi, yi, PlotText(str, fnt), pgf_thickness_scaling(series))
|
||||
end
|
||||
end
|
||||
|
||||
# add the annotations
|
||||
for ann in sp[:annotations]
|
||||
pgf_add_annotation!(
|
||||
o,
|
||||
locate_annotation(sp, ann...)...,
|
||||
pgf_thickness_scaling(sp),
|
||||
)
|
||||
pgf_add_annotation!(o, locate_annotation(sp, ann...)..., pgf_thickness_scaling(sp))
|
||||
end
|
||||
|
||||
|
||||
# add the PGFPlots.Axis to the list
|
||||
push!(plt.o, o)
|
||||
end
|
||||
@ -718,11 +580,7 @@ end
|
||||
|
||||
function _show(io::IO, mime::MIME"application/x-tex", plt::Plot{PGFPlotsBackend})
|
||||
fn = tempname()*".tex"
|
||||
PGFPlots.save(
|
||||
fn,
|
||||
backend_object(plt),
|
||||
include_preamble = plt.attr[:tex_output_standalone],
|
||||
)
|
||||
PGFPlots.save(fn, backend_object(plt), include_preamble=plt.attr[:tex_output_standalone])
|
||||
write(io, read(open(fn), String))
|
||||
end
|
||||
|
||||
@ -740,5 +598,3 @@ function _display(plt::Plot{PGFPlotsBackend})
|
||||
# cleanup
|
||||
PGFPlots.cleanup(plt.o)
|
||||
end
|
||||
|
||||
# COV_EXCL_STOP
|
||||
|
||||
@ -1,604 +0,0 @@
|
||||
# https://github.com/mbaz/Gaston.
|
||||
|
||||
should_warn_on_unsupported(::GastonBackend) = false
|
||||
|
||||
# Create the window/figure for this backend.
|
||||
function _create_backend_figure(plt::Plot{GastonBackend})
|
||||
state_handle = Gaston.nexthandle() # for now all the figures will be kept
|
||||
plt.o = Gaston.newfigure(state_handle)
|
||||
end
|
||||
|
||||
function _before_layout_calcs(plt::Plot{GastonBackend})
|
||||
# Initialize all the subplots first
|
||||
plt.o.subplots = Gaston.SubPlot[]
|
||||
|
||||
n1 = n2 = 0
|
||||
if length(plt.inset_subplots) > 0
|
||||
n1, sps = gaston_get_subplots(0, plt.inset_subplots, plt.layout)
|
||||
gaston_init_subplots(plt, sps)
|
||||
end
|
||||
|
||||
if length(plt.subplots) > 0
|
||||
n2, sps = gaston_get_subplots(0, plt.subplots, plt.layout)
|
||||
end
|
||||
|
||||
if (n = n1 + n2) != length(plt.subplots)
|
||||
@error "Gaston: $n != $(length(plt.subplots))"
|
||||
end
|
||||
|
||||
plt.o.layout = gaston_init_subplots(plt, sps)
|
||||
|
||||
# Then add the series (curves in gaston)
|
||||
for series in plt.series_list
|
||||
gaston_add_series(plt, series)
|
||||
end
|
||||
|
||||
for sp in plt.subplots
|
||||
sp === nothing && continue
|
||||
for ann in sp[:annotations]
|
||||
x, y, val = locate_annotation(sp, ann...)
|
||||
sp.o.axesconf *= "\nset label '$(val.str)' at $x,$y $(gaston_font(val.font))"
|
||||
end
|
||||
end
|
||||
nothing
|
||||
end
|
||||
|
||||
function _update_min_padding!(sp::Subplot{GastonBackend})
|
||||
sp.minpad = 0mm, 0mm, 0mm, 0mm
|
||||
nothing
|
||||
end
|
||||
|
||||
function _update_plot_object(plt::Plot{GastonBackend})
|
||||
# respect the layout ratio
|
||||
dat = gaston_multiplot_pos_size(plt.layout, (0, 0, 1, 1))
|
||||
gaston_multiplot_pos_size!(dat)
|
||||
nothing
|
||||
end
|
||||
|
||||
for (mime, term) in (
|
||||
"application/eps" => "epscairo",
|
||||
"image/eps" => "epslatex",
|
||||
"application/pdf" => "pdfcairo",
|
||||
"application/postscript" => "postscript",
|
||||
"image/png" => "png",
|
||||
"image/svg+xml" => "svg",
|
||||
"text/latex" => "tikz",
|
||||
"application/x-tex" => "epslatex",
|
||||
"text/plain" => "dumb",
|
||||
)
|
||||
@eval function _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{GastonBackend})
|
||||
term = String($term)
|
||||
tmpfile = "$(Gaston.tempname()).$term"
|
||||
|
||||
Gaston.save(
|
||||
term = term,
|
||||
output = tmpfile,
|
||||
handle = plt.o.handle,
|
||||
saveopts = gaston_saveopts(plt),
|
||||
)
|
||||
while !isfile(tmpfile)
|
||||
end # avoid race condition with read in next line
|
||||
write(io, read(tmpfile))
|
||||
rm(tmpfile, force = true)
|
||||
nothing
|
||||
end
|
||||
end
|
||||
|
||||
_display(plt::Plot{GastonBackend}) = display(plt.o)
|
||||
|
||||
# --------------------------------------------
|
||||
# These functions are gaston specific
|
||||
# --------------------------------------------
|
||||
|
||||
function gaston_saveopts(plt::Plot{GastonBackend})
|
||||
saveopts = String["size $(join(plt.attr[:size], ","))"]
|
||||
|
||||
push!(
|
||||
saveopts,
|
||||
gaston_font(
|
||||
plottitlefont(plt),
|
||||
rot = false,
|
||||
align = false,
|
||||
color = false,
|
||||
scale = 1,
|
||||
),
|
||||
)
|
||||
|
||||
push!(saveopts, "background $(gaston_color(plt.attr[:background_color]))")
|
||||
|
||||
# push!(saveopts, "title '$(plt.attr[:window_title])'")
|
||||
|
||||
# Scale all plot elements to match Plots.jl DPI standard
|
||||
scaling = plt.attr[:dpi] / Plots.DPI
|
||||
push!(saveopts, "fontscale $scaling lw $scaling dl $scaling") # ps $scaling
|
||||
|
||||
return join(saveopts, " ")
|
||||
end
|
||||
|
||||
function gaston_get_subplots(n, plt_subplots, layout)
|
||||
nr, nc = size(layout)
|
||||
sps = Array{Any}(nothing, nr, nc)
|
||||
for r in 1:nr, c in 1:nc # NOTE: col major
|
||||
l = layout[r, c]
|
||||
if l isa GridLayout
|
||||
n, sub = gaston_get_subplots(n, plt_subplots, l)
|
||||
sps[r, c] = size(sub) == (1, 1) ? only(sub) : sub
|
||||
else
|
||||
sps[r, c] = get(l.attr, :blank, false) ? nothing : plt_subplots[n += 1]
|
||||
end
|
||||
end
|
||||
return n, sps
|
||||
end
|
||||
|
||||
function gaston_init_subplots(plt, sps)
|
||||
sz = nr, nc = size(sps)
|
||||
for c in 1:nc, r in 1:nr # NOTE: row major
|
||||
sp = sps[r, c]
|
||||
if sp isa Subplot || sp === nothing
|
||||
gaston_init_subplot(plt, sp)
|
||||
else
|
||||
gaston_init_subplots(plt, sp)
|
||||
sz = max.(sz, size(sp))
|
||||
end
|
||||
end
|
||||
return sz
|
||||
end
|
||||
|
||||
function gaston_init_subplot(
|
||||
plt::Plot{GastonBackend},
|
||||
sp::Union{Nothing,Subplot{GastonBackend}},
|
||||
)
|
||||
if sp === nothing
|
||||
push!(plt.o.subplots, sp)
|
||||
else
|
||||
dims =
|
||||
RecipesPipeline.is3d(sp) ||
|
||||
sp.attr[:projection] == "3d" ||
|
||||
needs_any_3d_axes(sp) ? 3 : 2
|
||||
any_label = false
|
||||
for series in series_list(sp)
|
||||
if dims == 2 && series[:seriestype] ∈ (:heatmap, :contour)
|
||||
dims = 3 # we need heatmap/contour to use splot, not plot
|
||||
end
|
||||
any_label |= should_add_to_legend(series)
|
||||
end
|
||||
sp.o = Gaston.Plot(
|
||||
dims = dims,
|
||||
curves = [],
|
||||
axesconf = gaston_parse_axes_args(plt, sp, dims, any_label),
|
||||
)
|
||||
push!(plt.o.subplots, sp.o)
|
||||
end
|
||||
nothing
|
||||
end
|
||||
|
||||
function gaston_multiplot_pos_size(layout, parent_xy_wh)
|
||||
nr, nc = size(layout)
|
||||
dat = Array{Any}(nothing, nr, nc)
|
||||
for r in 1:nr, c in 1:nc
|
||||
l = layout[r, c]
|
||||
# width and height (pct) are multiplicative (parent)
|
||||
w = layout.widths[c].value * parent_xy_wh[3]
|
||||
h = layout.heights[r].value * parent_xy_wh[4]
|
||||
if isa(l, EmptyLayout)
|
||||
dat[r, c] = (c - 1) * w, (r - 1) * h, w, h, nothing
|
||||
else
|
||||
# previous position (origin)
|
||||
prev_r = r > 1 ? dat[r - 1, c] : nothing
|
||||
prev_c = c > 1 ? dat[r, c - 1] : nothing
|
||||
prev_r isa Array && (prev_r = prev_r[end, end])
|
||||
prev_c isa Array && (prev_c = prev_c[end, end])
|
||||
x = prev_c !== nothing ? prev_c[1] + prev_c[3] : parent_xy_wh[1]
|
||||
y = prev_r !== nothing ? prev_r[2] + prev_r[4] : parent_xy_wh[2]
|
||||
if l isa GridLayout
|
||||
sub = gaston_multiplot_pos_size(l, (x, y, w, h))
|
||||
dat[r, c] = size(sub) == (1, 1) ? only(sub) : sub
|
||||
else
|
||||
dat[r, c] = x, y, w, h, l
|
||||
end
|
||||
end
|
||||
end
|
||||
return dat
|
||||
end
|
||||
|
||||
function gaston_multiplot_pos_size!(dat)
|
||||
nr, nc = size(dat)
|
||||
for r in 1:nr, c in 1:nc
|
||||
xy_wh_sp = dat[r, c]
|
||||
if xy_wh_sp isa Array
|
||||
gaston_multiplot_pos_size!(xy_wh_sp)
|
||||
elseif xy_wh_sp isa Tuple
|
||||
x, y, w, h, sp = xy_wh_sp
|
||||
sp === nothing && continue
|
||||
sp.o === nothing && continue
|
||||
# gnuplot screen coordinates: bottom left at 0,0 and top right at 1,1
|
||||
sp.o.axesconf = "set origin $x, $(1 - y - h)\nset size $w, $h\n" * sp.o.axesconf
|
||||
end
|
||||
end
|
||||
nothing
|
||||
end
|
||||
|
||||
function gaston_add_series(plt::Plot{GastonBackend}, series::Series)
|
||||
sp = series[:subplot]
|
||||
gsp = sp.o
|
||||
x, y, z = series[:x], series[:y], series[:z]
|
||||
st = series[:seriestype]
|
||||
curves = []
|
||||
if gsp.dims == 2 && z === nothing
|
||||
for (n, seg) in enumerate(series_segments(series, st; check = true))
|
||||
i, rng = seg.attr_index, seg.range
|
||||
fr = _cycle(series[:fillrange], 1:length(x[rng]))
|
||||
for sc in gaston_seriesconf!(sp, series, i, n == 1)
|
||||
push!(curves, Gaston.Curve(x[rng], y[rng], nothing, fr, sc))
|
||||
end
|
||||
end
|
||||
else
|
||||
if z isa Surface
|
||||
z = z.surf
|
||||
if st == :image
|
||||
z = reverse(Float32.(Gray.(z)), dims = 1) # flip y axis
|
||||
nr, nc = size(z)
|
||||
if (ly = length(y)) == 2 && ly != nr
|
||||
y = collect(range(y[1], y[2], length = nr))
|
||||
end
|
||||
if (lx = length(x)) == 2 && lx != nc
|
||||
x = collect(range(x[1], x[2], length = nc))
|
||||
end
|
||||
end
|
||||
length(x) == size(z, 2) + 1 && (x = (x[1:(end - 1)] + x[2:end]) / 2)
|
||||
length(y) == size(z, 1) + 1 && (y = (y[1:(end - 1)] + y[2:end]) / 2)
|
||||
end
|
||||
if st == :mesh3d
|
||||
x, y, z = mesh3d_triangles(x, y, z, series[:connections])
|
||||
end
|
||||
for sc in gaston_seriesconf!(sp, series, 1, true)
|
||||
push!(curves, Gaston.Curve(x, y, z, nothing, sc))
|
||||
end
|
||||
end
|
||||
|
||||
for c in curves
|
||||
append = length(gsp.curves) > 0
|
||||
push!(gsp.curves, c)
|
||||
Gaston.write_data(c, gsp.dims, gsp.datafile, append = append)
|
||||
end
|
||||
nothing
|
||||
end
|
||||
|
||||
function gaston_seriesconf!(
|
||||
sp::Subplot{GastonBackend},
|
||||
series::Series,
|
||||
i::Int,
|
||||
add_to_legend::Bool,
|
||||
)
|
||||
#=
|
||||
gnuplot abbreviations (see gnuplot/src/set.c)
|
||||
---------------------------------------------
|
||||
dl: dashlength
|
||||
dt: dashtype
|
||||
fc: fillcolor
|
||||
fs: fillstyle
|
||||
lc: linecolor
|
||||
lp: linespoints
|
||||
ls: linestyle
|
||||
lt: linetype
|
||||
lw: linewidth
|
||||
pi: pointinterval
|
||||
pn: pointnumber
|
||||
ps: pointscale
|
||||
pt: pointtype
|
||||
tc: textcolor
|
||||
w: with
|
||||
=#
|
||||
gsp = sp.o
|
||||
st = series[:seriestype]
|
||||
extra = []
|
||||
add_to_legend &= should_add_to_legend(series)
|
||||
curveconf = String[add_to_legend ? "title '$(series[:label])'" : "notitle"]
|
||||
|
||||
clims = get_clims(sp, series)
|
||||
if st ∈ (:scatter, :scatter3d)
|
||||
lc, dt, lw = gaston_lc_ls_lw(series, clims, i)
|
||||
pt, ps, mc = gaston_mk_ms_mc(series, clims, i)
|
||||
push!(curveconf, "w points pt $pt ps $ps lc $mc")
|
||||
elseif st ∈ (:path, :straightline, :path3d)
|
||||
fr = series[:fillrange]
|
||||
fc = gaston_color(get_fillcolor(series, i), get_fillalpha(series, i))
|
||||
lc, dt, lw = gaston_lc_ls_lw(series, clims, i)
|
||||
if fr !== nothing # filled curves, but not filled curves with markers
|
||||
push!(
|
||||
curveconf,
|
||||
"w filledcurves fc $fc fs solid border lc $lc lw $lw dt $dt,'' w lines lc $lc lw $lw dt $dt",
|
||||
)
|
||||
elseif series[:markershape] == :none # simplepath
|
||||
push!(curveconf, "w lines lc $lc dt $dt lw $lw")
|
||||
else
|
||||
pt, ps, mc = gaston_mk_ms_mc(series, clims, i)
|
||||
push!(curveconf, "w lp lc $mc dt $dt lw $lw pt $pt ps $ps")
|
||||
end
|
||||
elseif st == :shape
|
||||
fc = gaston_color(get_fillcolor(series, i), get_fillalpha(series, i))
|
||||
lc, _ = gaston_lc_ls_lw(series, clims, i)
|
||||
push!(curveconf, "w filledcurves fc $fc fs solid border lc $lc")
|
||||
elseif st ∈ (:steppre, :stepmid, :steppost)
|
||||
step = if st == :steppre
|
||||
"fsteps"
|
||||
elseif st == :stepmid
|
||||
"histeps"
|
||||
elseif st == :steppost
|
||||
"steps"
|
||||
end
|
||||
push!(curveconf, "w $step")
|
||||
lc, dt, lw = gaston_lc_ls_lw(series, clims, i)
|
||||
push!(extra, "w points lc $lc dt $dt lw $lw notitle")
|
||||
elseif st == :image
|
||||
palette = gaston_palette(series[:seriescolor])
|
||||
gsp.axesconf *= "\nset palette model RGB defined $palette"
|
||||
push!(curveconf, "w image pixels")
|
||||
elseif st ∈ (:contour, :contour3d)
|
||||
push!(curveconf, "w lines")
|
||||
st == :contour && (gsp.axesconf *= "\nset view map\nunset surface") # 2D
|
||||
levels = join(map(string, collect(contour_levels(series, clims))), ", ")
|
||||
gsp.axesconf *= "\nset contour base\nset cntrparam levels discrete $levels"
|
||||
elseif st ∈ (:surface, :heatmap)
|
||||
push!(curveconf, "w pm3d")
|
||||
palette = gaston_palette(series[:seriescolor])
|
||||
gsp.axesconf *= "\nset palette model RGB defined $palette"
|
||||
st == :heatmap && (gsp.axesconf *= "\nset view map")
|
||||
elseif st ∈ (:wireframe, :mesh3d)
|
||||
lc, dt, lw = gaston_lc_ls_lw(series, clims, i)
|
||||
push!(curveconf, "w lines lc $lc dt $dt lw $lw")
|
||||
elseif st == :quiver
|
||||
push!(curveconf, "w vectors filled")
|
||||
else
|
||||
@warn "Gaston: $st is not implemented yet"
|
||||
end
|
||||
|
||||
return [join(curveconf, " "), extra...]
|
||||
end
|
||||
|
||||
function gaston_parse_axes_args(
|
||||
plt::Plot{GastonBackend},
|
||||
sp::Subplot{GastonBackend},
|
||||
dims::Int,
|
||||
any_label::Bool,
|
||||
)
|
||||
# axesconf = String["set margins 2, 2, 2, 2"] # left, right, bottom, top
|
||||
axesconf = String[]
|
||||
|
||||
polar = ispolar(sp) && dims == 2 # cannot splot in polar coordinates
|
||||
|
||||
for letter in (:x, :y, :z)
|
||||
(letter == :z && dims == 2) && continue
|
||||
axis = sp.attr[get_attr_symbol(letter, :axis)]
|
||||
# label names
|
||||
push!(
|
||||
axesconf,
|
||||
"set $(letter)label '$(axis[:guide])' $(gaston_font(guidefont(axis)))",
|
||||
)
|
||||
mirror = axis[:mirror] ? "mirror" : "nomirror"
|
||||
|
||||
if axis[:scale] == :identity
|
||||
logscale, base = "nologscale", ""
|
||||
elseif axis[:scale] == :log10
|
||||
logscale, base = "logscale", "10"
|
||||
elseif axis[:scale] == :log2
|
||||
logscale, base = "logscale", "2"
|
||||
elseif axis[:scale] == :ln
|
||||
logscale, base = "logscale", "e"
|
||||
end
|
||||
push!(axesconf, "set $logscale $letter $base")
|
||||
|
||||
# handle ticks
|
||||
if polar
|
||||
push!(axesconf, "set size square\nunset $(letter)tics")
|
||||
else
|
||||
push!(
|
||||
axesconf,
|
||||
"set $(letter)tics $(mirror) $(axis[:tick_direction]) $(gaston_font(tickfont(axis)))",
|
||||
)
|
||||
|
||||
# major tick locations
|
||||
if axis[:ticks] != :native
|
||||
if axis[:flip]
|
||||
hi, lo = axis_limits(sp, letter)
|
||||
else
|
||||
lo, hi = axis_limits(sp, letter)
|
||||
end
|
||||
push!(axesconf, "set $(letter)range [$lo:$hi]")
|
||||
|
||||
ticks = get_ticks(sp, axis)
|
||||
gaston_set_ticks!(axesconf, ticks, letter, "", "")
|
||||
|
||||
if axis[:minorticks] != :native
|
||||
minor_ticks = get_minor_ticks(sp, axis, ticks)
|
||||
gaston_set_ticks!(axesconf, minor_ticks, letter, "m", "add")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if axis[:grid]
|
||||
push!(axesconf, "set grid " * (polar ? "polar" : "$(letter)tics"))
|
||||
axis[:minorgrid] &&
|
||||
push!(axesconf, "set grid " * (polar ? "polar" : "m$(letter)tics"))
|
||||
end
|
||||
|
||||
ratio = get_aspect_ratio(sp)
|
||||
if ratio != :none
|
||||
ratio == :equal && (ratio = -1)
|
||||
push!(axesconf, "set size ratio $ratio")
|
||||
end
|
||||
end
|
||||
gaston_set_legend!(axesconf, sp, any_label)
|
||||
|
||||
if hascolorbar(sp)
|
||||
push!(axesconf, "set cbtics $(gaston_font(colorbartitlefont(sp)))")
|
||||
end
|
||||
|
||||
if sp[:title] !== nothing
|
||||
push!(axesconf, "set title '$(sp[:title])' $(gaston_font(titlefont(sp)))")
|
||||
end
|
||||
|
||||
if polar
|
||||
push!(axesconf, "unset border\nset polar\nset border polar")
|
||||
tmin, tmax = axis_limits(sp, :x, false, false)
|
||||
rmin, rmax = axis_limits(sp, :y, false, false)
|
||||
rticks = get_ticks(sp, :y)
|
||||
if (ttype = ticksType(rticks)) == :ticks
|
||||
gaston_ticks = string.(rticks)
|
||||
elseif ttype == :ticks_and_labels
|
||||
gaston_ticks = String["'$l' $t" for (t, l) in zip(rticks...)]
|
||||
end
|
||||
push!(
|
||||
axesconf,
|
||||
"set rtics ( " *
|
||||
join(gaston_ticks, ", ") *
|
||||
" ) $(gaston_font(tickfont(sp.attr[:yaxis])))",
|
||||
)
|
||||
push!(axesconf, "set trange [$(min(0, tmin)):$(max(2π, tmax))]")
|
||||
push!(axesconf, "set rrange [$rmin:$rmax]")
|
||||
push!(
|
||||
axesconf,
|
||||
"set ttics 0,30 format \"%g\".GPVAL_DEGREE_SIGN $(gaston_font(tickfont(sp.attr[:xaxis])))",
|
||||
)
|
||||
push!(axesconf, "set mttics 3")
|
||||
end
|
||||
|
||||
return join(axesconf, "\n")
|
||||
end
|
||||
|
||||
function gaston_set_ticks!(axesconf, ticks, letter, maj_min, add)
|
||||
ticks == :auto && return
|
||||
if ticks ∈ (:none, nothing, false)
|
||||
push!(axesconf, "unset $(maj_min)$(letter)tics")
|
||||
return
|
||||
end
|
||||
|
||||
gaston_ticks = String[]
|
||||
if (ttype = ticksType(ticks)) == :ticks
|
||||
tick_locs = @view ticks[:]
|
||||
for i in eachindex(tick_locs)
|
||||
tick = if maj_min == "m"
|
||||
"'' $(tick_locs[i]) 1" # see gnuplot manual 'Mxtics'
|
||||
else
|
||||
"$(tick_locs[i])"
|
||||
end
|
||||
push!(gaston_ticks, tick)
|
||||
end
|
||||
elseif ttype == :ticks_and_labels
|
||||
tick_locs = @view ticks[1][:]
|
||||
tick_labels = @view ticks[2][:]
|
||||
for i in eachindex(tick_locs)
|
||||
lab = gaston_enclose_tick_string(tick_labels[i])
|
||||
push!(gaston_ticks, "'$lab' $(tick_locs[i])")
|
||||
end
|
||||
else
|
||||
gaston_ticks = nothing
|
||||
@error "Gaston: invalid input for $(maj_min)$(letter)ticks: $ticks"
|
||||
end
|
||||
if gaston_ticks !== nothing
|
||||
push!(axesconf, "set $(letter)tics $add (" * join(gaston_ticks, ", ") * ")")
|
||||
end
|
||||
nothing
|
||||
end
|
||||
|
||||
function gaston_set_legend!(axesconf, sp, any_label)
|
||||
leg = sp[:legend_position]
|
||||
if sp[:legend_position] ∉ (:none, :inline) && any_label
|
||||
leg == :best && (leg = :topright)
|
||||
|
||||
push!(
|
||||
axesconf,
|
||||
"set key " * (occursin("outer", string(leg)) ? "outside" : "inside"),
|
||||
)
|
||||
for position in ("top", "bottom", "left", "right")
|
||||
occursin(position, string(leg)) && push!(axesconf, "set key $position")
|
||||
end
|
||||
push!(axesconf, "set key $(gaston_font(legendfont(sp), rot=false, align=false))")
|
||||
if sp[:legend_title] !== nothing
|
||||
# NOTE: cannot use legendtitlefont(sp) as it will override legendfont
|
||||
push!(axesconf, "set key title '$(sp[:legend_title])'")
|
||||
end
|
||||
push!(axesconf, "set key box lw 1 opaque")
|
||||
push!(axesconf, "set border back")
|
||||
else
|
||||
push!(axesconf, "set key off")
|
||||
end
|
||||
nothing
|
||||
end
|
||||
|
||||
# --------------------------------------------
|
||||
# Helpers
|
||||
# --------------------------------------------
|
||||
|
||||
gaston_halign(k) = (left = :left, hcenter = :center, right = :right)[k]
|
||||
gaston_valign(k) = (top = :top, vcenter = :center, bottom = :bottom)[k]
|
||||
|
||||
gaston_alpha(alpha) = alpha === nothing ? 0 : alpha
|
||||
|
||||
gaston_lc_ls_lw(series::Series, clims, i::Int) = (
|
||||
gaston_color(get_linecolor(series, clims, i), get_linealpha(series, i)),
|
||||
gaston_linestyle(get_linestyle(series, i)),
|
||||
get_linewidth(series, i),
|
||||
)
|
||||
|
||||
gaston_mk_ms_mc(series::Series, clims, i::Int) = (
|
||||
gaston_marker(_cycle(series[:markershape], i), get_markeralpha(series, i)),
|
||||
_cycle(series[:markersize], i) * 1.3 / 5,
|
||||
gaston_color(get_markercolor(series, clims, i), get_markeralpha(series, i)),
|
||||
)
|
||||
|
||||
function gaston_font(f; rot = true, align = true, color = true, scale = 1)
|
||||
font = String["font '$(f.family),$(round(Int, scale * f.pointsize))'"]
|
||||
align && push!(font, "$(gaston_halign(f.halign))")
|
||||
rot && push!(font, "rotate by $(f.rotation)")
|
||||
color && push!(font, "textcolor $(gaston_color(f.color))")
|
||||
return join(font, " ")
|
||||
end
|
||||
|
||||
function gaston_palette(gradient)
|
||||
palette = String[]
|
||||
n = -1
|
||||
for rgba in gradient # FIXME: naive conversion, inefficient ?
|
||||
push!(palette, "$(n += 1) $(rgba.r) $(rgba.g) $(rgba.b)")
|
||||
end
|
||||
return '(' * join(palette, ", ") * ')'
|
||||
end
|
||||
|
||||
function gaston_marker(marker, alpha)
|
||||
# NOTE: :rtriangle, :ltriangle, :hexagon, :heptagon, :octagon seems unsupported by gnuplot
|
||||
filled = gaston_alpha(alpha) == 0
|
||||
marker == :none && return -1
|
||||
marker == :pixel && return 0
|
||||
marker ∈ (:+, :cross) && return 1
|
||||
marker ∈ (:x, :xcross) && return 2
|
||||
marker == :star5 && return 3
|
||||
marker == :rect && return filled ? 5 : 4
|
||||
marker == :circle && return filled ? 7 : 6
|
||||
marker == :utriangle && return filled ? 9 : 8
|
||||
marker == :dtriangle && return filled ? 11 : 10
|
||||
marker == :diamond && return filled ? 13 : 12
|
||||
marker == :pentagon && return filled ? 15 : 14
|
||||
|
||||
@warn "Gaston: unsupported marker $marker"
|
||||
return 1
|
||||
end
|
||||
|
||||
function gaston_color(col, alpha = 0)
|
||||
col = single_color(col) # in case of gradients
|
||||
col = alphacolor(col, gaston_alpha(alpha)) # add a default alpha if non existent
|
||||
return "rgb '#$(hex(col, :aarrggbb))'"
|
||||
end
|
||||
|
||||
function gaston_linestyle(style)
|
||||
style == :solid && return "1"
|
||||
style == :dash && return "2"
|
||||
style == :dot && return "3"
|
||||
style == :dashdot && return "4"
|
||||
style == :dashdotdot && return "5"
|
||||
end
|
||||
|
||||
function gaston_enclose_tick_string(tick_string)
|
||||
findfirst("^", tick_string) === nothing && return tick_string
|
||||
base, power = split(tick_string, "^")
|
||||
return "$base^{$power}"
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,7 @@ Read from .hdf5 file using:
|
||||
display(pread)
|
||||
==#
|
||||
|
||||
|
||||
#==TODO
|
||||
===============================================================================
|
||||
1. Support more features.
|
||||
@ -55,8 +56,7 @@ import ..HDF5PLOT_MAP_STR2TELEM, ..HDF5PLOT_MAP_TELEM2STR
|
||||
import ..HDF5Plot_PlotRef, ..HDF5PLOT_PLOTREF
|
||||
import ..BoundingBox, ..Extrema, ..Length
|
||||
import ..RecipesPipeline.datetimeformatter
|
||||
import ..PlotUtils.ColorPalette,
|
||||
..PlotUtils.CategoricalColorGradient, ..PlotUtils.ContinuousColorGradient
|
||||
import ..PlotUtils.ColorPalette, ..PlotUtils.CategoricalColorGradient, ..PlotUtils.ContinuousColorGradient
|
||||
import ..Surface, ..Shape, ..Arrow
|
||||
import ..GridLayout, ..RootLayout
|
||||
import ..Font, ..PlotText, ..SeriesAnnotations
|
||||
@ -70,9 +70,10 @@ const HDF5_SupportedTypes = Union{Number,String}
|
||||
#TODO: Types_HDF5Support
|
||||
|
||||
#Dispatch types:
|
||||
struct CplxTuple end #Identifies a "complex" tuple structure (not merely numbers)
|
||||
struct CplxTuple; end #Identifies a "complex" tuple structure (not merely numbers)
|
||||
#HDF5 reader will auto-detect type correctly:
|
||||
struct HDF5_AutoDetect end #See HDF5_SupportedTypes
|
||||
struct HDF5_AutoDetect; end #See HDF5_SupportedTypes
|
||||
|
||||
|
||||
#==
|
||||
===============================================================================#
|
||||
@ -86,7 +87,8 @@ if length(HDF5PLOT_MAP_TELEM2STR) < 1
|
||||
"SYMBOL" => Symbol,
|
||||
"RGBA" => Colorant, #Write out any Colorant to an #RRGGBBAA string
|
||||
"TUPLE" => Tuple,
|
||||
"CTUPLE" => CplxTuple,
|
||||
"CTUPLE" => CplxTuple, #Tuple of complex structures
|
||||
|
||||
"EXTREMA" => Extrema,
|
||||
"LENGTH" => Length,
|
||||
"ARRAY" => Array, #Array{Any} (because Array{T<:Union{Number, String}} natively supported by HDF5)
|
||||
@ -113,12 +115,10 @@ if length(HDF5PLOT_MAP_TELEM2STR) < 1
|
||||
"SUBPLOT" => Subplot,
|
||||
)
|
||||
merge!(HDF5PLOT_MAP_STR2TELEM, _telem2str) #Faster to create than push!()??
|
||||
merge!(
|
||||
HDF5PLOT_MAP_TELEM2STR,
|
||||
Dict{Type,String}(v => k for (k, v) in HDF5PLOT_MAP_STR2TELEM),
|
||||
)
|
||||
merge!(HDF5PLOT_MAP_TELEM2STR, Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM))
|
||||
end
|
||||
|
||||
|
||||
#==Helper functions
|
||||
===============================================================================#
|
||||
|
||||
@ -151,14 +151,15 @@ function _hdf5_merge!(dest::AKW, src::AKW)
|
||||
end
|
||||
|
||||
#_type_for_map returns the type to use with HDF5PLOT_MAP_TELEM2STR[], in case it is not concrete:
|
||||
_type_for_map(::Type{T}) where {T} = T #Catch-all
|
||||
_type_for_map(::Type{T}) where {T<:BoundingBox} = BoundingBox
|
||||
_type_for_map(::Type{T}) where {T<:ColorScheme} = ColorScheme
|
||||
_type_for_map(::Type{T}) where {T<:Surface} = Surface
|
||||
_type_for_map(::Type{T}) where T = T #Catch-all
|
||||
_type_for_map(::Type{T}) where T<:BoundingBox = BoundingBox
|
||||
_type_for_map(::Type{T}) where T<:ColorScheme = ColorScheme
|
||||
_type_for_map(::Type{T}) where T<:Surface = Surface
|
||||
|
||||
|
||||
#==Read/write things like type name in attributes
|
||||
===============================================================================#
|
||||
function _write_datatype_attr(ds::Union{Group,Dataset}, ::Type{T}) where {T}
|
||||
function _write_datatype_attr(ds::Union{Group, Dataset}, ::Type{T}) where T
|
||||
typestr = HDF5PLOT_MAP_TELEM2STR[T]
|
||||
HDF5.attributes(ds)["TYPE"] = typestr
|
||||
end
|
||||
@ -172,7 +173,7 @@ function _read_datatype_attr(ds::Union{Group,Dataset})
|
||||
end
|
||||
|
||||
#Type parameter attributes:
|
||||
function _write_typeparam_attr(ds::Dataset, v::Length{T}) where {T}
|
||||
function _write_typeparam_attr(ds::Dataset, v::Length{T}) where T
|
||||
HDF5.attributes(ds)["TYPEPARAM"] = string(T) #Need to add units for Length
|
||||
end
|
||||
_read_typeparam_attr(ds::Dataset) = HDF5.read(HDF5.attributes(ds)["TYPEPARAM"])
|
||||
@ -185,8 +186,8 @@ _read_length_attr(::Type{Vector}, grp::Group) = HDF5.read(HDF5.attributes(grp)["
|
||||
function _write_size_attr(grp::Group, v::Array) #of an array
|
||||
HDF5.attributes(grp)["SIZE"] = [size(v)...]
|
||||
end
|
||||
_read_size_attr(::Type{Array}, grp::Group) =
|
||||
tuple(HDF5.read(HDF5.attributes(grp)["SIZE"])...)
|
||||
_read_size_attr(::Type{Array}, grp::Group) = tuple(HDF5.read(HDF5.attributes(grp)["SIZE"])...)
|
||||
|
||||
|
||||
#==_write_typed(): Simple (leaf) datatypes. (Labels with type name.)
|
||||
===============================================================================#
|
||||
@ -229,7 +230,7 @@ function _write_typed(grp::Group, name::String, v::typeof(datetimeformatter))
|
||||
grp[name] = string(v) #Just write something that helps reader
|
||||
_write_datatype_attr(grp[name], typeof(datetimeformatter))
|
||||
end
|
||||
function _write_typed(grp::Group, name::String, v::Array{T}) where {T<:Number} #Default for arrays
|
||||
function _write_typed(grp::Group, name::String, v::Array{T}) where T<:Number #Default for arrays
|
||||
grp[name] = v
|
||||
return #No need to _write_datatype_attr
|
||||
end
|
||||
@ -237,6 +238,8 @@ function _write_typed(grp::Group, name::String, v::AbstractRange)
|
||||
_write_typed(grp, name, collect(v)) #For now
|
||||
end
|
||||
|
||||
|
||||
|
||||
#== Helper functions for writing complex data structures
|
||||
===============================================================================#
|
||||
|
||||
@ -267,7 +270,7 @@ function _write(grp::Group, name::String, d::AbstractDict)
|
||||
end
|
||||
|
||||
#Write out arbitrary `struct`s:
|
||||
function _writestructgeneric(grp::Group, obj::T) where {T}
|
||||
function _writestructgeneric(grp::Group, obj::T) where T
|
||||
for fname in fieldnames(T)
|
||||
v = getfield(obj, fname)
|
||||
_write_typed(grp, String(fname), v)
|
||||
@ -275,11 +278,12 @@ function _writestructgeneric(grp::Group, obj::T) where {T}
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
#==_write_typed(): More complex structures. (Labels with type name.)
|
||||
===============================================================================#
|
||||
|
||||
#Catch-all (default behaviour for `struct`s):
|
||||
function _write_typed(grp::Group, name::String, v::T) where {T}
|
||||
function _write_typed(grp::Group, name::String, v::T) where T
|
||||
#NOTE: need "name" parameter so that call signature is same with built-ins
|
||||
MT = _type_for_map(T)
|
||||
try #Check to see if type is supported
|
||||
@ -295,12 +299,12 @@ function _write_typed(grp::Group, name::String, v::T) where {T}
|
||||
_writestructgeneric(objgrp, v)
|
||||
end
|
||||
|
||||
function _write_typed(grp::Group, name::String, v::Array{T}) where {T}
|
||||
function _write_typed(grp::Group, name::String, v::Array{T}) where T
|
||||
_write_harray(grp, name, v)
|
||||
_write_datatype_attr(grp[name], Array) #{Any}
|
||||
end
|
||||
|
||||
function _write_typed(grp::Group, name::String, v::Tuple, ::Type{ELT}) where {ELT<:Number} #Basic Tuple
|
||||
function _write_typed(grp::Group, name::String, v::Tuple, ::Type{ELT}) where ELT<: Number #Basic Tuple
|
||||
_write_typed(grp, name, [v...])
|
||||
_write_datatype_attr(grp[name], Tuple)
|
||||
end
|
||||
@ -343,6 +347,7 @@ function _write_typed(grp::Group, name::String, v::Plot)
|
||||
#Don't write plot references
|
||||
end
|
||||
|
||||
|
||||
#==_write(): Write out more complex structures
|
||||
NOTE: No need to write out type information (inferred from hierarchy)
|
||||
===============================================================================#
|
||||
@ -373,11 +378,7 @@ function _write(grp::Group, plt::Plot{HDF5Backend})
|
||||
return
|
||||
end
|
||||
|
||||
function hdf5plot_write(
|
||||
plt::Plot{HDF5Backend},
|
||||
path::AbstractString;
|
||||
name::String = "_unnamed",
|
||||
)
|
||||
function hdf5plot_write(plt::Plot{HDF5Backend}, path::AbstractString; name::String="_unnamed")
|
||||
HDF5.h5open(path, "w") do file
|
||||
HDF5.write_dataset(file, "VERSION_INFO", _get_Plots_versionstr())
|
||||
grp = HDF5.create_group(file, h5plotpath(name))
|
||||
@ -385,6 +386,7 @@ function hdf5plot_write(
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#== _read(): Read data, but not type information.
|
||||
===============================================================================#
|
||||
|
||||
@ -415,6 +417,7 @@ function _read(::Type{Length}, ds::Dataset)
|
||||
end
|
||||
_read(::Type{typeof(datetimeformatter)}, ds::Dataset) = datetimeformatter
|
||||
|
||||
|
||||
#== Helper functions for reading in complex data structures
|
||||
===============================================================================#
|
||||
|
||||
@ -426,7 +429,7 @@ function _read_typed(grp::Group, name::String)
|
||||
end
|
||||
|
||||
#_readstructgeneric: Needs object values to be written out with _write_typed():
|
||||
function _readstructgeneric(::Type{T}, grp::Group) where {T}
|
||||
function _readstructgeneric(::Type{T}, grp::Group) where T
|
||||
vlist = Array{Any}(nothing, fieldcount(T))
|
||||
for (i, fname) in enumerate(fieldnames(T))
|
||||
vlist[i] = _read_typed(grp, String(fname))
|
||||
@ -451,6 +454,7 @@ function _read(::Type{KW}, grp::Group)
|
||||
return d
|
||||
end
|
||||
|
||||
|
||||
#== _read(): More complex structures.
|
||||
===============================================================================#
|
||||
|
||||
@ -459,9 +463,7 @@ _read(T::Type, grp::Group) = _readstructgeneric(T, grp)
|
||||
|
||||
function _read(::Type{Array}, grp::Group) #Array{Any}
|
||||
sz = _read_size_attr(Array, grp)
|
||||
if tuple(0) == sz
|
||||
return []
|
||||
end
|
||||
if tuple(0) == sz; return []; end
|
||||
result = Array{Any}(undef, sz)
|
||||
lidx = LinearIndices(sz)
|
||||
|
||||
@ -496,9 +498,7 @@ function _read(::Type{DefaultsDict}, grp::Group)
|
||||
#User should set DefaultsDict.defaults to one of:
|
||||
# _plot_defaults, _subplot_defaults, _axis_defaults, _series_defaults
|
||||
path = HDF5.name(ds)
|
||||
@warn(
|
||||
"Cannot yet read DefaultsDict using _read_typed():\n $path\nCannot fully reconstruct plot."
|
||||
)
|
||||
@warn("Cannot yet read DefaultsDict using _read_typed():\n $path\nCannot fully reconstruct plot.")
|
||||
end
|
||||
function _read(::Type{Axis}, grp::Group)
|
||||
#1st arg appears to be ref to subplots. Seems to work without it.
|
||||
@ -510,6 +510,7 @@ function _read(::Type{Subplot}, grp::Group)
|
||||
return HDF5PLOT_PLOTREF.ref.subplots[idx]
|
||||
end
|
||||
|
||||
|
||||
#== _read(): Main plot structures
|
||||
===============================================================================#
|
||||
|
||||
@ -558,8 +559,10 @@ function hdf5plot_read(path::AbstractString; name::String = "_unnamed")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end #module _hdf5_implementation
|
||||
|
||||
|
||||
#==Implement Plots.jl backend interface for HDF5Backend
|
||||
===============================================================================#
|
||||
|
||||
@ -637,8 +640,7 @@ end
|
||||
#==Interface actually required to use HDF5Backend
|
||||
===============================================================================#
|
||||
|
||||
hdf5plot_write(plt::Plot{HDF5Backend}, path::AbstractString) =
|
||||
_hdf5_implementation.hdf5plot_write(plt, path)
|
||||
hdf5plot_write(plt::Plot{HDF5Backend}, path::AbstractString) = _hdf5_implementation.hdf5plot_write(plt, path)
|
||||
hdf5plot_write(path::AbstractString) = _hdf5_implementation.hdf5plot_write(current(), path)
|
||||
hdf5plot_read(path::AbstractString) = _hdf5_implementation.hdf5plot_read(path)
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ Add in functionality to Plots.jl:
|
||||
:aspect_ratio,
|
||||
=#
|
||||
|
||||
should_warn_on_unsupported(::InspectDRBackend) = false
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
is_marker_supported(::InspectDRBackend, shape::Shape) = true
|
||||
|
||||
@ -64,18 +64,11 @@ function _inspectdr_add_annotations(plot, x, y, val::PlotText)
|
||||
vmap = Dict{Symbol, Symbol}(:top=>:t, :bottom=>:b) #:vcenter
|
||||
hmap = Dict{Symbol, Symbol}(:left=>:l, :right=>:r) #:hcenter
|
||||
align = Symbol(get(vmap, val.font.valign, :c), get(hmap, val.font.halign, :c))
|
||||
fnt = InspectDR.Font(
|
||||
val.font.family,
|
||||
val.font.pointsize,
|
||||
color = _inspectdr_mapcolor(val.font.color),
|
||||
fnt = InspectDR.Font(val.font.family, val.font.pointsize,
|
||||
color =_inspectdr_mapcolor(val.font.color)
|
||||
)
|
||||
ann = InspectDR.atext(
|
||||
texmath2unicode(val.str),
|
||||
x = x,
|
||||
y = y,
|
||||
font = fnt,
|
||||
angle = val.font.rotation,
|
||||
align = align,
|
||||
ann = InspectDR.atext(val.str, x=x, y=y,
|
||||
font=fnt, angle=val.font.rotation, align=align
|
||||
)
|
||||
InspectDR.add(plot, ann)
|
||||
return
|
||||
@ -91,9 +84,7 @@ function _inspectdr_getaxisticks(ticks, gridlines, xfrm)
|
||||
if ticks == :native
|
||||
#keep current
|
||||
elseif ttype == :ticks_and_labels
|
||||
pos = ticks[1]
|
||||
labels = ticks[2]
|
||||
nticks = length(ticks[1])
|
||||
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
|
||||
@ -154,8 +145,9 @@ end
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
#Glyph used when plotting "Shape"s:
|
||||
INSPECTDR_GLYPH_SHAPE =
|
||||
InspectDR.GlyphPolyline(2 * InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y)
|
||||
INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline(
|
||||
2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y
|
||||
)
|
||||
|
||||
mutable struct InspecDRPlotRef
|
||||
mplot::Union{Nothing, InspectDR.Multiplot}
|
||||
@ -208,9 +200,7 @@ end
|
||||
function _initialize_subplot(plt::Plot{InspectDRBackend}, sp::Subplot{InspectDRBackend})
|
||||
plot = sp.o
|
||||
#Don't do anything without a "subplot" object: Will process later.
|
||||
if nothing == plot
|
||||
return
|
||||
end
|
||||
if nothing == plot; return; end
|
||||
plot.data = []
|
||||
plot.userannot = [] #Clear old markers/text annotation/polyline "annotation"
|
||||
return plot
|
||||
@ -229,9 +219,7 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
|
||||
clims = get_clims(sp, series)
|
||||
|
||||
#Don't do anything without a "subplot" object: Will process later.
|
||||
if nothing == plot
|
||||
return
|
||||
end
|
||||
if nothing == plot; return; end
|
||||
|
||||
_vectorize(v) = isa(v, Vector) ? v : collect(v) #InspectDR only supports vectors
|
||||
x, y = if st == :straightline
|
||||
@ -242,19 +230,16 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
|
||||
|
||||
#No support for polar grid... but can still perform polar transformation:
|
||||
if ispolar(sp)
|
||||
Θ = x
|
||||
r = y
|
||||
x = r .* cos.(Θ)
|
||||
y = r .* sin.(Θ)
|
||||
Θ = x; r = y
|
||||
x = r.*cos.(Θ); y = r.*sin.(Θ)
|
||||
end
|
||||
|
||||
# doesn't handle mismatched x/y - wrap data (pyplot behaviour):
|
||||
nx = length(x)
|
||||
ny = length(y)
|
||||
nx = length(x); ny = length(y)
|
||||
if nx < ny
|
||||
series[:x] = Float64[x[mod1(i, nx)] for i in 1:ny]
|
||||
series[:x] = Float64[x[mod1(i,nx)] for i=1:ny]
|
||||
elseif ny > nx
|
||||
series[:y] = Float64[y[mod1(i, ny)] for i in 1:nx]
|
||||
series[:y] = Float64[y[mod1(i,ny)] for i=1:nx]
|
||||
end
|
||||
|
||||
#= TODO: Eventually support
|
||||
@ -276,12 +261,11 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
|
||||
linecolor = _inspectdr_mapcolor(_cycle(c, i))
|
||||
c = plot_color(get_fillcolor(series), get_fillalpha(series))
|
||||
fillcolor = _inspectdr_mapcolor(_cycle(c, i))
|
||||
line = InspectDR.line(style = :solid, width = linewidth, color = linecolor)
|
||||
line = InspectDR.line(
|
||||
style=:solid, width=linewidth, color=linecolor
|
||||
)
|
||||
apline = InspectDR.PolylineAnnotation(
|
||||
x[rng],
|
||||
y[rng],
|
||||
line = line,
|
||||
fillcolor = fillcolor,
|
||||
x[rng], y[rng], line=line, fillcolor=fillcolor
|
||||
)
|
||||
InspectDR.add(plot, apline)
|
||||
end
|
||||
@ -296,14 +280,11 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
|
||||
fillcolor = _inspectdr_mapcolor(_cycle(c, i))
|
||||
wfrm = InspectDR.add(plot, Float64[], Float64[], id=series[:label])
|
||||
wfrm.line = InspectDR.line(
|
||||
style = :none,
|
||||
width = linewidth, #linewidth affects glyph
|
||||
style=:none, width=linewidth, #linewidth affects glyph
|
||||
)
|
||||
wfrm.glyph = InspectDR.glyph(
|
||||
shape = INSPECTDR_GLYPH_SHAPE,
|
||||
size = 8,
|
||||
color = linecolor,
|
||||
fillcolor = fillcolor,
|
||||
shape = INSPECTDR_GLYPH_SHAPE, size = 8,
|
||||
color = linecolor, fillcolor = fillcolor
|
||||
)
|
||||
end
|
||||
elseif st in (:path, :scatter, :straightline) #, :steppre, :stepmid, :steppost)
|
||||
@ -325,12 +306,8 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
|
||||
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(get_markerstrokecolor(series), get_markerstrokealpha(series))),
|
||||
fillcolor = _inspectdr_mapcolor(plot_color(get_markercolor(series, clims), get_markeralpha(series))),
|
||||
)
|
||||
end
|
||||
|
||||
@ -356,8 +333,7 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
||||
plot = sp.o
|
||||
strip = plot.strips[1] #Only 1 strip supported with Plots.jl
|
||||
|
||||
xaxis = sp[:xaxis]
|
||||
yaxis = sp[:yaxis]
|
||||
xaxis = sp[:xaxis]; yaxis = sp[:yaxis]
|
||||
xgrid_show = xaxis[:grid]
|
||||
ygrid_show = yaxis[:grid]
|
||||
|
||||
@ -384,53 +360,47 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
||||
_inspectdr_setticks(sp, plot, strip, xaxis, yaxis)
|
||||
|
||||
a = plot.annotation
|
||||
a.title = texmath2unicode(sp[:title])
|
||||
a.xlabel = texmath2unicode(xaxis[:guide])
|
||||
a.ylabels = [texmath2unicode(yaxis[:guide])]
|
||||
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
|
||||
#IMPORTANT: Don't forget to actually register changes
|
||||
#(TODO: need to find a better way to set layout properties)
|
||||
l[:frame_canvas].fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
|
||||
l[:frame_canvas] = l[:frame_canvas] #register changes
|
||||
l[:frame_data].fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
|
||||
l[:frame_data] = l[:frame_data] #register changes
|
||||
|
||||
l[:frame_data].line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
|
||||
l[:frame_data] = l[:frame_data] #register changes
|
||||
l[:font_title] = InspectDR.Font(sp[:titlefontfamily],
|
||||
_inspectdr_mapptsize(sp[:titlefontsize]),
|
||||
color = _inspectdr_mapcolor(sp[:titlefontcolor]),
|
||||
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]),
|
||||
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]),
|
||||
color = _inspectdr_mapcolor(xaxis[:tickfontcolor])
|
||||
)
|
||||
l.enable_legend = (sp[:legend_position] != :none)
|
||||
#l.halloc_legend = 150 #TODO: compute???
|
||||
l.font_legend = InspectDR.Font(
|
||||
sp[:legend_font_family],
|
||||
_inspectdr_mapptsize(sp[:legend_font_pointsize]),
|
||||
color = _inspectdr_mapcolor(sp[:legend_font_color]),
|
||||
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[:legend_background_color])
|
||||
#_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])
|
||||
l[:frame_legend] = l[:frame_legend] #register changes
|
||||
end
|
||||
|
||||
# called just before updating layout bounding boxes... in case you need to prep
|
||||
# for the calcs
|
||||
function _before_layout_calcs(plt::Plot{InspectDRBackend})
|
||||
mplot = _inspectdr_getmplot(plt.o)
|
||||
if nothing == mplot
|
||||
return
|
||||
end
|
||||
if nothing == mplot; return; end
|
||||
|
||||
mplot.title = plt[:plot_title]
|
||||
if "" == mplot.title
|
||||
@ -483,9 +453,7 @@ end
|
||||
# to fit ticks, tick labels, guides, colorbars, etc.
|
||||
function _update_min_padding!(sp::Subplot{InspectDRBackend})
|
||||
plot = sp.o
|
||||
if !isa(plot, InspectDR.Plot2D)
|
||||
return sp.minpad
|
||||
end
|
||||
if !isa(plot, InspectDR.Plot2D); return sp.minpad; end
|
||||
#Computing plotbounds with 0-BoundingBox returns required padding:
|
||||
bb = InspectDR.plotbounds(plot.layout.values, InspectDR.BoundingBox(0,0,0,0))
|
||||
#NOTE: plotbounds always pads for titles, legends, etc. even if not in use.
|
||||
@ -504,9 +472,7 @@ end
|
||||
# Override this to update plot items (title, xlabel, etc), and add annotations (plotattributes[:annotations])
|
||||
function _update_plot_object(plt::Plot{InspectDRBackend})
|
||||
mplot = _inspectdr_getmplot(plt.o)
|
||||
if nothing == mplot
|
||||
return
|
||||
end
|
||||
if nothing == mplot; return; end
|
||||
mplot.bblist = InspectDR.BoundingBox[]
|
||||
|
||||
for (i, sp) in enumerate(plt.subplots)
|
||||
@ -520,9 +486,7 @@ function _update_plot_object(plt::Plot{InspectDRBackend})
|
||||
end
|
||||
|
||||
gplot = _inspectdr_getgui(plt.o)
|
||||
if nothing == gplot
|
||||
return
|
||||
end
|
||||
if nothing == gplot; return; end
|
||||
|
||||
gplot.src = mplot #Ensure still references current plot
|
||||
InspectDR.refresh(gplot)
|
||||
@ -558,9 +522,7 @@ end
|
||||
# Display/show the plot (open a GUI window, or browser page, for example).
|
||||
function _display(plt::Plot{InspectDRBackend})
|
||||
mplot = _inspectdr_getmplot(plt.o)
|
||||
if nothing == mplot
|
||||
return
|
||||
end
|
||||
if nothing == mplot; return; end
|
||||
gplot = _inspectdr_getgui(plt.o)
|
||||
|
||||
if nothing == gplot
|
||||
|
||||
@ -8,11 +8,23 @@ Base.@kwdef mutable struct PGFPlotsXPlot
|
||||
function PGFPlotsXPlot(is_created, was_shown, the_plot)
|
||||
pgfx_plot = new(is_created, was_shown, the_plot)
|
||||
# tikz libraries
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, "\\usetikzlibrary{arrows.meta}")
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, "\\usetikzlibrary{backgrounds}")
|
||||
PGFPlotsX.push_preamble!(
|
||||
pgfx_plot.the_plot,
|
||||
"\\usetikzlibrary{arrows.meta}",
|
||||
)
|
||||
PGFPlotsX.push_preamble!(
|
||||
pgfx_plot.the_plot,
|
||||
"\\usetikzlibrary{backgrounds}",
|
||||
)
|
||||
# pgfplots libraries
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, "\\usepgfplotslibrary{patchplots}")
|
||||
PGFPlotsX.push_preamble!(pgfx_plot.the_plot, "\\usepgfplotslibrary{fillbetween}")
|
||||
PGFPlotsX.push_preamble!(
|
||||
pgfx_plot.the_plot,
|
||||
"\\usepgfplotslibrary{patchplots}",
|
||||
)
|
||||
PGFPlotsX.push_preamble!(
|
||||
pgfx_plot.the_plot,
|
||||
"\\usepgfplotslibrary{fillbetween}",
|
||||
)
|
||||
# compatibility fixes
|
||||
# add background layer to standard layers
|
||||
PGFPlotsX.push_preamble!(
|
||||
@ -70,7 +82,6 @@ function surface_to_vecs(x::AVec, y::AVec, s::Union{AMat,Surface})
|
||||
end
|
||||
return xn, yn, zn
|
||||
end
|
||||
surface_to_vecs(x::AVec, y::AVec, z::AVec) = x, y, z
|
||||
|
||||
function Base.push!(pgfx_plot::PGFPlotsXPlot, item)
|
||||
push!(pgfx_plot.the_plot, item)
|
||||
@ -89,9 +100,8 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
extra_plot = wraptuple(extra_plot)
|
||||
push!(the_plot, extra_plot...)
|
||||
end
|
||||
bgc =
|
||||
plt.attr[:background_color_outside] == :match ? plt.attr[:background_color] :
|
||||
plt.attr[:background_color_outside]
|
||||
bgc = plt.attr[:background_color_outside] == :match ?
|
||||
plt.attr[:background_color] : plt.attr[:background_color_outside]
|
||||
if bgc isa Colors.Colorant
|
||||
cstr = plot_color(bgc)
|
||||
a = alpha(cstr)
|
||||
@ -107,27 +117,11 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
end
|
||||
|
||||
for sp in plt.subplots
|
||||
bb1 = sp.plotarea
|
||||
bb2 = bbox(sp)
|
||||
sp_width = width(bb2)
|
||||
sp_height = height(bb2)
|
||||
dx, dy = bb2.x0
|
||||
sp_width = width(bb2)
|
||||
sp_height = height(bb2)
|
||||
if sp[:subplot_index] == plt[:plot_titleindex]
|
||||
x = dx + sp_width / 2 - 10mm # FIXME: get rid of magic constant
|
||||
y = dy + sp_height / 2
|
||||
pgfx_add_annotation!(
|
||||
the_plot,
|
||||
x,
|
||||
y,
|
||||
PlotText(plt[:plot_title], plottitlefont(plt)),
|
||||
pgfx_thickness_scaling(plt);
|
||||
cs = "",
|
||||
options = PGFPlotsX.Options("anchor" => "center"),
|
||||
)
|
||||
continue
|
||||
end
|
||||
|
||||
sp_width = width(bb2)
|
||||
sp_height = height(bb2)
|
||||
lpad = leftpad(sp) + sp[:left_margin]
|
||||
rpad = rightpad(sp) + sp[:right_margin]
|
||||
tpad = toppad(sp) + sp[:top_margin]
|
||||
@ -136,35 +130,61 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
dy += tpad
|
||||
axis_height = sp_height - (tpad + bpad)
|
||||
axis_width = sp_width - (rpad + lpad)
|
||||
|
||||
cstr = plot_color(sp[:background_color_legend])
|
||||
a = alpha(cstr)
|
||||
fg_alpha = alpha(plot_color(sp[:foreground_color_legend]))
|
||||
title_cstr = plot_color(sp[:titlefontcolor])
|
||||
title_a = alpha(title_cstr)
|
||||
title_loc = sp[:titlelocation]
|
||||
bgc_inside = plot_color(sp[:background_color_inside])
|
||||
bgc_inside_a = alpha(bgc_inside)
|
||||
update_clims(sp)
|
||||
axis_opt = PGFPlotsX.Options(
|
||||
"point meta max" => get_clims(sp)[2],
|
||||
"point meta min" => get_clims(sp)[1],
|
||||
"legend cell align" => "left",
|
||||
"legend columns" => pgfx_legend_col(sp[:legend_column]),
|
||||
"title" => sp[:title],
|
||||
"title style" => PGFPlotsX.Options(
|
||||
pgfx_get_title_pos(title_loc)...,
|
||||
"font" => pgfx_font(sp[:titlefontsize], pgfx_thickness_scaling(sp)),
|
||||
"font" => pgfx_font(
|
||||
sp[:titlefontsize],
|
||||
pgfx_thickness_scaling(sp),
|
||||
),
|
||||
"color" => title_cstr,
|
||||
"draw opacity" => title_a,
|
||||
"rotate" => sp[:titlefontrotation],
|
||||
),
|
||||
"legend style" => pgfx_get_legend_style(sp),
|
||||
"axis background/.style" =>
|
||||
PGFPlotsX.Options("fill" => bgc_inside, "opacity" => bgc_inside_a),
|
||||
"legend style" => PGFPlotsX.Options(
|
||||
pgfx_linestyle(
|
||||
pgfx_thickness_scaling(sp),
|
||||
sp[:foreground_color_legend],
|
||||
fg_alpha,
|
||||
"solid",
|
||||
) => nothing,
|
||||
"fill" => cstr,
|
||||
"fill opacity" => a,
|
||||
"text opacity" => alpha(plot_color(sp[:legendfontcolor])),
|
||||
"font" => pgfx_font(
|
||||
sp[:legendfontsize],
|
||||
pgfx_thickness_scaling(sp),
|
||||
),
|
||||
"text" => plot_color(sp[:legendfontcolor]),
|
||||
),
|
||||
"axis background/.style" => PGFPlotsX.Options(
|
||||
"fill" => bgc_inside,
|
||||
"opacity" => bgc_inside_a,
|
||||
),
|
||||
# These are for layouting
|
||||
"anchor" => "north west",
|
||||
"xshift" => string(dx),
|
||||
"yshift" => string(-dy),
|
||||
)
|
||||
sp_width > 0 * mm ? push!(axis_opt, "width" => string(axis_width)) : nothing
|
||||
sp_height > 0 * mm ? push!(axis_opt, "height" => string(axis_height)) : nothing
|
||||
sp_width > 0 * mm ? push!(axis_opt, "width" => string(axis_width)) :
|
||||
nothing
|
||||
sp_height > 0 * mm ? push!(axis_opt, "height" => string(axis_height)) :
|
||||
nothing
|
||||
# legend position
|
||||
push!(axis_opt["legend style"], pgfx_get_legend_pos(sp[:legend])...)
|
||||
for letter in (:x, :y, :z)
|
||||
if letter != :z || RecipesPipeline.is3d(sp)
|
||||
pgfx_axis!(axis_opt, sp, letter)
|
||||
@ -205,23 +225,16 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
@label colorbar_end
|
||||
|
||||
if hascolorbar(sp)
|
||||
cticks = get_colorbar_ticks(sp)[2]
|
||||
colorbar_style = PGFPlotsX.Options(
|
||||
"title" => sp[:colorbar_title],
|
||||
"xticklabel style" => pgfx_get_ticklabel_style(sp, sp[:xaxis]),
|
||||
"yticklabel style" => pgfx_get_ticklabel_style(sp, sp[:yaxis]),
|
||||
)
|
||||
if sp[:colorbar] === :top
|
||||
colorbar_style = PGFPlotsX.Options("xlabel" => sp[:colorbar_title])
|
||||
push!(
|
||||
colorbar_style,
|
||||
push!(colorbar_style,
|
||||
"at" => string((0.5, 1.05)),
|
||||
"anchor" => "south",
|
||||
"xtick" => string("{", join(cticks, ","), "}"),
|
||||
"xticklabel pos" => "upper",
|
||||
"xticklabel style" => pgfx_get_colorbar_ticklabel_style(sp),
|
||||
)
|
||||
else
|
||||
colorbar_style = PGFPlotsX.Options("ylabel" => sp[:colorbar_title])
|
||||
push!(
|
||||
colorbar_style,
|
||||
"ytick" => string("{", join(cticks, ","), "}"),
|
||||
"yticklabel style" => pgfx_get_colorbar_ticklabel_style(sp),
|
||||
)
|
||||
end
|
||||
push!(
|
||||
@ -229,8 +242,6 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
string("colorbar", pgfx_get_colorbar_pos(sp[:colorbar])) => nothing,
|
||||
"colorbar style" => colorbar_style,
|
||||
)
|
||||
else
|
||||
push!(axis_opt, "colorbar" => "false")
|
||||
end
|
||||
if RecipesPipeline.is3d(sp)
|
||||
azim, elev = sp[:camera]
|
||||
@ -249,18 +260,12 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
extra_sp = wraptuple(extra_sp)
|
||||
push!(axis, extra_sp...)
|
||||
end
|
||||
if sp[:legend_title] !== nothing
|
||||
legtfont = legendtitlefont(sp)
|
||||
if sp[:legendtitle] !== nothing
|
||||
push!(axis, PGFPlotsX.Options("\\addlegendimage{empty legend}" => nothing))
|
||||
push!(
|
||||
axis,
|
||||
PGFPlotsX.LegendEntry(
|
||||
PGFPlotsX.Options(
|
||||
"font" =>
|
||||
pgfx_font(legtfont.pointsize, pgfx_thickness_scaling(sp)),
|
||||
"text" => legtfont.color,
|
||||
),
|
||||
string("\\hspace{-.6cm}{\\textbf{", sp[:legend_title], "}}"),
|
||||
string("\\hspace{-.6cm}{\\textbf{", sp[:legendtitle], "}}"),
|
||||
false,
|
||||
),
|
||||
)
|
||||
@ -276,19 +281,15 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
"color" => single_color(opt[:linecolor]),
|
||||
"name path" => string(series_id),
|
||||
)
|
||||
extra_series, extra_series_opt =
|
||||
pgfx_split_extra_opts(series[:extra_kwargs])
|
||||
extra_series, extra_series_opt = pgfx_split_extra_opts(series[:extra_kwargs])
|
||||
series_opt = merge(series_opt, PGFPlotsX.Options(extra_series_opt...))
|
||||
if (
|
||||
RecipesPipeline.is3d(series) ||
|
||||
st in (:heatmap, :contour) ||
|
||||
(st == :quiver && opt[:z] !== nothing)
|
||||
)
|
||||
if RecipesPipeline.is3d(series) || st in (:heatmap, :contour) || (st == :quiver && opt[:z] !== nothing)
|
||||
series_func = PGFPlotsX.Plot3
|
||||
else
|
||||
series_func = PGFPlotsX.Plot
|
||||
end
|
||||
if sf !== nothing && !isfilledcontour(series) && series[:ribbon] === nothing
|
||||
if sf !== nothing &&
|
||||
!isfilledcontour(series) && series[:ribbon] === nothing
|
||||
push!(series_opt, "area legend" => nothing)
|
||||
end
|
||||
pgfx_add_series!(Val(st), axis, series_opt, series, series_func, opt)
|
||||
@ -338,9 +339,9 @@ end
|
||||
|
||||
function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, opt)
|
||||
# treat segments
|
||||
segments = collect(series_segments(series, series[:seriestype]; check = true))
|
||||
segments = collect(series_segments(series, series[:seriestype]))
|
||||
sf = opt[:fillrange]
|
||||
for (k, segment) in enumerate(segments)
|
||||
for segment in segments
|
||||
i, rng = segment.attr_index, segment.range
|
||||
segment_opt = PGFPlotsX.Options()
|
||||
segment_opt = merge(segment_opt, pgfx_linestyle(opt, i))
|
||||
@ -352,7 +353,10 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
|
||||
scale_factor = 0.00125
|
||||
mark_size = opt[:markersize] * scale_factor
|
||||
path = join(
|
||||
["($(x[i] * mark_size), $(y[i] * mark_size))" for i in eachindex(x)],
|
||||
[
|
||||
"($(x[i] * mark_size), $(y[i] * mark_size))"
|
||||
for i in eachindex(x)
|
||||
],
|
||||
" -- ",
|
||||
)
|
||||
c = get_markercolor(series, i)
|
||||
@ -370,9 +374,17 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
|
||||
segment_opt = merge(segment_opt, pgfx_marker(opt, i))
|
||||
end
|
||||
# add fillrange
|
||||
if sf !== nothing && !isfilledcontour(series)
|
||||
if sf !== nothing &&
|
||||
!isfilledcontour(series)
|
||||
if sf isa Number || sf isa AVec
|
||||
pgfx_fillrange_series!(axis, series, series_func, i, _cycle(sf, rng), rng)
|
||||
pgfx_fillrange_series!(
|
||||
axis,
|
||||
series,
|
||||
series_func,
|
||||
i,
|
||||
_cycle(sf, rng),
|
||||
rng,
|
||||
)
|
||||
elseif sf isa Tuple && series[:ribbon] !== nothing
|
||||
for sfi in sf
|
||||
pgfx_fillrange_series!(
|
||||
@ -386,8 +398,7 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
|
||||
end
|
||||
end
|
||||
if i == 1 &&
|
||||
series[:subplot][:legend_position] != :none &&
|
||||
pgfx_should_add_to_legend(series)
|
||||
series[:subplot][:legend] != :none && pgfx_should_add_to_legend(series)
|
||||
pgfx_filllegend!(series_opt, opt)
|
||||
end
|
||||
end
|
||||
@ -396,22 +407,18 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
|
||||
if arrow isa Arrow
|
||||
arrow_opt = merge(
|
||||
segment_opt,
|
||||
PGFPlotsX.Options(
|
||||
"quiver" => PGFPlotsX.Options(
|
||||
PGFPlotsX.Options("quiver" => PGFPlotsX.Options(
|
||||
"u" => "\\thisrow{u}",
|
||||
"v" => "\\thisrow{v}",
|
||||
pgfx_arrow(arrow, :head) => nothing,
|
||||
),
|
||||
),
|
||||
)
|
||||
if opt[:label] == ""
|
||||
push!(arrow_opt, "forget plot" => nothing)
|
||||
end
|
||||
)
|
||||
)
|
||||
if arrow.side == :head
|
||||
x_arrow = opt[:x][rng][(end - 1):end]
|
||||
y_arrow = opt[:y][rng][(end - 1):end]
|
||||
x_path = opt[:x][rng][1:(end - 1)]
|
||||
y_path = opt[:y][rng][1:(end - 1)]
|
||||
x_arrow = opt[:x][rng][end-1:end]
|
||||
y_arrow = opt[:y][rng][end-1:end]
|
||||
x_path = opt[:x][rng][1:end-1]
|
||||
y_path = opt[:y][rng][1:end-1]
|
||||
elseif arrow.side == :tail
|
||||
x_arrow = opt[:x][rng][2:-1:1]
|
||||
y_arrow = opt[:y][rng][2:-1:1]
|
||||
@ -420,24 +427,26 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
|
||||
elseif arrow.side == :both
|
||||
x_arrow = opt[:x][rng][[2,1,end-1,end]]
|
||||
y_arrow = opt[:y][rng][[2,1,end-1,end]]
|
||||
x_path = opt[:x][rng][2:(end - 1)]
|
||||
y_path = opt[:y][rng][2:(end - 1)]
|
||||
x_path = opt[:x][rng][2:end-1]
|
||||
y_path = opt[:y][rng][2:end-1]
|
||||
end
|
||||
coordinates = PGFPlotsX.Table([
|
||||
:x => x_arrow[1:2:(end - 1)],
|
||||
:y => y_arrow[1:2:(end - 1)],
|
||||
:x => x_arrow[1:2:end-1],
|
||||
:y => y_arrow[1:2:end-1],
|
||||
:u => [x_arrow[i] - x_arrow[i-1] for i in 2:2:lastindex(x_arrow)],
|
||||
:v => [y_arrow[i] - y_arrow[i-1] for i in 2:2:lastindex(y_arrow)],
|
||||
])
|
||||
arrow_plot = series_func(merge(series_opt, arrow_opt), coordinates)
|
||||
push!(series_opt, "forget plot" => nothing)
|
||||
arrow_plot =
|
||||
series_func(merge(series_opt, arrow_opt), coordinates)
|
||||
push!(axis, arrow_plot)
|
||||
coordinates = PGFPlotsX.Table(x_path, y_path)
|
||||
segment_plot = series_func(merge(series_opt, segment_opt), coordinates)
|
||||
segment_plot =
|
||||
series_func(merge(series_opt, segment_opt), coordinates)
|
||||
push!(axis, segment_plot)
|
||||
else
|
||||
coordinates = PGFPlotsX.Table(pgfx_series_arguments(series, opt, rng)...)
|
||||
segment_plot = series_func(merge(series_opt, segment_opt), coordinates)
|
||||
segment_plot =
|
||||
series_func(merge(series_opt, segment_opt), coordinates)
|
||||
push!(axis, segment_plot)
|
||||
end
|
||||
# fill between functions
|
||||
@ -455,14 +464,11 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
|
||||
),
|
||||
)
|
||||
end
|
||||
pgfx_add_legend!(axis, series, opt, k)
|
||||
pgfx_add_legend!(axis, series, opt, i)
|
||||
end # for segments
|
||||
# get that last marker
|
||||
if !isnothing(opt[:y]) && !any(isnan, opt[:y]) && opt[:markershape] isa AVec
|
||||
additional_plot = PGFPlotsX.PlotInc(
|
||||
pgfx_marker(opt, length(segments) + 1),
|
||||
PGFPlotsX.Coordinates(tuple((last(opt[:x]), last(opt[:y])))),
|
||||
)
|
||||
additional_plot = PGFPlotsX.PlotInc(pgfx_marker(opt, length(segments) + 1), PGFPlotsX.Coordinates(tuple((last(opt[:x]), last(opt[:y])))))
|
||||
push!(axis, additional_plot)
|
||||
end
|
||||
end
|
||||
@ -486,20 +492,21 @@ function pgfx_add_series!(::Val{:scatter3d}, axis, series_opt, series, series_fu
|
||||
end
|
||||
|
||||
function pgfx_add_series!(::Val{:surface}, axis, series_opt, series, series_func, opt)
|
||||
alpha = get_fillalpha(series)
|
||||
push!(
|
||||
series_opt,
|
||||
"surf" => nothing,
|
||||
"mesh/rows" => length(unique(opt[:x])), # unique if its all vectors
|
||||
"mesh/cols" => length(unique(opt[:y])),
|
||||
"mesh/rows" => length(opt[:x]),
|
||||
"mesh/cols" => length(opt[:y]),
|
||||
"z buffer" => "sort",
|
||||
"opacity" => alpha === nothing ? 1.0 : alpha,
|
||||
"opacity" => get_fillalpha(series),
|
||||
)
|
||||
pgfx_add_series!(axis, series_opt, series, series_func, opt)
|
||||
end
|
||||
|
||||
function pgfx_add_series!(::Val{:wireframe}, axis, series_opt, series, series_func, opt)
|
||||
push!(series_opt, "mesh" => nothing, "mesh/rows" => length(opt[:x]))
|
||||
push!(series_opt, "mesh" => nothing,
|
||||
"mesh/rows" => length(opt[:x])
|
||||
)
|
||||
pgfx_add_series!(axis, series_opt, series, series_func, opt)
|
||||
end
|
||||
|
||||
@ -524,34 +531,12 @@ function pgfx_add_series!(::Val{:heatmap}, axis, series_opt, series, series_func
|
||||
end
|
||||
|
||||
function pgfx_add_series!(::Val{:mesh3d}, axis, series_opt, series, series_func, opt)
|
||||
if opt[:connections] isa Tuple{Array,Array,Array}
|
||||
# 0-based indexing
|
||||
ptable = join(
|
||||
[string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)],
|
||||
"\n ",
|
||||
)
|
||||
elseif typeof(opt[:connections]) <: AbstractVector{NTuple{3,Int}}
|
||||
# 1-based indexing
|
||||
ptable = join(
|
||||
[
|
||||
string(i - 1, " ", j - 1, " ", k - 1, "\\\\") for
|
||||
(i, j, k) in opt[:connections]
|
||||
],
|
||||
"\n ",
|
||||
)
|
||||
else
|
||||
throw(
|
||||
ArgumentError(
|
||||
"Argument connections has to be either a tuple of three arrays (0-based indexing)
|
||||
or an AbstractVector{NTuple{3,Int}} (1-based indexing).",
|
||||
),
|
||||
)
|
||||
end
|
||||
ptable = join([ string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...) ], "\n ")
|
||||
push!(
|
||||
series_opt,
|
||||
"patch" => nothing,
|
||||
"table/row sep" => "\\\\",
|
||||
"patch table" => ptable,
|
||||
"patch table" => ptable
|
||||
)
|
||||
pgfx_add_series!(axis, series_opt, series, series_func, opt)
|
||||
end
|
||||
@ -588,8 +573,7 @@ function pgfx_add_series!(::Val{:contour3d}, axis, series_opt, series, series_fu
|
||||
)
|
||||
series_opt = merge( series_opt, pgfx_linestyle(opt) )
|
||||
args = pgfx_series_arguments(series, opt)
|
||||
series_plot =
|
||||
series_func(series_opt, PGFPlotsX.Table(Contour.contours(args..., opt[:levels])))
|
||||
series_plot = series_func(series_opt, PGFPlotsX.Table(Contour.contours(args..., opt[:levels])))
|
||||
push!(axis, series_plot)
|
||||
pgfx_add_legend!(axis, series, opt)
|
||||
end
|
||||
@ -664,7 +648,7 @@ function pgfx_add_series!(::Val{:xsticks}, axis, series_opt, series, series_func
|
||||
end
|
||||
|
||||
function pgfx_add_legend!(axis, series, opt, i = 1)
|
||||
if series[:subplot][:legend_position] != :none
|
||||
if series[:subplot][:legend] != :none
|
||||
leg_entry = if opt[:label] isa AVec
|
||||
get(opt[:label], i, "")
|
||||
elseif opt[:label] isa AbstractString
|
||||
@ -687,8 +671,7 @@ function pgfx_add_legend!(axis, series, opt, i = 1)
|
||||
return nothing
|
||||
end
|
||||
|
||||
pgfx_series_arguments(series, opt, range) =
|
||||
(arg[range] for arg in pgfx_series_arguments(series, opt))
|
||||
pgfx_series_arguments(series, opt, range) = (arg[range] for arg in pgfx_series_arguments(series, opt))
|
||||
function pgfx_series_arguments(series, opt)
|
||||
st = series[:seriestype]
|
||||
return if st in (:contour, :contour3d)
|
||||
@ -726,7 +709,7 @@ pgfx_get_marker(k) = get(
|
||||
none = "none",
|
||||
cross = "+",
|
||||
xcross = "x",
|
||||
(+) = "+",
|
||||
+ = "+",
|
||||
x = "x",
|
||||
utriangle = "triangle*",
|
||||
dtriangle = "triangle*",
|
||||
@ -752,7 +735,7 @@ pgfx_get_xguide_pos(k) = get(
|
||||
left = "at={(ticklabel* cs:-0.02)}, anchor=east,",
|
||||
),
|
||||
k,
|
||||
"at={(ticklabel cs:0.5)}, anchor=near ticklabel",
|
||||
"at={(ticklabel cs:0.5)}, anchor=near ticklabel"
|
||||
)
|
||||
|
||||
pgfx_get_yguide_pos(k) = get(
|
||||
@ -762,7 +745,7 @@ pgfx_get_yguide_pos(k) = get(
|
||||
bottom = "at={(ticklabel* cs:-0.02)}, anchor=north,",
|
||||
),
|
||||
k,
|
||||
"at={(ticklabel cs:0.5)}, anchor=near ticklabel",
|
||||
"at={(ticklabel cs:0.5)}, anchor=near ticklabel"
|
||||
)
|
||||
|
||||
pgfx_get_legend_pos(k) = get(
|
||||
@ -787,17 +770,15 @@ pgfx_get_legend_pos(k) = get(
|
||||
Symbol(k),
|
||||
("at" => string((1.02, 1)), "anchor" => "north west"),
|
||||
)
|
||||
pgfx_get_legend_pos(t::Tuple{S,T}) where {S<:Real,T<:Real} =
|
||||
("at" => "{$(string(t))}", "anchor" => "north west")
|
||||
pgfx_get_legend_pos(nt::NamedTuple) =
|
||||
("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
|
||||
pgfx_get_legend_pos(t::Tuple{S,T}) where {S<:Real,T<:Real} = ("at" => "{$(string(t))}", "anchor" => "north west")
|
||||
pgfx_get_legend_pos(nt::NamedTuple) = ("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
|
||||
pgfx_get_legend_pos(theta::Real) = pgfx_get_legend_pos((theta,:inner))
|
||||
function pgfx_get_legend_pos(v::Tuple{S,Symbol}) where {S<:Real}
|
||||
function pgfx_get_legend_pos(v::Tuple{S,Symbol}) where S <: Real
|
||||
(s,c) = sincosd(v[1])
|
||||
anchors = [
|
||||
"south west" "south" "south east"
|
||||
"west" "center" "east"
|
||||
"north west" "north" "north east"
|
||||
"south west" "south" "south east";
|
||||
"west" "center" "east";
|
||||
"north west" "north" "north east";
|
||||
]
|
||||
|
||||
if v[2] === :inner
|
||||
@ -810,70 +791,33 @@ function pgfx_get_legend_pos(v::Tuple{S,Symbol}) where {S<:Real}
|
||||
return ("at"=>"$(string(legend_pos_from_angle(v[1],rect...)))", "anchor"=>anchor)
|
||||
end
|
||||
|
||||
function pgfx_get_legend_style(sp)
|
||||
cstr = plot_color(sp[:legend_background_color])
|
||||
a = alpha(cstr)
|
||||
fg_alpha = alpha(plot_color(sp[:legend_foreground_color]))
|
||||
legfont = legendfont(sp)
|
||||
PGFPlotsX.Options(
|
||||
pgfx_linestyle(
|
||||
pgfx_thickness_scaling(sp),
|
||||
sp[:legend_foreground_color],
|
||||
fg_alpha,
|
||||
"solid",
|
||||
) => nothing,
|
||||
"fill" => cstr,
|
||||
"fill opacity" => a,
|
||||
"text opacity" => alpha(plot_color(sp[:legend_font_color])),
|
||||
"font" => pgfx_font(sp[:legend_font_pointsize], pgfx_thickness_scaling(sp)),
|
||||
"text" => plot_color(sp[:legend_font_color]),
|
||||
"cells" => PGFPlotsX.Options(
|
||||
"anchor" => get(
|
||||
(left = "west", right = "east", hcenter = "center"),
|
||||
legfont.halign,
|
||||
"west",
|
||||
),
|
||||
),
|
||||
pgfx_get_legend_pos(sp[:legend_position])...,
|
||||
)
|
||||
end
|
||||
|
||||
pgfx_get_colorbar_pos(s) =
|
||||
get((left = " left", bottom = " horizontal", top = " horizontal"), s, "")
|
||||
pgfx_get_colorbar_pos(b::Bool) = ""
|
||||
|
||||
pgfx_get_title_pos(s) = get(
|
||||
(
|
||||
pgfx_get_title_pos(s) =
|
||||
get((
|
||||
left = ("at" => "{(0,1)}", "anchor" => "south west"),
|
||||
right = ("at" => "{(1,1)}", "anchor" => "south east"),
|
||||
),
|
||||
s,
|
||||
("at" => "{(0.5,1)}", "anchor" => "south"),
|
||||
)
|
||||
), s,
|
||||
("at" => "{(0.5,1)}", "anchor" => "south"))
|
||||
pgfx_get_title_pos(t::Tuple) = ("at" => "{$(string(t))}", "anchor" => "south")
|
||||
pgfx_get_title_pos(nt::NamedTuple) =
|
||||
("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
|
||||
pgfx_get_title_pos(nt::NamedTuple) = ("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
|
||||
|
||||
function pgfx_get_ticklabel_style(sp, axis)
|
||||
cstr = plot_color(axis[:tickfontcolor])
|
||||
return PGFPlotsX.Options(
|
||||
"font" => pgfx_font(axis[:tickfontsize], pgfx_thickness_scaling(sp)),
|
||||
"font" => pgfx_font(
|
||||
axis[:tickfontsize], pgfx_thickness_scaling(sp)
|
||||
),
|
||||
"color" => cstr,
|
||||
"draw opacity" => alpha(cstr),
|
||||
"rotate" => axis[:tickfontrotation],
|
||||
)
|
||||
end
|
||||
|
||||
function pgfx_get_colorbar_ticklabel_style(sp)
|
||||
cstr = plot_color(sp[:colorbar_tickfontcolor])
|
||||
return PGFPlotsX.Options(
|
||||
"font" => pgfx_font(sp[:colorbar_tickfontsize], pgfx_thickness_scaling(sp)),
|
||||
"color" => cstr,
|
||||
"draw opacity" => alpha(cstr),
|
||||
"rotate" => sp[:colorbar_tickfontrotation],
|
||||
)
|
||||
end
|
||||
## --------------------------------------------------------------------------------------
|
||||
# Generates a colormap for pgfplots based on a ColorGradient
|
||||
pgfx_arrow(::Nothing) = "every arrow/.append style={-}"
|
||||
function pgfx_arrow(arr::Arrow, side = arr.side)
|
||||
components = String[]
|
||||
@ -904,7 +848,6 @@ function pgfx_filllegend!(series_opt, opt)
|
||||
}""")
|
||||
end
|
||||
|
||||
# Generates a colormap for pgfplots based on a ColorGradient
|
||||
pgfx_colormap(cl::PlotUtils.AbstractColorList) = pgfx_colormap(color_list(cl))
|
||||
function pgfx_colormap(v::Vector{<:Colorant})
|
||||
join(map(v) do c
|
||||
@ -912,26 +855,18 @@ function pgfx_colormap(v::Vector{<:Colorant})
|
||||
end, "\n")
|
||||
end
|
||||
function pgfx_colormap(cg::ColorGradient)
|
||||
join(
|
||||
map(1:length(cg)) do i
|
||||
@sprintf(
|
||||
"rgb(%.8f)=(%.8f,%.8f,%.8f)",
|
||||
cg.values[i],
|
||||
red(cg.colors[i]),
|
||||
green(cg.colors[i]),
|
||||
blue(cg.colors[i])
|
||||
)
|
||||
end,
|
||||
"\n",
|
||||
)
|
||||
join(map(1:length(cg)) do i
|
||||
@sprintf("rgb(%.8f)=(%.8f,%.8f,%.8f)", cg.values[i], red(cg.colors[i]), green(cg.colors[i]), blue(cg.colors[i]))
|
||||
end, "\n")
|
||||
end
|
||||
|
||||
|
||||
function pgfx_framestyle(style::Symbol)
|
||||
if style in (:box, :axes, :origin, :zerolines, :grid, :none)
|
||||
return style
|
||||
else
|
||||
default_style = get((semi = :box,), style, :axes)
|
||||
@warn "Framestyle :$style is not (yet) supported by the PGFPlotsX backend. :$default_style was chosen instead."
|
||||
@warn( "Framestyle :$style is not (yet) supported by the PGFPlotsX backend. :$default_style was cosen instead.",)
|
||||
default_style
|
||||
end
|
||||
end
|
||||
@ -960,9 +895,6 @@ function pgfx_linestyle(linewidth::Real, color, α = 1, linestyle = :solid)
|
||||
)
|
||||
end
|
||||
|
||||
pgfx_legend_col(s::Symbol) = s == :horizontal ? -1 : 1
|
||||
pgfx_legend_col(n) = n
|
||||
|
||||
function pgfx_linestyle(plotattributes, i = 1)
|
||||
lw = pgfx_thickness_scaling(plotattributes) * get_linewidth(plotattributes, i)
|
||||
lc = single_color(get_linecolor(plotattributes, i))
|
||||
@ -984,7 +916,8 @@ function pgfx_font(fontsize::Nothing, thickness_scaling = 1, font = "\\selectfon
|
||||
end
|
||||
|
||||
function pgfx_should_add_to_legend(series::Series)
|
||||
series.plotattributes[:primary] && !(
|
||||
series.plotattributes[:primary] &&
|
||||
!(
|
||||
series.plotattributes[:seriestype] in (
|
||||
:hexbin,
|
||||
:bins2d,
|
||||
@ -1014,8 +947,7 @@ function pgfx_marker(plotattributes, i = 1)
|
||||
pgfx_thickness_scaling(plotattributes) *
|
||||
0.75 *
|
||||
_cycle(plotattributes[:markersize], i)
|
||||
mark_freq =
|
||||
!any(isnan, plotattributes[:y]) && plotattributes[:markershape] isa AVec ?
|
||||
mark_freq = !any(isnan, plotattributes[:y]) && plotattributes[:markershape] isa AVec ?
|
||||
length(plotattributes[:markershape]) : 1
|
||||
return PGFPlotsX.Options(
|
||||
"mark" => shape isa Shape ? "PlotsShape$i" : pgfx_get_marker(shape),
|
||||
@ -1039,47 +971,29 @@ function pgfx_marker(plotattributes, i = 1)
|
||||
else
|
||||
0
|
||||
end,
|
||||
pgfx_get_linestyle(_cycle(plotattributes[:markerstrokestyle], i)) =>
|
||||
nothing,
|
||||
pgfx_get_linestyle(_cycle(plotattributes[:markerstrokestyle], i)) => nothing,
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
function pgfx_add_annotation!(
|
||||
o,
|
||||
x,
|
||||
y,
|
||||
val,
|
||||
thickness_scaling = 1;
|
||||
cs = "axis cs:",
|
||||
options = PGFPlotsX.Options(),
|
||||
)
|
||||
function pgfx_add_annotation!(o, x, y, val, thickness_scaling = 1)
|
||||
# Construct the style string.
|
||||
cstr = val.font.color
|
||||
a = alpha(cstr)
|
||||
push!(
|
||||
o,
|
||||
join([
|
||||
[
|
||||
"\\node",
|
||||
sprint(
|
||||
PGFPlotsX.print_tex,
|
||||
merge(
|
||||
PGFPlotsX.Options(
|
||||
get(
|
||||
(hcenter = "", left = "right", right = "left"),
|
||||
val.font.halign,
|
||||
"",
|
||||
) => nothing,
|
||||
get((center = "", left = "right", right = "left"), val.font.halign, "") =>
|
||||
nothing,
|
||||
"color" => cstr,
|
||||
"draw opacity" => convert(Float16, a),
|
||||
"rotate" => val.font.rotation,
|
||||
"font" => pgfx_font(val.font.pointsize, thickness_scaling),
|
||||
),
|
||||
options,
|
||||
),
|
||||
),
|
||||
string(" at (", cs, x, ",", y, ") {", val.str, "};"),
|
||||
]),
|
||||
" at (axis cs:$x, $y) {$(val.str)};",
|
||||
],
|
||||
)
|
||||
end
|
||||
|
||||
@ -1144,13 +1058,15 @@ end
|
||||
function pgfx_fillrange_series!(axis, series, series_func, i, fillrange, rng)
|
||||
fillrange_opt = PGFPlotsX.Options("line width" => "0", "draw opacity" => "0")
|
||||
fillrange_opt = merge(fillrange_opt, pgfx_fillstyle(series, i))
|
||||
push!(fillrange_opt, "mark" => "none") # no markers on fillranges
|
||||
fillrange_opt = merge(fillrange_opt, pgfx_marker(series, i))
|
||||
push!(fillrange_opt, "forget plot" => nothing)
|
||||
opt = series.plotattributes
|
||||
args =
|
||||
RecipesPipeline.is3d(series) ? (opt[:x][rng], opt[:y][rng], opt[:z][rng]) :
|
||||
args = RecipesPipeline.is3d(series) ? (opt[:x][rng], opt[:y][rng], opt[:z][rng]) :
|
||||
(opt[:x][rng], opt[:y][rng])
|
||||
push!(axis, PGFPlotsX.PlotInc(fillrange_opt, pgfx_fillrange_args(fillrange, args...)))
|
||||
push!(
|
||||
axis,
|
||||
PGFPlotsX.PlotInc(fillrange_opt, pgfx_fillrange_args(fillrange, args...)),
|
||||
)
|
||||
return axis
|
||||
end
|
||||
|
||||
@ -1202,24 +1118,16 @@ function pgfx_sanitize_plot!(plt)
|
||||
if key == :annotations && subplot.attr[:annotations] !== nothing
|
||||
old_ann = subplot.attr[key]
|
||||
for i in eachindex(old_ann)
|
||||
subplot.attr[key][i] =
|
||||
(old_ann[i][1], old_ann[i][2], pgfx_sanitize_string(old_ann[i][3]))
|
||||
subplot.attr[key][i] = (old_ann[i][1], old_ann[i][2], pgfx_sanitize_string(old_ann[i][3]))
|
||||
end
|
||||
elseif value isa Union{AbstractString, AbstractVector{<:AbstractString}}
|
||||
subplot.attr[key] = pgfx_sanitize_string.(value)
|
||||
elseif value isa Axis
|
||||
for (k, v) in value.plotattributes
|
||||
if v isa Union{AbstractString,AbstractVector{<:AbstractString}}
|
||||
value.plotattributes[k] = pgfx_sanitize_string.(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for series in plt.series_list
|
||||
for (key, value) in series.plotattributes
|
||||
if key == :series_annotations &&
|
||||
series.plotattributes[:series_annotations] !== nothing
|
||||
if key == :series_annotations && series.plotattributes[:series_annotations] !== nothing
|
||||
old_ann = series.plotattributes[key].strs
|
||||
for i in eachindex(old_ann)
|
||||
series.plotattributes[key].strs[i] = pgfx_sanitize_string(old_ann[i])
|
||||
@ -1231,37 +1139,29 @@ function pgfx_sanitize_plot!(plt)
|
||||
end
|
||||
##
|
||||
end
|
||||
|
||||
function wrap_power_labels(ticks)
|
||||
# wrap the power part of label with }
|
||||
tick_labels = similar(ticks)
|
||||
for (i, label) in enumerate(ticks)
|
||||
base, power = split(label, "^")
|
||||
power = string("{", power, "}")
|
||||
tick_labels[i] = string(base, "^", power)
|
||||
end
|
||||
tick_labels
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
axis = sp[get_attr_symbol(letter, :axis)]
|
||||
axis = sp[Symbol(letter, :axis)]
|
||||
|
||||
# turn off scaled ticks
|
||||
push!(opt, "scaled $(letter) ticks" => "false", string(letter, :label) => axis[:guide])
|
||||
tick_color = plot_color(axis[:foreground_color_axis])
|
||||
push!(
|
||||
opt,
|
||||
"$(letter) tick style" =>
|
||||
PGFPlotsX.Options("color" => color(tick_color), "opacity" => alpha(tick_color)),
|
||||
"scaled $(letter) ticks" => "false",
|
||||
string(letter, :label) => axis[:guide],
|
||||
)
|
||||
tick_color = plot_color(axis[:foreground_color_axis])
|
||||
push!(opt,
|
||||
"$(letter) tick style" => PGFPlotsX.Options(
|
||||
"color" => color(tick_color),
|
||||
"opacity" => alpha(tick_color),
|
||||
),
|
||||
)
|
||||
tick_label_color = plot_color(axis[:tickfontcolor])
|
||||
push!(
|
||||
opt,
|
||||
push!(opt,
|
||||
"$(letter) tick label style" => PGFPlotsX.Options(
|
||||
"color" => color(tick_color),
|
||||
"opacity" => alpha(tick_color),
|
||||
"rotate" => axis[:rotation],
|
||||
"rotate" => axis[:rotation]
|
||||
),
|
||||
)
|
||||
|
||||
@ -1283,12 +1183,6 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
opt,
|
||||
string(letter, "label style") => PGFPlotsX.Options(
|
||||
labelpos => nothing,
|
||||
"at" => string(
|
||||
"{(ticklabel cs:",
|
||||
get((left = 0, right = 1), axis[:guidefonthalign], 0.5),
|
||||
")}",
|
||||
),
|
||||
"anchor" => "near ticklabel",
|
||||
"font" => pgfx_font(axis[:guidefontsize], pgfx_thickness_scaling(sp)),
|
||||
"color" => cstr,
|
||||
"draw opacity" => α,
|
||||
@ -1301,10 +1195,10 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
|
||||
# scale
|
||||
scale = axis[:scale]
|
||||
is_log_scale = scale in (:ln, :log2, :log10)
|
||||
if is_log_scale
|
||||
if scale in (:log2, :ln, :log10)
|
||||
push!(opt, string(letter, :mode) => "log")
|
||||
scale == :ln || push!(opt, "log basis $letter" => "$(scale == :log2 ? 2 : 10)")
|
||||
scale == :ln ||
|
||||
push!(opt, "log basis $letter" => "$(scale == :log2 ? 2 : 10)")
|
||||
end
|
||||
|
||||
# ticks on or off
|
||||
@ -1315,14 +1209,14 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
end
|
||||
|
||||
# grid on or off
|
||||
push!(
|
||||
opt,
|
||||
"$(letter)majorgrids" => axis[:grid] && framestyle != :none ? "true" : "false",
|
||||
)
|
||||
if axis[:grid] && framestyle != :none
|
||||
push!(opt, "$(letter)majorgrids" => "true")
|
||||
else
|
||||
push!(opt, "$(letter)majorgrids" => "false")
|
||||
end
|
||||
|
||||
# limits
|
||||
lims =
|
||||
ispolar(sp) && letter == :x ? rad2deg.(axis_limits(sp, :x)) :
|
||||
lims = ispolar(sp) && letter == :x ? rad2deg.(axis_limits(sp, :x)) :
|
||||
axis_limits(sp, letter)
|
||||
push!(opt, string(letter, :min) => lims[1], string(letter, :max) => lims[2])
|
||||
|
||||
@ -1333,43 +1227,48 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
tick_values =
|
||||
ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] :
|
||||
ticks[1]
|
||||
push!(opt, string(letter, "tick") => string("{", join(tick_values, ","), "}"))
|
||||
if axis[:showaxis] && is_log_scale && axis[:ticks] == :auto
|
||||
tick_labels = wrap_power_labels(ticks[2])
|
||||
if tick_labels isa Vector{String}
|
||||
push!(
|
||||
opt,
|
||||
string(letter, "tick") => string("{", join(tick_values, ","), "}"),
|
||||
)
|
||||
if axis[:showaxis] &&
|
||||
axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto
|
||||
# wrap the power part of label with }
|
||||
tick_labels = Vector{String}(undef, length(ticks[2]))
|
||||
for (i, label) in enumerate(ticks[2])
|
||||
base, power = split(label, "^")
|
||||
power = string("{", power, "}")
|
||||
tick_labels[i] = string(base, "^", power)
|
||||
end
|
||||
push!(
|
||||
opt,
|
||||
string(letter, "ticklabels") =>
|
||||
string("{\$", join(tick_labels, "\$,\$"), "\$}"),
|
||||
)
|
||||
elseif tick_labels isa Vector{LaTeXString}
|
||||
push!(opt, string(letter, "ticklabels") => join(tick_labels))
|
||||
end
|
||||
elseif axis[:showaxis]
|
||||
tick_labels =
|
||||
ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2]
|
||||
is_log_scale && (tick_labels = wrap_power_labels(tick_labels))
|
||||
if axis[:formatter] in (:scientific, :auto) && tick_labels isa Vector{String}
|
||||
ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] :
|
||||
ticks[2]
|
||||
if axis[:formatter] in (:scientific, :auto)
|
||||
tick_labels = string.("\$", convert_sci_unicode.(tick_labels), "\$")
|
||||
tick_labels = replace.(tick_labels, Ref("×" => "\\times"))
|
||||
end
|
||||
push!(
|
||||
opt,
|
||||
string(letter, "ticklabels") => string("{", join(tick_labels, ","), "}"),
|
||||
string(letter, "ticklabels") =>
|
||||
string("{", join(tick_labels, ","), "}"),
|
||||
)
|
||||
else
|
||||
push!(opt, string(letter, "ticklabels") => "{}")
|
||||
end
|
||||
if axis[:tick_direction] === :none
|
||||
push!(opt, string(letter, "tick style") => "draw=none")
|
||||
else
|
||||
push!(
|
||||
opt,
|
||||
string(letter, "tick align") =>
|
||||
(axis[:tick_direction] == :out ? "outside" : "inside"),
|
||||
)
|
||||
end
|
||||
push!(opt, string(letter, "ticklabel style") => pgfx_get_ticklabel_style(sp, axis))
|
||||
push!(
|
||||
opt, string(letter, "ticklabel style") => pgfx_get_ticklabel_style(sp, axis)
|
||||
)
|
||||
push!(
|
||||
opt,
|
||||
string(letter, " grid style") => pgfx_linestyle(
|
||||
@ -1393,8 +1292,7 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
minor_ticks
|
||||
push!(
|
||||
opt,
|
||||
string("extra ", letter, " ticks") =>
|
||||
string("{", join(minor_ticks, ","), "}"),
|
||||
string("extra ", letter, " ticks") => string("{", join(minor_ticks, ","), "}"),
|
||||
)
|
||||
push!(opt, string("extra ", letter, " tick labels") => "")
|
||||
push!(
|
||||
@ -1407,9 +1305,7 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
axis[:minorgridalpha],
|
||||
axis[:minorgridstyle],
|
||||
),
|
||||
"major tick length" =>
|
||||
typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 ||
|
||||
axis[:minorticks] ? "0.1cm" : "0",
|
||||
"major tick length" => typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 || axis[:minorticks] ? "0.1cm" : "0"
|
||||
),
|
||||
)
|
||||
end
|
||||
@ -1465,9 +1361,8 @@ end
|
||||
# Set the (left, top, right, bottom) minimum padding around the plot area
|
||||
# to fit ticks, tick labels, guides, colorbars, etc.
|
||||
function _update_min_padding!(sp::Subplot{PGFPlotsXBackend})
|
||||
leg = sp[:legend_position]
|
||||
if leg in (:best, :outertopright, :outerright, :outerbottomright) ||
|
||||
(leg isa Tuple && leg[1] >= 1)
|
||||
leg = sp[:legend]
|
||||
if leg in (:best, :outertopright, :outerright, :outerbottomright) || (leg isa Tuple && leg[1] >= 1)
|
||||
sp.minpad = (0mm, 0mm, 5mm, 0mm)
|
||||
else
|
||||
sp.minpad = (0mm, 0mm, 0mm, 0mm)
|
||||
@ -1487,13 +1382,21 @@ function _update_plot_object(plt::Plot{PGFPlotsXBackend})
|
||||
end
|
||||
|
||||
for mime in ("application/pdf", "image/svg+xml")
|
||||
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{PGFPlotsXBackend})
|
||||
@eval function _show(
|
||||
io::IO,
|
||||
mime::MIME{Symbol($mime)},
|
||||
plt::Plot{PGFPlotsXBackend},
|
||||
)
|
||||
plt.o.was_shown = true
|
||||
show(io, mime, plt.o.the_plot)
|
||||
end
|
||||
end
|
||||
|
||||
function _show(io::IO, mime::MIME{Symbol("image/png")}, plt::Plot{PGFPlotsXBackend})
|
||||
function _show(
|
||||
io::IO,
|
||||
mime::MIME{Symbol("image/png")},
|
||||
plt::Plot{PGFPlotsXBackend},
|
||||
)
|
||||
plt.o.was_shown = true
|
||||
plt_file = tempname() * ".png"
|
||||
PGFPlotsX.pgfsave(plt_file, plt.o.the_plot; dpi=plt[:dpi])
|
||||
@ -1501,7 +1404,11 @@ function _show(io::IO, mime::MIME{Symbol("image/png")}, plt::Plot{PGFPlotsXBacke
|
||||
rm(plt_file; force = true)
|
||||
end
|
||||
|
||||
function _show(io::IO, mime::MIME{Symbol("application/x-tex")}, plt::Plot{PGFPlotsXBackend})
|
||||
function _show(
|
||||
io::IO,
|
||||
mime::MIME{Symbol("application/x-tex")},
|
||||
plt::Plot{PGFPlotsXBackend},
|
||||
)
|
||||
plt.o.was_shown = true
|
||||
PGFPlotsX.print_tex(
|
||||
io,
|
||||
|
||||
@ -7,13 +7,12 @@ function _plotly_framestyle(style::Symbol)
|
||||
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."
|
||||
)
|
||||
@warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was cosen instead.")
|
||||
default_style
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
|
||||
using UUIDs
|
||||
@ -38,20 +37,25 @@ function plotly_font(font::Font, color = font.color)
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
function plotly_annotation_dict(x, y, val; xref="paper", yref="paper")
|
||||
KW(:text => val, :xref => xref, :x => x, :yref => yref, :y => y, :showarrow => false)
|
||||
KW(
|
||||
:text => val,
|
||||
:xref => xref,
|
||||
:x => x,
|
||||
:yref => yref,
|
||||
:y => y,
|
||||
:showarrow => false,
|
||||
)
|
||||
end
|
||||
|
||||
function plotly_annotation_dict(x, y, ptxt::PlotText; xref="paper", yref="paper")
|
||||
merge(
|
||||
plotly_annotation_dict(x, y, ptxt.str; xref = xref, yref = yref),
|
||||
KW(
|
||||
merge(plotly_annotation_dict(x, y, ptxt.str; xref=xref, yref=yref), KW(
|
||||
:font => plotly_font(ptxt.font),
|
||||
:xanchor => ptxt.font.halign == :hcenter ? :center : ptxt.font.halign,
|
||||
:yanchor => ptxt.font.valign == :vcenter ? :middle : ptxt.font.valign,
|
||||
:rotation => -ptxt.font.rotation,
|
||||
),
|
||||
)
|
||||
))
|
||||
end
|
||||
|
||||
# function get_annotation_dict_for_arrow(plotattributes::KW, xyprev::Tuple, xy::Tuple, a::Arrow)
|
||||
@ -114,6 +118,7 @@ function plotly_apply_aspect_ratio(sp::Subplot, plotarea, pcts)
|
||||
pcts
|
||||
end
|
||||
|
||||
|
||||
# this method gets the start/end in percentage of the canvas for this axis direction
|
||||
function plotly_domain(sp::Subplot)
|
||||
figw, figh = sp.plt[:size]
|
||||
@ -124,6 +129,7 @@ function plotly_domain(sp::Subplot)
|
||||
return x_domain, y_domain
|
||||
end
|
||||
|
||||
|
||||
function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
|
||||
letter = axis[:letter]
|
||||
framestyle = sp[:framestyle]
|
||||
@ -131,16 +137,13 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
|
||||
:visible => framestyle != :none,
|
||||
:title => axis[:guide],
|
||||
:showgrid => axis[:grid],
|
||||
:gridcolor =>
|
||||
rgba_string(plot_color(axis[:foreground_color_grid], axis[:gridalpha])),
|
||||
:gridcolor => rgba_string(plot_color(axis[:foreground_color_grid], axis[:gridalpha])),
|
||||
:gridwidth => axis[:gridlinewidth],
|
||||
:zeroline => framestyle == :zerolines,
|
||||
: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],
|
||||
)
|
||||
@ -162,9 +165,7 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
|
||||
if !(axis[:ticks] in (nothing, :none, false))
|
||||
ax[:titlefont] = plotly_font(guidefont(axis))
|
||||
ax[:tickfont] = plotly_font(tickfont(axis))
|
||||
ax[:tickcolor] =
|
||||
framestyle in (:zerolines, :grid) || !axis[:showaxis] ?
|
||||
rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis])
|
||||
ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis])
|
||||
ax[:linecolor] = rgba_string(axis[:foreground_color_axis])
|
||||
|
||||
# ticks
|
||||
@ -193,7 +194,10 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
|
||||
end
|
||||
|
||||
function plotly_polaraxis(sp::Subplot, axis::Axis)
|
||||
ax = KW(:visible => axis[:showaxis], :showline => axis[:grid])
|
||||
ax = KW(
|
||||
:visible => axis[:showaxis],
|
||||
:showline => axis[:grid],
|
||||
)
|
||||
|
||||
if axis[:letter] == :x
|
||||
ax[:range] = rad2deg.(axis_limits(sp, :x))
|
||||
@ -234,10 +238,7 @@ function plotly_layout(plt::Plot)
|
||||
end
|
||||
titlex, titley = xy_mm_to_pcts(xmm, top(bbox(sp)), w*px, h*px)
|
||||
title_font = font(titlefont(sp), :top)
|
||||
push!(
|
||||
plotattributes_out[:annotations],
|
||||
plotly_annotation_dict(titlex, titley, text(sp[:title], title_font)),
|
||||
)
|
||||
push!(plotattributes_out[:annotations], plotly_annotation_dict(titlex, titley, text(sp[:title], title_font)))
|
||||
end
|
||||
|
||||
plotattributes_out[:plot_bgcolor] = rgba_string(sp[:background_color_inside])
|
||||
@ -246,10 +247,8 @@ function plotly_layout(plt::Plot)
|
||||
sp[:framestyle] = _plotly_framestyle(sp[:framestyle])
|
||||
|
||||
if ispolar(sp)
|
||||
plotattributes_out[Symbol("angularaxis$(spidx)")] =
|
||||
plotly_polaraxis(sp, sp[:xaxis])
|
||||
plotattributes_out[Symbol("radialaxis$(spidx)")] =
|
||||
plotly_polaraxis(sp, sp[:yaxis])
|
||||
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)
|
||||
@ -286,28 +285,16 @@ function plotly_layout(plt::Plot)
|
||||
|
||||
# annotations
|
||||
for ann in sp[:annotations]
|
||||
append!(
|
||||
plotattributes_out[:annotations],
|
||||
KW[plotly_annotation_dict(
|
||||
locate_annotation(sp, ann...)...;
|
||||
xref = "x$(x_idx)",
|
||||
yref = "y$(y_idx)",
|
||||
)],
|
||||
)
|
||||
append!(plotattributes_out[:annotations], KW[plotly_annotation_dict(locate_annotation(sp, ann...)...; xref = "x$(x_idx)", yref = "y$(y_idx)")])
|
||||
end
|
||||
# series_annotations
|
||||
for series in series_list(sp)
|
||||
anns = series[:series_annotations]
|
||||
for (xi,yi,str,fnt) in EachAnn(anns, series[:x], series[:y])
|
||||
push!(
|
||||
plotattributes_out[:annotations],
|
||||
plotly_annotation_dict(
|
||||
push!(plotattributes_out[:annotations], plotly_annotation_dict(
|
||||
xi,
|
||||
yi,
|
||||
PlotText(str, fnt);
|
||||
xref = "x$(x_idx)",
|
||||
yref = "y$(y_idx)",
|
||||
),
|
||||
PlotText(str,fnt); xref = "x$(x_idx)", yref = "y$(y_idx)")
|
||||
)
|
||||
end
|
||||
end
|
||||
@ -337,13 +324,14 @@ function plotly_layout(plt::Plot)
|
||||
plotattributes_out = recursive_merge(plotattributes_out, plt.attr[:extra_plot_kwargs])
|
||||
end
|
||||
|
||||
|
||||
function plotly_add_legend!(plotattributes_out::KW, sp::Subplot)
|
||||
plotattributes_out[:showlegend] = sp[:legend_position] != :none
|
||||
legend_position = plotly_legend_pos(sp[:legend_position])
|
||||
if sp[:legend_position] != :none
|
||||
plotattributes_out[:legend_position] = KW(
|
||||
:bgcolor => rgba_string(sp[:legend_background_color]),
|
||||
:bordercolor => rgba_string(sp[:legend_foreground_color]),
|
||||
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,
|
||||
@ -353,7 +341,7 @@ function plotly_add_legend!(plotattributes_out::KW, sp::Subplot)
|
||||
:x => legend_position.coords[1],
|
||||
:y => legend_position.coords[2],
|
||||
:title => KW(
|
||||
:text => sp[:legend_title] === nothing ? "" : string(sp[:legend_title]),
|
||||
:text => sp[:legendtitle] === nothing ? "" : string(sp[:legendtitle]),
|
||||
:font => plotly_font(legendtitlefont(sp)),
|
||||
),
|
||||
)
|
||||
@ -362,7 +350,6 @@ end
|
||||
|
||||
function plotly_legend_pos(pos::Symbol)
|
||||
xleft = 0.07
|
||||
xright = 1.0
|
||||
ybot = 0.07
|
||||
ytop = 1.0
|
||||
xcenter = 0.55
|
||||
@ -373,47 +360,33 @@ function plotly_legend_pos(pos::Symbol)
|
||||
xouterright = 1.05
|
||||
xouterleft = -0.15
|
||||
plotly_legend_position_mapping = (
|
||||
right = (coords = [xright, ycenter], xanchor = "right", yanchor = "middle"),
|
||||
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 = [xright, ybot], xanchor = "right", yanchor = "bottom"),
|
||||
topright = (coords = [xright, ytop], xanchor = "right", yanchor = "top"),
|
||||
topleft = (coords = [xleft, ytop], xanchor = "left", yanchor = "top"),
|
||||
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 = [xright, ytop], xanchor = "auto", yanchor = "auto"),
|
||||
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)
|
||||
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(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}
|
||||
function plotly_legend_pos(v::Tuple{S,Symbol}) where S<:Real
|
||||
(s,c) = sincosd(v[1])
|
||||
xanchors = ["left", "center", "right"]
|
||||
yanchors = ["bottom", "middle", "top"]
|
||||
@ -427,17 +400,15 @@ function plotly_legend_pos(v::Tuple{S,Symbol}) where {S<:Real}
|
||||
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,
|
||||
)
|
||||
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)
|
||||
@ -456,12 +427,13 @@ function plotly_colorscale(cg::PlotUtils.CategoricalColorGradient, α = nothing)
|
||||
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)
|
||||
[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), α)
|
||||
|
||||
|
||||
get_plotly_marker(k, def) = get(
|
||||
(
|
||||
rect = "square",
|
||||
@ -488,11 +460,12 @@ function plotly_link_indicies(plt::Plot, sp::Subplot)
|
||||
x_idx, y_idx
|
||||
end
|
||||
|
||||
|
||||
# the Shape contructor will automatically close the shape. since we need it closed,
|
||||
# we split by NaNs and then construct/destruct the shapes to get the closed coords
|
||||
function plotly_close_shapes(x, y)
|
||||
xs, ys = nansplit(x), nansplit(y)
|
||||
for i in eachindex(xs)
|
||||
for i=eachindex(xs)
|
||||
shape = Shape(xs[i], ys[i])
|
||||
xs[i], ys[i] = coords(shape)
|
||||
end
|
||||
@ -500,7 +473,7 @@ function plotly_close_shapes(x, y)
|
||||
end
|
||||
|
||||
function plotly_data(series::Series, letter::Symbol, data)
|
||||
axis = series[:subplot][get_attr_symbol(letter, :axis)]
|
||||
axis = series[:subplot][Symbol(letter, :axis)]
|
||||
|
||||
data = if axis[:ticks] == :native && data !== nothing
|
||||
plotly_native_data(axis, data)
|
||||
@ -538,9 +511,7 @@ function plotly_convert_to_datetime(x::AbstractArray, formatter::Function)
|
||||
elseif formatter == timeformatter
|
||||
map(xi -> string(Dates.Date(Dates.now()), " ", formatter(xi)), x)
|
||||
else
|
||||
error(
|
||||
"Invalid DateTime formatter. Expected Plots.datetime/date/time formatter but got $formatter",
|
||||
)
|
||||
error("Invalid DateTime formatter. Expected Plots.datetime/date/time formatter but got $formatter")
|
||||
end
|
||||
end
|
||||
#ensures that a gradient is called if a single color is supplied where a gradient is needed (e.g. if a series recipe defines marker_z)
|
||||
@ -581,9 +552,8 @@ function plotly_series(plt::Plot, series::Series)
|
||||
x, y, z = series[:x], series[:y], series[:z]
|
||||
end
|
||||
|
||||
x, y, z = (
|
||||
plotly_data(series, letter, data) for
|
||||
(letter, data) in zip((:x, :y, :z), (x, y, z))
|
||||
x, y, z = (plotly_data(series, letter, data)
|
||||
for (letter, data) in zip((:x, :y, :z), (x, y, z))
|
||||
)
|
||||
|
||||
plotattributes_out[:name] = series[:label]
|
||||
@ -591,8 +561,7 @@ function plotly_series(plt::Plot, series::Series)
|
||||
isscatter = st in (:scatter, :scatter3d, :scattergl)
|
||||
hasmarker = isscatter || series[:markershape] != :none
|
||||
hasline = st in (:path, :path3d, :straightline)
|
||||
hasfillrange =
|
||||
st in (:path, :scatter, :scattergl, :straightline) &&
|
||||
hasfillrange = st in (:path, :scatter, :scattergl, :straightline) &&
|
||||
(isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple))
|
||||
|
||||
plotattributes_out[:colorbar] = KW(:title => sp[:colorbar_title])
|
||||
@ -610,44 +579,16 @@ function plotly_series(plt::Plot, series::Series)
|
||||
y = heatmap_edges(y, sp[:yaxis][:scale])
|
||||
plotattributes_out[:type] = "heatmap"
|
||||
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
|
||||
plotattributes_out[:colorscale] =
|
||||
plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
||||
plotattributes_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
||||
plotattributes_out[:showscale] = hascolorbar(sp)
|
||||
|
||||
elseif st == :contour
|
||||
filled = isfilledcontour(series)
|
||||
plotattributes_out[:type] = "contour"
|
||||
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
|
||||
plotattributes_out[:contours] = KW(
|
||||
:coloring => filled ? "fill" : "lines",
|
||||
:showlabels => series[:contour_labels] == true,
|
||||
)
|
||||
# Plotly does not support arbitrary sets of contours
|
||||
# (https://github.com/plotly/plotly.js/issues/4503)
|
||||
# so we distinguish AbstractRanges and AbstractVectors
|
||||
let levels = series[:levels]
|
||||
if levels isa AbstractRange
|
||||
plotattributes_out[:contours][:start] = first(levels)
|
||||
plotattributes_out[:contours][:end] = last(levels)
|
||||
plotattributes_out[:contours][:size] = step(levels)
|
||||
elseif levels isa AVec
|
||||
levels_range =
|
||||
range(first(levels), stop = last(levels), length = length(levels))
|
||||
plotattributes_out[:contours][:start] = first(levels_range)
|
||||
plotattributes_out[:contours][:end] = last(levels_range)
|
||||
plotattributes_out[:contours][:size] = step(levels_range)
|
||||
@warn(
|
||||
"setting arbitrary contour levels with Plotly backend is not supported; " *
|
||||
"use a range to set equally-spaced contours or an integer to set the " *
|
||||
"approximate number of contours with the keyword `levels`. " *
|
||||
"Setting levels to $(levels_range)"
|
||||
)
|
||||
elseif levels isa Integer
|
||||
plotattributes_out[:ncontours] = levels + 2
|
||||
end
|
||||
end
|
||||
plotattributes_out[:colorscale] =
|
||||
plotly_colorscale(series[:linecolor], series[:linealpha])
|
||||
plotattributes_out[:ncontours] = series[:levels] + 2
|
||||
plotattributes_out[:contours] = KW(:coloring => filled ? "fill" : "lines", :showlabels => series[:contour_labels] == true)
|
||||
plotattributes_out[:colorscale] = plotly_colorscale(series[:linecolor], series[:linealpha])
|
||||
plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series)
|
||||
|
||||
elseif st in (:surface, :wireframe)
|
||||
@ -657,16 +598,13 @@ function plotly_series(plt::Plot, series::Series)
|
||||
plotattributes_out[:hidesurface] = true
|
||||
wirelines = KW(
|
||||
:show => true,
|
||||
:color =>
|
||||
rgba_string(plot_color(series[:linecolor], series[:linealpha])),
|
||||
:color => rgba_string(plot_color(series[:linecolor], series[:linealpha])),
|
||||
:highlightwidth => series[:linewidth],
|
||||
)
|
||||
plotattributes_out[:contours] =
|
||||
KW(:x => wirelines, :y => wirelines, :z => wirelines)
|
||||
plotattributes_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines)
|
||||
plotattributes_out[:showscale] = false
|
||||
else
|
||||
plotattributes_out[:colorscale] =
|
||||
plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
||||
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])
|
||||
@ -679,40 +617,19 @@ function plotly_series(plt::Plot, series::Series)
|
||||
|
||||
if series[:connections] !== nothing
|
||||
if typeof(series[:connections]) <: Tuple{Array,Array,Array}
|
||||
# 0-based indexing
|
||||
i,j,k = series[:connections]
|
||||
if !(length(i) == length(j) == length(k))
|
||||
throw(
|
||||
ArgumentError(
|
||||
"Argument connections must consist of equally sized arrays.",
|
||||
),
|
||||
)
|
||||
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
|
||||
end
|
||||
plotattributes_out[:i] = i
|
||||
plotattributes_out[:j] = j
|
||||
plotattributes_out[:k] = k
|
||||
elseif typeof(series[:connections]) <: AbstractVector{NTuple{3,Int}}
|
||||
# 1-based indexing
|
||||
i, j, k = broadcast(
|
||||
i -> [inds[i] - 1 for inds in series[:connections]],
|
||||
(1, 2, 3),
|
||||
)
|
||||
plotattributes_out[:i] = i
|
||||
plotattributes_out[:j] = j
|
||||
plotattributes_out[:k] = k
|
||||
else
|
||||
throw(
|
||||
ArgumentError(
|
||||
"Argument connections has to be either a tuple of three arrays (0-based indexing)
|
||||
or an AbstractVector{NTuple{3,Int}} (1-based indexing).",
|
||||
),
|
||||
)
|
||||
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[: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])
|
||||
@ -727,39 +644,26 @@ 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_marker(series[:markershape], string(series[:markershape])),
|
||||
# :opacity => series[:markeralpha],
|
||||
:size => 2 * _cycle(series[:markersize], inds),
|
||||
:color =>
|
||||
rgba_string.(
|
||||
plot_color.(
|
||||
get_markercolor.(series, inds),
|
||||
get_markeralpha.(series, inds),
|
||||
),
|
||||
),
|
||||
:color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))),
|
||||
:line => KW(
|
||||
:color =>
|
||||
rgba_string.(
|
||||
plot_color.(
|
||||
get_markerstrokecolor.(series, inds),
|
||||
get_markerstrokealpha.(series, inds),
|
||||
),
|
||||
),
|
||||
:color => rgba_string.(plot_color.(get_markerstrokecolor.(series, inds), get_markerstrokealpha.(series, inds))),
|
||||
:width => _cycle(series[:markerstrokewidth], inds),
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
plotly_polar!(plotattributes_out, series)
|
||||
plotly_adjust_hover_label!(plotattributes_out, series[:hover])
|
||||
plotly_hover!(plotattributes_out, series[:hover])
|
||||
|
||||
return [merge(plotattributes_out, series[:extra_kwargs])]
|
||||
return [plotattributes_out]
|
||||
end
|
||||
|
||||
function plotly_series_shapes(plt::Plot, series::Series, clims)
|
||||
segments = series_segments(series; check = true)
|
||||
plotattributes_outs = [KW() for _ in 1:length(segments)]
|
||||
segments = collect(series_segments(series))
|
||||
plotattributes_outs = Vector{KW}(undef, length(segments))
|
||||
|
||||
# TODO: create a plotattributes_out for each polygon
|
||||
# x, y = series[:x], series[:y]
|
||||
@ -773,52 +677,41 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
|
||||
:legendgroup => series[:label],
|
||||
)
|
||||
|
||||
x, y = (
|
||||
plotly_data(series, letter, data) for
|
||||
(letter, data) in zip((:x, :y), shape_data(series, 100))
|
||||
x, y = (plotly_data(series, letter, data)
|
||||
for (letter, data) in zip((:x, :y), shape_data(series, 100))
|
||||
)
|
||||
|
||||
for (k, segment) in enumerate(segments)
|
||||
for segment in segments
|
||||
i, rng = segment.attr_index, segment.range
|
||||
length(rng) < 2 && continue
|
||||
|
||||
# to draw polygons, we actually draw lines with fill
|
||||
plotattributes_out = merge(
|
||||
plotattributes_base,
|
||||
KW(
|
||||
plotattributes_out = merge(plotattributes_base, KW(
|
||||
:type => "scatter",
|
||||
:mode => "lines",
|
||||
:x => vcat(x[rng], x[rng[1]]),
|
||||
:y => vcat(y[rng], y[rng[1]]),
|
||||
:fill => "tozeroy",
|
||||
:fillcolor => rgba_string(
|
||||
plot_color(get_fillcolor(series, clims, i), get_fillalpha(series, i)),
|
||||
),
|
||||
),
|
||||
)
|
||||
:fillcolor => rgba_string(plot_color(get_fillcolor(series, clims, i), get_fillalpha(series, i))),
|
||||
))
|
||||
if series[:markerstrokewidth] > 0
|
||||
plotattributes_out[:line] = KW(
|
||||
:color => rgba_string(
|
||||
plot_color(get_linecolor(series, clims, i), get_linealpha(series, i)),
|
||||
),
|
||||
:color => rgba_string(plot_color(get_linecolor(series, clims, i), get_linealpha(series, i))),
|
||||
:width => get_linewidth(series, i),
|
||||
: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_adjust_hover_label!(plotattributes_out, _cycle(series[:hover], i))
|
||||
plotattributes_outs[k] = merge(plotattributes_out, series[:extra_kwargs])
|
||||
plotly_hover!(plotattributes_out, _cycle(series[:hover], i))
|
||||
plotattributes_outs[i] = plotattributes_out
|
||||
end
|
||||
if series[:fill_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill))
|
||||
elseif series[:line_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :line))
|
||||
elseif series[:marker_z] !== nothing
|
||||
push!(
|
||||
plotattributes_outs,
|
||||
plotly_colorbar_hack(series, plotattributes_base, :marker),
|
||||
)
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :marker))
|
||||
end
|
||||
plotattributes_outs
|
||||
end
|
||||
@ -829,8 +722,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
isscatter = st in (:scatter, :scatter3d, :scattergl)
|
||||
hasmarker = isscatter || series[:markershape] != :none
|
||||
hasline = st in (:path, :path3d, :straightline)
|
||||
hasfillrange =
|
||||
st in (:path, :scatter, :scattergl, :straightline) &&
|
||||
hasfillrange = st in (:path, :scatter, :scattergl, :straightline) &&
|
||||
(isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple))
|
||||
|
||||
segments = collect(series_segments(series, st))
|
||||
@ -853,22 +745,14 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
else
|
||||
hasline ? "lines" : "none"
|
||||
end
|
||||
if series[:fillrange] == true ||
|
||||
series[:fillrange] == 0 ||
|
||||
isa(series[:fillrange], Tuple)
|
||||
if series[:fillrange] == true || series[:fillrange] == 0 || isa(series[:fillrange], Tuple)
|
||||
plotattributes_out[:fill] = "tozeroy"
|
||||
plotattributes_out[:fillcolor] = rgba_string(
|
||||
plot_color(get_fillcolor(series, clims, i), get_fillalpha(series, i)),
|
||||
)
|
||||
plotattributes_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, clims, i), get_fillalpha(series, i)))
|
||||
elseif typeof(series[:fillrange]) <: Union{AbstractVector{<:Real}, Real}
|
||||
plotattributes_out[:fill] = "tonexty"
|
||||
plotattributes_out[:fillcolor] = rgba_string(
|
||||
plot_color(get_fillcolor(series, clims, i), get_fillalpha(series, i)),
|
||||
)
|
||||
plotattributes_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, clims, i), get_fillalpha(series, i)))
|
||||
elseif !(series[:fillrange] in (false, nothing))
|
||||
@warn(
|
||||
"fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])"
|
||||
)
|
||||
@warn("fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])")
|
||||
end
|
||||
plotattributes_out[:x], plotattributes_out[:y] = x[rng], y[rng]
|
||||
|
||||
@ -879,32 +763,20 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
else
|
||||
hasline ? "lines" : "none"
|
||||
end
|
||||
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] =
|
||||
x[rng], y[rng], z[rng]
|
||||
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x[rng], y[rng], z[rng]
|
||||
end
|
||||
|
||||
# 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),
|
||||
),
|
||||
)
|
||||
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)),
|
||||
),
|
||||
:symbol => get_plotly_marker(_cycle(series[:markershape], i), string(_cycle(series[:markershape], i))),
|
||||
# :opacity => needs_scatter_fix ? [1, 0] : 1,
|
||||
:size => 2 * _cycle(series[:markersize], i),
|
||||
:color => needs_scatter_fix ? [mcolor, "rgba(0, 0, 0, 0.000)"] : mcolor,
|
||||
:line => KW(
|
||||
:color =>
|
||||
needs_scatter_fix ? [lcolor, "rgba(0, 0, 0, 0.000)"] : lcolor,
|
||||
:color => needs_scatter_fix ? [lcolor, "rgba(0, 0, 0, 0.000)"] : lcolor,
|
||||
:width => _cycle(series[:markerstrokewidth], i),
|
||||
),
|
||||
)
|
||||
@ -913,9 +785,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
# add "line"
|
||||
if hasline
|
||||
plotattributes_out[:line] = KW(
|
||||
:color => rgba_string(
|
||||
plot_color(get_linecolor(series, clims, i), get_linealpha(series, i)),
|
||||
),
|
||||
:color => rgba_string(plot_color(get_linecolor(series, clims, i), get_linealpha(series, i))),
|
||||
:width => get_linewidth(series, i),
|
||||
:shape => if st == :steppre
|
||||
"vh"
|
||||
@ -931,7 +801,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
end
|
||||
|
||||
plotly_polar!(plotattributes_out, series)
|
||||
plotly_adjust_hover_label!(plotattributes_out, _cycle(series[:hover], rng))
|
||||
plotly_hover!(plotattributes_out, _cycle(series[:hover], rng))
|
||||
|
||||
if hasfillrange
|
||||
# if hasfillrange is true, return two dictionaries (one for original
|
||||
@ -940,15 +810,11 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
plotattributes_out_fillrange[:showlegend] = false
|
||||
# if fillrange is provided as real or tuple of real, expand to array
|
||||
if typeof(series[:fillrange]) <: Real
|
||||
plotattributes_out[:fillrange] = fill(series[:fillrange], length(rng))
|
||||
series[:fillrange] = fill(series[:fillrange], length(rng))
|
||||
elseif typeof(series[:fillrange]) <: Tuple
|
||||
f1 =
|
||||
typeof(series[:fillrange][1]) <: Real ?
|
||||
fill(series[:fillrange][1], length(rng)) : series[:fillrange][1][rng]
|
||||
f2 =
|
||||
typeof(series[:fillrange][2]) <: Real ?
|
||||
fill(series[:fillrange][2], length(rng)) : series[:fillrange][2][rng]
|
||||
plotattributes_out[:fillrange] = (f1, f2)
|
||||
f1 = typeof(series[:fillrange][1]) <: Real ? fill(series[:fillrange][1], length(rng)) : series[:fillrange][1][rng]
|
||||
f2 = typeof(series[:fillrange][2]) <: Real ? fill(series[:fillrange][2], length(rng)) : series[:fillrange][2][rng]
|
||||
series[:fillrange] = (f1, f2)
|
||||
end
|
||||
if isa(series[:fillrange], AbstractVector)
|
||||
plotattributes_out_fillrange[:y] = series[:fillrange][rng]
|
||||
@ -957,19 +823,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])
|
||||
plotattributes_out_fillrange[:x], plotattributes_out_fillrange[:y] = concatenate_fillrange(x[rng], series[:fillrange])
|
||||
plotattributes_out_fillrange[:line][:width] = 0
|
||||
delete!(plotattributes_out, :fill)
|
||||
delete!(plotattributes_out, :fillcolor)
|
||||
end
|
||||
|
||||
plotattributes_outs[(2k - 1):(2k)] =
|
||||
[plotattributes_out_fillrange, plotattributes_out]
|
||||
plotattributes_outs[(2k-1):(2k)] = [plotattributes_out_fillrange, plotattributes_out]
|
||||
else
|
||||
plotattributes_outs[k] = plotattributes_out
|
||||
end
|
||||
plotattributes_outs[k] = merge(plotattributes_outs[k], series[:extra_kwargs])
|
||||
end
|
||||
|
||||
if series[:line_z] !== nothing
|
||||
@ -977,10 +840,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
|
||||
elseif series[:fill_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill))
|
||||
elseif series[:marker_z] !== nothing
|
||||
push!(
|
||||
plotattributes_outs,
|
||||
plotly_colorbar_hack(series, plotattributes_base, :marker),
|
||||
)
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :marker))
|
||||
end
|
||||
|
||||
plotattributes_outs
|
||||
@ -1010,34 +870,33 @@ function plotly_colorbar_hack(series::Series, plotattributes_base::KW, sym::Symb
|
||||
return plotattributes_out
|
||||
end
|
||||
|
||||
|
||||
function plotly_polar!(plotattributes_out::KW, series::Series)
|
||||
# convert polar plots x/y to theta/radius
|
||||
if ispolar(series[:subplot])
|
||||
theta, r = pop!(plotattributes_out, :x), pop!(plotattributes_out, :y)
|
||||
plotattributes_out[:theta] = rad2deg.(theta)
|
||||
plotattributes_out[:t] = rad2deg.(theta)
|
||||
plotattributes_out[:r] = r
|
||||
plotattributes_out[:type] = :scatterpolar
|
||||
end
|
||||
end
|
||||
|
||||
function plotly_adjust_hover_label!(plotattributes_out::KW, hover)
|
||||
if hover === nothing
|
||||
return nothing
|
||||
elseif all(in([:none, false]), hover)
|
||||
function plotly_hover!(plotattributes_out::KW, hover)
|
||||
# hover text
|
||||
if hover === nothing || all(in([:none, false]), hover)
|
||||
plotattributes_out[:hoverinfo] = "none"
|
||||
elseif any(!isnothing, hover)
|
||||
plotattributes_out[:hoverinfo] = "text"
|
||||
plotattributes_out[:text] = hover
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
# get a list of dictionaries, each representing the series params
|
||||
function plotly_series(plt::Plot)
|
||||
if isempty(plt.series_list)
|
||||
return KW[]
|
||||
slist = []
|
||||
for series in plt.series_list
|
||||
append!(slist, plotly_series(plt, series))
|
||||
end
|
||||
reduce(vcat, plotly_series(plt, series) for series in plt.series_list)
|
||||
slist
|
||||
end
|
||||
|
||||
# get json string for a list of dictionaries, each representing the series params
|
||||
@ -1050,15 +909,11 @@ html_body(plt::Plot{PlotlyBackend}) = plotly_html_body(plt)
|
||||
|
||||
function plotly_html_head(plt::Plot)
|
||||
plotly =
|
||||
use_local_dependencies[] ? ("file:///" * plotly_local_file_path[]) :
|
||||
"https://cdn.plot.ly/$(_plotly_min_js_filename)"
|
||||
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"
|
||||
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
|
||||
@ -1078,9 +933,8 @@ function plotly_html_body(plt, style = nothing)
|
||||
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)]
|
||||
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({
|
||||
@ -1098,7 +952,8 @@ function plotly_html_body(plt, style = nothing)
|
||||
<div id=\"$(uuid)\" style=\"$(style)\"></div>
|
||||
<script>
|
||||
$(requirejs_prefix)
|
||||
$(js_body(plt, uuid))
|
||||
PLOT = document.getElementById('$(uuid)');
|
||||
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
|
||||
$(requirejs_suffix)
|
||||
</script>
|
||||
"""
|
||||
@ -1107,12 +962,16 @@ end
|
||||
|
||||
function js_body(plt::Plot, uuid)
|
||||
js = """
|
||||
Plotly.newPlot('$(uuid)', $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
|
||||
PLOT = document.getElementById('$(uuid)');
|
||||
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
|
||||
"""
|
||||
end
|
||||
|
||||
function plotly_show_js(io::IO, plot::Plot)
|
||||
data = plotly_series(plot)
|
||||
data = []
|
||||
for series in plot.series_list
|
||||
append!(data, plotly_series(plot, series))
|
||||
end
|
||||
layout = plotly_layout(plot)
|
||||
JSON.print(io, Dict(:data => data, :layout => layout))
|
||||
end
|
||||
@ -1125,10 +984,12 @@ function _show(io::IO, ::MIME"application/vnd.plotly.v1+json", plot::Plot{Plotly
|
||||
plotly_show_js(io, plot)
|
||||
end
|
||||
|
||||
|
||||
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
|
||||
write(io, embeddable_html(plt))
|
||||
write(io, standalone_html(plt))
|
||||
end
|
||||
|
||||
|
||||
function _display(plt::Plot{PlotlyBackend})
|
||||
standalone_html_window(plt)
|
||||
end
|
||||
|
||||
@ -8,7 +8,6 @@ function plotlyjs_syncplot(plt::Plot{PlotlyJSBackend})
|
||||
traces = PlotlyJS.GenericTrace[]
|
||||
for series_dict in plotly_series(plt)
|
||||
plotly_type = pop!(series_dict, :type)
|
||||
series_dict[:transpose] = false
|
||||
push!(traces, PlotlyJS.GenericTrace(plotly_type; series_dict...))
|
||||
end
|
||||
PlotlyJS.addtraces!(plt.o, traces...)
|
||||
@ -26,19 +25,16 @@ for (mime, fmt) in (
|
||||
"image/svg+xml" => "svg",
|
||||
"image/eps" => "eps",
|
||||
)
|
||||
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) =
|
||||
PlotlyJS.savefig(io, plotlyjs_syncplot(plt), format = $fmt)
|
||||
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plotlyjs_syncplot(plt), format = $fmt)
|
||||
end
|
||||
|
||||
# Use the Plotly implementation for json and html:
|
||||
_show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) =
|
||||
plotly_show_js(io, plt)
|
||||
_show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend}) = plotly_show_js(io, plt)
|
||||
|
||||
html_head(plt::Plot{PlotlyJSBackend}) = plotly_html_head(plt)
|
||||
html_body(plt::Plot{PlotlyJSBackend}) = plotly_html_body(plt)
|
||||
|
||||
_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) =
|
||||
write(io, 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))
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,373 +1,180 @@
|
||||
# https://github.com/JuliaPlots/UnicodePlots.jl
|
||||
|
||||
const _canvas_map = (
|
||||
# https://github.com/Evizero/UnicodePlots.jl
|
||||
|
||||
|
||||
# don't warn on unsupported... there's just too many warnings!!
|
||||
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
|
||||
function _canvas_map()
|
||||
(
|
||||
braille = UnicodePlots.BrailleCanvas,
|
||||
density = UnicodePlots.DensityCanvas,
|
||||
heatmap = UnicodePlots.HeatmapCanvas,
|
||||
lookup = UnicodePlots.LookupCanvas,
|
||||
ascii = UnicodePlots.AsciiCanvas,
|
||||
block = UnicodePlots.BlockCanvas,
|
||||
dot = UnicodePlots.DotCanvas,
|
||||
density = UnicodePlots.DensityCanvas,
|
||||
)
|
||||
end
|
||||
|
||||
should_warn_on_unsupported(::UnicodePlotsBackend) = false
|
||||
|
||||
function _before_layout_calcs(plt::Plot{UnicodePlotsBackend})
|
||||
plt.o = UnicodePlots.Plot[]
|
||||
up_width = UnicodePlots.DEFAULT_WIDTH[]
|
||||
up_height = UnicodePlots.DEFAULT_HEIGHT[]
|
||||
# do all the magic here... build it all at once, since we need to know about all the series at the very beginning
|
||||
function rebuildUnicodePlot!(plt::Plot, width, height)
|
||||
plt.o = []
|
||||
|
||||
has_layout = prod(size(plt.layout)) > 1
|
||||
for sp in plt.subplots
|
||||
sp_kw = sp[:extra_kwargs]
|
||||
xaxis = sp[:xaxis]
|
||||
yaxis = sp[:yaxis]
|
||||
xlim = collect(axis_limits(sp, :x))
|
||||
ylim = collect(axis_limits(sp, :y))
|
||||
zlim = collect(axis_limits(sp, :z))
|
||||
F = float(eltype(xlim))
|
||||
xlim = axis_limits(sp, :x)
|
||||
ylim = axis_limits(sp, :y)
|
||||
|
||||
# We set x/y to have a single point,
|
||||
# since we need to create the plot with some data.
|
||||
# Since this point is at the bottom left corner of the plot,
|
||||
# it should be hidden by consecutive plotting commands.
|
||||
x = Vector{F}(xlim)
|
||||
y = Vector{F}(ylim)
|
||||
z = Vector{F}(zlim)
|
||||
# make vectors
|
||||
xlim = [xlim[1], xlim[2]]
|
||||
ylim = [ylim[1], ylim[2]]
|
||||
|
||||
# create a plot window with xlim/ylim set,
|
||||
# but the X/Y vectors are outside the bounds
|
||||
canvas = if (up_c = get(sp_kw, :canvas, :auto)) === :auto
|
||||
isijulia() ? :ascii : :braille
|
||||
# we set x/y to have a single point, since we need to create the plot with some data.
|
||||
# since this point is at the bottom left corner of the plot, it shouldn't actually be shown
|
||||
x = Float64[xlim[1]]
|
||||
y = Float64[ylim[1]]
|
||||
|
||||
# create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds
|
||||
ct = _canvas_type[]
|
||||
canvas_type = if ct == :auto
|
||||
isijulia() ? UnicodePlots.AsciiCanvas : UnicodePlots.BrailleCanvas
|
||||
else
|
||||
up_c
|
||||
_canvas_map()[ct]
|
||||
end
|
||||
|
||||
border = if (up_b = get(sp_kw, :border, :auto)) === :auto
|
||||
isijulia() ? :ascii : :solid
|
||||
else
|
||||
up_b
|
||||
end
|
||||
|
||||
# blank plots will not be shown
|
||||
width = has_layout && isempty(series_list(sp)) ? 0 : get(sp_kw, :width, up_width)
|
||||
height = get(sp_kw, :height, up_height)
|
||||
|
||||
plot_3d = is3d(sp)
|
||||
blend = get(sp_kw, :blend, true)
|
||||
grid = xaxis[:grid] && yaxis[:grid]
|
||||
quiver = contour = false
|
||||
for series in series_list(sp)
|
||||
st = series[:seriestype]
|
||||
blend &= get(series[:extra_kwargs], :blend, true)
|
||||
quiver |= series[:arrow] isa Arrow # post-pipeline detection (:quiver -> :path)
|
||||
contour |= st === :contour
|
||||
if st === :histogram2d
|
||||
xlim = ylim = (0, 0)
|
||||
elseif st === :spy || st === :heatmap
|
||||
width = height = 0
|
||||
grid = false
|
||||
end
|
||||
end
|
||||
grid &= !(quiver || contour)
|
||||
blend &= !(quiver || contour)
|
||||
|
||||
plot_3d && (xlim = ylim = (0, 0)) # determined using projection
|
||||
azimuth, elevation = sp[:camera] # PyPlot: azimuth = -60 & elevation = 30
|
||||
projection = plot_3d ? get(sp_kw, :projection, :orthographic) : nothing
|
||||
|
||||
kw = (
|
||||
compact = true,
|
||||
title = texmath2unicode(sp[:title]),
|
||||
xlabel = texmath2unicode(xaxis[:guide]),
|
||||
ylabel = texmath2unicode(yaxis[:guide]),
|
||||
grid = grid,
|
||||
blend = blend,
|
||||
height = height,
|
||||
# special handling for spy
|
||||
if length(sp.series_list) == 1
|
||||
series = sp.series_list[1]
|
||||
if series[:seriestype] == :spy
|
||||
push!(plt.o, UnicodePlots.spy(
|
||||
series[:z].surf,
|
||||
width = width,
|
||||
xscale = xaxis[:scale],
|
||||
yscale = yaxis[:scale],
|
||||
border = border,
|
||||
height = height,
|
||||
title = sp[:title],
|
||||
canvas = canvas_type
|
||||
))
|
||||
continue
|
||||
end
|
||||
end
|
||||
|
||||
# # make it a bar canvas if plotting bar
|
||||
# if any(series -> series[:seriestype] == :bar, series_list(sp))
|
||||
# canvas_type = UnicodePlots.BarplotGraphics
|
||||
# end
|
||||
|
||||
o = UnicodePlots.Plot(x, y, canvas_type;
|
||||
width = width,
|
||||
height = height,
|
||||
title = sp[:title],
|
||||
xlim = xlim,
|
||||
ylim = ylim,
|
||||
# 3d
|
||||
projection = projection,
|
||||
elevation = elevation,
|
||||
azimuth = azimuth,
|
||||
zoom = get(sp_kw, :zoom, 1),
|
||||
up = get(sp_kw, :up, :z),
|
||||
border = isijulia() ? :ascii : :solid
|
||||
)
|
||||
|
||||
o = UnicodePlots.Plot(x, y, plot_3d ? z : nothing, _canvas_map[canvas]; kw...)
|
||||
for series in series_list(sp)
|
||||
o = addUnicodeSeries!(
|
||||
sp,
|
||||
o,
|
||||
kw,
|
||||
series,
|
||||
sp[:legend_position] !== :none,
|
||||
plot_3d,
|
||||
)
|
||||
end
|
||||
|
||||
for ann in sp[:annotations]
|
||||
x, y, val = locate_annotation(sp, ann...)
|
||||
o = UnicodePlots.annotate!(
|
||||
o,
|
||||
x,
|
||||
y,
|
||||
texmath2unicode(val.str);
|
||||
color = up_color(val.font.color),
|
||||
halign = val.font.halign,
|
||||
valign = val.font.valign,
|
||||
)
|
||||
end
|
||||
|
||||
push!(plt.o, o) # save the object
|
||||
end
|
||||
end
|
||||
|
||||
up_color(col::UnicodePlots.UserColorType) = col
|
||||
up_color(col::RGBA) =
|
||||
(c = convert(ARGB32, col); map(Int, (red(c).i, green(c).i, blue(c).i)))
|
||||
up_color(col) = :auto
|
||||
|
||||
function up_cmap(series)
|
||||
rng = range(0, 1, length = length(UnicodePlots.COLOR_MAP_DATA[:viridis]))
|
||||
[(red(c), green(c), blue(c)) for c in get(get_colorgradient(series), rng)]
|
||||
end
|
||||
|
||||
# add a single series
|
||||
function addUnicodeSeries!(
|
||||
sp::Subplot{UnicodePlotsBackend},
|
||||
up::UnicodePlots.Plot,
|
||||
kw,
|
||||
series,
|
||||
addlegend::Bool,
|
||||
plot_3d::Bool,
|
||||
)
|
||||
st = series[:seriestype]
|
||||
se_kw = series[:extra_kwargs]
|
||||
|
||||
# get the series data and label
|
||||
x, y = if st === :straightline
|
||||
straightline_data(series)
|
||||
elseif st === :shape
|
||||
shape_data(series)
|
||||
else
|
||||
series[:x], series[:y]
|
||||
end
|
||||
|
||||
if ispolar(sp) || ispolar(series)
|
||||
return UnicodePlots.polarplot(x, y)
|
||||
end
|
||||
|
||||
# special handling (src/interface)
|
||||
fix_ar = get(se_kw, :fix_ar, true)
|
||||
if st === :histogram2d
|
||||
return UnicodePlots.densityplot(x, y; kw...)
|
||||
elseif st === :spy
|
||||
return UnicodePlots.spy(Array(series[:z]); fix_ar = fix_ar, kw...)
|
||||
elseif st in (:contour, :heatmap) # 2D
|
||||
colormap = get(se_kw, :colormap, :none)
|
||||
kw = (
|
||||
kw...,
|
||||
zlabel = sp[:colorbar_title],
|
||||
colormap = colormap === :none ? up_cmap(series) : colormap,
|
||||
colorbar = hascolorbar(sp),
|
||||
)
|
||||
if st === :contour
|
||||
isfilledcontour(series) &&
|
||||
@warn "Plots(UnicodePlots): filled contour is not implemented"
|
||||
return UnicodePlots.contourplot(
|
||||
x,
|
||||
y,
|
||||
Array(series[:z]);
|
||||
kw...,
|
||||
levels = series[:levels],
|
||||
)
|
||||
elseif st === :heatmap
|
||||
return UnicodePlots.heatmap(Array(series[:z]); fix_ar = fix_ar, kw...)
|
||||
end
|
||||
elseif st in (:surface, :wireframe) # 3D
|
||||
colormap = get(se_kw, :colormap, :none)
|
||||
lines = get(se_kw, :lines, st === :wireframe)
|
||||
zscale = get(se_kw, :zscale, :identity)
|
||||
kw = (
|
||||
kw...,
|
||||
zlabel = sp[:colorbar_title],
|
||||
colormap = colormap === :none ? up_cmap(series) : colormap,
|
||||
colorbar = hascolorbar(sp),
|
||||
color = st === :wireframe ? up_color(get_linecolor(series, 1)) : nothing,
|
||||
zscale = zscale,
|
||||
lines = lines,
|
||||
)
|
||||
return UnicodePlots.surfaceplot(x, y, Array(series[:z]); kw...)
|
||||
elseif st === :mesh3d
|
||||
return UnicodePlots.lineplot!(
|
||||
up,
|
||||
mesh3d_triangles(x, y, series[:z], series[:connections])...,
|
||||
)
|
||||
end
|
||||
# set the axis labels
|
||||
UnicodePlots.xlabel!(o, xaxis[:guide])
|
||||
UnicodePlots.ylabel!(o, yaxis[:guide])
|
||||
|
||||
# now use the ! functions to add to the plot
|
||||
if st in (:path, :path3d, :straightline, :shape, :mesh3d)
|
||||
for series in series_list(sp)
|
||||
addUnicodeSeries!(o, series.plotattributes, sp[:legend] != :none, xlim, ylim)
|
||||
end
|
||||
|
||||
# save the object
|
||||
push!(plt.o, o)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# add a single series
|
||||
function addUnicodeSeries!(o, plotattributes, addlegend::Bool, xlim, ylim)
|
||||
# get the function, or special handling for step/bar/hist
|
||||
st = plotattributes[:seriestype]
|
||||
if st == :histogram2d
|
||||
UnicodePlots.densityplot!(o, plotattributes[:x], plotattributes[:y])
|
||||
return
|
||||
end
|
||||
|
||||
if st in (:path, :straightline)
|
||||
func = UnicodePlots.lineplot!
|
||||
series_kw = (; head_tail = series[:arrow] isa Arrow ? series[:arrow].side : nothing)
|
||||
elseif st in (:scatter, :scatter3d) || series[:markershape] !== :none
|
||||
elseif st == :scatter || plotattributes[:markershape] != :none
|
||||
func = UnicodePlots.scatterplot!
|
||||
series_kw = (; marker = series[:markershape])
|
||||
# elseif st == :bar
|
||||
# func = UnicodePlots.barplot!
|
||||
elseif st == :shape
|
||||
func = UnicodePlots.lineplot!
|
||||
else
|
||||
error("Plots(UnicodePlots): series type $st not supported")
|
||||
error("Linestyle $st not supported by UnicodePlots")
|
||||
end
|
||||
|
||||
label = addlegend ? series[:label] : ""
|
||||
|
||||
for (n, segment) in enumerate(series_segments(series, st; check = true))
|
||||
i, rng = segment.attr_index, segment.range
|
||||
lc = get_linecolor(series, i)
|
||||
up = func(
|
||||
up,
|
||||
x[rng],
|
||||
y[rng],
|
||||
plot_3d ? series[:z][rng] : nothing;
|
||||
color = up_color(lc),
|
||||
name = n == 1 ? label : "",
|
||||
series_kw...,
|
||||
)
|
||||
end
|
||||
|
||||
for (xi, yi, str, fnt) in EachAnn(series[:series_annotations], x, y)
|
||||
up = UnicodePlots.annotate!(
|
||||
up,
|
||||
xi,
|
||||
yi,
|
||||
str;
|
||||
color = up_color(fnt.color),
|
||||
halign = fnt.halign,
|
||||
valign = fnt.valign,
|
||||
)
|
||||
end
|
||||
|
||||
up
|
||||
end
|
||||
|
||||
# ------------------------------------------------------------------------------------------
|
||||
|
||||
function _show(io::IO, ::MIME"image/png", plt::Plot{UnicodePlotsBackend})
|
||||
prepare_output(plt)
|
||||
nr, nc = size(plt.layout)
|
||||
s1 = zeros(Int, nr, nc)
|
||||
s2 = zeros(Int, nr, nc)
|
||||
canvas_type = nothing
|
||||
imgs = []
|
||||
sps = 0
|
||||
for r in 1:nr
|
||||
for c in 1:nc
|
||||
if (l = plt.layout[r, c]) isa GridLayout && size(l) != (1, 1)
|
||||
error("Plots(UnicodePlots): complex nested layout is currently unsupported")
|
||||
# get the series data and label
|
||||
x, y = if st == :straightline
|
||||
straightline_data(plotattributes)
|
||||
elseif st == :shape
|
||||
shape_data(plotattributes)
|
||||
else
|
||||
img = UnicodePlots.png_image(plt.o[sps += 1])
|
||||
canvas_type = eltype(img)
|
||||
h, w = size(img)
|
||||
s1[r, c] = h
|
||||
s2[r, c] = w
|
||||
push!(imgs, img)
|
||||
[collect(float(plotattributes[s])) for s in (:x, :y)]
|
||||
end
|
||||
end
|
||||
end
|
||||
if canvas_type !== nothing
|
||||
m1 = maximum(s1; dims = 2)
|
||||
m2 = maximum(s2; dims = 1)
|
||||
img = zeros(canvas_type, sum(m1), sum(m2))
|
||||
sps = 0
|
||||
n1 = 1
|
||||
for r in 1:nr
|
||||
n2 = 1
|
||||
for c in 1:nc
|
||||
sp = imgs[sps += 1]
|
||||
h, w = size(sp)
|
||||
img[n1:(n1 + (h - 1)), n2:(n2 + (w - 1))] = sp
|
||||
n2 += m2[c]
|
||||
end
|
||||
n1 += m1[r]
|
||||
end
|
||||
stream = UnicodePlots.FileIO.Stream{UnicodePlots.FileIO.format"PNG"}(io)
|
||||
UnicodePlots.FileIO.save(stream, img)
|
||||
end
|
||||
nothing
|
||||
label = addlegend ? plotattributes[:label] : ""
|
||||
|
||||
# if we happen to pass in allowed color symbols, great... otherwise let UnicodePlots decide
|
||||
color = plotattributes[:linecolor] in UnicodePlots.color_cycle ? plotattributes[:linecolor] : :auto
|
||||
|
||||
# add the series
|
||||
x, y = RecipesPipeline.unzip(collect(Base.Iterators.filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y))))
|
||||
func(o, x, y; color = color, name = label)
|
||||
end
|
||||
|
||||
Base.show(plt::Plot{UnicodePlotsBackend}) = show(stdout, plt)
|
||||
Base.show(io::IO, plt::Plot{UnicodePlotsBackend}) = _show(io, MIME("text/plain"), plt)
|
||||
# -------------------------------
|
||||
|
||||
# since this is such a hack, it's only callable using `png`... should error during normal `show`
|
||||
function png(plt::AbstractPlot{UnicodePlotsBackend}, fn::AbstractString)
|
||||
fn = addExtension(fn, "png")
|
||||
|
||||
# make some whitespace and show the plot
|
||||
println("\n\n\n\n\n\n")
|
||||
gui(plt)
|
||||
|
||||
# @osx_only begin
|
||||
@static if Sys.isapple()
|
||||
# BEGIN HACK
|
||||
|
||||
# wait while the plot gets drawn
|
||||
sleep(0.5)
|
||||
|
||||
# use osx screen capture when my terminal is maximized and cursor starts at the bottom (I know, right?)
|
||||
# TODO: compute size of plot to adjust these numbers (or maybe implement something good??)
|
||||
run(`screencapture -R50,600,700,420 $fn`)
|
||||
|
||||
# END HACK (phew)
|
||||
return
|
||||
end
|
||||
|
||||
error("Can only savepng on osx with UnicodePlots (though even then I wouldn't do it)")
|
||||
end
|
||||
|
||||
# -------------------------------
|
||||
|
||||
# we don't do very much for subplots... just stack them vertically
|
||||
|
||||
function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend})
|
||||
w, h = plt[:size]
|
||||
plt.attr[:color_palette] = [RGB(0,0,0)]
|
||||
rebuildUnicodePlot!(plt, div(w, 10), div(h, 20))
|
||||
end
|
||||
|
||||
# NOTE: _show(...) must be kept for Base.showable (src/output.jl)
|
||||
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
|
||||
prepare_output(plt)
|
||||
nr, nc = size(plt.layout)
|
||||
if nr == 1 && nc == 1 # fast path
|
||||
n = length(plt.o)
|
||||
for (i, p) in enumerate(plt.o)
|
||||
show(io, p)
|
||||
i < n && println(io)
|
||||
end
|
||||
else
|
||||
have_color = Base.get_have_color()
|
||||
buf = IOContext(PipeBuffer(), :color => have_color)
|
||||
lines_colored = Array{Union{Nothing,Vector{String}}}(undef, nr, nc)
|
||||
lines_uncolored = have_color ? similar(lines_colored) : lines_colored
|
||||
l_max = zeros(Int, nr)
|
||||
w_max = zeros(Int, nc)
|
||||
sps = 0
|
||||
for r in 1:nr
|
||||
lmax = 0
|
||||
for c in 1:nc
|
||||
if (l = plt.layout[r, c]) isa GridLayout && size(l) != (1, 1)
|
||||
error(
|
||||
"Plots(UnicodePlots): complex nested layout is currently unsupported",
|
||||
)
|
||||
else
|
||||
if get(l.attr, :blank, false)
|
||||
lines_colored[r, c] = lines_uncolored[r, c] = nothing
|
||||
else
|
||||
sp = plt.o[sps += 1]
|
||||
show(buf, sp)
|
||||
colored = read(buf, String)
|
||||
lines_colored[r, c] = lu = lc = split(colored, '\n')
|
||||
if have_color
|
||||
uncolored = UnicodePlots.no_ansi_escape(colored)
|
||||
lines_uncolored[r, c] = lu = split(uncolored, '\n')
|
||||
end
|
||||
lmax = max(length(lc), lmax)
|
||||
w_max[c] = max(maximum(length.(lu)), w_max[c])
|
||||
end
|
||||
end
|
||||
end
|
||||
l_max[r] = lmax
|
||||
end
|
||||
empty = String[' '^w for w in w_max]
|
||||
for r in 1:nr
|
||||
for n in 1:l_max[r]
|
||||
for c in 1:nc
|
||||
pre = c == 1 ? '\0' : ' '
|
||||
lc = lines_colored[r, c]
|
||||
if lc === nothing || length(lc) < n
|
||||
print(io, pre, empty[c])
|
||||
else
|
||||
lu = lines_uncolored[r, c]
|
||||
print(io, pre, lc[n], ' '^(w_max[c] - length(lu[n])))
|
||||
end
|
||||
end
|
||||
n < l_max[r] && println(io)
|
||||
end
|
||||
r < nr && println(io)
|
||||
end
|
||||
end
|
||||
unicodeplots_rebuild(plt)
|
||||
foreach(x -> show(io, x), plt.o)
|
||||
nothing
|
||||
end
|
||||
|
||||
# we only support MIME"text/plain", hence display(...) falls back to plain-text on stdout
|
||||
|
||||
function _display(plt::Plot{UnicodePlotsBackend})
|
||||
show(stdout, plt)
|
||||
println(stdout)
|
||||
unicodeplots_rebuild(plt)
|
||||
map(show, plt.o)
|
||||
nothing
|
||||
end
|
||||
|
||||
@ -3,10 +3,7 @@
|
||||
|
||||
# CREDIT: parts of this implementation were inspired by @joshday's PlotlyLocal.jl
|
||||
|
||||
function standalone_html(
|
||||
plt::AbstractPlot;
|
||||
title::AbstractString = get(plt.attr, :window_title, "Plots.jl"),
|
||||
)
|
||||
function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr, :window_title, "Plots.jl"))
|
||||
"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -22,10 +19,6 @@ function standalone_html(
|
||||
"""
|
||||
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)`)
|
||||
@ -52,8 +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[] = plotly_local_file_path[] === nothing ? false : isfile(plotly_local_file_path[])
|
||||
filename = write_temp_html(plt)
|
||||
open_browser_window(filename)
|
||||
# restore for other backends
|
||||
@ -62,9 +54,7 @@ end
|
||||
|
||||
# uses wkhtmltopdf/wkhtmltoimage: http://wkhtmltopdf.org/downloads.html
|
||||
function html_to_png(html_fn, png_fn, w, h)
|
||||
run(
|
||||
`wkhtmltoimage -f png -q --width $w --height $h --disable-smart-width $html_fn $png_fn`,
|
||||
)
|
||||
run(`wkhtmltoimage -f png -q --width $w --height $h --disable-smart-width $html_fn $png_fn`)
|
||||
end
|
||||
|
||||
function show_png_from_html(io::IO, plt::AbstractPlot)
|
||||
|
||||
@ -1,60 +1,47 @@
|
||||
# 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(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
|
||||
|
||||
get_clims(sp::Subplot)::Tuple{Float64,Float64} =
|
||||
haskey(sp.attr, :clims_calculated) ? sp[:clims_calculated] : update_clims(sp)
|
||||
get_clims(series::Series)::Tuple{Float64,Float64} =
|
||||
haskey(series.plotattributes, :clims_calculated) ?
|
||||
series[:clims_calculated]::Tuple{Float64,Float64} : update_clims(series)
|
||||
get_clims(sp::Subplot, series::Series)::Tuple{Float64,Float64} =
|
||||
series[:colorbar_entry] ? get_clims(sp) : get_clims(series)
|
||||
|
||||
function update_clims(sp::Subplot, op = process_clims(sp[:clims]))::Tuple{Float64,Float64}
|
||||
function get_clims(sp::Subplot, op=process_clims(sp[:clims]))
|
||||
zmin, zmax = Inf, -Inf
|
||||
for series in series_list(sp)
|
||||
if series[:colorbar_entry]::Bool
|
||||
zmin, zmax = _update_clims(zmin, zmax, update_clims(series, op)...)
|
||||
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
|
||||
update_clims(series, op)
|
||||
get_clims(series, op)
|
||||
end
|
||||
end
|
||||
return sp[:clims_calculated] = zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
|
||||
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
|
||||
end
|
||||
|
||||
"""
|
||||
update_clims(::Series, op=Plots.ignorenan_extrema)
|
||||
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. The value is stored as a series property, which is retrieved by `get_clims`.
|
||||
values of the input.
|
||||
"""
|
||||
function update_clims(series::Series, op = ignorenan_extrema)::Tuple{Float64,Float64}
|
||||
function get_clims(series::Series, op=ignorenan_extrema)
|
||||
zmin, zmax = Inf, -Inf
|
||||
|
||||
# keeping this unrolled has higher performance
|
||||
if series[:seriestype] ∈ _z_colored_series && series[:z] !== nothing
|
||||
zmin, zmax = update_clims(zmin, zmax, series[:z], op)
|
||||
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
|
||||
if series[:line_z] !== nothing
|
||||
zmin, zmax = update_clims(zmin, zmax, series[:line_z], op)
|
||||
end
|
||||
if series[:marker_z] !== nothing
|
||||
zmin, zmax = update_clims(zmin, zmax, series[:marker_z], op)
|
||||
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
|
||||
end
|
||||
if series[:fill_z] !== nothing
|
||||
zmin, zmax = update_clims(zmin, zmax, series[:fill_z], op)
|
||||
end
|
||||
return series[:clims_calculated] = zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
|
||||
end
|
||||
|
||||
update_clims(zmin, zmax, vals::AbstractSurface, op)::Tuple{Float64,Float64} =
|
||||
update_clims(zmin, zmax, vals.surf, op)
|
||||
update_clims(zmin, zmax, vals::Any, op)::Tuple{Float64,Float64} =
|
||||
_update_clims(zmin, zmax, op(vals)...)
|
||||
update_clims(zmin, zmax, ::Nothing, ::Any)::Tuple{Float64,Float64} = zmin, zmax
|
||||
|
||||
_update_clims(zmin, zmax, emin, emax) = NaNMath.min(zmin, emin), NaNMath.max(zmax, emax)
|
||||
|
||||
@ -74,7 +61,7 @@ function colorbar_style(series::Series)
|
||||
elseif iscontour(series)
|
||||
cbar_lines
|
||||
elseif series[:seriestype] ∈ (:heatmap,:surface) ||
|
||||
any(series[z] !== nothing for z in [:marker_z, :line_z, :fill_z])
|
||||
any(series[z] !== nothing for z ∈ [:marker_z,:line_z,:fill_z])
|
||||
cbar_gradient
|
||||
else
|
||||
nothing
|
||||
@ -82,8 +69,7 @@ function colorbar_style(series::Series)
|
||||
end
|
||||
|
||||
hascolorbar(series::Series) = colorbar_style(series) !== nothing
|
||||
hascolorbar(sp::Subplot) =
|
||||
sp[:colorbar] != :none && any(hascolorbar(s) for s in series_list(sp))
|
||||
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)
|
||||
@ -101,5 +87,4 @@ end
|
||||
|
||||
function _update_subplot_colorbars(sp::Subplot)
|
||||
# Dynamic callback from the pipeline if needed
|
||||
update_clims(sp)
|
||||
end
|
||||
|
||||
@ -1,20 +1,17 @@
|
||||
const P2 = GeometryBasics.Point2{Float64}
|
||||
const P3 = GeometryBasics.Point3{Float64}
|
||||
|
||||
const _haligns = :hcenter, :left, :right
|
||||
const _valigns = :vcenter, :top, :bottom
|
||||
|
||||
nanpush!(a::AVec{P2}, b) = (push!(a, P2(NaN, NaN)); push!(a, b))
|
||||
nanappend!(a::AVec{P2}, b) = (push!(a, P2(NaN, NaN)); append!(a, b))
|
||||
nanpush!(a::AVec{P3}, b) = (push!(a, P3(NaN, NaN, NaN)); push!(a, b))
|
||||
nanappend!(a::AVec{P3}, b) = (push!(a, P3(NaN, NaN, NaN)); append!(a, b))
|
||||
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))
|
||||
nanpush!(a::AbstractVector{P3}, b) = (push!(a, P3(NaN,NaN,NaN)); push!(a, b))
|
||||
nanappend!(a::AbstractVector{P3}, b) = (push!(a, P3(NaN,NaN,NaN)); append!(a, b))
|
||||
compute_angle(v::P2) = (angle = atan(v[2], v[1]); angle < 0 ? 2π - angle : angle)
|
||||
|
||||
# -------------------------------------------------------------
|
||||
|
||||
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]))
|
||||
@ -41,13 +38,22 @@ vertices(shape::Shape) = collect(zip(shape.x, shape.y))
|
||||
@deprecate shape_coords coords
|
||||
|
||||
"return the vertex points from a Shape or Segments object"
|
||||
coords(shape::Shape) = shape.x, shape.y
|
||||
function coords(shape::Shape)
|
||||
shape.x, shape.y
|
||||
end
|
||||
|
||||
coords(shapes::AVec{<:Shape}) = unzip(map(coords, shapes))
|
||||
#coords(shapes::AVec{Shape}) = unzip(map(coords, shapes))
|
||||
function coords(shapes::AVec{Shape})
|
||||
c = map(coords, shapes)
|
||||
x = [q[1] for q in c]
|
||||
y = [q[2] for q in c]
|
||||
x, y
|
||||
end
|
||||
|
||||
"get an array of tuples of points on a circle with radius `r`"
|
||||
partialcircle(start_θ, end_θ, n = 20, r = 1) =
|
||||
[(r * cos(u), r * sin(u)) for u in range(start_θ, stop = end_θ, length = n)]
|
||||
function partialcircle(start_θ, end_θ, n = 20, r=1)
|
||||
Tuple{Float64,Float64}[(r*cos(u),r*sin(u)) for u in range(start_θ, stop=end_θ, length=n)]
|
||||
end
|
||||
|
||||
"interleave 2 vectors into each other (like a zipper's teeth)"
|
||||
function weave(x,y; ordering = Vector[x,y])
|
||||
@ -75,33 +81,27 @@ function makestar(n; offset = -0.5, radius = 1.0)
|
||||
end
|
||||
|
||||
"create a shape by picking points around the unit circle. `n` is the number of point/sides, `offset` is the starting angle"
|
||||
makeshape(n; offset = -0.5, radius = 1.0) =
|
||||
Shape(partialcircle(offset * π, offset * π + 2π, n + 1, radius))
|
||||
function makeshape(n; offset = -0.5, radius = 1.0)
|
||||
z = offset * π
|
||||
Shape(partialcircle(z, z + 2π, n+1, radius))
|
||||
end
|
||||
|
||||
function makecross(; offset = -0.5, radius = 1.0)
|
||||
z2 = offset * π
|
||||
z1 = z2 - π/8
|
||||
outercircle = partialcircle(z1, z1 + 2π, 9, radius)
|
||||
innercircle = partialcircle(z2, z2 + 2π, 5, 0.5radius)
|
||||
Shape(
|
||||
weave(
|
||||
outercircle,
|
||||
innercircle,
|
||||
ordering = Vector[outercircle, innercircle, outercircle],
|
||||
),
|
||||
)
|
||||
Shape(weave(outercircle, innercircle,
|
||||
ordering=Vector[outercircle,innercircle,outercircle]))
|
||||
end
|
||||
|
||||
from_polar(angle, dist) = P2(dist*cos(angle), dist*sin(angle))
|
||||
|
||||
makearrowhead(angle; h = 2.0, w = 0.4, tip = from_polar(angle, h)) = Shape(
|
||||
P2[
|
||||
(0, 0),
|
||||
from_polar(angle - 0.5π, w) - tip,
|
||||
from_polar(angle + 0.5π, w) - tip,
|
||||
(0, 0),
|
||||
],
|
||||
)
|
||||
function makearrowhead(angle; h = 2.0, w = 0.4)
|
||||
tip = from_polar(angle, h)
|
||||
Shape(P2[(0,0), from_polar(angle - 0.5π, w) - tip,
|
||||
from_polar(angle + 0.5π, w) - tip, (0,0)])
|
||||
end
|
||||
|
||||
const _shapes = KW(
|
||||
:circle => makeshape(20),
|
||||
@ -121,7 +121,7 @@ const _shapes = KW(
|
||||
:hline => Shape([(1,0),(-1,0)]),
|
||||
)
|
||||
|
||||
for n in 4:8
|
||||
for n in [4,5,6,7,8]
|
||||
_shapes[Symbol("star$n")] = makestar(n)
|
||||
end
|
||||
|
||||
@ -129,18 +129,19 @@ Shape(k::Symbol) = deepcopy(_shapes[k])
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
|
||||
# uses the centroid calculation from https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
|
||||
"return the centroid of a Shape"
|
||||
function center(shape::Shape)
|
||||
x, y = coords(shape)
|
||||
n = length(x)
|
||||
A, Cx, Cy = 0, 0, 0
|
||||
for i in 1:n
|
||||
A, Cx, Cy = 0.0, 0.0, 0.0
|
||||
for i=1:n
|
||||
ip1 = i==n ? 1 : i+1
|
||||
A += x[i] * y[ip1] - x[ip1] * y[i]
|
||||
end
|
||||
A *= 0.5
|
||||
for i in 1:n
|
||||
for i=1:n
|
||||
ip1 = i==n ? 1 : i+1
|
||||
m = (x[i] * y[ip1] - x[ip1] * y[i])
|
||||
Cx += (x[i] + x[ip1]) * m
|
||||
@ -152,67 +153,66 @@ end
|
||||
function scale!(shape::Shape, x::Real, y::Real = x, c = center(shape))
|
||||
sx, sy = coords(shape)
|
||||
cx, cy = c
|
||||
for i in eachindex(sx)
|
||||
for i=eachindex(sx)
|
||||
sx[i] = (sx[i] - cx) * x + cx
|
||||
sy[i] = (sy[i] - cy) * y + cy
|
||||
end
|
||||
shape
|
||||
end
|
||||
|
||||
"""
|
||||
scale(shape, x, y = x, c = center(shape))
|
||||
scale!(shape, x, y = x, c = center(shape))
|
||||
|
||||
Scale shape by a factor.
|
||||
"""
|
||||
scale(shape::Shape, x::Real, y::Real = x, c = center(shape)) =
|
||||
scale!(deepcopy(shape), x, y, c)
|
||||
function scale(shape::Shape, x::Real, y::Real = x, c = center(shape))
|
||||
shapecopy = deepcopy(shape)
|
||||
scale!(shapecopy, x, y, c)
|
||||
end
|
||||
|
||||
"translate a Shape in space"
|
||||
function translate!(shape::Shape, x::Real, y::Real = x)
|
||||
sx, sy = coords(shape)
|
||||
for i in eachindex(sx)
|
||||
for i=eachindex(sx)
|
||||
sx[i] += x
|
||||
sy[i] += y
|
||||
end
|
||||
shape
|
||||
end
|
||||
|
||||
"""
|
||||
translate(shape, x, y = x)
|
||||
translate!(shape, x, y = x)
|
||||
function translate(shape::Shape, x::Real, y::Real = x)
|
||||
shapecopy = deepcopy(shape)
|
||||
translate!(shapecopy, x, y)
|
||||
end
|
||||
|
||||
Translate a Shape in space.
|
||||
"""
|
||||
translate(shape::Shape, x::Real, y::Real = x) = translate!(deepcopy(shape), x, y)
|
||||
function rotate_x(x::Real, y::Real, Θ::Real, centerx::Real, centery::Real)
|
||||
(x - centerx) * cos(Θ) - (y - centery) * sin(Θ) + centerx
|
||||
end
|
||||
|
||||
rotate_x(x::Real, y::Real, θ::Real, centerx::Real, centery::Real) =
|
||||
((x - centerx) * cos(θ) - (y - centery) * sin(θ) + centerx)
|
||||
function rotate_y(x::Real, y::Real, Θ::Real, centerx::Real, centery::Real)
|
||||
(y - centery) * cos(Θ) + (x - centerx) * sin(Θ) + centery
|
||||
end
|
||||
|
||||
rotate_y(x::Real, y::Real, θ::Real, centerx::Real, centery::Real) =
|
||||
((y - centery) * cos(θ) + (x - centerx) * sin(θ) + centery)
|
||||
function rotate(x::Real, y::Real, θ::Real, c = center(shape))
|
||||
cx, cy = c
|
||||
rotate_x(x, y, Θ, cx, cy), rotate_y(x, y, Θ, cx, cy)
|
||||
end
|
||||
|
||||
rotate(x::Real, y::Real, θ::Real, c) = (rotate_x(x, y, θ, c...), rotate_y(x, y, θ, c...))
|
||||
|
||||
function rotate!(shape::Shape, θ::Real, c = center(shape))
|
||||
function rotate!(shape::Shape, Θ::Real, c = center(shape))
|
||||
x, y = coords(shape)
|
||||
for i in eachindex(x)
|
||||
xi = rotate_x(x[i], y[i], θ, c...)
|
||||
yi = rotate_y(x[i], y[i], θ, c...)
|
||||
cx, cy = c
|
||||
for i=eachindex(x)
|
||||
xi = rotate_x(x[i], y[i], Θ, cx, cy)
|
||||
yi = rotate_y(x[i], y[i], Θ, cx, cy)
|
||||
x[i], y[i] = xi, yi
|
||||
end
|
||||
shape
|
||||
end
|
||||
|
||||
"rotate an object in space"
|
||||
function rotate(shape::Shape, θ::Real, c = center(shape))
|
||||
x, y = coords(shape)
|
||||
x_new = rotate_x.(x, y, θ, c...)
|
||||
y_new = rotate_y.(x, y, θ, c...)
|
||||
Shape(x_new, y_new)
|
||||
function rotate(shape::Shape, Θ::Real, c = center(shape))
|
||||
shapecopy = deepcopy(shape)
|
||||
rotate!(shapecopy, Θ, c)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
|
||||
mutable struct Font
|
||||
family::AbstractString
|
||||
pointsize::Int
|
||||
@ -240,17 +240,17 @@ julia> font(family="serif", halign=:center, rotation=45.0)
|
||||
```
|
||||
"""
|
||||
function font(args...;kw...)
|
||||
|
||||
# defaults
|
||||
family = "sans-serif"
|
||||
pointsize = 14
|
||||
halign = :hcenter
|
||||
valign = :vcenter
|
||||
rotation = 0
|
||||
rotation = 0.0
|
||||
color = colorant"black"
|
||||
|
||||
for arg in args
|
||||
T = typeof(arg)
|
||||
@assert arg !== :match
|
||||
|
||||
if T == Font
|
||||
family = arg.family
|
||||
@ -262,9 +262,9 @@ function font(args...; kw...)
|
||||
elseif arg == :center
|
||||
halign = :hcenter
|
||||
valign = :vcenter
|
||||
elseif arg ∈ _haligns
|
||||
elseif arg in (:hcenter, :left, :right)
|
||||
halign = arg
|
||||
elseif arg ∈ _valigns
|
||||
elseif arg in (:vcenter, :top, :bottom)
|
||||
valign = arg
|
||||
elseif T <: Colorant
|
||||
color = arg
|
||||
@ -274,34 +274,38 @@ function font(args...; kw...)
|
||||
catch
|
||||
family = string(arg)
|
||||
end
|
||||
elseif T <: Integer
|
||||
elseif typeof(arg) <: Integer
|
||||
pointsize = arg
|
||||
elseif T <: Real
|
||||
elseif typeof(arg) <: Real
|
||||
rotation = convert(Float64, arg)
|
||||
else
|
||||
@warn "Unused font arg: $arg ($T)"
|
||||
@warn("Unused font arg: $arg ($(typeof(arg)))")
|
||||
end
|
||||
end
|
||||
|
||||
for sym in keys(kw)
|
||||
if sym == :family
|
||||
family = string(kw[sym])
|
||||
elseif sym == :pointsize
|
||||
pointsize = kw[sym]
|
||||
elseif sym == :halign
|
||||
halign = kw[sym]
|
||||
halign == :center && (halign = :hcenter)
|
||||
@assert halign ∈ _haligns
|
||||
elseif sym == :valign
|
||||
valign = kw[sym]
|
||||
valign == :center && (valign = :vcenter)
|
||||
@assert valign ∈ _valigns
|
||||
elseif sym == :rotation
|
||||
rotation = kw[sym]
|
||||
elseif sym == :color
|
||||
color = parse(Colorant, kw[sym])
|
||||
for symbol in keys(kw)
|
||||
if symbol == :family
|
||||
family = kw[:family]
|
||||
elseif symbol == :pointsize
|
||||
pointsize = kw[:pointsize]
|
||||
elseif symbol == :halign
|
||||
halign = kw[:halign]
|
||||
if halign == :center
|
||||
halign = :hcenter
|
||||
end
|
||||
@assert halign in (:hcenter, :left, :right)
|
||||
elseif symbol == :valign
|
||||
valign = kw[:valign]
|
||||
if valign == :center
|
||||
valign = :vcenter
|
||||
end
|
||||
@assert valign in (:vcenter, :top, :bottom)
|
||||
elseif symbol == :rotation
|
||||
rotation = kw[:rotation]
|
||||
elseif symbol == :color
|
||||
color = parse(Colorant, kw[:color])
|
||||
else
|
||||
@warn "Unused font kwarg: $sym"
|
||||
@warn("Unused font kwarg: $symbol")
|
||||
end
|
||||
end
|
||||
|
||||
@ -320,13 +324,13 @@ 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 keys(merge(_initial_plt_fontsizes, _initial_sp_fontsizes))
|
||||
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
|
||||
scalefontsize(k, factor)
|
||||
end
|
||||
|
||||
for letter in (:x,:y,:z)
|
||||
for k in keys(_initial_ax_fontsizes)
|
||||
scalefontsize(get_attr_symbol(letter, k), factor)
|
||||
for k in (:guidefontsize, :tickfontsize)
|
||||
scalefontsize(Symbol(letter, k), factor)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -337,7 +341,7 @@ end
|
||||
Resets font sizes to initial default values.
|
||||
"""
|
||||
function scalefontsizes()
|
||||
for k in keys(merge(_initial_plt_fontsizes, _initial_sp_fontsizes))
|
||||
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
|
||||
f = default(k)
|
||||
if k in keys(_initial_fontsizes)
|
||||
factor = f / _initial_fontsizes[k]
|
||||
@ -346,11 +350,11 @@ function scalefontsizes()
|
||||
end
|
||||
|
||||
for letter in (:x,:y,:z)
|
||||
for k in keys(_initial_ax_fontsizes)
|
||||
for k in (:guidefontsize, :tickfontsize)
|
||||
if k in keys(_initial_fontsizes)
|
||||
f = default(get_attr_symbol(letter, k))
|
||||
f = default(Symbol(letter, k))
|
||||
factor = f / _initial_fontsizes[k]
|
||||
scalefontsize(get_attr_symbol(letter, k), 1.0 / factor)
|
||||
scalefontsize(Symbol(letter, k), 1.0/factor)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -374,12 +378,16 @@ Create a PlotText object wrapping a string with font info, for plot annotations.
|
||||
text(t::PlotText) = t
|
||||
text(t::PlotText, font::Font) = PlotText(t.str, font)
|
||||
text(str::AbstractString, f::Font) = PlotText(str, f)
|
||||
text(str, args...; kw...) = PlotText(string(str), font(args...; kw...))
|
||||
function text(str, args...;kw...)
|
||||
PlotText(string(str), font(args...;kw...))
|
||||
end
|
||||
|
||||
Base.length(t::PlotText) = length(t.str)
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
struct Stroke
|
||||
width
|
||||
color
|
||||
@ -415,13 +423,14 @@ function stroke(args...; alpha = nothing)
|
||||
elseif allReals(arg)
|
||||
width = arg
|
||||
else
|
||||
@warn "Unused stroke arg: $arg ($(typeof(arg)))"
|
||||
@warn("Unused stroke arg: $arg ($(typeof(arg)))")
|
||||
end
|
||||
end
|
||||
|
||||
Stroke(width, color, alpha, style)
|
||||
end
|
||||
|
||||
|
||||
struct Brush
|
||||
size # fillrange, markersize, or any other sizey attribute
|
||||
color
|
||||
@ -447,7 +456,7 @@ function brush(args...; alpha = nothing)
|
||||
elseif allReals(arg)
|
||||
size = arg
|
||||
else
|
||||
@warn "Unused brush arg: $arg ($(typeof(arg)))"
|
||||
@warn("Unused brush arg: $arg ($(typeof(arg)))")
|
||||
end
|
||||
end
|
||||
|
||||
@ -457,40 +466,28 @@ end
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
mutable struct SeriesAnnotations
|
||||
strs::AVec # the labels/names
|
||||
strs::AbstractVector # the labels/names
|
||||
font::Font
|
||||
baseshape::Union{Shape,AVec{Shape},Nothing}
|
||||
baseshape::Union{Shape, AbstractVector{Shape}, Nothing}
|
||||
scalefactor::Tuple
|
||||
end
|
||||
|
||||
_text_label(lab::Tuple, font) = text(lab[1], font, lab[2:end]...)
|
||||
_text_label(lab::PlotText, font) = lab
|
||||
_text_label(lab, font) = text(lab, font)
|
||||
|
||||
series_annotations(anns::AMat) = map(series_annotations, anns)
|
||||
series_annotations(scalar) = series_annotations([scalar])
|
||||
series_annotations(anns::SeriesAnnotations) = anns
|
||||
series_annotations(::Nothing) = nothing
|
||||
|
||||
function series_annotations(strs::AVec, args...)
|
||||
function series_annotations(strs::AbstractVector, args...)
|
||||
fnt = font()
|
||||
shp = nothing
|
||||
scalefactor = 1, 1
|
||||
scalefactor = (1,1)
|
||||
for arg in args
|
||||
if isa(arg, Shape) || (isa(arg, AVec) && eltype(arg) == Shape)
|
||||
if isa(arg, Shape) || (isa(arg, AbstractVector) && eltype(arg) == Shape)
|
||||
shp = arg
|
||||
elseif isa(arg, Font)
|
||||
fnt = arg
|
||||
elseif isa(arg, Symbol) && haskey(_shapes, arg)
|
||||
shp = _shapes[arg]
|
||||
elseif isa(arg, Number)
|
||||
scalefactor = arg, arg
|
||||
scalefactor = (arg,arg)
|
||||
elseif is_2tuple(arg)
|
||||
scalefactor = arg
|
||||
elseif isa(arg, AVec)
|
||||
strs = collect(zip(strs, arg))
|
||||
else
|
||||
@warn "Unused SeriesAnnotations arg: $arg ($(typeof(arg)))"
|
||||
@warn("Unused SeriesAnnotations arg: $arg ($(typeof(arg)))")
|
||||
end
|
||||
end
|
||||
# if scalefactor != 1
|
||||
@ -498,14 +495,16 @@ function series_annotations(strs::AVec, args...)
|
||||
# scale!(s, scalefactor, scalefactor, (0,0))
|
||||
# end
|
||||
# end
|
||||
SeriesAnnotations([_text_label(s, fnt) for s in strs], fnt, shp, scalefactor)
|
||||
SeriesAnnotations(strs, fnt, shp, scalefactor)
|
||||
end
|
||||
series_annotations(anns::SeriesAnnotations) = anns
|
||||
series_annotations(::Nothing) = nothing
|
||||
|
||||
function series_annotations_shapes!(series::Series, scaletype::Symbol = :pixels)
|
||||
anns = series[:series_annotations]
|
||||
# msw,msh = anns.scalefactor
|
||||
# ms = series[:markersize]
|
||||
# msw, msh = if isa(ms, AVec)
|
||||
# msw,msh = if isa(ms, AbstractVector)
|
||||
# 1,1
|
||||
# elseif is_2tuple(ms)
|
||||
# ms
|
||||
@ -538,8 +537,7 @@ function series_annotations_shapes!(series::Series, scaletype::Symbol = :pixels)
|
||||
maxscale = max(xscale, yscale)
|
||||
push!(msize, maxscale)
|
||||
baseshape = _cycle(anns.baseshape, i)
|
||||
shapes[i] =
|
||||
scale(baseshape, msw * xscale / maxscale, msh * yscale / maxscale, (0, 0))
|
||||
shapes[i] = scale(baseshape, msw*xscale/maxscale, msh*yscale/maxscale, (0,0))
|
||||
end
|
||||
series[:markershape] = shapes
|
||||
series[:markersize] = msize
|
||||
@ -555,7 +553,7 @@ end
|
||||
|
||||
function Base.iterate(ea::EachAnn, i = 1)
|
||||
if ea.anns === nothing || isempty(ea.anns.strs) || i > length(ea.y)
|
||||
return
|
||||
return nothing
|
||||
end
|
||||
|
||||
tmp = _cycle(ea.anns.strs,i)
|
||||
@ -567,30 +565,14 @@ function Base.iterate(ea::EachAnn, i = 1)
|
||||
((_cycle(ea.x,i), _cycle(ea.y,i), str, fnt), i+1)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
annotations(anns::AMat) = map(annotations, anns)
|
||||
annotations(sa::SeriesAnnotations) = sa
|
||||
annotations(::Nothing) = []
|
||||
annotations(anns::AVec) = anns
|
||||
annotations(anns) = Any[anns]
|
||||
annotations(::Nothing) = []
|
||||
annotations(sa::SeriesAnnotations) = sa
|
||||
|
||||
_annotationfont(sp::Subplot) = Plots.font(;
|
||||
family = sp[:annotationfontfamily],
|
||||
pointsize = sp[:annotationfontsize],
|
||||
halign = sp[:annotationhalign],
|
||||
valign = sp[:annotationvalign],
|
||||
rotation = sp[:annotationrotation],
|
||||
color = sp[:annotationcolor],
|
||||
)
|
||||
|
||||
_annotation(sp::Subplot, font, lab, pos...; alphabet = "abcdefghijklmnopqrstuvwxyz") = (
|
||||
pos...,
|
||||
lab == :auto ? text("($(alphabet[sp[:subplot_index]]))", font) : _text_label(lab, font),
|
||||
)
|
||||
|
||||
# Expand arrays of coordinates, positions and labels into individual annotations
|
||||
# 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 = _annotationfont(sp))
|
||||
function process_annotation(sp::Subplot, xs, ys, labs, font = font())
|
||||
anns = []
|
||||
labs = makevec(labs)
|
||||
xlength = length(methods(length, (typeof(xs),))) == 0 ? 1 : length(xs)
|
||||
@ -599,63 +581,51 @@ function process_annotation(sp::Subplot, xs, ys, labs, font = _annotationfont(sp
|
||||
x, y, lab = _cycle(xs, i), _cycle(ys, i), _cycle(labs, i)
|
||||
x = typeof(x) <: TimeType ? Dates.value(x) : x
|
||||
y = typeof(y) <: TimeType ? Dates.value(y) : y
|
||||
push!(anns, _annotation(sp, font, lab, x, y))
|
||||
if lab == :auto
|
||||
alphabet = "abcdefghijklmnopqrstuvwxyz"
|
||||
push!(anns, (x, y, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
|
||||
else
|
||||
push!(anns, (x, y, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab...) : text(lab, font)))
|
||||
end
|
||||
end
|
||||
anns
|
||||
end
|
||||
|
||||
function process_annotation(
|
||||
sp::Subplot,
|
||||
positions::Union{AVec{Symbol},Symbol,Tuple},
|
||||
labs,
|
||||
font = _annotationfont(sp),
|
||||
)
|
||||
function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, labs, font = font())
|
||||
anns = []
|
||||
positions, labs = makevec(positions), makevec(labs)
|
||||
for i in 1:max(length(positions), length(labs))
|
||||
pos, lab = _cycle(positions, i), _cycle(labs, i)
|
||||
push!(anns, _annotation(sp, font, lab, get(_positionAliases, pos, pos)))
|
||||
pos = get(_positionAliases, pos, pos)
|
||||
if lab == :auto
|
||||
alphabet = "abcdefghijklmnopqrstuvwxyz"
|
||||
push!(anns, (pos, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
|
||||
else
|
||||
push!(anns, (pos, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab...) : text(lab, font)))
|
||||
end
|
||||
end
|
||||
anns
|
||||
end
|
||||
|
||||
_relative_position(xmin, xmax, pos::Length{:pct}) = xmin + pos.value * (xmax - xmin)
|
||||
|
||||
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,
|
||||
label::PlotText;
|
||||
function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText)
|
||||
position_multiplier = Dict{Symbol, Tuple{Float64,Float64}}(
|
||||
:topleft => (0.1pct, 0.9pct),
|
||||
:topcenter => (0.5pct, 0.9pct),
|
||||
:topright => (0.9pct, 0.9pct),
|
||||
:bottomleft => (0.1pct, 0.1pct),
|
||||
:bottomcenter => (0.5pct, 0.1pct),
|
||||
:bottomright => (0.9pct, 0.1pct),
|
||||
),
|
||||
)
|
||||
x, y = position_multiplier[pos]
|
||||
(
|
||||
_relative_position(axis_limits(sp, :x)..., x),
|
||||
_relative_position(axis_limits(sp, :y)..., y),
|
||||
label,
|
||||
:topleft => (0.1, 0.9),
|
||||
:topcenter => (0.5, 0.9),
|
||||
:topright => (0.9, 0.9),
|
||||
:bottomleft => (0.1, 0.1),
|
||||
:bottomcenter => (0.5, 0.1),
|
||||
:bottomright => (0.9, 0.1),
|
||||
)
|
||||
xmin, xmax = ignorenan_extrema(sp[:xaxis])
|
||||
ymin, ymax = ignorenan_extrema(sp[:yaxis])
|
||||
x, y = (xmin, ymin).+ position_multiplier[pos].* (xmax - xmin, ymax - ymin)
|
||||
(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)
|
||||
|
||||
locate_annotation(sp::Subplot, rel::NTuple{2,<:Number}, label::PlotText) = (
|
||||
_relative_position(axis_limits(sp, :x)..., rel[1] * Plots.pct),
|
||||
_relative_position(axis_limits(sp, :y)..., rel[2] * Plots.pct),
|
||||
label,
|
||||
)
|
||||
locate_annotation(sp::Subplot, rel::NTuple{3,<:Number}, label::PlotText) = (
|
||||
_relative_position(axis_limits(sp, :x)..., rel[1] * Plots.pct),
|
||||
_relative_position(axis_limits(sp, :y)..., rel[2] * Plots.pct),
|
||||
_relative_position(axis_limits(sp, :z)..., rel[3] * Plots.pct),
|
||||
label,
|
||||
)
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
"type which represents z-values for colors and sizes (and anything else that might come up)"
|
||||
@ -664,10 +634,7 @@ struct ZValues
|
||||
zrange::Tuple{Float64,Float64}
|
||||
end
|
||||
|
||||
function zvalues(
|
||||
values::AVec{T},
|
||||
zrange::Tuple{T,T} = (ignorenan_minimum(values), ignorenan_maximum(values)),
|
||||
) where {T<:Real}
|
||||
function zvalues(values::AVec{T}, zrange::Tuple{T,T} = (ignorenan_minimum(values), ignorenan_maximum(values))) where T<:Real
|
||||
ZValues(collect(float(values)), map(Float64, zrange))
|
||||
end
|
||||
|
||||
@ -686,11 +653,14 @@ struct SurfaceFunction <: AbstractSurface
|
||||
f::Function
|
||||
end
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
# # I don't want to clash with ValidatedNumerics, but this would be nice:
|
||||
# ..(a::T, b::T) = (a,b)
|
||||
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
# style is :open or :closed (for now)
|
||||
@ -710,7 +680,8 @@ Define arrowheads to apply to lines - args are `style` (`:open` or `:closed`),
|
||||
function arrow(args...)
|
||||
style = :simple
|
||||
side = :head
|
||||
headlength = headwidth = 0.3
|
||||
headlength = 0.3
|
||||
headwidth = 0.3
|
||||
setlength = false
|
||||
for arg in args
|
||||
T = typeof(arg)
|
||||
@ -730,16 +701,17 @@ function arrow(args...)
|
||||
elseif T <: Tuple && length(arg) == 2
|
||||
headlength, headwidth = Float64(arg[1]), Float64(arg[2])
|
||||
else
|
||||
@warn "Skipped arrow arg $arg"
|
||||
@warn("Skipped arrow arg $arg")
|
||||
end
|
||||
end
|
||||
Arrow(style, side, headlength, headwidth)
|
||||
end
|
||||
|
||||
|
||||
# allow for do-block notation which gets called on every valid start/end pair which
|
||||
# we need to draw an arrow
|
||||
function add_arrows(func::Function, x::AVec, y::AVec)
|
||||
for i in 2:length(x)
|
||||
for i=2:length(x)
|
||||
xyprev = (x[i-1], y[i-1])
|
||||
xy = (x[i], y[i])
|
||||
if ok(xyprev) && ok(xy)
|
||||
@ -768,8 +740,13 @@ 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(first(range), stop=last(range), length=n))
|
||||
|
||||
# build a BezierCurve which leaves point p vertically upwards and arrives point q vertically upwards.
|
||||
# may create a loop if necessary. Assumes the view is [0,1]
|
||||
function directed_curve(args...; kw...)
|
||||
error("directed_curve has been moved to PlotRecipes")
|
||||
end
|
||||
|
||||
function extrema_plus_buffer(v, buffmult = 0.2)
|
||||
vmin,vmax = ignorenan_extrema(v)
|
||||
@ -777,20 +754,3 @@ function extrema_plus_buffer(v, buffmult = 0.2)
|
||||
buffer = vdiff * buffmult
|
||||
vmin - buffer, vmax + buffer
|
||||
end
|
||||
|
||||
### Legend
|
||||
|
||||
@add_attributes subplot struct Legend
|
||||
background_color = :match
|
||||
foreground_color = :match
|
||||
position = :best
|
||||
title = nothing
|
||||
font::Font = font(8)
|
||||
title_font::Font = font(11)
|
||||
column = 1
|
||||
end :match = (
|
||||
:legend_font_family,
|
||||
:legend_font_color,
|
||||
:legend_title_font_family,
|
||||
:legend_title_font_color,
|
||||
)
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
|
||||
const _deprecated_attributes = Dict{Symbol,Symbol}(:orientation => :permute)
|
||||
const _all_defaults = KW[_series_defaults, _plot_defaults, _subplot_defaults]
|
||||
|
||||
const _initial_defaults = deepcopy(_all_defaults)
|
||||
const _initial_axis_defaults = deepcopy(_axis_defaults)
|
||||
|
||||
# add defaults for the letter versions
|
||||
const _axis_defaults_byletter = KW()
|
||||
|
||||
function reset_axis_defaults_byletter!()
|
||||
for letter in (:x, :y, :z)
|
||||
_axis_defaults_byletter[letter] = KW()
|
||||
for (k, v) in _axis_defaults
|
||||
_axis_defaults_byletter[letter][k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
reset_axis_defaults_byletter!()
|
||||
|
||||
# to be able to reset font sizes to initial values
|
||||
const _initial_plt_fontsizes =
|
||||
Dict(:plot_titlefontsize => _plot_defaults[:plot_titlefontsize])
|
||||
|
||||
const _initial_sp_fontsizes = Dict(
|
||||
:titlefontsize => _subplot_defaults[:titlefontsize],
|
||||
:legend_font_pointsize => _subplot_defaults[:legend_font_pointsize],
|
||||
:legend_title_font_pointsize => _subplot_defaults[:legend_title_font_pointsize],
|
||||
:annotationfontsize => _subplot_defaults[:annotationfontsize],
|
||||
:colorbar_tickfontsize => _subplot_defaults[:colorbar_tickfontsize],
|
||||
:colorbar_titlefontsize => _subplot_defaults[:colorbar_titlefontsize],
|
||||
)
|
||||
|
||||
const _initial_ax_fontsizes = Dict(
|
||||
:tickfontsize => _axis_defaults[:tickfontsize],
|
||||
:guidefontsize => _axis_defaults[:guidefontsize],
|
||||
)
|
||||
|
||||
const _initial_fontsizes =
|
||||
merge(_initial_plt_fontsizes, _initial_sp_fontsizes, _initial_ax_fontsizes)
|
||||
|
||||
const _internal_args =
|
||||
[:plot_object, :series_plotindex, :markershape_to_add, :letter, :idxfilter]
|
||||
|
||||
const _axis_args = Set(keys(_axis_defaults))
|
||||
const _series_args = Set(keys(_series_defaults))
|
||||
const _subplot_args = Set(keys(_subplot_defaults))
|
||||
const _plot_args = Set(keys(_plot_defaults))
|
||||
|
||||
const _magic_axis_args = [:axis, :tickfont, :guidefont, :grid, :minorgrid]
|
||||
const _magic_subplot_args =
|
||||
[:title_font, :legend_font, :legend_title_font, :plot_title_font, :colorbar_titlefont]
|
||||
const _magic_series_args = [:line, :marker, :fill]
|
||||
const _all_magic_args =
|
||||
Set(union(_magic_axis_args, _magic_series_args, _magic_subplot_args))
|
||||
|
||||
const _all_axis_args = union(_axis_args, _magic_axis_args)
|
||||
const _lettered_all_axis_args =
|
||||
Set([Symbol(letter, kw) for letter in (:x, :y, :z) for kw in _all_axis_args])
|
||||
const _all_subplot_args = union(_subplot_args, _magic_subplot_args)
|
||||
const _all_series_args = union(_series_args, _magic_series_args)
|
||||
const _all_plot_args = _plot_args
|
||||
|
||||
const _all_args =
|
||||
union(_lettered_all_axis_args, _all_subplot_args, _all_series_args, _all_plot_args)
|
||||
|
||||
# add all pluralized forms to the _keyAliases dict
|
||||
for arg in _all_args
|
||||
add_aliases(arg, makeplural(arg))
|
||||
end
|
||||
|
||||
# fill symbol cache
|
||||
for letter in (:x, :y, :z)
|
||||
_attrsymbolcache[letter] = Dict{Symbol,Symbol}()
|
||||
for k in _axis_args
|
||||
# populate attribute cache
|
||||
lk = Symbol(letter, k)
|
||||
_attrsymbolcache[letter][k] = lk
|
||||
# allow the underscore version too: xguide or x_guide
|
||||
add_aliases(lk, Symbol(letter, "_", k))
|
||||
end
|
||||
for k in (_magic_axis_args..., :(_discrete_indices))
|
||||
_attrsymbolcache[letter][k] = Symbol(letter, k)
|
||||
end
|
||||
end
|
||||
|
||||
# add all non_underscored forms to the _keyAliases
|
||||
add_non_underscore_aliases!(_keyAliases)
|
||||
486
src/examples.jl
486
src/examples.jl
@ -7,7 +7,7 @@ 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
|
||||
"Lines",
|
||||
@ -28,33 +28,35 @@ const _examples = PlotExample[
|
||||
to generate the animation.) Use command `gif(anim, filename, fps=15)` to save the
|
||||
animation.
|
||||
""",
|
||||
[
|
||||
:(
|
||||
[:(
|
||||
begin
|
||||
p = plot(
|
||||
[sin, cos],
|
||||
zeros(0),
|
||||
leg = false,
|
||||
xlims = (0, 2π),
|
||||
ylims = (-1, 1),
|
||||
)
|
||||
p = plot([sin, cos], zeros(0), leg = false, xlims = (0, 2π), ylims = (-1, 1))
|
||||
anim = Animation()
|
||||
for x in range(0, stop = 2π, length = 20)
|
||||
push!(p, x, Float64[sin(x), cos(x)])
|
||||
frame(anim)
|
||||
end
|
||||
end
|
||||
),
|
||||
],
|
||||
)],
|
||||
),
|
||||
PlotExample( # 3
|
||||
"Parametric plots",
|
||||
"Plot function pair (x(u), y(u)).",
|
||||
[:(
|
||||
[
|
||||
:(
|
||||
begin
|
||||
plot(sin, x -> sin(2x), 0, 2π, line = 4, leg = false, fill = (0, :orange))
|
||||
plot(
|
||||
sin,
|
||||
x -> sin(2x),
|
||||
0,
|
||||
2π,
|
||||
line = 4,
|
||||
leg = false,
|
||||
fill = (0, :orange),
|
||||
)
|
||||
end
|
||||
)],
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 4
|
||||
"Colors",
|
||||
@ -113,11 +115,12 @@ const _examples = PlotExample[
|
||||
)
|
||||
vline!([5, 10])
|
||||
title!("TITLE")
|
||||
yaxis!("YLABEL", :log10, minorgrid = true)
|
||||
yaxis!("YLABEL", :log10)
|
||||
end
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
PlotExample( # 6
|
||||
"Images",
|
||||
"Plot an image. y-axis is set to flipped",
|
||||
@ -125,10 +128,8 @@ const _examples = PlotExample[
|
||||
:(
|
||||
begin
|
||||
import FileIO
|
||||
import Downloads
|
||||
path = Downloads.download(
|
||||
"http://juliaplots.org/PlotReferenceImages.jl/Plots/pyplot/0.7.0/ref1.png",
|
||||
)
|
||||
path =
|
||||
download("http://juliaplots.org/PlotReferenceImages.jl/Plots/pyplot/0.7.0/ref1.png")
|
||||
img = FileIO.load(path)
|
||||
plot(img)
|
||||
end
|
||||
@ -189,11 +190,12 @@ const _examples = PlotExample[
|
||||
PlotExample( # 11
|
||||
"Line types",
|
||||
"",
|
||||
[:(
|
||||
[
|
||||
:(
|
||||
begin
|
||||
linetypes = [:path :steppre :steppost :sticks :scatter]
|
||||
n = length(linetypes)
|
||||
x = Vector[sort(rand(20)) for i in 1:n]
|
||||
x = Vector[sort(rand(20)) for i = 1:n]
|
||||
y = rand(20, n)
|
||||
plot(
|
||||
x,
|
||||
@ -203,7 +205,8 @@ const _examples = PlotExample[
|
||||
ms = 15,
|
||||
)
|
||||
end
|
||||
)],
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 12
|
||||
"Line styles",
|
||||
@ -234,17 +237,18 @@ const _examples = PlotExample[
|
||||
[
|
||||
:(
|
||||
begin
|
||||
markers =
|
||||
filter(m -> m in Plots.supported_markers(), Plots._shape_keys)
|
||||
markers = permutedims(markers)
|
||||
markers = filter(
|
||||
m -> m in Plots.supported_markers(),
|
||||
Plots._shape_keys,
|
||||
)
|
||||
markers = reshape(markers, 1, length(markers))
|
||||
n = length(markers)
|
||||
x = range(0, stop = 10, length = n + 2)[2:(end - 1)]
|
||||
y = repeat(reshape(reverse(x), 1, :), n, 1)
|
||||
scatter(
|
||||
x,
|
||||
y,
|
||||
m = markers,
|
||||
markersize = 8,
|
||||
m = (8, :auto),
|
||||
lab = map(string, markers),
|
||||
bg = :linen,
|
||||
xlim = (0, 10),
|
||||
@ -266,11 +270,17 @@ const _examples = PlotExample[
|
||||
PlotExample( # 15
|
||||
"Histogram",
|
||||
"",
|
||||
[:(
|
||||
[
|
||||
:(
|
||||
begin
|
||||
histogram(randn(1000), bins = :scott, weights = repeat(1:5, outer = 200))
|
||||
histogram(
|
||||
randn(1000),
|
||||
bins = :scott,
|
||||
weights = repeat(1:5, outer = 200),
|
||||
)
|
||||
end
|
||||
)],
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 16
|
||||
"Subplots",
|
||||
@ -316,13 +326,15 @@ const _examples = PlotExample[
|
||||
PlotExample( # 18
|
||||
"",
|
||||
"",
|
||||
[:(
|
||||
[
|
||||
:(
|
||||
begin
|
||||
using Random
|
||||
Random.seed!(111)
|
||||
plot!(Plots.fakedata(100, 10))
|
||||
end
|
||||
)],
|
||||
)
|
||||
]
|
||||
),
|
||||
PlotExample( # 19
|
||||
"Open/High/Low/Close",
|
||||
@ -345,7 +357,8 @@ const _examples = PlotExample[
|
||||
bot[i] + hgt[i],
|
||||
bot[i],
|
||||
closepct[i] * hgt[i] + bot[i],
|
||||
) for i in 1:n
|
||||
)
|
||||
for i = 1:n
|
||||
]
|
||||
ohlc(y)
|
||||
end
|
||||
@ -356,21 +369,10 @@ const _examples = PlotExample[
|
||||
"Annotations",
|
||||
"""
|
||||
The `annotations` keyword is used for text annotations in data-coordinates. Pass in a
|
||||
tuple `(x, y, text)`, a vector of annotations, each of which is a tuple of `x`, `y`
|
||||
and `text`. You can position annotations using relative coordinates with the syntax
|
||||
`((px, py), text)`, where for example `px=.25` positions the annotation at `25%` of
|
||||
the subplot's axis width.
|
||||
`text` may be a simple `String`, or a `PlotText` object, which can be built with the
|
||||
method `text(string, attrs...)`.
|
||||
This wraps font and color attributes and allows you to set text styling.
|
||||
`text` may also be a tuple `(string, attrs...)` of arguments which are passed
|
||||
to `Plots.text`.
|
||||
|
||||
`annotate!(ann)` is shorthand for `plot!(; annotation=ann)`.
|
||||
|
||||
Series annotations are used for annotating individual data points.
|
||||
They require only the annotation; x/y values are computed. Series annotations
|
||||
require either plain `String`s or `PlotText` objects.
|
||||
tuple (x,y,text) or a vector of annotations. `annotate!(ann)` is shorthand for `plot!(;
|
||||
annotation=ann)`. Series annotations are used for annotating individual data points.
|
||||
They require only the annotation... x/y values are computed. A `PlotText` object can be
|
||||
build with the method `text(string, attr...)`, which wraps font and color attributes.
|
||||
""",
|
||||
[
|
||||
:(
|
||||
@ -382,8 +384,12 @@ const _examples = PlotExample[
|
||||
leg = false,
|
||||
)
|
||||
annotate!([
|
||||
(5, y[5], ("this is #5", 16, :red, :center)),
|
||||
(10, y[10], ("this is #10", :right, 20, "courier")),
|
||||
(5, y[5], Plots.text("this is #5", 16, :red, :center)),
|
||||
(
|
||||
10,
|
||||
y[10],
|
||||
Plots.text("this is #10", :right, 20, "courier"),
|
||||
),
|
||||
])
|
||||
scatter!(
|
||||
range(2, stop = 8, length = 6),
|
||||
@ -562,8 +568,8 @@ const _examples = PlotExample[
|
||||
"",
|
||||
[:(
|
||||
begin
|
||||
xs = [string("x", i) for i in 1:10]
|
||||
ys = [string("y", i) for i in 1:4]
|
||||
xs = [string("x", i) for i = 1:10]
|
||||
ys = [string("y", i) for i = 1:4]
|
||||
z = float((1:4) * reshape(1:10, 1, :))
|
||||
heatmap(xs, ys, z, aspect_ratio = 1)
|
||||
end
|
||||
@ -598,7 +604,12 @@ const _examples = PlotExample[
|
||||
begin
|
||||
import RDatasets
|
||||
singers = RDatasets.dataset("lattice", "singer")
|
||||
@df singers violin(:VoicePart, :Height, line = 0, fill = (0.2, :blue))
|
||||
@df singers violin(
|
||||
:VoicePart,
|
||||
:Height,
|
||||
line = 0,
|
||||
fill = (0.2, :blue),
|
||||
)
|
||||
@df singers boxplot!(
|
||||
:VoicePart,
|
||||
:Height,
|
||||
@ -626,7 +637,11 @@ const _examples = PlotExample[
|
||||
|
||||
anim = Animation()
|
||||
for x in range(1, stop = 2π, length = 20)
|
||||
plot(push!(p, x, Float64[sin(x), cos(x), atan(x), cos(x), log(x)]))
|
||||
plot(push!(
|
||||
p,
|
||||
x,
|
||||
Float64[sin(x), cos(x), atan(x), cos(x), log(x)],
|
||||
))
|
||||
frame(anim)
|
||||
end
|
||||
end
|
||||
@ -651,8 +666,18 @@ const _examples = PlotExample[
|
||||
10 => ones(40),
|
||||
-10 => ones(40),
|
||||
)
|
||||
b = spdiagm(0 => 1:50, 1 => 1:49, -1 => 1:49, 10 => 1:40, -10 => 1:40)
|
||||
plot(spy(a), spy(b), title = ["Unique nonzeros" "Different nonzeros"])
|
||||
b = spdiagm(
|
||||
0 => 1:50,
|
||||
1 => 1:49,
|
||||
-1 => 1:49,
|
||||
10 => 1:40,
|
||||
-10 => 1:40,
|
||||
)
|
||||
plot(
|
||||
spy(a),
|
||||
spy(b),
|
||||
title = ["Unique nonzeros" "Different nonzeros"],
|
||||
)
|
||||
end
|
||||
),
|
||||
],
|
||||
@ -717,24 +742,33 @@ const _examples = PlotExample[
|
||||
You can use the `line_z` and `marker_z` properties to associate a color with
|
||||
each line segment or marker in the plot.
|
||||
""",
|
||||
[:(
|
||||
[
|
||||
:(
|
||||
begin
|
||||
t = range(0, stop = 1, length = 100)
|
||||
θ = 6π .* t
|
||||
x = t .* cos.(θ)
|
||||
y = t .* sin.(θ)
|
||||
p1 = plot(x, y, line_z = t, linewidth = 3, legend = false)
|
||||
p2 = scatter(x, y, marker_z = +, color = :bluesreds, legend = false)
|
||||
p2 = scatter(
|
||||
x,
|
||||
y,
|
||||
marker_z = +,
|
||||
color = :bluesreds,
|
||||
legend = false,
|
||||
)
|
||||
plot(p1, p2)
|
||||
end
|
||||
)],
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 36
|
||||
"Portfolio Composition maps",
|
||||
"""
|
||||
see: http://stackoverflow.com/a/37732384/5075246
|
||||
""",
|
||||
[:(
|
||||
[
|
||||
:(
|
||||
begin
|
||||
using Random
|
||||
Random.seed!(111)
|
||||
@ -745,9 +779,14 @@ const _examples = PlotExample[
|
||||
weights ./= sum(weights, dims = 2)
|
||||
returns = sort!((1:N) + D * randn(N))
|
||||
|
||||
portfoliocomposition(weights, returns, labels = permutedims(tickers))
|
||||
portfoliocomposition(
|
||||
weights,
|
||||
returns,
|
||||
labels = permutedims(tickers),
|
||||
)
|
||||
end
|
||||
)],
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 37
|
||||
"Ribbons",
|
||||
@ -760,7 +799,10 @@ const _examples = PlotExample[
|
||||
:(
|
||||
begin
|
||||
plot(
|
||||
plot(0:10; ribbon = (LinRange(0, 2, 11), LinRange(0, 1, 11))),
|
||||
plot(
|
||||
0:10;
|
||||
ribbon = (LinRange(0, 2, 11), LinRange(0, 1, 11)),
|
||||
),
|
||||
plot(0:10; ribbon = 0:0.5:5),
|
||||
plot(0:10; ribbon = sqrt),
|
||||
plot(0:10; ribbon = 1),
|
||||
@ -825,7 +867,11 @@ const _examples = PlotExample[
|
||||
plot!([(0, 0), (0, 0.9), (2, 0.9), (3, 1), (4, 0.9), (80, 0)])
|
||||
plot!([(0, 0), (0, 0.9), (3, 0.9), (4, 1), (5, 0.9), (80, 0)])
|
||||
plot!([(0, 0), (0, 0.9), (4, 0.9), (5, 1), (6, 0.9), (80, 0)])
|
||||
lens!([1, 6], [0.9, 1.1], inset = (1, bbox(0.5, 0.0, 0.4, 0.4)))
|
||||
lens!(
|
||||
[1, 6],
|
||||
[0.9, 1.1],
|
||||
inset = (1, bbox(0.5, 0.0, 0.4, 0.4)),
|
||||
)
|
||||
end
|
||||
end,
|
||||
],
|
||||
@ -833,7 +879,8 @@ const _examples = PlotExample[
|
||||
PlotExample( # 41
|
||||
"Array Types",
|
||||
"Plots supports different `Array` types that follow the `AbstractArray` interface, like `StaticArrays` and `OffsetArrays.`",
|
||||
[quote
|
||||
[
|
||||
quote
|
||||
begin
|
||||
using StaticArrays, OffsetArrays
|
||||
sv = SVector{10}(rand(10))
|
||||
@ -841,7 +888,8 @@ const _examples = PlotExample[
|
||||
plot([sv, ov], label = ["StaticArray" "OffsetArray"])
|
||||
plot!(3ov, ribbon=ov, label="OffsetArray ribbon")
|
||||
end
|
||||
end],
|
||||
end,
|
||||
],
|
||||
),
|
||||
PlotExample( # 42
|
||||
"Setting defaults and font arguments",
|
||||
@ -849,6 +897,7 @@ const _examples = PlotExample[
|
||||
[
|
||||
quote
|
||||
begin
|
||||
using Plots
|
||||
default(
|
||||
titlefont = (20, "times"),
|
||||
legendfontsize = 18,
|
||||
@ -856,7 +905,7 @@ const _examples = PlotExample[
|
||||
tickfont = (12, :orange),
|
||||
guide = "x",
|
||||
framestyle = :zerolines,
|
||||
yminorgrid = true,
|
||||
yminorgrid = true
|
||||
)
|
||||
plot(
|
||||
[sin, cos],
|
||||
@ -875,7 +924,8 @@ const _examples = PlotExample[
|
||||
PlotExample( # 43
|
||||
"Heatmap with DateTime axis",
|
||||
"",
|
||||
[quote
|
||||
[
|
||||
quote
|
||||
begin
|
||||
using Dates
|
||||
z = rand(5, 5)
|
||||
@ -883,17 +933,20 @@ const _examples = PlotExample[
|
||||
y = 1:5
|
||||
heatmap(x, y, z)
|
||||
end
|
||||
end],
|
||||
end,
|
||||
],
|
||||
),
|
||||
PlotExample( # 44
|
||||
"Linked axes",
|
||||
"",
|
||||
[quote
|
||||
[
|
||||
quote
|
||||
begin
|
||||
x = -5:0.1:5
|
||||
plot(plot(x, x->x^2), plot(x, x->sin(x)), layout = 2, link = :y)
|
||||
end
|
||||
end],
|
||||
end,
|
||||
],
|
||||
),
|
||||
PlotExample( # 45
|
||||
"Error bars and array type recipes",
|
||||
@ -908,21 +961,8 @@ const _examples = PlotExample[
|
||||
value(m::Measurement) = m.val
|
||||
uncertainty(m::Measurement) = m.err
|
||||
|
||||
@recipe function f(
|
||||
::Type{T},
|
||||
m::T,
|
||||
) where {T<:AbstractArray{<:Measurement}}
|
||||
if !(
|
||||
get(plotattributes, :seriestype, :path) in [
|
||||
:contour,
|
||||
:contourf,
|
||||
:contour3d,
|
||||
:heatmap,
|
||||
:surface,
|
||||
:wireframe,
|
||||
:image,
|
||||
]
|
||||
)
|
||||
@recipe function f(::Type{T}, m::T) where T <: AbstractArray{<:Measurement}
|
||||
if !(get(plotattributes, :seriestype, :path) in [:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image])
|
||||
error_sym = Symbol(plotattributes[:letter], :error)
|
||||
plotattributes[error_sym] = uncertainty.(m)
|
||||
end
|
||||
@ -939,7 +979,7 @@ const _examples = PlotExample[
|
||||
scatter(x, y, z),
|
||||
heatmap(x, y, surf),
|
||||
wireframe(x, y, surf),
|
||||
legend = :topleft,
|
||||
legend = :topleft
|
||||
)
|
||||
end
|
||||
end,
|
||||
@ -954,17 +994,15 @@ const _examples = PlotExample[
|
||||
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],
|
||||
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 can be specified in two ways: Either as a tuple of vectors where 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. Or as a vector of NTuple{3,Ints} where each element
|
||||
contains the 1-based indices of the three points of a triangle.
|
||||
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.
|
||||
""",
|
||||
[
|
||||
:(
|
||||
@ -980,21 +1018,9 @@ const _examples = PlotExample[
|
||||
i=[0, 0, 0, 1]
|
||||
j=[1, 2, 3, 2]
|
||||
k=[2, 3, 1, 3]
|
||||
# Or: cns = [(1, 2, 3), (1, 3, 4), (1, 4, 2), (2, 3, 4)] (1-based indexing)
|
||||
|
||||
# the four triangles gives above give a tetrahedron
|
||||
mesh3d(
|
||||
x,
|
||||
y,
|
||||
z;
|
||||
connections = (i, j, k), # connections = cns
|
||||
title = "triangles",
|
||||
xlabel = "x",
|
||||
ylabel = "y",
|
||||
zlabel = "z",
|
||||
legend = :none,
|
||||
margin = 2Plots.mm,
|
||||
)
|
||||
mesh3d(x,y,z;connections=(i,j,k))
|
||||
end
|
||||
),
|
||||
],
|
||||
@ -1002,8 +1028,7 @@ const _examples = PlotExample[
|
||||
PlotExample( # 48
|
||||
"Vectors of markershapes and segments",
|
||||
"",
|
||||
[
|
||||
quote
|
||||
[quote
|
||||
using Base.Iterators: cycle, take
|
||||
|
||||
yv = ones(9)
|
||||
@ -1015,7 +1040,7 @@ const _examples = PlotExample[
|
||||
seriestype = [:path :path :scatter :scatter],
|
||||
markershape = collect(take(cycle((:utriangle, :rect)), 9)),
|
||||
markersize = 8,
|
||||
color = collect(take(cycle((:red, :black)), 9)),
|
||||
color = collect(take(cycle((:red, :black)), 9))
|
||||
)
|
||||
|
||||
plt_z_cols = plot(
|
||||
@ -1024,12 +1049,11 @@ const _examples = PlotExample[
|
||||
markersize = [5 10 10 5],
|
||||
marker_z = [5 4 3 2],
|
||||
line_z = [1 3 3 1],
|
||||
linewidth = [1 10 5 1],
|
||||
linewidth = [1 10 5 1]
|
||||
)
|
||||
|
||||
plot(plt_color_rows, plt_z_cols)
|
||||
end,
|
||||
],
|
||||
end]
|
||||
),
|
||||
PlotExample( # 49
|
||||
"Polar heatmaps",
|
||||
@ -1039,57 +1063,47 @@ const _examples = PlotExample[
|
||||
y = 0:4
|
||||
z = (1:4) .+ (1:8)'
|
||||
heatmap(x, y, z, projection = :polar)
|
||||
end],
|
||||
end]
|
||||
),
|
||||
PlotExample( # 50
|
||||
"3D surface with axis guides",
|
||||
"",
|
||||
[
|
||||
quote
|
||||
[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)
|
||||
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]
|
||||
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),
|
||||
plot(x_grid, a_grid, f.(x_grid,a_grid),
|
||||
st = :surface,
|
||||
xlabel = "longer xlabel",
|
||||
ylabel = "longer ylabel",
|
||||
zlabel = "longer zlabel",
|
||||
)
|
||||
end,
|
||||
],
|
||||
end]
|
||||
),
|
||||
PlotExample( # 51
|
||||
"Images with custom axes",
|
||||
"",
|
||||
[
|
||||
quote
|
||||
[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([-π, π], [-1, 1], reverse(img, dims=1), yflip=false, aspect_ratio=:none)
|
||||
# plot other data
|
||||
plot!(sin, -π, π, lw=3, color=:red)
|
||||
end,
|
||||
],
|
||||
end]
|
||||
),
|
||||
PlotExample( # 52
|
||||
PlotExample(
|
||||
"3d quiver",
|
||||
"",
|
||||
[quote
|
||||
using Plots
|
||||
|
||||
ϕs = range(-π, π, length=50)
|
||||
θs = range(0, π, length=25)
|
||||
θqs = range(1, π-1, length=25)
|
||||
@ -1103,7 +1117,7 @@ const _examples = PlotExample[
|
||||
w = 0.1 * vec([cos(θ) for (ϕ, θ) in Iterators.product(ϕs, θqs)])
|
||||
|
||||
quiver(x,y,z, quiver=(u,v,w))
|
||||
end],
|
||||
end]
|
||||
),
|
||||
PlotExample( # 53
|
||||
"Step Types",
|
||||
@ -1115,28 +1129,10 @@ const _examples = PlotExample[
|
||||
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),
|
||||
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
|
||||
),
|
||||
@ -1160,132 +1156,7 @@ const _examples = PlotExample[
|
||||
ymirror=[false true true false],
|
||||
xmirror=[false false true true],
|
||||
legend=false,
|
||||
seriestype = [:bar :scatter :path :stepmid],
|
||||
)
|
||||
end
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 55
|
||||
"3D axis flip / mirror",
|
||||
"",
|
||||
[
|
||||
:(
|
||||
begin
|
||||
using LinearAlgebra
|
||||
scalefontsizes(0.4)
|
||||
|
||||
x, y = collect(-6:0.5:10), collect(-8:0.5:8)
|
||||
|
||||
args = x, y, (x, y) -> sinc(norm([x, y]) / π)
|
||||
kwargs = Dict(
|
||||
:xlabel => "x",
|
||||
:ylabel => "y",
|
||||
:zlabel => "z",
|
||||
:grid => true,
|
||||
:minorgrid => true,
|
||||
)
|
||||
|
||||
plots = [wireframe(args..., title = "wire"; kwargs...)]
|
||||
|
||||
for ax in (:x, :y, :z)
|
||||
push!(
|
||||
plots,
|
||||
wireframe(
|
||||
args...,
|
||||
title = "wire-flip-$ax",
|
||||
xflip = ax == :x,
|
||||
yflip = ax == :y,
|
||||
zflip = ax == :z;
|
||||
kwargs...,
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
for ax in (:x, :y, :z)
|
||||
push!(
|
||||
plots,
|
||||
wireframe(
|
||||
args...,
|
||||
title = "wire-mirror-$ax",
|
||||
xmirror = ax == :x,
|
||||
ymirror = ax == :y,
|
||||
zmirror = ax == :z;
|
||||
kwargs...,
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
plt = plot(
|
||||
plots...,
|
||||
layout = (@layout [_ ° _; ° ° °; ° ° °]),
|
||||
margin = 0Plots.px,
|
||||
)
|
||||
|
||||
resetfontsizes()
|
||||
plt
|
||||
end
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 56
|
||||
"Bar plot customizations",
|
||||
"""
|
||||
Width of bars may be specified as `bar_width`.
|
||||
The bars' baseline may be specified as `fillto`.
|
||||
Each may be scalar, or a vector spcifying one value per bar.
|
||||
""",
|
||||
[
|
||||
:(
|
||||
begin
|
||||
plot(
|
||||
bar(
|
||||
[-1, 0, 2, 3],
|
||||
[1, 3, 6, 2],
|
||||
fill_z = 4:-1:1,
|
||||
alpha = [1, 0.2, 0.8, 0.5],
|
||||
label = "",
|
||||
bar_width = 1:4,
|
||||
),
|
||||
bar(
|
||||
rand(5),
|
||||
bar_width = 1.2,
|
||||
alpha = 0.8,
|
||||
color = [:lightsalmon, :tomato, :crimson, :firebrick, :darkred],
|
||||
fillto = 0:-0.1:-0.4,
|
||||
label = "reds",
|
||||
),
|
||||
)
|
||||
end
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 57
|
||||
"Vertical and horizonal spans",
|
||||
"""
|
||||
`vspan` and `hspan` can be used to shade horizontal and vertical ranges.
|
||||
""",
|
||||
[:(
|
||||
begin
|
||||
hspan([1, 2, 3, 4]; label = "hspan", legend = :topleft)
|
||||
vspan!([2, 3]; alpha = 0.5, label = "vspan")
|
||||
plot!([0, 2, 3, 5], [-1, 3, 2, 6]; c = :black, lw = 2, label = "line")
|
||||
end
|
||||
)],
|
||||
),
|
||||
PlotExample( # 58
|
||||
"Stacked area chart",
|
||||
"""
|
||||
`areaplot` draws stacked area plots.
|
||||
""",
|
||||
[
|
||||
:(
|
||||
begin
|
||||
areaplot(
|
||||
1:3,
|
||||
[1 2 3; 7 8 9; 4 5 6],
|
||||
seriescolor = [:red :green :blue],
|
||||
fillalpha = [0.2 0.3 0.4],
|
||||
seriestype=[:bar :scatter :path :stepmid]
|
||||
)
|
||||
end
|
||||
),
|
||||
@ -1296,9 +1167,10 @@ const _examples = PlotExample[
|
||||
# Some constants for PlotDocs and PlotReferenceImages
|
||||
_animation_examples = [2, 31]
|
||||
_backend_skips = Dict(
|
||||
:gr => [30],
|
||||
:pyplot => [2, 25, 30, 31, 49, 55, 56],
|
||||
:plotlyjs => [2, 21, 24, 25, 30, 31, 49, 50, 51, 55, 56],
|
||||
: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, 51],
|
||||
:pgfplotsx => [
|
||||
2, # animation
|
||||
6, # images
|
||||
@ -1308,35 +1180,10 @@ _backend_skips = Dict(
|
||||
32, # spy
|
||||
49, # polar heatmap
|
||||
51, # image with custom axes
|
||||
56, # custom bar plot
|
||||
],
|
||||
:inspectdr => [4, 6, 10, 22, 24, 28, 30, 38, 43, 45, 47, 48, 49, 50, 51, 55, 56],
|
||||
:unicodeplots => [
|
||||
5, # limits issue
|
||||
6, # embedded images unsupported
|
||||
16, # nested layout unsupported
|
||||
21, # custom markers unsupported
|
||||
26, # nested layout unsupported
|
||||
29, # nested layout unsupported
|
||||
31, # nested layout unsupported
|
||||
33, # grid lines unsupported
|
||||
34, # framestyle unsupported
|
||||
37, # ribbons / filled unsupported
|
||||
43, # heatmap with DateTime
|
||||
45, # error bars
|
||||
49, # polar heatmap
|
||||
51, # embedded images unsupported
|
||||
55, # mirror unsupported, resolution too low
|
||||
56, # barplots
|
||||
],
|
||||
:gaston => [
|
||||
2, # animations
|
||||
31, # animations
|
||||
49, # TODO: support polar
|
||||
50, # TODO: 1D data not supported for pm3d
|
||||
],
|
||||
)
|
||||
_backend_skips[:plotly] = _backend_skips[:plotlyjs]
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
@ -1352,8 +1199,11 @@ function test_examples(pkgname::Symbol, idx::Int; debug = false, disp = true)
|
||||
Base.eval(m, :(using Plots))
|
||||
map(exprs -> Base.eval(m, exprs), _examples[idx].exprs)
|
||||
|
||||
disp && Base.eval(m, :(gui(current())))
|
||||
current()
|
||||
plt = current()
|
||||
if disp
|
||||
gui(plt)
|
||||
end
|
||||
plt
|
||||
end
|
||||
|
||||
# generate all plots and create a dict mapping idx --> plt
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
# ---------------------------------------------------------
|
||||
# A backup, if no PNG generation is defined, is to try to make a PDF and use FileIO to convert
|
||||
|
||||
_fileio_load(@nospecialize(filename::AbstractString)) =
|
||||
FileIO.load(filename::AbstractString)
|
||||
_fileio_save(@nospecialize(filename::AbstractString), @nospecialize(x)) =
|
||||
FileIO.save(filename::AbstractString, x)
|
||||
_fileio_load(@nospecialize(filename::AbstractString)) = FileIO.load(filename::AbstractString)
|
||||
_fileio_save(@nospecialize(filename::AbstractString), @nospecialize(x)) = FileIO.save(filename::AbstractString, x)
|
||||
|
||||
function _show_pdfbackends(io::IO, ::MIME"image/png", plt::Plot)
|
||||
fn = tempname()
|
||||
@ -23,5 +21,4 @@ function _show_pdfbackends(io::IO, ::MIME"image/png", plt::Plot)
|
||||
write(io, read(open(pngfn), String))
|
||||
end
|
||||
|
||||
const PDFBackends =
|
||||
Union{PGFPlotsBackend,PlotlyJSBackend,PyPlotBackend,InspectDRBackend,GRBackend}
|
||||
const PDFBackends = Union{PGFPlotsBackend,PlotlyJSBackend,PyPlotBackend,InspectDRBackend,GRBackend}
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
const use_local_dependencies = Ref(false)
|
||||
const use_local_plotlyjs = Ref(false)
|
||||
|
||||
|
||||
function _init_ijulia_plotting()
|
||||
# IJulia is more stable with local file
|
||||
use_local_plotlyjs[] =
|
||||
plotly_local_file_path[] === nothing ? false : isfile(plotly_local_file_path[])
|
||||
use_local_plotlyjs[] = plotly_local_file_path[] === nothing ? false : isfile(plotly_local_file_path[])
|
||||
|
||||
ENV["MPLBACKEND"] = "Agg"
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
Add extra jupyter mimetypes to display_dict based on the plot backed.
|
||||
|
||||
@ -19,17 +20,22 @@ frontends like jupyterlab and nteract.
|
||||
_ijulia__extra_mime_info!(plt::Plot, out::Dict) = out
|
||||
|
||||
function _ijulia__extra_mime_info!(plt::Plot{PlotlyJSBackend}, out::Dict)
|
||||
out["application/vnd.plotly.v1+json"] =
|
||||
Dict(:data => plotly_series(plt), :layout => plotly_layout(plt))
|
||||
out["application/vnd.plotly.v1+json"] = Dict(
|
||||
:data => plotly_series(plt),
|
||||
:layout => plotly_layout(plt)
|
||||
)
|
||||
out
|
||||
end
|
||||
|
||||
function _ijulia__extra_mime_info!(plt::Plot{PlotlyBackend}, out::Dict)
|
||||
out["application/vnd.plotly.v1+json"] =
|
||||
Dict(:data => plotly_series(plt), :layout => plotly_layout(plt))
|
||||
out["application/vnd.plotly.v1+json"] = Dict(
|
||||
:data => plotly_series(plt),
|
||||
:layout => plotly_layout(plt)
|
||||
)
|
||||
out
|
||||
end
|
||||
|
||||
|
||||
function _ijulia_display_dict(plt::Plot)
|
||||
output_type = Symbol(plt.attr[:html_output_format])
|
||||
if output_type == :auto
|
||||
@ -49,9 +55,6 @@ function _ijulia_display_dict(plt::Plot)
|
||||
mime = "text/html"
|
||||
out[mime] = sprint(show, MIME(mime), plt)
|
||||
_ijulia__extra_mime_info!(plt, out)
|
||||
elseif output_type == :pdf
|
||||
mime = "application/pdf"
|
||||
out[mime] = base64encode(show, MIME(mime), plt)
|
||||
else
|
||||
error("Unsupported output type $output_type")
|
||||
end
|
||||
|
||||
41
src/init.jl
41
src/init.jl
@ -3,6 +3,7 @@ using Scratch
|
||||
|
||||
const plotly_local_file_path = Ref{Union{Nothing, String}}(nothing)
|
||||
|
||||
|
||||
function _plots_defaults()
|
||||
if isdefined(Main, :PLOTS_DEFAULTS)
|
||||
copy(Dict{Symbol,Any}(Main.PLOTS_DEFAULTS))
|
||||
@ -11,6 +12,7 @@ function _plots_defaults()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function __init__()
|
||||
user_defaults = _plots_defaults()
|
||||
if haskey(user_defaults, :theme)
|
||||
@ -19,27 +21,14 @@ function __init__()
|
||||
default(; user_defaults...)
|
||||
end
|
||||
|
||||
insert!(
|
||||
Base.Multimedia.displays,
|
||||
findlast(
|
||||
x -> x isa Base.TextDisplay || x isa REPL.REPLDisplay,
|
||||
Base.Multimedia.displays,
|
||||
) + 1,
|
||||
PlotsDisplay(),
|
||||
)
|
||||
insert!(Base.Multimedia.displays, findlast(x -> x isa Base.TextDisplay || x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, PlotsDisplay())
|
||||
|
||||
atreplinit(
|
||||
i -> begin
|
||||
atreplinit(i -> begin
|
||||
while PlotsDisplay() in Base.Multimedia.displays
|
||||
popdisplay(PlotsDisplay())
|
||||
end
|
||||
insert!(
|
||||
Base.Multimedia.displays,
|
||||
findlast(x -> x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1,
|
||||
PlotsDisplay(),
|
||||
)
|
||||
end,
|
||||
)
|
||||
insert!(Base.Multimedia.displays, findlast(x -> x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, PlotsDisplay())
|
||||
end)
|
||||
|
||||
@require HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" begin
|
||||
fn = joinpath(@__DIR__, "backends", "hdf5.jl")
|
||||
@ -81,26 +70,18 @@ function __init__()
|
||||
include(fn)
|
||||
end
|
||||
|
||||
@require Gaston = "4b11ee91-296f-5714-9832-002c20994614" begin
|
||||
fn = joinpath(@__DIR__, "backends", "gaston.jl")
|
||||
include(fn)
|
||||
end
|
||||
|
||||
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
|
||||
if IJulia.inited
|
||||
_init_ijulia_plotting()
|
||||
|
||||
IJulia.display_dict(plt::Plot) = _ijulia_display_dict(plt)
|
||||
end
|
||||
end
|
||||
|
||||
if get(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL", "false") == "true"
|
||||
global plotly_local_file_path[] =
|
||||
joinpath(@get_scratch!("plotly"), _plotly_min_js_filename)
|
||||
global plotly_local_file_path[] = joinpath(@get_scratch!("plotly"), _plotly_min_js_filename)
|
||||
if !isfile(plotly_local_file_path[])
|
||||
Downloads.download(
|
||||
"https://cdn.plot.ly/$(_plotly_min_js_filename)",
|
||||
plotly_local_file_path[],
|
||||
)
|
||||
download("https://cdn.plot.ly/$(_plotly_min_js_filename)", plotly_local_file_path[])
|
||||
end
|
||||
|
||||
use_local_plotlyjs[] = true
|
||||
@ -108,8 +89,8 @@ function __init__()
|
||||
|
||||
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)
|
||||
_show(io::IO, mime::MIME"image/png", plt::Plot{<:PDFBackends}) = _show_pdfbackends(io, mime, plt)
|
||||
end
|
||||
end
|
||||
|
||||
272
src/layouts.jl
272
src/layouts.jl
@ -61,10 +61,7 @@ function bbox_to_pcts(bb::BoundingBox, figw, figh, flipy = true)
|
||||
end
|
||||
|
||||
function Base.show(io::IO, bbox::BoundingBox)
|
||||
print(
|
||||
io,
|
||||
"BBox{l,t,r,b,w,h = $(left(bbox)),$(top(bbox)), $(right(bbox)),$(bottom(bbox)), $(width(bbox)),$(height(bbox))}",
|
||||
)
|
||||
print(io, "BBox{l,t,r,b,w,h = $(left(bbox)),$(top(bbox)), $(right(bbox)),$(bottom(bbox)), $(width(bbox)),$(height(bbox))}")
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------
|
||||
@ -91,6 +88,7 @@ function resolve_mixed(mix::MixedMeasures, sp::Subplot, letter::Symbol)
|
||||
xy
|
||||
end
|
||||
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# AbstractLayout
|
||||
|
||||
@ -162,8 +160,7 @@ parent_bbox(layout::AbstractLayout) = bbox(parent(layout))
|
||||
# padding(layout::AbstractLayout) = (padding_w(layout), padding_h(layout))
|
||||
|
||||
update_position!(layout::AbstractLayout) = nothing
|
||||
update_child_bboxes!(layout::AbstractLayout, minimum_perimeter = [0mm, 0mm, 0mm, 0mm]) =
|
||||
nothing
|
||||
update_child_bboxes!(layout::AbstractLayout, minimum_perimeter = [0mm,0mm,0mm,0mm]) = nothing
|
||||
|
||||
left(layout::AbstractLayout) = left(bbox(layout))
|
||||
top(layout::AbstractLayout) = top(bbox(layout))
|
||||
@ -238,13 +235,11 @@ columns of different width.
|
||||
"""
|
||||
grid(args...; kw...) = GridLayout(args...; kw...)
|
||||
|
||||
function GridLayout(
|
||||
dims...;
|
||||
function GridLayout(dims...;
|
||||
parent = RootLayout(),
|
||||
widths = zeros(dims[2]),
|
||||
heights = zeros(dims[1]),
|
||||
kw...,
|
||||
)
|
||||
kw...)
|
||||
grid = Matrix{AbstractLayout}(undef, dims...)
|
||||
layout = GridLayout(
|
||||
parent,
|
||||
@ -255,8 +250,7 @@ function GridLayout(
|
||||
Measure[h*pct for h in heights],
|
||||
# convert(Vector{Float64}, widths),
|
||||
# convert(Vector{Float64}, heights),
|
||||
KW(kw),
|
||||
)
|
||||
KW(kw))
|
||||
for i in eachindex(grid)
|
||||
grid[i] = EmptyLayout(layout)
|
||||
end
|
||||
@ -269,15 +263,13 @@ Base.getindex(layout::GridLayout, r::Int, c::Int) = layout.grid[r, c]
|
||||
function Base.setindex!(layout::GridLayout, v, r::Int, c::Int)
|
||||
layout.grid[r,c] = v
|
||||
end
|
||||
function Base.setindex!(layout::GridLayout, v, ci::CartesianIndex)
|
||||
layout.grid[ci] = v
|
||||
end
|
||||
|
||||
leftpad(layout::GridLayout) = layout.minpad[1]
|
||||
toppad(layout::GridLayout) = layout.minpad[2]
|
||||
rightpad(layout::GridLayout) = layout.minpad[3]
|
||||
bottompad(layout::GridLayout) = layout.minpad[4]
|
||||
|
||||
|
||||
# here's how this works... first we recursively "update the minimum padding" (which
|
||||
# means to calculate the minimum size needed from the edge of the subplot to plot area)
|
||||
# for the whole layout tree. then we can compute the "padding borders" of this
|
||||
@ -292,10 +284,11 @@ function _update_min_padding!(layout::GridLayout)
|
||||
maximum(map(leftpad, layout.grid[:,1])),
|
||||
maximum(map(toppad, layout.grid[1,:])),
|
||||
maximum(map(rightpad, layout.grid[:,end])),
|
||||
maximum(map(bottompad, layout.grid[end, :])),
|
||||
maximum(map(bottompad, layout.grid[end,:]))
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
function update_position!(layout::GridLayout)
|
||||
map(update_position!, layout.grid)
|
||||
end
|
||||
@ -314,9 +307,7 @@ function recompute_lengths(v)
|
||||
end
|
||||
leftover = 1.0pct - tot
|
||||
if cnt > 1 && leftover.value <= 0
|
||||
error(
|
||||
"Not enough length left over in layout! v = $v, cnt = $cnt, leftover = $leftover",
|
||||
)
|
||||
error("Not enough length left over in layout! v = $v, cnt = $cnt, leftover = $leftover")
|
||||
end
|
||||
|
||||
# now fill in the blanks
|
||||
@ -364,7 +355,7 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm, 0mm,
|
||||
# denom_h = sum(layout.heights)
|
||||
|
||||
# we have all the data we need... lets compute the plot areas and set the bounding boxes
|
||||
for r in 1:nr, c in 1:nc
|
||||
for r=1:nr, c=1:nc
|
||||
child = layout[r,c]
|
||||
|
||||
# get the top-left corner of this child... the first one is top-left of the parent (i.e. layout)
|
||||
@ -376,10 +367,7 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm, 0mm,
|
||||
plotarea_top = child_top + pad_top[r]
|
||||
plotarea_width = total_plotarea_horizontal * layout.widths[c]
|
||||
plotarea_height = total_plotarea_vertical * layout.heights[r]
|
||||
plotarea!(
|
||||
child,
|
||||
BoundingBox(plotarea_left, plotarea_top, plotarea_width, plotarea_height),
|
||||
)
|
||||
plotarea!(child, BoundingBox(plotarea_left, plotarea_top, plotarea_width, plotarea_height))
|
||||
|
||||
# compute child bbox
|
||||
child_width = pad_left[c] + plotarea_width + pad_right[c]
|
||||
@ -392,7 +380,7 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm, 0mm,
|
||||
c == 1 ? layout.minpad[1] : pad_left[c],
|
||||
r == 1 ? layout.minpad[2] : pad_top[r],
|
||||
c == nc ? layout.minpad[3] : pad_right[c],
|
||||
r == nr ? layout.minpad[4] : pad_bottom[r],
|
||||
r == nr ? layout.minpad[4] : pad_bottom[r]
|
||||
]
|
||||
|
||||
# recursively update the child's children
|
||||
@ -407,21 +395,18 @@ function update_inset_bboxes!(plt::Plot)
|
||||
p_area = Measures.resolve(plotarea(sp.parent), sp[:relative_bbox])
|
||||
plotarea!(sp, p_area)
|
||||
|
||||
bbox!(
|
||||
sp,
|
||||
bbox(
|
||||
bbox!(sp, bbox(
|
||||
left(p_area) - leftpad(sp),
|
||||
top(p_area) - toppad(sp),
|
||||
width(p_area) + leftpad(sp) + rightpad(sp),
|
||||
height(p_area) + toppad(sp) + bottompad(sp),
|
||||
),
|
||||
)
|
||||
height(p_area) + toppad(sp) + bottompad(sp)
|
||||
))
|
||||
end
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
calc_num_subplots(layout::AbstractLayout) = get(layout.attr, :blank, false) ? 0 : 1
|
||||
calc_num_subplots(layout::AbstractLayout) = 1
|
||||
function calc_num_subplots(layout::GridLayout)
|
||||
tot = 0
|
||||
for l in layout.grid
|
||||
@ -456,9 +441,7 @@ end
|
||||
function layout_args(plotattributes::AKW, n_override::Integer)
|
||||
layout, n = layout_args(n_override, get(plotattributes, :layout, n_override))
|
||||
if n != n_override
|
||||
error(
|
||||
"When doing layout, n ($n) != n_override ($(n_override)). You're probably trying to force existing plots into a layout that doesn't fit them.",
|
||||
)
|
||||
error("When doing layout, n ($n) != n_override ($(n_override)). You're probably trying to force existing plots into a layout that doesn't fit them.")
|
||||
end
|
||||
layout, n
|
||||
end
|
||||
@ -494,19 +477,6 @@ function layout_args(sztup::NTuple{3,Integer})
|
||||
GridLayout(nr, nc), n
|
||||
end
|
||||
|
||||
layout_args(nt::NamedTuple) = EmptyLayout(; nt...), 1
|
||||
|
||||
function layout_args(m::AbstractVecOrMat)
|
||||
sz = size(m)
|
||||
nr = sz[1]
|
||||
nc = get(sz, 2, 1)
|
||||
gl = GridLayout(nr, nc)
|
||||
for ci in CartesianIndices(m)
|
||||
gl[ci] = layout_args(m[ci])[1]
|
||||
end
|
||||
layout_args(gl)
|
||||
end
|
||||
|
||||
# compute number of subplots
|
||||
function layout_args(layout::GridLayout)
|
||||
# recursively get the size of the grid
|
||||
@ -514,50 +484,44 @@ function layout_args(layout::GridLayout)
|
||||
layout, n
|
||||
end
|
||||
|
||||
layout_args(n_override::Integer, layout::Union{AbstractVecOrMat,GridLayout}) =
|
||||
layout_args(layout)
|
||||
layout_args(n_override::Integer, layout::GridLayout) = layout_args(layout)
|
||||
|
||||
layout_args(huh) = error("unhandled layout type $(typeof(huh)): $huh")
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
function build_layout(args...)
|
||||
layout, n = layout_args(args...)
|
||||
build_layout(layout, n, Array{Plot}(undef, 0))
|
||||
build_layout(layout, n)
|
||||
end
|
||||
|
||||
# n is the number of subplots...
|
||||
function build_layout(layout::GridLayout, n::Integer, plts::AVec{Plot})
|
||||
# # just a single subplot
|
||||
# function build_layout(sp::Subplot, n::Integer)
|
||||
# sp, Subplot[sp], SubplotMap(gensym() => sp)
|
||||
# end
|
||||
|
||||
# n is the number of subplots... build a grid and initialize the inner subplots recursively
|
||||
function build_layout(layout::GridLayout, n::Integer)
|
||||
nr, nc = size(layout)
|
||||
subplots = Subplot[]
|
||||
spmap = SubplotMap()
|
||||
empty = isempty(plts)
|
||||
i = 0
|
||||
for r in 1:nr, c in 1:nc
|
||||
for r=1:nr, c=1:nc
|
||||
l = layout[r,c]
|
||||
if isa(l, EmptyLayout) && !get(l.attr, :blank, false)
|
||||
if empty
|
||||
# initialize the inner subplots recursively
|
||||
sp = Subplot(backend(), parent=layout)
|
||||
layout[r,c] = sp
|
||||
push!(subplots, sp)
|
||||
spmap[attr(l,:label,gensym())] = sp
|
||||
inc = 1
|
||||
else
|
||||
# build a layout from a list of existing Plot objects
|
||||
plt = popfirst!(plts) # grab the first plot out of the list
|
||||
layout[r, c] = plt.layout
|
||||
append!(subplots, plt.subplots)
|
||||
merge!(spmap, plt.spmap)
|
||||
inc = length(plt.subplots)
|
||||
end
|
||||
if get(l.attr, :width, :auto) != :auto
|
||||
layout.widths[c] = attr(l,:width)
|
||||
end
|
||||
if get(l.attr, :height, :auto) != :auto
|
||||
layout.heights[r] = attr(l,:height)
|
||||
end
|
||||
i += inc
|
||||
i += 1
|
||||
elseif isa(l, GridLayout)
|
||||
# sub-grid
|
||||
if get(l.attr, :width, :auto) != :auto
|
||||
@ -566,11 +530,11 @@ function build_layout(layout::GridLayout, n::Integer, plts::AVec{Plot})
|
||||
if get(l.attr, :height, :auto) != :auto
|
||||
layout.heights[r] = attr(l,:height)
|
||||
end
|
||||
l, sps, m = build_layout(l, n - i, plts)
|
||||
l, sps, m = build_layout(l, n-i)
|
||||
append!(subplots, sps)
|
||||
merge!(spmap, m)
|
||||
i += length(sps)
|
||||
elseif isa(l, Subplot) && empty
|
||||
elseif isa(l, Subplot)
|
||||
error("Subplot exists. Cannot re-use existing layout. Please make a new one.")
|
||||
end
|
||||
i >= n && break # only add n subplots
|
||||
@ -579,13 +543,161 @@ function build_layout(layout::GridLayout, n::Integer, plts::AVec{Plot})
|
||||
layout, subplots, spmap
|
||||
end
|
||||
|
||||
# build a layout from a list of existing Plot objects
|
||||
# TODO... much of the logic overlaps with the method above... can we merge?
|
||||
function build_layout(layout::GridLayout, numsp::Integer, plts::AVec{Plot})
|
||||
nr, nc = size(layout)
|
||||
subplots = Subplot[]
|
||||
spmap = SubplotMap()
|
||||
i = 0
|
||||
for r=1:nr, c=1:nc
|
||||
l = layout[r,c]
|
||||
if isa(l, EmptyLayout) && !get(l.attr, :blank, false)
|
||||
plt = popfirst!(plts) # grab the first plot out of the list
|
||||
layout[r,c] = plt.layout
|
||||
append!(subplots, plt.subplots)
|
||||
merge!(spmap, plt.spmap)
|
||||
if get(l.attr, :width, :auto) != :auto
|
||||
layout.widths[c] = attr(l,:width)
|
||||
end
|
||||
if get(l.attr, :height, :auto) != :auto
|
||||
layout.heights[r] = attr(l,:height)
|
||||
end
|
||||
i += length(plt.subplots)
|
||||
elseif isa(l, GridLayout)
|
||||
# sub-grid
|
||||
if get(l.attr, :width, :auto) != :auto
|
||||
layout.widths[c] = attr(l,:width)
|
||||
end
|
||||
if get(l.attr, :height, :auto) != :auto
|
||||
layout.heights[r] = attr(l,:height)
|
||||
end
|
||||
l, sps, m = build_layout(l, numsp-i, plts)
|
||||
append!(subplots, sps)
|
||||
merge!(spmap, m)
|
||||
i += length(sps)
|
||||
end
|
||||
i >= numsp && break # only add n subplots
|
||||
end
|
||||
layout, subplots, spmap
|
||||
end
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# @layout macro
|
||||
|
||||
function add_layout_pct!(kw::AKW, v::Expr, idx::Integer, nidx::Integer)
|
||||
# dump(v)
|
||||
# something like {0.2w}?
|
||||
if v.head == :call && v.args[1] == :*
|
||||
num = v.args[2]
|
||||
if length(v.args) == 3 && isa(num, Number)
|
||||
units = v.args[3]
|
||||
if units == :h
|
||||
return kw[:h] = num*pct
|
||||
elseif units == :w
|
||||
return kw[:w] = num*pct
|
||||
elseif units in (:pct, :px, :mm, :cm, :inch)
|
||||
idx == 1 && (kw[:w] = v)
|
||||
(idx == 2 || nidx == 1) && (kw[:h] = v)
|
||||
# return kw[idx == 1 ? :w : :h] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
error("Couldn't match layout curly (idx=$idx): $v")
|
||||
end
|
||||
|
||||
function add_layout_pct!(kw::AKW, v::Number, idx::Integer)
|
||||
# kw[idx == 1 ? :w : :h] = v*pct
|
||||
idx == 1 && (kw[:w] = v*pct)
|
||||
(idx == 2 || nidx == 1) && (kw[:h] = v*pct)
|
||||
end
|
||||
|
||||
isrow(v) = isa(v, Expr) && v.head in (:hcat,:row)
|
||||
iscol(v) = isa(v, Expr) && v.head == :vcat
|
||||
rowsize(v) = isrow(v) ? length(v.args) : 1
|
||||
|
||||
|
||||
function create_grid(expr::Expr)
|
||||
if iscol(expr)
|
||||
create_grid_vcat(expr)
|
||||
elseif isrow(expr)
|
||||
:(let cell = GridLayout(1, $(length(expr.args)))
|
||||
$([:(cell[1,$i] = $(create_grid(v))) for (i,v) in enumerate(expr.args)]...)
|
||||
cell
|
||||
end)
|
||||
|
||||
elseif expr.head == :curly
|
||||
create_grid_curly(expr)
|
||||
else
|
||||
# if it's something else, just return that (might be an existing layout?)
|
||||
esc(expr)
|
||||
end
|
||||
end
|
||||
|
||||
function create_grid_vcat(expr::Expr)
|
||||
rowsizes = map(rowsize, expr.args)
|
||||
rmin, rmax = extrema(rowsizes)
|
||||
if rmin > 0 && rmin == rmax
|
||||
# we have a grid... build the whole thing
|
||||
# note: rmin is the number of columns
|
||||
nr = length(expr.args)
|
||||
nc = rmin
|
||||
body = Expr(:block)
|
||||
for r=1:nr
|
||||
arg = expr.args[r]
|
||||
if isrow(arg)
|
||||
for (c,item) in enumerate(arg.args)
|
||||
push!(body.args, :(cell[$r,$c] = $(create_grid(item))))
|
||||
end
|
||||
else
|
||||
push!(body.args, :(cell[$r,1] = $(create_grid(arg))))
|
||||
end
|
||||
end
|
||||
:(let cell = GridLayout($nr, $nc)
|
||||
$body
|
||||
cell
|
||||
end)
|
||||
else
|
||||
# otherwise just build one row at a time
|
||||
:(let cell = GridLayout($(length(expr.args)), 1)
|
||||
$([:(cell[$i,1] = $(create_grid(v))) for (i,v) in enumerate(expr.args)]...)
|
||||
cell
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function create_grid_curly(expr::Expr)
|
||||
kw = KW()
|
||||
for (i,arg) in enumerate(expr.args[2:end])
|
||||
add_layout_pct!(kw, arg, i, length(expr.args)-1)
|
||||
end
|
||||
s = expr.args[1]
|
||||
if isa(s, Expr) && s.head == :call && s.args[1] == :grid
|
||||
create_grid(:(grid($(s.args[2:end]...), width = $(get(kw, :w, QuoteNode(:auto))), height = $(get(kw, :h, QuoteNode(:auto))))))
|
||||
elseif isa(s, Symbol)
|
||||
:(EmptyLayout(label = $(QuoteNode(s)), width = $(get(kw, :w, QuoteNode(:auto))), height = $(get(kw, :h, QuoteNode(:auto)))))
|
||||
else
|
||||
error("Unknown use of curly brackets: $expr")
|
||||
end
|
||||
end
|
||||
|
||||
function create_grid(s::Symbol)
|
||||
:(EmptyLayout(label = $(QuoteNode(s)), blank = $(s == :_)))
|
||||
end
|
||||
|
||||
macro layout(mat::Expr)
|
||||
create_grid(mat)
|
||||
end
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# make all reference the same axis extrema/values.
|
||||
# merge subplot lists.
|
||||
function link_axes!(axes::Axis...)
|
||||
a1 = axes[1]
|
||||
for i in 2:length(axes)
|
||||
for i=2:length(axes)
|
||||
a2 = axes[i]
|
||||
expand_extrema!(a1, ignorenan_extrema(a2))
|
||||
for k in (:extrema, :discrete_values, :continuous_values, :discrete_map)
|
||||
@ -624,18 +736,19 @@ function link_axes!(a::AbstractArray{AbstractLayout}, axissym::Symbol)
|
||||
end
|
||||
|
||||
# don't do anything for most layout types
|
||||
function link_axes!(l::AbstractLayout, link::Symbol) end
|
||||
function link_axes!(l::AbstractLayout, link::Symbol)
|
||||
end
|
||||
|
||||
# process a GridLayout, recursively linking axes according to the link symbol
|
||||
function link_axes!(layout::GridLayout, link::Symbol)
|
||||
nr, nc = size(layout)
|
||||
if link in (:x, :both)
|
||||
for c in 1:nc
|
||||
for c=1:nc
|
||||
link_axes!(layout.grid[:,c], :xaxis)
|
||||
end
|
||||
end
|
||||
if link in (:y, :both)
|
||||
for r in 1:nr
|
||||
for r=1:nr
|
||||
link_axes!(layout.grid[r,:], :yaxis)
|
||||
end
|
||||
end
|
||||
@ -662,18 +775,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])
|
||||
|
||||
@ -4,7 +4,8 @@ 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`).
|
||||
`(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)
|
||||
@ -14,6 +15,7 @@ function legend_pos_from_angle(theta, xmin, xcenter, xmax, ymin, ycenter, ymax)
|
||||
return (xcenter + A*c, ycenter + A*s)
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
Split continuous range `[-1,1]` evenly into an integer `[1,2,3]`
|
||||
"""
|
||||
@ -32,7 +34,7 @@ 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::Tuple{S,Symbol}) where S<:Real = leg
|
||||
legend_angle(leg::Symbol) = get(
|
||||
(
|
||||
topleft = (135,:inner),
|
||||
@ -53,5 +55,5 @@ legend_angle(leg::Symbol) = get(
|
||||
outerbottomright = (315,:outer),
|
||||
),
|
||||
leg,
|
||||
(45, :inner),
|
||||
(45, :inner)
|
||||
)
|
||||
|
||||
@ -2,68 +2,78 @@
|
||||
defaultOutputFormat(plt::Plot) = "png"
|
||||
|
||||
function png(plt::Plot, fn::AbstractString)
|
||||
open(addExtension(fn, "png"), "w") do io
|
||||
fn = addExtension(fn, "png")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("image/png"), plt)
|
||||
end
|
||||
close(io)
|
||||
end
|
||||
png(fn::AbstractString) = png(current(), fn)
|
||||
|
||||
function svg(plt::Plot, fn::AbstractString)
|
||||
open(addExtension(fn, "svg"), "w") do io
|
||||
fn = addExtension(fn, "svg")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("image/svg+xml"), plt)
|
||||
end
|
||||
close(io)
|
||||
end
|
||||
svg(fn::AbstractString) = svg(current(), fn)
|
||||
|
||||
function pdf(plt::Plot, fn::AbstractString)
|
||||
open(addExtension(fn, "pdf"), "w") do io
|
||||
fn = addExtension(fn, "pdf")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("application/pdf"), plt)
|
||||
end
|
||||
close(io)
|
||||
end
|
||||
pdf(fn::AbstractString) = pdf(current(), fn)
|
||||
|
||||
function ps(plt::Plot, fn::AbstractString)
|
||||
open(addExtension(fn, "ps"), "w") do io
|
||||
fn = addExtension(fn, "ps")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("application/postscript"), plt)
|
||||
end
|
||||
close(io)
|
||||
end
|
||||
ps(fn::AbstractString) = ps(current(), fn)
|
||||
|
||||
function eps(plt::Plot, fn::AbstractString)
|
||||
open(addExtension(fn, "eps"), "w") do io
|
||||
fn = addExtension(fn, "eps")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("image/eps"), plt)
|
||||
end
|
||||
close(io)
|
||||
end
|
||||
eps(fn::AbstractString) = eps(current(), fn)
|
||||
|
||||
function tex(plt::Plot, fn::AbstractString)
|
||||
open(addExtension(fn, "tex"), "w") do io
|
||||
fn = addExtension(fn, "tex")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("application/x-tex"), plt)
|
||||
end
|
||||
close(io)
|
||||
end
|
||||
tex(fn::AbstractString) = tex(current(), fn)
|
||||
|
||||
function json(plt::Plot, fn::AbstractString)
|
||||
open(addExtension(fn, "json"), "w") do io
|
||||
fn = addExtension(fn, "json")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("application/vnd.plotly.v1+json"), plt)
|
||||
end
|
||||
close(io)
|
||||
end
|
||||
json(fn::AbstractString) = json(current(), fn)
|
||||
|
||||
function html(plt::Plot, fn::AbstractString)
|
||||
open(addExtension(fn, "html"), "w") do io
|
||||
fn = addExtension(fn, "html")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("text/html"), plt)
|
||||
end
|
||||
close(io)
|
||||
end
|
||||
html(fn::AbstractString) = html(current(), fn)
|
||||
|
||||
function txt(plt::Plot, fn::AbstractString; color::Bool = true)
|
||||
open(addExtension(fn, "txt"), "w") do io
|
||||
show(IOContext(io, :color => color), MIME("text/plain"), plt)
|
||||
end
|
||||
function txt(plt::Plot, fn::AbstractString)
|
||||
fn = addExtension(fn, "txt")
|
||||
io = open(fn, "w")
|
||||
show(io, MIME("text/plain"), plt)
|
||||
close(io)
|
||||
end
|
||||
txt(fn::AbstractString) = txt(current(), fn)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
const _savemap = Dict(
|
||||
@ -79,13 +89,6 @@ const _savemap = Dict(
|
||||
"txt" => txt,
|
||||
)
|
||||
|
||||
for out in Symbol.(unique(values(_savemap)))
|
||||
@eval @doc """
|
||||
$($out)([plot,], filename)
|
||||
Save plot as $($out)-file.
|
||||
""" $out
|
||||
end
|
||||
|
||||
const _extension_map = Dict("tikz" => "tex")
|
||||
|
||||
function addExtension(fn::AbstractString, ext::AbstractString)
|
||||
@ -125,6 +128,7 @@ function savefig(plt::Plot, fn::AbstractString)
|
||||
end
|
||||
savefig(fn::AbstractString) = savefig(current(), fn)
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
"""
|
||||
@ -194,7 +198,6 @@ 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",
|
||||
"text/latex",
|
||||
"image/png",
|
||||
"image/eps",
|
||||
"image/svg+xml",
|
||||
@ -215,14 +218,13 @@ for mime in (
|
||||
end
|
||||
end
|
||||
|
||||
Base.showable(::MIME"text/html", plt::Plot{UnicodePlotsBackend}) = false # Pluto
|
||||
|
||||
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) =
|
||||
showjuno(io, MIME("text/html"), plt)
|
||||
|
||||
"Close all open gui windows of the current backend"
|
||||
closeall() = closeall(backend())
|
||||
|
||||
|
||||
# function html_output_format(fmt)
|
||||
# if fmt == "png"
|
||||
# @eval function Base.show(io::IO, ::MIME"text/html", plt::Plot)
|
||||
@ -239,6 +241,7 @@ closeall() = closeall(backend())
|
||||
#
|
||||
# html_output_format("svg")
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Atom PlotPane
|
||||
# ---------------------------------------------------------
|
||||
|
||||
172
src/pipeline.jl
172
src/pipeline.jl
@ -8,18 +8,29 @@ function RecipesPipeline.warn_on_recipe_aliases!(
|
||||
recipe_type::Symbol,
|
||||
@nospecialize(args)
|
||||
)
|
||||
pkeys = keys(plotattributes)
|
||||
for k in pkeys
|
||||
dk = get(_keyAliases, k, nothing)
|
||||
if dk !== nothing
|
||||
kv = RecipesPipeline.pop_kw!(plotattributes, k)
|
||||
if dk ∉ pkeys
|
||||
plotattributes[dk] = kv
|
||||
end
|
||||
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`."
|
||||
end
|
||||
plotattributes[dk] = RecipesPipeline.pop_kw!(plotattributes, k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
## Grouping
|
||||
|
||||
RecipesPipeline.splittable_attribute(plt::Plot, key, val::SeriesAnnotations, len) =
|
||||
@ -30,6 +41,7 @@ function RecipesPipeline.split_attribute(plt::Plot, key, val::SeriesAnnotations,
|
||||
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
|
||||
@ -50,6 +62,7 @@ RecipesPipeline.is_axis_attribute(plt::Plot, attr) = is_axis_attr_noletter(attr)
|
||||
|
||||
RecipesPipeline.is_subplot_attribute(plt::Plot, attr) = is_subplot_attr(attr) # in src/args.jl
|
||||
|
||||
|
||||
## User recipes
|
||||
|
||||
function RecipesPipeline.process_userrecipe!(plt::Plot, kw_list, kw)
|
||||
@ -68,32 +81,23 @@ end
|
||||
function _preprocess_userrecipe(kw::AKW)
|
||||
_add_markershape(kw)
|
||||
|
||||
if get(kw, :permute, default(:permute)) != :none
|
||||
l1, l2 = kw[:permute]
|
||||
for k in _axis_args
|
||||
k1 = _attrsymbolcache[l1][k]
|
||||
k2 = _attrsymbolcache[l2][k]
|
||||
kwk = keys(kw)
|
||||
if k1 in kwk || k2 in kwk
|
||||
kw[k1], kw[k2] = get(kw, k2, default(k2)), get(kw, k1, default(k1))
|
||||
end
|
||||
end
|
||||
end
|
||||
# map marker_z if it's a Function
|
||||
if isa(get(kw, :marker_z, default(:marker_z)), Function)
|
||||
if isa(get(kw, :marker_z, nothing), Function)
|
||||
# TODO: should this take y and/or z as arguments?
|
||||
kw[:marker_z] =
|
||||
isa(kw[:z], Nothing) ? map(kw[:marker_z], kw[:x], kw[:y]) :
|
||||
kw[:marker_z] = isa(kw[:z], Nothing) ? map(kw[:marker_z], kw[:x], kw[:y]) :
|
||||
map(kw[:marker_z], kw[:x], kw[:y], kw[:z])
|
||||
end
|
||||
|
||||
# map line_z if it's a Function
|
||||
if isa(get(kw, :line_z, default(:line_z)), Function)
|
||||
kw[:line_z] =
|
||||
isa(kw[:z], Nothing) ? map(kw[:line_z], kw[:x], kw[:y]) :
|
||||
if isa(get(kw, :line_z, nothing), Function)
|
||||
kw[:line_z] = isa(kw[:z], Nothing) ? map(kw[:line_z], kw[:x], kw[:y]) :
|
||||
map(kw[:line_z], kw[:x], kw[:y], kw[:z])
|
||||
end
|
||||
|
||||
# convert a ribbon into a fillrange
|
||||
if get(kw, :ribbon, nothing) !== nothing
|
||||
make_fillrange_from_ribbon(kw)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
@ -136,12 +140,15 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::AKW)
|
||||
end
|
||||
end
|
||||
|
||||
RecipesPipeline.get_axis_limits(plt::Plot, letter) = axis_limits(plt[1], letter, false)
|
||||
|
||||
RecipesPipeline.get_axis_limits(plt::Plot, letter) = axis_limits(plt[1], letter)
|
||||
|
||||
|
||||
## Plot recipes
|
||||
|
||||
RecipesPipeline.type_alias(plt::Plot) = get(_typeAliases, st, st)
|
||||
|
||||
|
||||
## Plot setup
|
||||
|
||||
function RecipesPipeline.plot_setup!(plt::Plot, plotattributes, kw_list)
|
||||
@ -152,8 +159,7 @@ 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)
|
||||
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])
|
||||
@ -161,25 +167,10 @@ function RecipesPipeline.process_sliced_series_attributes!(plt::Plots.Plot, kw_l
|
||||
kw_list[ind-1] = tmp
|
||||
end
|
||||
end
|
||||
|
||||
for kw in kw_list
|
||||
rib = get(kw, :ribbon, default(:ribbon))
|
||||
fr = get(kw, :fillrange, default(:fillrange))
|
||||
# map ribbon if it's a Function
|
||||
if rib isa Function
|
||||
kw[:ribbon] = map(rib, kw[:x])
|
||||
end
|
||||
# convert a ribbon into a fillrange
|
||||
if rib !== nothing
|
||||
make_fillrange_from_ribbon(kw)
|
||||
# map fillrange if it's a Function
|
||||
elseif fr !== nothing && fr isa Function
|
||||
kw[:fillrange] = map(fr, kw[:x])
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
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
|
||||
@ -202,6 +193,7 @@ function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
|
||||
plt.init = true
|
||||
end
|
||||
|
||||
|
||||
# handle inset subplots
|
||||
insets = plt[:inset_subplots]
|
||||
if insets !== nothing
|
||||
@ -251,33 +243,25 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
|
||||
attr = KW()
|
||||
for (k, v) in collect(kw)
|
||||
if is_subplot_attr(k) || is_axis_attr(k)
|
||||
v = pop!(kw, k)
|
||||
if sps isa AbstractArray && v isa AbstractArray && length(v) == length(sps)
|
||||
v = v[series_idx(kw_list, kw)]
|
||||
end
|
||||
attr[k] = v
|
||||
attr[k] = pop!(kw, k)
|
||||
end
|
||||
if is_axis_attr_noletter(k)
|
||||
v = pop!(kw, k)
|
||||
if sps isa AbstractArray && v isa AbstractArray && length(v) == length(sps)
|
||||
v = v[series_idx(kw_list, kw)]
|
||||
end
|
||||
for letter in (:x, :y, :z)
|
||||
attr[get_attr_symbol(letter, k)] = v
|
||||
end
|
||||
attr[Symbol(letter, k)] = v
|
||||
end
|
||||
end
|
||||
for k in (:scale,), letter in (:x, :y, :z)
|
||||
# Series recipes may need access to this information
|
||||
lk = get_attr_symbol(letter, k)
|
||||
lk = Symbol(letter, k)
|
||||
if haskey(attr, lk)
|
||||
kw[lk] = attr[lk]
|
||||
end
|
||||
end
|
||||
end
|
||||
sp_attrs[sp] = attr
|
||||
end
|
||||
|
||||
_add_plot_title!(plt)
|
||||
# override subplot/axis args. `sp_attrs` take precendence
|
||||
for (idx, sp) in enumerate(plt.subplots)
|
||||
attr = if !haskey(plotattributes, :subplot) || plotattributes[:subplot] == idx
|
||||
@ -290,48 +274,12 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
|
||||
|
||||
# do we need to link any axes together?
|
||||
link_axes!(plt.layout, plt[:link])
|
||||
return nothing
|
||||
end
|
||||
|
||||
function series_idx(kw_list::AVec{KW}, kw::AKW)
|
||||
Int(kw[:series_plotindex]) - Int(kw_list[1][:series_plotindex]) + 1
|
||||
end
|
||||
|
||||
function _add_plot_title!(plt)
|
||||
plot_title = plt[:plot_title]
|
||||
plot_titleindex = nothing
|
||||
|
||||
if plot_title != ""
|
||||
# make new subplot for plot title
|
||||
if plt[:plot_titleindex] == 0
|
||||
the_layout = plt.layout
|
||||
vspan = plt[:plot_titlevspan]
|
||||
plt.layout = grid(2, 1, heights = (vspan, 1 - vspan))
|
||||
plt.layout.grid[1, 1] =
|
||||
subplot = Subplot(plt.backend, parent = plt.layout[1, 1])
|
||||
plt.layout.grid[2, 1] = the_layout
|
||||
subplot.plt = plt
|
||||
|
||||
top = plt.backend isa PyPlotBackend ? nothing : 0mm
|
||||
bot = 0mm
|
||||
plt[:force_minpad] = nothing, top, nothing, bot
|
||||
subplot[:subplot_index] = last(plt.subplots)[:subplot_index] + 1
|
||||
plt[:plot_titleindex] = subplot[:subplot_index]
|
||||
subplot[:framestyle] = :none
|
||||
subplot[:margin] = 0px
|
||||
push!(plt.subplots, subplot)
|
||||
end
|
||||
|
||||
# propagate arguments plt[:plot_titleXXX] --> subplot[:titleXXX]
|
||||
plot_titleindex = plt[:plot_titleindex]
|
||||
subplot = plt.subplots[plot_titleindex]
|
||||
for sym in filter(x -> startswith(string(x), "plot_title"), keys(_plot_defaults))
|
||||
subplot[Symbol(string(sym)[(length("plot_") + 1):end])] = plt[sym]
|
||||
end
|
||||
end
|
||||
|
||||
return plot_titleindex
|
||||
end
|
||||
|
||||
## Series recipes
|
||||
|
||||
@ -349,19 +297,6 @@ RecipesPipeline.is_seriestype_supported(plt::Plot, st) = is_seriestype_supported
|
||||
|
||||
function RecipesPipeline.add_series!(plt::Plot, plotattributes)
|
||||
sp = _prepare_subplot(plt, plotattributes)
|
||||
if plotattributes[:permute] != :none
|
||||
letter1, letter2 = plotattributes[:permute]
|
||||
if plotattributes[:markershape] == :hline &&
|
||||
(plotattributes[:permute] == (:x, :y) || plotattributes[:permute] == (:y, :x))
|
||||
plotattributes[:markershape] = :vline
|
||||
elseif plotattributes[:markershape] == :vline && (
|
||||
plotattributes[:permute] == (:x, :y) || plotattributes[:permute] == (:y, :x)
|
||||
)
|
||||
plotattributes[:markershape] = :hline
|
||||
end
|
||||
plotattributes[letter1], plotattributes[letter2] =
|
||||
plotattributes[letter2], plotattributes[letter1]
|
||||
end
|
||||
_expand_subplot_extrema(sp, plotattributes, plotattributes[:seriestype])
|
||||
_update_series_attributes!(plotattributes, plt, sp)
|
||||
_add_the_series(plt, sp, plotattributes)
|
||||
@ -378,10 +313,7 @@ function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where {T}
|
||||
st = _override_seriestype_check(plotattributes, st)
|
||||
|
||||
# change to a 3d projection for this subplot?
|
||||
if (
|
||||
RecipesPipeline.needs_3d_axes(st) ||
|
||||
(st == :quiver && plotattributes[:z] !== nothing)
|
||||
)
|
||||
if RecipesPipeline.needs_3d_axes(st)
|
||||
sp.attr[:projection] = "3d"
|
||||
end
|
||||
|
||||
@ -397,10 +329,8 @@ 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))
|
||||
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
|
||||
end
|
||||
@ -408,14 +338,6 @@ function _override_seriestype_check(plotattributes::AKW, st::Symbol)
|
||||
st
|
||||
end
|
||||
|
||||
function needs_any_3d_axes(sp::Subplot)
|
||||
any(
|
||||
RecipesPipeline.needs_3d_axes(
|
||||
_override_seriestype_check(s.plotattributes, s.plotattributes[:seriestype]),
|
||||
) for s in series_list(sp)
|
||||
)
|
||||
end
|
||||
|
||||
function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
|
||||
# adjust extrema and discrete info
|
||||
if st == :image
|
||||
@ -451,16 +373,6 @@ function _add_the_series(plt, sp, plotattributes)
|
||||
warn_on_unsupported(plt.backend, plotattributes)
|
||||
series = Series(plotattributes)
|
||||
push!(plt.series_list, series)
|
||||
z_order = plotattributes[:z_order]
|
||||
if z_order == :front
|
||||
push!(sp.series_list, series)
|
||||
elseif z_order == :back
|
||||
pushfirst!(sp.series_list, series)
|
||||
elseif z_order isa Integer
|
||||
insert!(sp.series_list, z_order, series)
|
||||
else
|
||||
@error "Wrong type $(typeof(z_order)) for attribute z_order"
|
||||
end
|
||||
_series_added(plt, series)
|
||||
_update_subplot_colorbars(sp)
|
||||
end
|
||||
|
||||
76
src/plot.jl
76
src/plot.jl
@ -20,44 +20,10 @@ current(plot::AbstractPlot) = (CURRENT_PLOT.nullableplot = plot)
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
Base.string(plt::Plot) = "Plot{$(plt.backend) n=$(plt.n)}"
|
||||
Base.print(io::IO, plt::Plot) = print(io, string(plt))
|
||||
function Base.show(io::IO, plt::Plot)
|
||||
print(io, string(plt))
|
||||
sp_ekwargs = getindex.(plt.subplots, :extra_kwargs)
|
||||
s_ekwargs = getindex.(plt.series_list, :extra_kwargs)
|
||||
if (
|
||||
isempty(plt[:extra_plot_kwargs]) &&
|
||||
all(isempty, sp_ekwargs) &&
|
||||
all(isempty, s_ekwargs)
|
||||
)
|
||||
return
|
||||
end
|
||||
print(io, "\nCaptured extra kwargs:\n")
|
||||
do_show = true
|
||||
for (key, value) in plt[:extra_plot_kwargs]
|
||||
do_show && println(io, " Plot:")
|
||||
println(io, " "^4, key, ": ", value)
|
||||
do_show = false
|
||||
end
|
||||
do_show = true
|
||||
for (i, ekwargs) in enumerate(sp_ekwargs)
|
||||
for (key, value) in ekwargs
|
||||
do_show && println(io, " SubplotPlot{$i}:")
|
||||
println(io, " "^4, key, ": ", value)
|
||||
do_show = false
|
||||
end
|
||||
do_show = true
|
||||
end
|
||||
for (i, ekwargs) in enumerate(s_ekwargs)
|
||||
for (key, value) in ekwargs
|
||||
do_show && println(io, " Series{$i}:")
|
||||
println(io, " "^4, key, ": ", value)
|
||||
do_show = false
|
||||
end
|
||||
do_show = true
|
||||
end
|
||||
end
|
||||
Base.show(io::IO, plt::Plot) = print(io, string(plt))
|
||||
|
||||
getplot(plt::Plot) = plt
|
||||
getattr(plt::Plot, idx::Int = 1) = plt.attr
|
||||
@ -65,6 +31,7 @@ convertSeriesIndex(plt::Plot, n::Int) = n
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
"""
|
||||
The main plot command. Use `plot` to create a new plot object, and `plot!` to add to an existing one:
|
||||
|
||||
@ -75,7 +42,7 @@ 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)`
|
||||
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")`.
|
||||
"""
|
||||
@ -92,21 +59,18 @@ function plot(args...; kw...)
|
||||
end
|
||||
|
||||
# build a new plot from existing plots
|
||||
# note: we split into plt1, plt2 and plts_tail so we can dispatch correctly
|
||||
plot(plt1::Plot, plt2::Plot, plts_tail::Plot...; kw...) =
|
||||
plot!(deepcopy(plt1), deepcopy(plt2), deepcopy.(plts_tail)...; kw...)
|
||||
function plot!(plt1::Plot, plt2::Plot, plts_tail::Plot...; kw...)
|
||||
# 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)
|
||||
|
||||
# build our plot vector from the args
|
||||
n = length(plts_tail) + 2
|
||||
n = length(plts_tail) + 1
|
||||
plts = Array{Plot}(undef, n)
|
||||
plts[1] = plt1
|
||||
plts[2] = plt2
|
||||
for (i,plt) in enumerate(plts_tail)
|
||||
plts[i + 2] = plt
|
||||
plts[i+1] = plt
|
||||
end
|
||||
|
||||
# compute the layout
|
||||
@ -163,11 +127,10 @@ function plot!(plt1::Plot, plt2::Plot, plts_tail::Plot...; kw...)
|
||||
cmdidx += 1
|
||||
end
|
||||
end
|
||||
ttl_idx = _add_plot_title!(plt)
|
||||
|
||||
# first apply any args for the subplots
|
||||
for (idx,sp) in enumerate(plt.subplots)
|
||||
_update_subplot_args(plt, sp, idx == ttl_idx ? KW() : plotattributes, idx, false)
|
||||
_update_subplot_args(plt, sp, plotattributes, idx, false)
|
||||
end
|
||||
|
||||
# finish up
|
||||
@ -176,6 +139,8 @@ function plot!(plt1::Plot, plt2::Plot, plts_tail::Plot...; kw...)
|
||||
plt
|
||||
end
|
||||
|
||||
|
||||
|
||||
# this adds to the current plot, or creates a new plot if none are current
|
||||
function plot!(args...; kw...)
|
||||
@nospecialize
|
||||
@ -189,7 +154,6 @@ function plot!(args...; kw...)
|
||||
end
|
||||
|
||||
# this adds to a specific plot... most plot commands will flow through here
|
||||
plot(plt::Plot, args...; kw...) = plot!(deepcopy(plt), args...; kw...)
|
||||
function plot!(plt::Plot, args...; kw...)
|
||||
@nospecialize
|
||||
plotattributes = KW(kw)
|
||||
@ -211,6 +175,7 @@ function _plot!(plt::Plot, plotattributes, args)
|
||||
return plt
|
||||
end
|
||||
|
||||
|
||||
# we're getting ready to display/output. prep for layout calcs, then update
|
||||
# the plot object after
|
||||
function prepare_output(plt::Plot)
|
||||
@ -226,17 +191,6 @@ function prepare_output(plt::Plot)
|
||||
_update_min_padding!(sp)
|
||||
end
|
||||
|
||||
# spedific to :plot_title see _add_plot_title!
|
||||
force_minpad = get(plt, :force_minpad, ())
|
||||
if !isempty(force_minpad)
|
||||
for i in eachindex(plt.layout.grid)
|
||||
plt.layout.grid[i].minpad = Tuple(
|
||||
i === nothing ? j : i for
|
||||
(i, j) in zip(force_minpad, plt.layout.grid[i].minpad)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# now another pass down, to update the bounding boxes
|
||||
update_child_bboxes!(plt.layout)
|
||||
|
||||
@ -247,12 +201,6 @@ function prepare_output(plt::Plot)
|
||||
_update_plot_object(plt)
|
||||
end
|
||||
|
||||
"""
|
||||
backend_object(plot)
|
||||
|
||||
Returns the backend representation of a Plot object.
|
||||
Returns `nothing` if the backend does not support this.
|
||||
"""
|
||||
function backend_object(plt::Plot)
|
||||
prepare_output(plt)
|
||||
plt.o
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
|
||||
const _attribute_defaults = Dict(
|
||||
:Series => _series_defaults,
|
||||
const _attribute_defaults = Dict(:Series => _series_defaults,
|
||||
:Subplot => _subplot_defaults,
|
||||
:Plot => _plot_defaults,
|
||||
:Axis => _axis_defaults,
|
||||
)
|
||||
:Axis => _axis_defaults)
|
||||
|
||||
attrtypes() = join(keys(_attribute_defaults), ", ")
|
||||
attributes(attrtype::Symbol) = sort(collect(keys(_attribute_defaults[attrtype])))
|
||||
@ -23,9 +21,7 @@ Look up the properties of a Plots attribute, or specify an attribute type. Call
|
||||
The information is the same as that given on https://docs.juliaplots.org/latest/attributes/.
|
||||
"""
|
||||
function plotattr()
|
||||
println(
|
||||
"Specify an attribute type to get a list of supported attributes. Options are $(attrtypes())",
|
||||
)
|
||||
println("Specify an attribute type to get a list of supported attributes. Options are $(attrtypes())")
|
||||
end
|
||||
|
||||
function plotattr(attrtype::Symbol)
|
||||
@ -48,8 +44,7 @@ printnothing(x) = x
|
||||
printnothing(x::Nothing) = "nothing"
|
||||
|
||||
function plotattr(attrtype::Symbol, attribute::AbstractString)
|
||||
in(attrtype, keys(_attribute_defaults)) ||
|
||||
ArgumentError("`attrtype` must match one of $(attrtypes())")
|
||||
in(attrtype, keys(_attribute_defaults)) || ArgumentError("`attrtype` must match one of $(attrtypes())")
|
||||
|
||||
attribute = Symbol(lookup_aliases(attrtype, attribute))
|
||||
|
||||
@ -59,21 +54,17 @@ function plotattr(attrtype::Symbol, attribute::AbstractString)
|
||||
typedesc = ""
|
||||
desc = strip(desc)
|
||||
else
|
||||
typedesc = desc[1:(first_period_idx - 1)]
|
||||
desc = strip(desc[(first_period_idx + 1):end])
|
||||
typedesc = desc[1:first_period_idx-1]
|
||||
desc = strip(desc[first_period_idx+1:end])
|
||||
end
|
||||
als = keys(filter(x->x[2]==attribute, _keyAliases)) |> collect |> sort
|
||||
als = join(map(string,als), ", ")
|
||||
def = _attribute_defaults[attrtype][attribute]
|
||||
|
||||
|
||||
# Looks up the different elements and plots them
|
||||
println(
|
||||
"$(printnothing(attribute)) ",
|
||||
typedesc == "" ? "" : "{$(printnothing(typedesc))}",
|
||||
"\n",
|
||||
println("$(printnothing(attribute)) ", typedesc == "" ? "" : "{$(printnothing(typedesc))}", "\n",
|
||||
als == "" ? "" : "$(printnothing(als))\n",
|
||||
"\n$(printnothing(desc))\n",
|
||||
"$(printnothing(attrtype)) attribute, ",
|
||||
def == "" ? "" : " default: $(printnothing(def))",
|
||||
)
|
||||
"$(printnothing(attrtype)) attribute, ", def == "" ? "" : " default: $(printnothing(def))")
|
||||
end
|
||||
|
||||
@ -1,40 +1,20 @@
|
||||
#! format: off
|
||||
should_precompile = true
|
||||
|
||||
|
||||
# Don't edit the following! Instead change the script for `snoop_bot`.
|
||||
ismultios = false
|
||||
ismultiversion = true
|
||||
ismultiversion = false
|
||||
# precompile_enclosure
|
||||
@static if !should_precompile
|
||||
# nothing
|
||||
elseif !ismultios && !ismultiversion
|
||||
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile/precompile_Plots.jl"))
|
||||
@static if isfile(joinpath(
|
||||
@__DIR__,
|
||||
"../deps/SnoopCompile/precompile/precompile_Plots.jl",
|
||||
))
|
||||
include("../deps/SnoopCompile/precompile/precompile_Plots.jl")
|
||||
_precompile_()
|
||||
end
|
||||
else
|
||||
@static if v"1.6.0-DEV" <= VERSION <= v"1.6.9"
|
||||
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile//1.6/precompile_Plots.jl"))
|
||||
include("../deps/SnoopCompile/precompile//1.6/precompile_Plots.jl")
|
||||
_precompile_()
|
||||
end
|
||||
elseif v"1.7.0-DEV" <= VERSION <= v"1.7.9"
|
||||
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile//1.7/precompile_Plots.jl"))
|
||||
include("../deps/SnoopCompile/precompile//1.7/precompile_Plots.jl")
|
||||
_precompile_()
|
||||
end
|
||||
elseif v"1.8.0-DEV" <= VERSION <= v"1.8.9"
|
||||
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile//1.8/precompile_Plots.jl"))
|
||||
include("../deps/SnoopCompile/precompile//1.8/precompile_Plots.jl")
|
||||
_precompile_()
|
||||
end
|
||||
elseif v"1.9.0-DEV" <= VERSION <= v"1.9.9"
|
||||
@static if isfile(joinpath(@__DIR__, "../deps/SnoopCompile/precompile//1.9/precompile_Plots.jl"))
|
||||
include("../deps/SnoopCompile/precompile//1.9/precompile_Plots.jl")
|
||||
_precompile_()
|
||||
end
|
||||
else
|
||||
end
|
||||
|
||||
end # precompile_enclosure
|
||||
|
||||
255
src/recipes.jl
255
src/recipes.jl
@ -41,16 +41,17 @@ function all_seriestypes()
|
||||
sort(collect(sts))
|
||||
end
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
num_series(x::AMat) = size(x, 2)
|
||||
num_series(x) = 1
|
||||
|
||||
RecipesBase.apply_recipe(plotattributes::AKW, ::Type{T}, plt::AbstractPlot) where {T} =
|
||||
nothing
|
||||
RecipesBase.apply_recipe(plotattributes::AKW, ::Type{T}, plt::AbstractPlot) where {T} = throw(MethodError(T, "Unmatched plot recipe: $T"))
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
# for seriestype `line`, need to sort by x values
|
||||
|
||||
const POTENTIAL_VECTOR_ARGUMENTS = [
|
||||
@ -114,7 +115,7 @@ end
|
||||
@recipe function f(::Type{Val{:hline}}, x, y, z)
|
||||
n = length(y)
|
||||
newx = repeat(Float64[1, 2, NaN], n)
|
||||
newy = vec(Float64[yi for i in 1:3, yi in y])
|
||||
newy = vec(Float64[yi for i = 1:3, yi in y])
|
||||
x := newx
|
||||
y := newy
|
||||
seriestype := :straightline
|
||||
@ -124,7 +125,7 @@ end
|
||||
|
||||
@recipe function f(::Type{Val{:vline}}, x, y, z)
|
||||
n = length(y)
|
||||
newx = vec(Float64[yi for i in 1:3, yi in y])
|
||||
newx = vec(Float64[yi for i = 1:3, yi in y])
|
||||
x := newx
|
||||
y := repeat(Float64[1, 2, NaN], n)
|
||||
seriestype := :straightline
|
||||
@ -135,7 +136,7 @@ end
|
||||
@recipe function f(::Type{Val{:hspan}}, x, y, z)
|
||||
n = div(length(y), 2)
|
||||
newx = repeat([-Inf, Inf, Inf, -Inf, NaN], outer = n)
|
||||
newy = vcat([[y[2i - 1], y[2i - 1], y[2i], y[2i], NaN] for i in 1:n]...)
|
||||
newy = vcat([[y[2i - 1], y[2i - 1], y[2i], y[2i], NaN] for i = 1:n]...)
|
||||
linewidth --> 0
|
||||
x := newx
|
||||
y := newy
|
||||
@ -146,7 +147,7 @@ end
|
||||
|
||||
@recipe function f(::Type{Val{:vspan}}, x, y, z)
|
||||
n = div(length(y), 2)
|
||||
newx = vcat([[y[2i - 1], y[2i - 1], y[2i], y[2i], NaN] for i in 1:n]...)
|
||||
newx = vcat([[y[2i - 1], y[2i - 1], y[2i], y[2i], NaN] for i = 1:n]...)
|
||||
newy = repeat([-Inf, Inf, Inf, -Inf, NaN], outer = n)
|
||||
linewidth --> 0
|
||||
x := newx
|
||||
@ -164,44 +165,19 @@ 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
|
||||
|
||||
@ -211,7 +187,7 @@ function make_steps(x::AbstractArray, st, even)
|
||||
n == 0 && return zeros(0)
|
||||
newx = zeros(2n - (even ? 0 : 1))
|
||||
newx[1] = x[1]
|
||||
for i in 2:n
|
||||
for i = 2:n
|
||||
idx = 2i - 1
|
||||
if st == :mid
|
||||
newx[idx] = newx[idx-1] = (x[i] + x[i-1]) / 2
|
||||
@ -225,6 +201,7 @@ function make_steps(x::AbstractArray, st, even)
|
||||
end
|
||||
make_steps(t::Tuple, st, even) = Tuple(make_steps(ti, st, even) for ti in t)
|
||||
|
||||
|
||||
@nospecialize
|
||||
|
||||
# create a path from steps
|
||||
@ -302,6 +279,7 @@ end
|
||||
end
|
||||
@deps steppost path scatter
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# sticks
|
||||
|
||||
@ -320,7 +298,7 @@ end
|
||||
end
|
||||
newx, newy = zeros(3n), zeros(3n)
|
||||
newz = z !== nothing ? zeros(3n) : nothing
|
||||
for (i, (xi, yi, zi)) in enumerate(zip(x, y, z !== nothing ? z : 1:n))
|
||||
for (i, (xi, yi, zi)) = enumerate(zip(x, y, z !== nothing ? z : 1:n))
|
||||
rng = (3i - 2):(3i)
|
||||
newx[rng] = [xi, xi, NaN]
|
||||
if z !== nothing
|
||||
@ -337,11 +315,7 @@ end
|
||||
end
|
||||
fillrange := nothing
|
||||
seriestype := :path
|
||||
if (
|
||||
plotattributes[:linecolor] == :auto &&
|
||||
plotattributes[:marker_z] !== nothing &&
|
||||
plotattributes[:line_z] === nothing
|
||||
)
|
||||
if plotattributes[:linecolor] == :auto && plotattributes[:marker_z] !== nothing && plotattributes[:line_z] === nothing
|
||||
line_z := plotattributes[:marker_z]
|
||||
end
|
||||
|
||||
@ -366,6 +340,7 @@ end
|
||||
|
||||
@specialize
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# bezier curves
|
||||
|
||||
@ -435,18 +410,17 @@ end
|
||||
|
||||
# create a bar plot as a filled step function
|
||||
@recipe function f(::Type{Val{:bar}}, x, y, z)
|
||||
procx, procy, xscale, yscale, baseline = _preprocess_barlike(plotattributes, x, y)
|
||||
procx, procy, xscale, yscale, baseline =
|
||||
_preprocess_barlike(plotattributes, x, y)
|
||||
nx, ny = length(procx), length(procy)
|
||||
axis = plotattributes[:subplot][isvertical(plotattributes) ? :xaxis : :yaxis]
|
||||
cv = [discrete_value!(plotattributes, :x, xi)[1] for xi in procx]
|
||||
cv = [discrete_value!(axis, xi)[1] for xi in procx]
|
||||
procx = if nx == ny
|
||||
cv
|
||||
elseif nx == ny + 1
|
||||
0.5 * diff(cv) + cv[1:(end - 1)]
|
||||
else
|
||||
error(
|
||||
"bar recipe: x must be same length as y (centers), or one more than y (edges).\n\t\tlength(x)=$(length(x)), length(y)=$(length(y))",
|
||||
)
|
||||
error("bar recipe: x must be same length as y (centers), or one more than y (edges).\n\t\tlength(x)=$(length(x)), length(y)=$(length(y))")
|
||||
end
|
||||
|
||||
# compute half-width of bars
|
||||
@ -470,8 +444,18 @@ 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 in 1:ny
|
||||
for i = 1:ny
|
||||
yi = procy[i]
|
||||
if !isnan(yi)
|
||||
center = procx[i]
|
||||
@ -495,42 +479,15 @@ end
|
||||
# switch back
|
||||
if !isvertical(plotattributes)
|
||||
xseg, yseg = yseg, xseg
|
||||
x, y = y, x
|
||||
end
|
||||
|
||||
|
||||
# reset orientation
|
||||
orientation := default(:orientation)
|
||||
|
||||
# draw the bar shapes
|
||||
@series begin
|
||||
seriestype := :shape
|
||||
series_annotations := nothing
|
||||
primary := true
|
||||
x := xseg.pts
|
||||
y := yseg.pts
|
||||
# expand attributes to match indices in new series data
|
||||
for k in _segmenting_vector_attributes ∪ _segmenting_array_attributes
|
||||
v = get(plotattributes, k, nothing)
|
||||
if v isa AVec
|
||||
if eachindex(v) != eachindex(y)
|
||||
@warn "Indices $(eachindex(v)) of attribute `$k` do not match data indices $(eachindex(y))."
|
||||
end
|
||||
# Each segment is 6 elements long, including the NaN separator.
|
||||
# There is no trailing NaN, so the last repetition is dropped.
|
||||
plotattributes[k] = @view repeat(v; inner = 6)[1:(end - 1)]
|
||||
end
|
||||
end
|
||||
()
|
||||
end
|
||||
|
||||
# add empty series
|
||||
primary := false
|
||||
seriestype := :scatter
|
||||
markersize := 0
|
||||
markeralpha := 0
|
||||
fillrange := nothing
|
||||
x := x
|
||||
y := y
|
||||
seriestype := :shape
|
||||
()
|
||||
end
|
||||
@deps bar shape
|
||||
@ -542,8 +499,8 @@ end
|
||||
m, n = size(z.surf)
|
||||
x_pts, y_pts = fill(NaN, 6 * m * n), fill(NaN, 6 * m * n)
|
||||
fz = zeros(m * n)
|
||||
for i in 1:m # y
|
||||
for j in 1:n # x
|
||||
for i = 1:m # y
|
||||
for j = 1:n # x
|
||||
k = (j - 1) * m + i
|
||||
inds = (6 * (k - 1) + 1):(6 * k - 1)
|
||||
x_pts[inds] .= [xe[j], xe[j + 1], xe[j + 1], xe[j], xe[j]]
|
||||
@ -590,6 +547,7 @@ function _scale_adjusted_values(
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function _binbarlike_baseline(min_value::T, scale::Symbol) where {T<:Real}
|
||||
if (scale in _logScales)
|
||||
!isnan(min_value) ? min_value / T(_logScaleBases[scale]^log10(2)) : T(1E-3)
|
||||
@ -598,6 +556,7 @@ function _binbarlike_baseline(min_value::T, scale::Symbol) where {T<:Real}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function _preprocess_binbarlike_weights(
|
||||
::Type{T},
|
||||
w,
|
||||
@ -626,10 +585,12 @@ function _preprocess_binlike(plotattributes, x, y)
|
||||
edge, weights, xscale, yscale, baseline
|
||||
end
|
||||
|
||||
|
||||
@nospecialize
|
||||
|
||||
@recipe function f(::Type{Val{:barbins}}, x, y, z)
|
||||
edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y)
|
||||
edge, weights, xscale, yscale, baseline =
|
||||
_preprocess_binlike(plotattributes, x, y)
|
||||
if (plotattributes[:bar_width] === nothing)
|
||||
bar_width := diff(edge)
|
||||
end
|
||||
@ -640,8 +601,10 @@ end
|
||||
end
|
||||
@deps barbins bar
|
||||
|
||||
|
||||
@recipe function f(::Type{Val{:scatterbins}}, x, y, z)
|
||||
edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y)
|
||||
edge, weights, xscale, yscale, baseline =
|
||||
_preprocess_binlike(plotattributes, x, y)
|
||||
@series begin
|
||||
x := _bin_centers(edge)
|
||||
xerror := diff(edge) / 2
|
||||
@ -658,7 +621,13 @@ end
|
||||
|
||||
@specialize
|
||||
|
||||
function _stepbins_path(edge, weights, baseline::Real, xscale::Symbol, yscale::Symbol)
|
||||
function _stepbins_path(
|
||||
edge,
|
||||
weights,
|
||||
baseline::Real,
|
||||
xscale::Symbol,
|
||||
yscale::Symbol,
|
||||
)
|
||||
log_scale_x = xscale in _logScales
|
||||
log_scale_y = yscale in _logScales
|
||||
|
||||
@ -720,9 +689,11 @@ end
|
||||
|
||||
@recipe function f(::Type{Val{:stepbins}}, x, y, z)
|
||||
@nospecialize
|
||||
axis = plotattributes[:subplot][Plots.isvertical(plotattributes) ? :xaxis : :yaxis]
|
||||
axis =
|
||||
plotattributes[:subplot][Plots.isvertical(plotattributes) ? :xaxis : :yaxis]
|
||||
|
||||
edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y)
|
||||
edge, weights, xscale, yscale, baseline =
|
||||
_preprocess_binlike(plotattributes, x, y)
|
||||
|
||||
xpts, ypts = _stepbins_path(edge, weights, baseline, xscale, yscale)
|
||||
if !isvertical(plotattributes)
|
||||
@ -774,9 +745,12 @@ function _auto_binning_nbins(
|
||||
|
||||
# The nd estimator is the key to most automatic binning methods, and is modified for twodimensional histograms to include correlation
|
||||
nd = n_samples^(1 / (2 + N))
|
||||
nd =
|
||||
N == 2 ?
|
||||
min(n_samples^(1 / (2 + N)), nd / (1 - cor(first(vs), last(vs))^2)^(3 // 8)) : nd # the >2-dimensional case does not have a nice solution to correlations
|
||||
nd = N == 2 ?
|
||||
min(
|
||||
n_samples^(1 / (2 + N)),
|
||||
nd / (1 - cor(first(vs), last(vs))^2)^(3 // 8),
|
||||
) :
|
||||
nd # the >2-dimensional case does not have a nice solution to correlations
|
||||
|
||||
v = vs[dim]
|
||||
|
||||
@ -795,7 +769,7 @@ function _auto_binning_nbins(
|
||||
elseif mode == :fd # Freedman–Diaconis rule
|
||||
_cl(_span(v) / (2 * _iqr(v) / nd))
|
||||
elseif mode == :wand
|
||||
wand_edges(v) # this makes this function not type stable, but the type instability does not propagate
|
||||
_cl(wand_edges(v)) # this makes this function not type stable, but the type instability does not propagate
|
||||
else
|
||||
error("Unknown auto-binning mode $mode")
|
||||
end
|
||||
@ -805,8 +779,11 @@ _hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) where {
|
||||
StatsBase.histrange(vs[dim], binning, :left)
|
||||
_hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) where {N} =
|
||||
_hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning))
|
||||
_hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) where {N} =
|
||||
binning
|
||||
_hist_edge(
|
||||
vs::NTuple{N,AbstractVector},
|
||||
dim::Integer,
|
||||
binning::AbstractVector,
|
||||
) where {N} = binning
|
||||
|
||||
_hist_edges(vs::NTuple{N,AbstractVector}, binning::NTuple{N,Any}) where {N} =
|
||||
map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...,))
|
||||
@ -898,6 +875,7 @@ end
|
||||
end
|
||||
@deps scatterhist scatterbins
|
||||
|
||||
|
||||
@recipe function f(h::StatsBase.Histogram{T,1,E}) where {T,E}
|
||||
seriestype --> :barbins
|
||||
|
||||
@ -907,7 +885,8 @@ end
|
||||
:step => :stepbins,
|
||||
:steppost => :stepbins, # :step can be mapped to :steppost in pre-processing
|
||||
)
|
||||
seriestype := get(st_map, plotattributes[:seriestype], plotattributes[:seriestype])
|
||||
seriestype :=
|
||||
get(st_map, plotattributes[:seriestype], plotattributes[:seriestype])
|
||||
|
||||
if plotattributes[:seriestype] == :scatterbins
|
||||
# Workaround, error bars currently not set correctly by scatterbins
|
||||
@ -921,6 +900,7 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@recipe function f(hv::AbstractVector{H}) where {H<:StatsBase.Histogram}
|
||||
for h in hv
|
||||
@series begin
|
||||
@ -929,6 +909,7 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Histogram 2D
|
||||
|
||||
@ -955,6 +936,7 @@ end
|
||||
end
|
||||
Plots.@deps bins2d heatmap
|
||||
|
||||
|
||||
@recipe function f(::Type{Val{:histogram2d}}, x, y, z)
|
||||
h = _make_hist(
|
||||
(x, y),
|
||||
@ -970,11 +952,13 @@ Plots.@deps bins2d heatmap
|
||||
end
|
||||
@deps histogram2d bins2d
|
||||
|
||||
|
||||
@recipe function f(h::StatsBase.Histogram{T,2,E}) where {T,E}
|
||||
seriestype --> :bins2d
|
||||
(h.edges[1], h.edges[2], Surface(h.weights))
|
||||
end
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# pie
|
||||
@recipe function f(::Type{Val{:pie}}, x, y, z)
|
||||
@ -996,6 +980,7 @@ end
|
||||
end
|
||||
@deps pie shape
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# mesh 3d replacement for non-plotly backends
|
||||
|
||||
@ -1003,15 +988,12 @@ end
|
||||
# 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.",
|
||||
),
|
||||
)
|
||||
throw(ArgumentError("Giving triangles using the connections argument is only supported on Plotly backend."))
|
||||
end
|
||||
()
|
||||
end
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# scatter 3d
|
||||
|
||||
@ -1037,45 +1019,36 @@ export lens!
|
||||
throw(ArgumentError("Inset bounding box needs to in relative coordinates."))
|
||||
end
|
||||
sp = plt.subplots[sp_index]
|
||||
xscale = sp[:xaxis][:scale]
|
||||
yscale = sp[:yaxis][:scale]
|
||||
xl1, xl2 = xlims(sp)
|
||||
xl1, xl2 = xlims(plt.subplots[sp_index])
|
||||
bbx1 = xl1 + left(inset_bbox).value * (xl2 - xl1)
|
||||
bbx2 = bbx1 + width(inset_bbox).value * (xl2 - xl1)
|
||||
yl1, yl2 = ylims(sp)
|
||||
yl1, yl2 = ylims(plt.subplots[sp_index])
|
||||
bby1 = yl1 + (1 - bottom(inset_bbox).value) * (yl2 - yl1)
|
||||
bby2 = bby1 + height(inset_bbox).value * (yl2 - yl1)
|
||||
bbx = bbx1 + width(inset_bbox).value * (xl2 - xl1) / 2 * (sp[:xaxis][:flip] ? -1 : 1)
|
||||
bby = bby1 + height(inset_bbox).value * (yl2 - yl1) / 2 * (sp[:yaxis][:flip] ? -1 : 1)
|
||||
bbx = bbx1 + width(inset_bbox).value * (xl2 - xl1) / 2
|
||||
bby = bby1 + height(inset_bbox).value * (yl2 - yl1) / 2
|
||||
lens_index = last(plt.subplots)[:subplot_index] + 1
|
||||
x1, x2 = RecipesPipeline.inverse_scale_func(xscale).(plotattributes[:x])
|
||||
y1, y2 = RecipesPipeline.inverse_scale_func(yscale).(plotattributes[:y])
|
||||
x1, x2 = plotattributes[:x]
|
||||
y1, y2 = plotattributes[:y]
|
||||
backup = copy(plotattributes)
|
||||
empty!(plotattributes)
|
||||
|
||||
series_plotindex := backup[:series_plotindex]
|
||||
seriestype := :path
|
||||
primary := false
|
||||
linecolor := get(backup, :linecolor, :lightgray)
|
||||
if haskey(backup, :linestyle)
|
||||
linestyle := backup[:linestyle]
|
||||
end
|
||||
if haskey(backup, :linewidth)
|
||||
linewidth := backup[:linewidth]
|
||||
end
|
||||
linecolor := :lightgray
|
||||
bbx_mag = (x1 + x2) / 2
|
||||
bby_mag = (y1 + y2) / 2
|
||||
xi_lens, yi_lens =
|
||||
intersection_point(bbx_mag, bby_mag, bbx, bby, abs(bby2 - bby1), abs(bbx2 - bbx1))
|
||||
xi_mag, yi_mag =
|
||||
intersection_point(bbx, bby, bbx_mag, bby_mag, abs(y2 - y1), abs(x2 - x1))
|
||||
xi_lens, yi_lens = intersection_point(bbx_mag, bby_mag, bbx, bby, abs(bby2 - bby1), abs(bbx2 - bbx1))
|
||||
xi_mag, yi_mag = intersection_point(bbx, bby, bbx_mag, bby_mag, abs(y2 - y1), abs(x2 - x1))
|
||||
# add lines
|
||||
if xl1 < xi_lens < xl2 && yl1 < yi_lens < yl2
|
||||
if xl1 < xi_lens < xl2 &&
|
||||
yl1 < yi_lens < yl2
|
||||
@series begin
|
||||
primary := false
|
||||
subplot := sp_index
|
||||
x := RecipesPipeline.scale_func(xscale).([xi_mag, xi_lens])
|
||||
y := RecipesPipeline.scale_func(yscale).([yi_mag, yi_lens])
|
||||
x := [xi_mag, xi_lens]
|
||||
y := [yi_mag, yi_lens]
|
||||
()
|
||||
end
|
||||
end
|
||||
@ -1083,8 +1056,8 @@ export lens!
|
||||
@series begin
|
||||
primary := false
|
||||
subplot := sp_index
|
||||
x := RecipesPipeline.scale_func(xscale).([x1, x1, x2, x2, x1])
|
||||
y := RecipesPipeline.scale_func(yscale).([y1, y2, y2, y1, y1])
|
||||
x := [x1, x1, x2, x2, x1]
|
||||
y := [y1, y2, y2, y1, y1]
|
||||
()
|
||||
end
|
||||
# add subplot
|
||||
@ -1093,8 +1066,8 @@ export lens!
|
||||
plotattributes = merge(backup, copy(series.plotattributes))
|
||||
subplot := lens_index
|
||||
primary := false
|
||||
xlims := RecipesPipeline.scale_func(xscale).((x1, x2))
|
||||
ylims := RecipesPipeline.scale_func(yscale).((y1, y2))
|
||||
xlims := (x1, x2)
|
||||
ylims := (y1, y2)
|
||||
()
|
||||
end
|
||||
end
|
||||
@ -1140,13 +1113,6 @@ end
|
||||
# Error Bars
|
||||
|
||||
function error_style!(plotattributes::AKW)
|
||||
# errorbar color should soley determined by markerstrokecolor
|
||||
if haskey(plotattributes, :marker_z)
|
||||
reset_kw!(plotattributes, :marker_z)
|
||||
end
|
||||
if haskey(plotattributes, :line_z)
|
||||
reset_kw!(plotattributes, :line_z)
|
||||
end
|
||||
msc = plotattributes[:markerstrokecolor]
|
||||
msc = if msc === :match
|
||||
plotattributes[:subplot][:foreground_color_subplot]
|
||||
@ -1277,7 +1243,7 @@ function quiver_using_arrows(plotattributes::AKW)
|
||||
# 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 in 1:max(length(xorig), length(yorig), is_3d ? 0 : length(zorig))
|
||||
for i = 1:max(length(xorig), length(yorig), is_3d ? 0 : length(zorig))
|
||||
# get the starting position
|
||||
xi = _cycle(xorig, i)
|
||||
yi = _cycle(yorig, i)
|
||||
@ -1327,7 +1293,7 @@ function quiver_using_hack(plotattributes::AKW)
|
||||
|
||||
# for each point, we create an arrow of velocity vi, translated to the x/y coordinates
|
||||
pts = P2[]
|
||||
for i in 1:max(length(xorig), length(yorig))
|
||||
for i = 1:max(length(xorig), length(yorig))
|
||||
|
||||
# get the starting position
|
||||
xi = _cycle(xorig, i)
|
||||
@ -1356,7 +1322,10 @@ function quiver_using_hack(plotattributes::AKW)
|
||||
U2 *= arrow_w
|
||||
|
||||
ppv = p + v
|
||||
nanappend!(pts, P2[p, ppv - U1, ppv - U1 + U2, ppv, ppv - U1 - U2, ppv - U1])
|
||||
nanappend!(
|
||||
pts,
|
||||
P2[p, ppv - U1, ppv - U1 + U2, ppv, ppv - U1 - U2, ppv - U1],
|
||||
)
|
||||
end
|
||||
|
||||
plotattributes[:x], plotattributes[:y] = RecipesPipeline.unzip(pts[2:end])
|
||||
@ -1375,6 +1344,7 @@ end
|
||||
end
|
||||
@deps quiver shape path
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# 1 argument
|
||||
# --------------------------------------------------------------------
|
||||
@ -1389,8 +1359,7 @@ function clamp_greys!(mat::AMat{<:Gray})
|
||||
end
|
||||
|
||||
@recipe function f(mat::AMat{<:Gray})
|
||||
n, m = map(a -> range(0.5, stop = a.stop + 0.5), axes(mat))
|
||||
|
||||
n, m = axes(mat)
|
||||
if is_seriestype_supported(:image)
|
||||
seriestype := :image
|
||||
yflip --> true
|
||||
@ -1408,7 +1377,7 @@ end
|
||||
|
||||
# images - colors
|
||||
@recipe function f(mat::AMat{T}) where {T <: Colorant}
|
||||
n, m = map(a -> range(0.5, stop = a.stop + 0.5), axes(mat))
|
||||
n, m = axes(mat)
|
||||
|
||||
if is_seriestype_supported(:image)
|
||||
seriestype := :image
|
||||
@ -1431,7 +1400,7 @@ 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
|
||||
@ -1446,13 +1415,14 @@ 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]))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# 3 arguments
|
||||
# --------------------------------------------------------------------
|
||||
@ -1551,7 +1521,8 @@ end
|
||||
@recipe f(
|
||||
x::AVec,
|
||||
ohlc::AVec{Tuple{R1,R2,R3,R4}},
|
||||
) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = x, OHLC[OHLC(t...) for t in ohlc]
|
||||
) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} =
|
||||
x, OHLC[OHLC(t...) for t in ohlc]
|
||||
|
||||
@recipe function f(x::AVec, v::AVec{OHLC})
|
||||
seriestype := :path
|
||||
@ -1570,6 +1541,7 @@ end
|
||||
# TODO: everything below here should be either changed to a
|
||||
# series recipe or moved to PlotRecipes
|
||||
|
||||
|
||||
# "Sparsity plot... heatmap of non-zero values of a matrix"
|
||||
# function spy{T<:Real}(z::AMat{T}; kw...)
|
||||
# mat = reshape(map(zi->float(zi!=0), z),1,:)
|
||||
@ -1617,6 +1589,7 @@ end
|
||||
|
||||
@specialize
|
||||
|
||||
|
||||
Plots.findnz(A::AbstractSparseMatrix) = SparseArrays.findnz(A)
|
||||
|
||||
# fallback function for finding non-zero elements of non-sparse matrices
|
||||
@ -1632,6 +1605,7 @@ 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...)
|
||||
|
||||
@ -1655,6 +1629,7 @@ end
|
||||
x, real.(y), imag.(y)
|
||||
end
|
||||
|
||||
|
||||
# Moved in from PlotRecipes - see: http://stackoverflow.com/a/37732384/5075246
|
||||
@userplot PortfolioComposition
|
||||
|
||||
@ -1676,6 +1651,16 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
areaplot([x,] y)
|
||||
areaplot!([x,] y)
|
||||
|
||||
Draw a stacked area plot of the matrix y.
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], fillalpha = [0.2 0.3 0.4])
|
||||
```
|
||||
"""
|
||||
@userplot AreaPlot
|
||||
|
||||
@recipe function f(a::AreaPlot)
|
||||
|
||||
@ -241,6 +241,7 @@ julia> ohlc(y)
|
||||
"""
|
||||
@shorthands ohlc
|
||||
|
||||
|
||||
"""
|
||||
contour(x,y,z)
|
||||
contour!(x,y,z)
|
||||
@ -262,6 +263,7 @@ julia> contour(x, y, (x, y) -> x^2 + y^2)
|
||||
"An alias for `contour` with fill = true."
|
||||
@shorthands contourf
|
||||
|
||||
|
||||
@shorthands contour3d
|
||||
|
||||
"""
|
||||
@ -348,10 +350,10 @@ Make a box and whisker plot.
|
||||
|
||||
# Keyword arguments
|
||||
- `notch`: Bool. Notch the box plot? (false)
|
||||
- `whisker_range`: Real. Whiskers extend `whisker_range`*IQR below the first quartile
|
||||
and above the third quartile. Values outside this range are shown as outliers (1.5)
|
||||
- `range`: Real. Values more than range*IQR below the first quartile
|
||||
or above the third quartile are shown as outliers (1.5)
|
||||
- `outliers`: Bool. Show outliers? (true)
|
||||
- `whisker_width`: Real or Symbol. Length of whiskers; the options are `:match` to match the box width, `:half`, or a number to indicate the total length. (:half)
|
||||
- `whisker_width`: Real or Symbol. Length of whiskers (:match)
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
@ -431,16 +433,17 @@ xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin, xmax), kw...)
|
||||
ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...)
|
||||
zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmin,zmax), kw...)
|
||||
|
||||
|
||||
"Set xticks for an existing plot"
|
||||
xticks!(v::TicksArgs; kw...) = plot!(; xticks = v, kw...)
|
||||
|
||||
"Set yticks for an existing plot"
|
||||
yticks!(v::TicksArgs; kw...) = plot!(; yticks = v, kw...)
|
||||
|
||||
xticks!(ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} =
|
||||
plot!(; xticks = (ticks, labels), kw...)
|
||||
yticks!(ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} =
|
||||
plot!(; yticks = (ticks, labels), kw...)
|
||||
xticks!(
|
||||
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...)
|
||||
yticks!(
|
||||
ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; yticks = (ticks,labels), kw...)
|
||||
|
||||
"""
|
||||
annotate!(anns...)
|
||||
@ -450,14 +453,12 @@ Add annotations to an existing plot.
|
||||
# Arguments
|
||||
|
||||
- `anns`: An `AbstractVector` of tuples of the form `(x,y,text)`. The `text` object
|
||||
can be a `String`, `PlotText` PlotText (created with `text(args...)`),
|
||||
or a tuple of arguments to `text` (e.g., `("Label", 8, :red, :top)`).
|
||||
can be a `String` or `PlotText`.
|
||||
|
||||
# Example
|
||||
```julia-repl
|
||||
julia> plot(1:10)
|
||||
julia> annotate!([(7,3,"(7,3)"),(3,7,text("hey", 14, :left, :top, :green))])
|
||||
julia> annotate!([(4, 4, ("More text", 8, 45.0, :bottom, :red))])
|
||||
```
|
||||
"""
|
||||
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
|
||||
@ -472,33 +473,10 @@ yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...)
|
||||
|
||||
"Specify x axis attributes for an existing plot"
|
||||
xaxis!(args...; kw...) = plot!(; xaxis = args, kw...)
|
||||
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
|
||||
|
||||
"Specify y axis attributes for an existing plot"
|
||||
yaxis!(args...; kw...) = plot!(; yaxis = args, kw...)
|
||||
xgrid!(args...; kw...) = plot!(; xgrid = args, kw...)
|
||||
ygrid!(args...; kw...) = plot!(; ygrid = args, kw...)
|
||||
|
||||
@doc """
|
||||
abline!([plot,] a, b; kwargs...)
|
||||
|
||||
Adds ax+b... straight line over the current plot, without changing the axis limits
|
||||
""" abline!
|
||||
|
||||
@doc """
|
||||
areaplot([x,] y)
|
||||
areaplot!([x,] y)
|
||||
|
||||
Draw a stacked area plot of the matrix y.
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], fillalpha = [0.2 0.3 0.4])
|
||||
```
|
||||
""" areaplot
|
||||
|
||||
@doc """
|
||||
lens!([plot,] x, y, inset = (sp_index, bbox(x1, x2, y1, y2)))
|
||||
|
||||
Magnify a region of a plot given by `x` and `y`.
|
||||
`sp_index` is the index of the subplot and `x1`, `x2`, `y1` and `y2` should be between `0` and `1`.
|
||||
""" lens!
|
||||
@specialize
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
|
||||
function Subplot(::T; parent = RootLayout()) where {T<:AbstractBackend}
|
||||
|
||||
function Subplot(::T; parent = RootLayout()) where T<:AbstractBackend
|
||||
Subplot{T}(
|
||||
parent,
|
||||
Series[],
|
||||
@ -8,7 +9,7 @@ function Subplot(::T; parent = RootLayout()) where {T<:AbstractBackend}
|
||||
defaultbox,
|
||||
DefaultsDict(KW(), _subplot_defaults),
|
||||
nothing,
|
||||
nothing,
|
||||
nothing
|
||||
)
|
||||
end
|
||||
|
||||
@ -20,6 +21,7 @@ Return the bounding box of a subplot
|
||||
plotarea(sp::Subplot) = sp.plotarea
|
||||
plotarea!(sp::Subplot, bbox::BoundingBox) = (sp.plotarea = bbox)
|
||||
|
||||
|
||||
Base.size(sp::Subplot) = (1,1)
|
||||
Base.length(sp::Subplot) = 1
|
||||
Base.getindex(sp::Subplot, r::Int, c::Int) = sp
|
||||
|
||||
@ -34,8 +34,11 @@ end
|
||||
|
||||
@userplot ShowTheme
|
||||
|
||||
_color_functions =
|
||||
KW(:protanopic => protanopic, :deuteranopic => deuteranopic, :tritanopic => tritanopic)
|
||||
_color_functions = KW(
|
||||
:protanopic => protanopic,
|
||||
:deuteranopic => deuteranopic,
|
||||
:tritanopic => tritanopic,
|
||||
)
|
||||
_get_showtheme_args(thm::Symbol) = thm, identity
|
||||
_get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func, identity)
|
||||
|
||||
@ -107,8 +110,8 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
|
||||
subplot := 4
|
||||
seriestype := :heatmap
|
||||
seriescolor := colorgradient
|
||||
xticks := ((-2π):(2π):(2π), string.(-2:2:2, "π"))
|
||||
yticks := ((-2π):(2π):(2π), string.(-2:2:2, "π"))
|
||||
xticks := (-2π:2π:2π, string.(-2:2:2, "π"))
|
||||
yticks := (-2π:2π:2π, string.(-2:2:2, "π"))
|
||||
x, y, z
|
||||
end
|
||||
|
||||
@ -116,8 +119,8 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
|
||||
subplot := 5
|
||||
seriestype := :surface
|
||||
seriescolor := colorgradient
|
||||
xticks := ((-2π):(2π):(2π), string.(-2:2:2, "π"))
|
||||
yticks := ((-2π):(2π):(2π), string.(-2:2:2, "π"))
|
||||
xticks := (-2π:2π:2π, string.(-2:2:2, "π"))
|
||||
yticks := (-2π:2π:2π, string.(-2:2:2, "π"))
|
||||
x, y, z
|
||||
end
|
||||
|
||||
@ -134,4 +137,5 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
|
||||
line_z := z
|
||||
x, y, z
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
19
src/types.jl
19
src/types.jl
@ -6,8 +6,7 @@ const AVec = AbstractVector
|
||||
const AMat = AbstractMatrix
|
||||
const KW = Dict{Symbol,Any}
|
||||
const AKW = AbstractDict{Symbol,Any}
|
||||
const TicksArgs =
|
||||
Union{AVec{T},Tuple{AVec{T},AVec{S}},Symbol} where {T<:Real,S<:AbstractString}
|
||||
const TicksArgs = Union{AVec{T}, Tuple{AVec{T}, AVec{S}}, Symbol} where {T<:Real, S<:AbstractString}
|
||||
|
||||
struct PlotsDisplay <: AbstractDisplay end
|
||||
|
||||
@ -64,6 +63,7 @@ const SubplotMap = Dict{Any,Subplot}
|
||||
|
||||
# -----------------------------------------------------------
|
||||
|
||||
|
||||
mutable struct Plot{T<:AbstractBackend} <: AbstractPlot{T}
|
||||
backend::T # the backend type
|
||||
n::Int # number of series
|
||||
@ -78,18 +78,9 @@ mutable struct Plot{T<:AbstractBackend} <: AbstractPlot{T}
|
||||
end
|
||||
|
||||
function Plot()
|
||||
Plot(
|
||||
backend(),
|
||||
0,
|
||||
DefaultsDict(KW(), _plot_defaults),
|
||||
Series[],
|
||||
nothing,
|
||||
Subplot[],
|
||||
SubplotMap(),
|
||||
EmptyLayout(),
|
||||
Subplot[],
|
||||
false,
|
||||
)
|
||||
Plot(backend(), 0, DefaultsDict(KW(), _plot_defaults), Series[], nothing,
|
||||
Subplot[], SubplotMap(), EmptyLayout(),
|
||||
Subplot[], false)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
470
src/utils.jl
470
src/utils.jl
@ -1,12 +1,10 @@
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
treats_y_as_x(seriestype) =
|
||||
seriestype in (:vline, :vspan, :histogram, :barhist, :stephist, :scatterhist)
|
||||
|
||||
function replace_image_with_heatmap(z::Array{T}) where {T<:Colorant}
|
||||
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)
|
||||
newz = reshape(1:n*m, n, m)
|
||||
newz, colors
|
||||
end
|
||||
|
||||
@ -23,6 +21,7 @@ Segments() = Segments(Float64)
|
||||
Segments(::Type{T}) where {T} = Segments(T[])
|
||||
Segments(p::Int) = Segments(NTuple{p, Float64}[])
|
||||
|
||||
|
||||
# Segments() = Segments(zeros(0))
|
||||
|
||||
to_nan(::Type{Float64}) = NaN
|
||||
@ -30,13 +29,10 @@ to_nan(::Type{NTuple{2,Float64}}) = (NaN, NaN)
|
||||
to_nan(::Type{NTuple{3,Float64}}) = (NaN, NaN, NaN)
|
||||
|
||||
coords(segs::Segments{Float64}) = segs.pts
|
||||
coords(segs::Segments{NTuple{2,Float64}}) =
|
||||
Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts]
|
||||
coords(segs::Segments{NTuple{3,Float64}}) = Float64[p[1] for p in segs.pts],
|
||||
Float64[p[2] for p in segs.pts],
|
||||
Float64[p[3] for p in segs.pts]
|
||||
coords(segs::Segments{NTuple{2,Float64}}) = Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts]
|
||||
coords(segs::Segments{NTuple{3,Float64}}) = Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts], Float64[p[3] for p in segs.pts]
|
||||
|
||||
function Base.push!(segments::Segments{T}, vs...) where {T}
|
||||
function Base.push!(segments::Segments{T}, vs...) where T
|
||||
if !isempty(segments.pts)
|
||||
push!(segments.pts, to_nan(T))
|
||||
end
|
||||
@ -46,7 +42,7 @@ function Base.push!(segments::Segments{T}, vs...) where {T}
|
||||
segments
|
||||
end
|
||||
|
||||
function Base.push!(segments::Segments{T}, vs::AVec) where {T}
|
||||
function Base.push!(segments::Segments{T}, vs::AVec) where T
|
||||
if !isempty(segments.pts)
|
||||
push!(segments.pts, to_nan(T))
|
||||
end
|
||||
@ -56,6 +52,7 @@ function Base.push!(segments::Segments{T}, vs::AVec) where {T}
|
||||
segments
|
||||
end
|
||||
|
||||
|
||||
struct SeriesSegment
|
||||
# indexes of this segement in series data vectors
|
||||
range::UnitRange
|
||||
@ -78,54 +75,27 @@ function iter_segments(args...)
|
||||
NaNSegmentsIterator(tup, n1, n2)
|
||||
end
|
||||
|
||||
function series_segments(series::Series, seriestype::Symbol = :path; check = false)
|
||||
function series_segments(series::Series, seriestype::Symbol = :path)
|
||||
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...))
|
||||
|
||||
if check
|
||||
scales = :xscale, :yscale, :zscale
|
||||
for (n, s) in enumerate(args)
|
||||
scale = get(series, scales[n], :identity)
|
||||
if scale ∈ _logScales
|
||||
for (i, v) in enumerate(s)
|
||||
if v <= 0
|
||||
@warn "Invalid negative or zero value $v found at series index $i for $(scale) based $(scales[n])"
|
||||
@debug "" exception = (DomainError(v), stacktrace())
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
segments = if has_attribute_segments(series)
|
||||
result = if has_attribute_segments(series)
|
||||
Iterators.flatten(map(nan_segments) do r
|
||||
if seriestype == :shape
|
||||
warn_on_inconsistent_shape_attr(series, x, y, z, r)
|
||||
(SeriesSegment(r, first(r)),)
|
||||
elseif seriestype in (:scatter, :scatter3d)
|
||||
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))
|
||||
(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),
|
||||
)
|
||||
seg_range = UnitRange(minimum(first(seg.range) for seg in result),
|
||||
maximum(last(seg.range) for seg in result))
|
||||
for attr in _segmenting_vector_attributes
|
||||
v = get(series, attr, nothing)
|
||||
if v isa AVec && eachindex(v) != seg_range
|
||||
@ -141,37 +111,25 @@ function warn_on_attr_dim_mismatch(series, x, y, z, segments)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function warn_on_inconsistent_shape_attr(series, x, y, z, r)
|
||||
for attr in _segmenting_vector_attributes
|
||||
v = get(series, attr, nothing)
|
||||
if v isa AVec && length(unique(v[r])) > 1
|
||||
@warn "Different values of `$attr` specified for different shape vertices. Only first one will be used."
|
||||
break
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
# helpers to figure out if there are NaN values in a list of array types
|
||||
anynan(i::Int, args::Tuple) = any(a -> try
|
||||
isnan(_cycle(a, i))
|
||||
catch MethodError
|
||||
false
|
||||
end, args)
|
||||
anynan(i::Int, args::Tuple) = any(a -> try isnan(_cycle(a,i)) catch MethodError false end, args)
|
||||
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)
|
||||
i = findfirst(!anynan(itr.args), nextidx:(itr.n2))
|
||||
i === nothing && return
|
||||
i = findfirst(!anynan(itr.args), nextidx:itr.n2)
|
||||
i === nothing && return nothing
|
||||
nextval = nextidx + i - 1
|
||||
|
||||
j = findfirst(anynan(itr.args), nextval:(itr.n2))
|
||||
j = findfirst(anynan(itr.args), nextval:itr.n2)
|
||||
nextnan = j === nothing ? itr.n2 + 1 : nextval + j - 1
|
||||
|
||||
nextval:(nextnan - 1), nextnan
|
||||
nextval:nextnan-1, nextnan
|
||||
end
|
||||
Base.IteratorSize(::NaNSegmentsIterator) = Base.SizeUnknown()
|
||||
|
||||
@ -183,6 +141,7 @@ float_extended_type(x::AbstractArray{T}) where {T<:Real} = Float64
|
||||
|
||||
# ------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
nop() = nothing
|
||||
notimpl() = error("This has not been implemented yet")
|
||||
|
||||
@ -215,12 +174,20 @@ makevec(v::T) where {T} = T[v]
|
||||
maketuple(x::Real) = (x,x)
|
||||
maketuple(x::Tuple{T,S}) where {T,S} = x
|
||||
|
||||
RecipesPipeline.unzip(v) = unzip(v)
|
||||
RecipesPipeline.unzip(points::AbstractVector{<:GeometryBasics.Point}) =
|
||||
unzip(Tuple.(points))
|
||||
RecipesPipeline.unzip(points::AbstractVector{GeometryBasics.Point{N,T}}) where {N,T} =
|
||||
isbitstype(T) && sizeof(T) > 0 ? unzip(reinterpret(NTuple{N,T}, points)) :
|
||||
unzip(Tuple.(points))
|
||||
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)...))
|
||||
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."
|
||||
)
|
||||
|
||||
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
|
||||
function _expand_limits(lims, x)
|
||||
@ -233,7 +200,7 @@ function _expand_limits(lims, x)
|
||||
nothing
|
||||
end
|
||||
|
||||
expand_data(v, n::Integer) = [_cycle(v, i) for i in 1:n]
|
||||
expand_data(v, n::Integer) = [_cycle(v, i) for i=1:n]
|
||||
|
||||
# if the type exists in a list, replace the first occurence. otherwise add it to the end
|
||||
function addOrReplace(v::AbstractVector, t::DataType, args...; kw...)
|
||||
@ -267,40 +234,27 @@ end
|
||||
|
||||
createSegments(z) = collect(repeat(reshape(z,1,:),2,1))[2:end]
|
||||
|
||||
|
||||
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]
|
||||
if isedges
|
||||
return v
|
||||
end
|
||||
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_max = (v[end] - v[end - 1]) / 2
|
||||
vcat(vmin - extra_min, 0.5 * (v[1:(end - 1)] + v[2:end]), vmax + extra_max)
|
||||
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, ispolar::Bool = false)
|
||||
f, invf = RecipesPipeline.scale_func(scale), RecipesPipeline.inverse_scale_func(scale)
|
||||
map(invf, _heatmap_edges(map(f,v), isedges, ispolar))
|
||||
end
|
||||
|
||||
function heatmap_edges(
|
||||
x::AVec,
|
||||
xscale::Symbol,
|
||||
y::AVec,
|
||||
yscale::Symbol,
|
||||
z_size::Tuple{Int,Int},
|
||||
ispolar::Bool = false,
|
||||
)
|
||||
function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size::Tuple{Int, Int}, ispolar::Bool = false)
|
||||
nx, ny = length(x), length(y)
|
||||
# ismidpoints = z_size == (ny, nx) # This fails some tests, but would actually be
|
||||
# the correct check, since (4, 3) != (3, 4) and a missleading plot is produced.
|
||||
@ -311,7 +265,8 @@ function heatmap_edges(
|
||||
Must be either `size(z) == (length(y), length(x))` (x & y define midpoints)
|
||||
or `size(z) == (length(y)+1, length(x)+1))` (x & y define edges).""")
|
||||
end
|
||||
x, y = heatmap_edges(x, xscale, isedges), heatmap_edges(y, yscale, isedges, ispolar) # special handle for `r` in polar plots
|
||||
x, y = heatmap_edges(x, xscale, isedges),
|
||||
heatmap_edges(y, yscale, isedges, ispolar) # special handle for `r` in polar plots
|
||||
return x, y
|
||||
end
|
||||
|
||||
@ -328,12 +283,10 @@ function convert_to_polar(theta, r, r_extrema = ignorenan_extrema(r))
|
||||
x, y
|
||||
end
|
||||
|
||||
fakedata(sz::Int...) = fakedata(Random.seed!(PLOTS_SEED), sz...)
|
||||
|
||||
function fakedata(rng::AbstractRNG, sz...)
|
||||
function fakedata(sz...)
|
||||
y = zeros(sz...)
|
||||
for r in 2:size(y,1)
|
||||
y[r, :] = 0.95 * vec(y[r - 1, :]) + randn(rng, size(y, 2))
|
||||
y[r,:] = 0.95 * vec(y[r-1,:]) + randn(size(y,2))
|
||||
end
|
||||
y
|
||||
end
|
||||
@ -352,20 +305,21 @@ isscalar(::Any) = false
|
||||
|
||||
is_2tuple(v) = typeof(v) <: Tuple && length(v) == 2
|
||||
|
||||
isvertical(plotattributes::AKW) =
|
||||
get(plotattributes, :orientation, :vertical) in (:vertical, :v, :vert)
|
||||
|
||||
isvertical(plotattributes::AKW) = get(plotattributes, :orientation, :vertical) in (:vertical, :v, :vert)
|
||||
isvertical(series::Series) = isvertical(series.plotattributes)
|
||||
|
||||
|
||||
ticksType(ticks::AVec{T}) where {T<:Real} = :ticks
|
||||
ticksType(ticks::AVec{T}) where {T<:AbstractString} = :labels
|
||||
ticksType(ticks::Tuple{T,S}) where {T<:Union{AVec,Tuple},S<:Union{AVec,Tuple}} =
|
||||
:ticks_and_labels
|
||||
ticksType(ticks::Tuple{T,S}) where {T<:Union{AVec,Tuple},S<:Union{AVec,Tuple}} = :ticks_and_labels
|
||||
ticksType(ticks) = :invalid
|
||||
|
||||
limsType(lims::Tuple{T,S}) where {T<:Real,S<:Real} = :limits
|
||||
limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
|
||||
limsType(lims) = :invalid
|
||||
|
||||
|
||||
# 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)
|
||||
@ -377,14 +331,15 @@ nanappend!(a::AbstractVector, b) = (push!(a, NaN); append!(a, b))
|
||||
function nansplit(v::AVec)
|
||||
vs = Vector{eltype(v)}[]
|
||||
while true
|
||||
if (idx = findfirst(isnan, v)) === nothing
|
||||
idx = findfirst(isnan, v)
|
||||
if idx <= 0
|
||||
# no nans
|
||||
push!(vs, v)
|
||||
break
|
||||
elseif idx > 1
|
||||
push!(vs, v[1:(idx - 1)])
|
||||
push!(vs, v[1:idx-1])
|
||||
end
|
||||
v = v[(idx + 1):end]
|
||||
v = v[idx+1:end]
|
||||
end
|
||||
vs
|
||||
end
|
||||
@ -409,7 +364,9 @@ end
|
||||
handle_surface(z) = z
|
||||
handle_surface(z::Surface) = permutedims(z.surf)
|
||||
|
||||
ok(x::Number, y::Number, z::Number = 0) = isfinite(x) && isfinite(y) && isfinite(z)
|
||||
function ok(x::Number, y::Number, z::Number = 0)
|
||||
isfinite(x) && isfinite(y) && isfinite(z)
|
||||
end
|
||||
ok(tup::Tuple) = ok(tup...)
|
||||
|
||||
# compute one side of a fill range from a ribbon
|
||||
@ -433,13 +390,15 @@ end
|
||||
|
||||
#turn tuple of fillranges to one path
|
||||
function concatenate_fillrange(x,y::Tuple)
|
||||
rib1, rib2 = collect(first(y)), collect(last(y)) # collect needed until https://github.com/JuliaLang/julia/pull/37629 is merged
|
||||
yline = vcat(rib1, reverse(rib2))
|
||||
xline = vcat(x, reverse(x))
|
||||
rib1, rib2 = first(y), last(y)
|
||||
yline = vcat(rib1,(rib2)[end:-1:1])
|
||||
xline = vcat(x,x[end:-1:1])
|
||||
return xline, yline
|
||||
end
|
||||
|
||||
get_sp_lims(sp::Subplot, letter::Symbol) = axis_limits(sp, letter)
|
||||
function get_sp_lims(sp::Subplot, letter::Symbol)
|
||||
axis_limits(sp, letter)
|
||||
end
|
||||
|
||||
"""
|
||||
xlims([plt])
|
||||
@ -479,13 +438,16 @@ function contour_levels(series::Series, clims)
|
||||
if levels isa Integer
|
||||
levels = range(zmin, stop=zmax, length=levels+2)
|
||||
if !isfilledcontour(series)
|
||||
levels = levels[2:(end - 1)]
|
||||
levels = levels[2:end-1]
|
||||
end
|
||||
end
|
||||
levels
|
||||
end
|
||||
|
||||
|
||||
|
||||
for comp in (:line, :fill, :marker)
|
||||
|
||||
compcolor = string(comp, :color)
|
||||
get_compcolor = Symbol(:get_, compcolor)
|
||||
comp_z = string(comp, :_z)
|
||||
@ -494,6 +456,7 @@ for comp in (:line, :fill, :marker)
|
||||
get_compalpha = Symbol(:get_, compalpha)
|
||||
|
||||
@eval begin
|
||||
|
||||
function $get_compcolor(series, cmin::Real, cmax::Real, i::Int = 1)
|
||||
c = series[$Symbol($compcolor)]
|
||||
z = series[$Symbol($comp_z)]
|
||||
@ -504,8 +467,7 @@ for comp in (:line, :fill, :marker)
|
||||
end
|
||||
end
|
||||
|
||||
$get_compcolor(series, clims::Tuple{<:Number,<:Number}, i::Int = 1) =
|
||||
$get_compcolor(series, clims[1], clims[2], i)
|
||||
$get_compcolor(series, clims, i::Int = 1) = $get_compcolor(series, clims[1], clims[2], i)
|
||||
|
||||
function $get_compcolor(series, i::Int = 1)
|
||||
if series[$Symbol($comp_z)] === nothing
|
||||
@ -541,17 +503,26 @@ get_gradient(c) = cgrad()
|
||||
get_gradient(cg::ColorGradient) = cg
|
||||
get_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
|
||||
|
||||
get_linewidth(series, i::Int = 1) = _cycle(series[:linewidth], i)
|
||||
get_linestyle(series, i::Int = 1) = _cycle(series[:linestyle], i)
|
||||
get_fillstyle(series, i::Int = 1) = _cycle(series[:fillstyle], i)
|
||||
function get_linewidth(series, i::Int = 1)
|
||||
_cycle(series[:linewidth], i)
|
||||
end
|
||||
|
||||
function get_linestyle(series, i::Int = 1)
|
||||
_cycle(series[:linestyle], i)
|
||||
end
|
||||
|
||||
function get_markerstrokecolor(series, i::Int = 1)
|
||||
msc = series[:markerstrokecolor]
|
||||
isa(msc, ColorGradient) ? msc : _cycle(msc, i)
|
||||
end
|
||||
|
||||
get_markerstrokealpha(series, i::Int = 1) = _cycle(series[:markerstrokealpha], i)
|
||||
get_markerstrokewidth(series, i::Int = 1) = _cycle(series[:markerstrokewidth], i)
|
||||
function get_markerstrokealpha(series, i::Int = 1)
|
||||
_cycle(series[:markerstrokealpha], i)
|
||||
end
|
||||
|
||||
function get_markerstrokewidth(series, i::Int = 1)
|
||||
_cycle(series[:markerstrokewidth], i)
|
||||
end
|
||||
|
||||
const _segmenting_vector_attributes = (
|
||||
:seriescolor,
|
||||
@ -562,7 +533,6 @@ const _segmenting_vector_attributes = (
|
||||
:linestyle,
|
||||
:fillcolor,
|
||||
:fillalpha,
|
||||
:fillstyle,
|
||||
:markercolor,
|
||||
:markeralpha,
|
||||
:markersize,
|
||||
@ -572,15 +542,15 @@ const _segmenting_vector_attributes = (
|
||||
:markershape,
|
||||
)
|
||||
|
||||
const _segmenting_array_attributes = :line_z, :fill_z, :marker_z
|
||||
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
|
||||
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
|
||||
return any(series[attr] isa AbstractVector && length(series[attr]) > 1
|
||||
for attr in _segmenting_vector_attributes
|
||||
) || any(series[attr] isa AbstractArray for attr in _segmenting_array_attributes)
|
||||
end
|
||||
|
||||
@ -597,10 +567,10 @@ function get_aspect_ratio(sp)
|
||||
return aspect_ratio
|
||||
end
|
||||
|
||||
get_size(series::Series) = get_size(series.plotattributes[:subplot])
|
||||
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)
|
||||
@ -609,6 +579,7 @@ get_thickness_scaling(series::Series) =
|
||||
get_thickness_scaling(series.plotattributes[:subplot])
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
makekw(; kw...) = KW(kw)
|
||||
|
||||
wraptuple(x::Tuple) = x
|
||||
@ -619,21 +590,16 @@ trueOrAllTrue(f::Function, x) = f(x)
|
||||
|
||||
allLineTypes(arg) = trueOrAllTrue(a -> get(_typeAliases, a, a) in _allTypes, arg)
|
||||
allStyles(arg) = trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
|
||||
allShapes(arg) = (
|
||||
trueOrAllTrue(a -> is_marker_supported(get(_markerAliases, a, a)), arg) ||
|
||||
allShapes(arg) = trueOrAllTrue(a -> is_marker_supported(get(_markerAliases, a, a)), arg) ||
|
||||
trueOrAllTrue(a -> isa(a, Shape), arg)
|
||||
)
|
||||
allAlphas(arg) = trueOrAllTrue(
|
||||
a ->
|
||||
(typeof(a) <: Real && a > 0 && a < 1) || (
|
||||
typeof(a) <: AbstractFloat && (a == zero(typeof(a)) || a == one(typeof(a)))
|
||||
),
|
||||
arg,
|
||||
)
|
||||
allAlphas(arg) = trueOrAllTrue(a -> (typeof(a) <: Real && a > 0 && a < 1) ||
|
||||
(typeof(a) <: AbstractFloat && (a == zero(typeof(a)) || a == one(typeof(a)))), arg)
|
||||
allReals(arg) = trueOrAllTrue(a -> typeof(a) <: Real, arg)
|
||||
allFunctions(arg) = trueOrAllTrue(a -> isa(a, Function), arg)
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
"""
|
||||
Allows temporary setting of backend and defaults for Plots. Settings apply only for the `do` block. Example:
|
||||
@ -651,7 +617,7 @@ function with(f::Function, args...; kw...)
|
||||
newdefs[:xticks] = nothing
|
||||
newdefs[:yticks] = nothing
|
||||
newdefs[:grid] = false
|
||||
newdefs[:legend_position] = false
|
||||
newdefs[:legend] = false
|
||||
end
|
||||
|
||||
# dict to store old and new keyword args for anything that changes
|
||||
@ -667,6 +633,7 @@ function with(f::Function, args...; kw...)
|
||||
oldbackend = CURRENT_BACKEND.sym
|
||||
|
||||
for arg in args
|
||||
|
||||
# change backend?
|
||||
if arg in backends()
|
||||
backend(arg)
|
||||
@ -727,7 +694,10 @@ mutable struct DebugMode
|
||||
end
|
||||
const _debugMode = DebugMode(false)
|
||||
|
||||
debugplots(on = true) = _debugMode.on = on
|
||||
function debugplots(on = true)
|
||||
_debugMode.on = on
|
||||
end
|
||||
|
||||
debugshow(io, x) = show(io, x)
|
||||
debugshow(io, x::AbstractArray) = print(io, summary(x))
|
||||
|
||||
@ -747,7 +717,9 @@ end
|
||||
DD(io::IO, plotattributes::AKW, prefix = "") = dumpdict(io, plotattributes, prefix, true)
|
||||
DD(plotattributes::AKW, prefix = "") = DD(stdout, plotattributes, prefix)
|
||||
|
||||
dumpcallstack() = error() # well... you wanted the stacktrace, didn't you?!?
|
||||
function dumpcallstack()
|
||||
error() # well... you wanted the stacktrace, didn't you?!?
|
||||
end
|
||||
|
||||
# -------------------------------------------------------
|
||||
# NOTE: backends should implement the following methods to get/set the x/y/z data objects
|
||||
@ -779,17 +751,17 @@ function setxyz!(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) where {X,Y,Z}
|
||||
_series_updated(plt, series)
|
||||
end
|
||||
|
||||
setxyz!(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) where {X,Y,Z<:AbstractMatrix} =
|
||||
(setxyz!(plt, (xyz[1], xyz[2], Surface(xyz[3])), i))
|
||||
function setxyz!(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) where {X,Y,Z<:AbstractMatrix}
|
||||
setxyz!(plt, (xyz[1], xyz[2], Surface(xyz[3])), i)
|
||||
end
|
||||
|
||||
|
||||
# -------------------------------------------------------
|
||||
# indexing notation
|
||||
|
||||
# Base.getindex(plt::Plot, i::Integer) = getxy(plt, i)
|
||||
Base.setindex!(plt::Plot, xy::Tuple{X,Y}, i::Integer) where {X,Y} =
|
||||
(setxy!(plt, xy, i); plt)
|
||||
Base.setindex!(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) where {X,Y,Z} =
|
||||
(setxyz!(plt, xyz, i); plt)
|
||||
Base.setindex!(plt::Plot, xy::Tuple{X,Y}, i::Integer) where {X,Y} = (setxy!(plt, xy, i); plt)
|
||||
Base.setindex!(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) where {X,Y,Z} = (setxyz!(plt, xyz, i); plt)
|
||||
|
||||
# -------------------------------------------------------
|
||||
# operate on individual series
|
||||
@ -820,7 +792,7 @@ end
|
||||
function extend_series_data!(series::Series, v, letter)
|
||||
copy_series!(series, letter)
|
||||
d = extend_by_data!(series[letter], v)
|
||||
expand_extrema!(series[:subplot][get_attr_symbol(letter, :axis)], d)
|
||||
expand_extrema!(series[:subplot][Symbol(letter, :axis)], d)
|
||||
return d
|
||||
end
|
||||
|
||||
@ -843,8 +815,9 @@ function extend_to_length!(v::AbstractVector, n)
|
||||
extend_by_data!(v, vmax .+ (1:(n - length(v))))
|
||||
end
|
||||
extend_by_data!(v::AbstractVector, x) = isimmutable(v) ? vcat(v, x) : push!(v, x)
|
||||
extend_by_data!(v::AbstractVector, x::AbstractVector) =
|
||||
function extend_by_data!(v::AbstractVector, x::AbstractVector)
|
||||
isimmutable(v) ? vcat(v, x) : append!(v, x)
|
||||
end
|
||||
|
||||
# -------------------------------------------------------
|
||||
|
||||
@ -895,7 +868,7 @@ Base.append!(plt::Plot, i::Integer, t::Tuple) = append!(plt, i, t...)
|
||||
# push y[i] to the ith series
|
||||
function Base.push!(plt::Plot, y::AVec)
|
||||
ny = length(y)
|
||||
for i in 1:(plt.n)
|
||||
for i in 1:plt.n
|
||||
push!(plt, i, y[mod1(i,ny)])
|
||||
end
|
||||
plt
|
||||
@ -903,13 +876,15 @@ end
|
||||
|
||||
# push y[i] to the ith series
|
||||
# same x for each series
|
||||
Base.push!(plt::Plot, x::Real, y::AVec) = push!(plt, [x], y)
|
||||
function Base.push!(plt::Plot, x::Real, y::AVec)
|
||||
push!(plt, [x], y)
|
||||
end
|
||||
|
||||
# push (x[i], y[i]) to the ith series
|
||||
function Base.push!(plt::Plot, x::AVec, y::AVec)
|
||||
nx = length(x)
|
||||
ny = length(y)
|
||||
for i in 1:(plt.n)
|
||||
for i in 1:plt.n
|
||||
push!(plt, i, x[mod1(i,nx)], y[mod1(i,ny)])
|
||||
end
|
||||
plt
|
||||
@ -920,14 +895,18 @@ function Base.push!(plt::Plot, x::AVec, y::AVec, z::AVec)
|
||||
nx = length(x)
|
||||
ny = length(y)
|
||||
nz = length(z)
|
||||
for i in 1:(plt.n)
|
||||
for i in 1:plt.n
|
||||
push!(plt, i, x[mod1(i,nx)], y[mod1(i,ny)], z[mod1(i,nz)])
|
||||
end
|
||||
plt
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
|
||||
# Some conversion functions
|
||||
# note: I borrowed these conversion constants from Compose.jl's Measure
|
||||
|
||||
@ -943,82 +922,80 @@ mm2inch(mm::Real) = float(mm / MM_PER_INCH)
|
||||
px2mm(px::Real) = float(px * MM_PER_PX)
|
||||
mm2px(mm::Real) = float(mm / MM_PER_PX)
|
||||
|
||||
|
||||
"Smallest x in plot"
|
||||
xmin(plt::Plot) = ignorenan_minimum([
|
||||
ignorenan_minimum(series.plotattributes[:x]) for series in plt.series_list
|
||||
])
|
||||
xmin(plt::Plot) = ignorenan_minimum([ignorenan_minimum(series.plotattributes[:x]) for series in plt.series_list])
|
||||
"Largest x in plot"
|
||||
xmax(plt::Plot) = ignorenan_maximum([
|
||||
ignorenan_maximum(series.plotattributes[:x]) for series in plt.series_list
|
||||
])
|
||||
xmax(plt::Plot) = ignorenan_maximum([ignorenan_maximum(series.plotattributes[:x]) for series in plt.series_list])
|
||||
|
||||
"Extrema of x-values in plot"
|
||||
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],
|
||||
plottitlefont(p::Plot) = font(
|
||||
p[:plot_titlefontfamily],
|
||||
p[:plot_titlefontsize],
|
||||
p[:plot_titlefontvalign],
|
||||
p[:plot_titlefonthalign],
|
||||
p[:plot_titlefontrotation],
|
||||
p[:plot_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],
|
||||
colorbartitlefont(sp::Subplot) = font(
|
||||
sp[:colorbar_titlefontfamily],
|
||||
sp[:colorbar_titlefontsize],
|
||||
sp[:colorbar_titlefontvalign],
|
||||
sp[:colorbar_titlefonthalign],
|
||||
sp[:colorbar_titlefontrotation],
|
||||
sp[:colorbar_titlefontcolor],
|
||||
)
|
||||
|
||||
titlefont(sp::Subplot) = font(;
|
||||
family = sp[:titlefontfamily],
|
||||
pointsize = sp[:titlefontsize],
|
||||
valign = sp[:titlefontvalign],
|
||||
halign = sp[:titlefonthalign],
|
||||
rotation = sp[:titlefontrotation],
|
||||
color = sp[:titlefontcolor],
|
||||
titlefont(sp::Subplot) = font(
|
||||
sp[:titlefontfamily],
|
||||
sp[:titlefontsize],
|
||||
sp[:titlefontvalign],
|
||||
sp[:titlefonthalign],
|
||||
sp[:titlefontrotation],
|
||||
sp[:titlefontcolor],
|
||||
)
|
||||
|
||||
legendfont(sp::Subplot) = font(;
|
||||
family = sp[:legend_font_family],
|
||||
pointsize = sp[:legend_font_pointsize],
|
||||
valign = sp[:legend_font_valign],
|
||||
halign = sp[:legend_font_halign],
|
||||
rotation = sp[:legend_font_rotation],
|
||||
color = sp[:legend_font_color],
|
||||
legendfont(sp::Subplot) = font(
|
||||
sp[:legendfontfamily],
|
||||
sp[:legendfontsize],
|
||||
sp[:legendfontvalign],
|
||||
sp[:legendfonthalign],
|
||||
sp[:legendfontrotation],
|
||||
sp[:legendfontcolor],
|
||||
)
|
||||
|
||||
legendtitlefont(sp::Subplot) = font(;
|
||||
family = sp[:legend_title_font_family],
|
||||
pointsize = sp[:legend_title_font_pointsize],
|
||||
valign = sp[:legend_title_font_valign],
|
||||
halign = sp[:legend_title_font_halign],
|
||||
rotation = sp[:legend_title_font_rotation],
|
||||
color = sp[:legend_title_font_color],
|
||||
legendtitlefont(sp::Subplot) = font(
|
||||
sp[:legendtitlefontfamily],
|
||||
sp[:legendtitlefontsize],
|
||||
sp[:legendtitlefontvalign],
|
||||
sp[:legendtitlefonthalign],
|
||||
sp[:legendtitlefontrotation],
|
||||
sp[:legendtitlefontcolor],
|
||||
)
|
||||
|
||||
tickfont(ax::Axis) = font(;
|
||||
family = ax[:tickfontfamily],
|
||||
pointsize = ax[:tickfontsize],
|
||||
valign = ax[:tickfontvalign],
|
||||
halign = ax[:tickfonthalign],
|
||||
rotation = ax[:tickfontrotation],
|
||||
color = ax[:tickfontcolor],
|
||||
tickfont(ax::Axis) = font(
|
||||
ax[:tickfontfamily],
|
||||
ax[:tickfontsize],
|
||||
ax[:tickfontvalign],
|
||||
ax[:tickfonthalign],
|
||||
ax[:tickfontrotation],
|
||||
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],
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
@ -1073,14 +1050,11 @@ function straightline_data(series, expansion_factor = 1)
|
||||
xdata, ydata = fill(NaN, n), fill(NaN, n)
|
||||
for i in 1:k
|
||||
inds = (3 * i - 2):(3 * i - 1)
|
||||
xdata[inds], ydata[inds] =
|
||||
straightline_data(xl, yl, x[inds], y[inds], expansion_factor)
|
||||
xdata[inds], ydata[inds] = straightline_data(xl, yl, x[inds], y[inds], expansion_factor)
|
||||
end
|
||||
xdata, ydata
|
||||
else
|
||||
error(
|
||||
"Misformed data. `straightline_data` either accepts vectors of length 2 or 3k. The provided series has length $n",
|
||||
)
|
||||
error("Misformed data. `straightline_data` either accepts vectors of length 2 or 3k. The provided series has length $n")
|
||||
end
|
||||
end
|
||||
|
||||
@ -1102,10 +1076,7 @@ function straightline_data(xl, yl, x, y, expansion_factor = 1)
|
||||
b = y[1] - (y[1] - y[2]) * x[1] / (x[1] - x[2])
|
||||
a = (y[1] - y[2]) / (x[1] - x[2])
|
||||
# get the data values
|
||||
xdata = [
|
||||
clamp(x[1] + (x[1] - x[2]) * (ylim - y[1]) / (y[1] - y[2]), xl...) for
|
||||
ylim in yl
|
||||
]
|
||||
xdata = [clamp(x[1] + (x[1] - x[2]) * (ylim - y[1]) / (y[1] - y[2]), xl...) for ylim in yl]
|
||||
|
||||
xdata, a .* xdata .+ b
|
||||
end
|
||||
@ -1146,19 +1117,18 @@ function shape_data(series, expansion_factor = 1)
|
||||
return x, y
|
||||
end
|
||||
|
||||
construct_categorical_data(x::AbstractArray, axis::Axis) =
|
||||
(map(xi -> axis[:discrete_values][searchsortedfirst(axis[:continuous_values], xi)], x))
|
||||
function construct_categorical_data(x::AbstractArray, axis::Axis)
|
||||
map(xi -> axis[:discrete_values][searchsortedfirst(axis[:continuous_values], xi)], x)
|
||||
end
|
||||
|
||||
_fmt_paragraph(paragraph::AbstractString; kwargs...) =
|
||||
_fmt_paragraph(IOBuffer(), paragraph, 0; kwargs...)
|
||||
_fmt_paragraph(paragraph::AbstractString;kwargs...) = _fmt_paragraph(IOBuffer(),paragraph,0;kwargs...)
|
||||
|
||||
function _fmt_paragraph(
|
||||
io::IOBuffer,
|
||||
function _fmt_paragraph(io::IOBuffer,
|
||||
remaining_text::AbstractString,
|
||||
column_count::Integer;
|
||||
fillwidth=60,
|
||||
leadingspaces = 0,
|
||||
)
|
||||
leadingspaces=0)
|
||||
|
||||
kwargs = (fillwidth = fillwidth, leadingspaces = leadingspaces)
|
||||
|
||||
m = match(r"(.*?) (.*)",remaining_text)
|
||||
@ -1181,68 +1151,6 @@ function _fmt_paragraph(
|
||||
end
|
||||
end
|
||||
|
||||
_document_argument(S::AbstractString) =
|
||||
function _document_argument(S::AbstractString)
|
||||
_fmt_paragraph("`$S`: "*_arg_desc[Symbol(S)],leadingspaces = 6 + length(S))
|
||||
|
||||
function mesh3d_triangles(x, y, z, cns::Tuple{Array,Array,Array})
|
||||
ci, cj, ck = cns
|
||||
if !(length(ci) == length(cj) == length(ck))
|
||||
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
|
||||
end
|
||||
X = zeros(eltype(x), 4length(ci))
|
||||
Y = zeros(eltype(y), 4length(cj))
|
||||
Z = zeros(eltype(z), 4length(ck))
|
||||
@inbounds for I in 1:length(ci)
|
||||
i = ci[I] + 1 # connections are 0-based
|
||||
j = cj[I] + 1
|
||||
k = ck[I] + 1
|
||||
m = 4(I - 1) + 1
|
||||
n = m + 1
|
||||
o = m + 2
|
||||
p = m + 3
|
||||
X[m] = X[p] = x[i]
|
||||
Y[m] = Y[p] = y[i]
|
||||
Z[m] = Z[p] = z[i]
|
||||
X[n] = x[j]
|
||||
Y[n] = y[j]
|
||||
Z[n] = z[j]
|
||||
X[o] = x[k]
|
||||
Y[o] = y[k]
|
||||
Z[o] = z[k]
|
||||
end
|
||||
return X, Y, Z
|
||||
end
|
||||
|
||||
function mesh3d_triangles(x, y, z, cns::AbstractVector{NTuple{3,Int}})
|
||||
X = zeros(eltype(x), 4length(cns))
|
||||
Y = zeros(eltype(y), 4length(cns))
|
||||
Z = zeros(eltype(z), 4length(cns))
|
||||
@inbounds for I in 1:length(cns)
|
||||
i = cns[I][1] # connections are 1-based
|
||||
j = cns[I][2]
|
||||
k = cns[I][3]
|
||||
m = 4(I - 1) + 1
|
||||
n = m + 1
|
||||
o = m + 2
|
||||
p = m + 3
|
||||
X[m] = X[p] = x[i]
|
||||
Y[m] = Y[p] = y[i]
|
||||
Z[m] = Z[p] = z[i]
|
||||
X[n] = x[j]
|
||||
Y[n] = y[j]
|
||||
Z[n] = z[j]
|
||||
X[o] = x[k]
|
||||
Y[o] = y[k]
|
||||
Z[o] = z[k]
|
||||
end
|
||||
return X, Y, Z
|
||||
end
|
||||
|
||||
# cache joined symbols so they can be looked up instead of constructed each time
|
||||
const _attrsymbolcache = Dict{Symbol,Dict{Symbol,Symbol}}()
|
||||
|
||||
get_attr_symbol(letter::Symbol, keyword::String) = get_attr_symbol(letter, Symbol(keyword))
|
||||
get_attr_symbol(letter::Symbol, keyword::Symbol) = _attrsymbolcache[letter][keyword]
|
||||
|
||||
texmath2unicode(s::AbstractString, pat = r"\$([^$]+)\$") =
|
||||
replace(s, pat => m -> UnicodeFun.to_latex(m[2:(length(m) - 1)]))
|
||||
|
||||
@ -6,13 +6,14 @@ function replace_rand!(ex::Expr)
|
||||
for arg in ex.args
|
||||
replace_rand!(arg)
|
||||
end
|
||||
if ex.head === :call && ex.args[1] ∈ (:rand, :randn, :(Plots.fakedata))
|
||||
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(
|
||||
@ -34,17 +35,13 @@ function image_comparison_tests(
|
||||
fn = "ref$idx.png"
|
||||
reffn = reference_file(pkg, idx, _current_plots_version)
|
||||
newfn = joinpath(reference_path(pkg, _current_plots_version), fn)
|
||||
@debug example.exprs
|
||||
|
||||
# test function
|
||||
func = (fn, idx) -> begin
|
||||
eval(:(rng = StableRNG(PLOTS_SEED)))
|
||||
for the_expr in example.exprs
|
||||
expr = Expr(:block)
|
||||
push!(expr.args, the_expr)
|
||||
append!(expr.args, example.exprs)
|
||||
fix_rand!(expr)
|
||||
eval(expr)
|
||||
end
|
||||
png(fn)
|
||||
end
|
||||
|
||||
@ -61,7 +58,7 @@ function image_comparison_facts(
|
||||
sigma = [1, 1], # number of pixels to "blur"
|
||||
tol = 1e-2,
|
||||
) # acceptable error (percent)
|
||||
for i in 1:length(Plots._examples)
|
||||
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) |>
|
||||
|
||||
617
test/runtests.jl
617
test/runtests.jl
@ -1,26 +1,17 @@
|
||||
using Plots: guidefont, series_annotations, PLOTS_SEED
|
||||
|
||||
using VisualRegressionTests
|
||||
using RecipesBase
|
||||
using StableRNGs
|
||||
using TestImages
|
||||
using LibGit2
|
||||
using Random
|
||||
using FileIO
|
||||
using Plots
|
||||
using Dates
|
||||
using JSON
|
||||
using Test
|
||||
using Gtk
|
||||
|
||||
import GeometryBasics
|
||||
import ImageMagick
|
||||
using VisualRegressionTests
|
||||
using Plots
|
||||
using Random
|
||||
using StableRNGs
|
||||
using Test
|
||||
using TestImages
|
||||
using FileIO
|
||||
using Gtk
|
||||
using LibGit2
|
||||
import GeometryBasics
|
||||
using Dates
|
||||
using RecipesBase
|
||||
|
||||
@testset "Infrastructure" begin
|
||||
@test_nowarn JSON.Parser.parse(
|
||||
String(read(joinpath(dirname(pathof(Plots)), "..", ".zenodo.json"))),
|
||||
)
|
||||
end
|
||||
|
||||
@testset "Plotly standalone" begin
|
||||
@test_nowarn Plots._init_ijulia_plotting()
|
||||
@ -35,107 +26,176 @@ end
|
||||
end
|
||||
Plots.plotly_local_file_path[] = nothing
|
||||
Plots.use_local_dependencies[] = temp
|
||||
end # testset
|
||||
|
||||
include("test_defaults.jl")
|
||||
include("test_axes.jl")
|
||||
include("test_axis_letter.jl")
|
||||
include("test_components.jl")
|
||||
include("test_shorthands.jl")
|
||||
include("integration_dates.jl")
|
||||
include("test_recipes.jl")
|
||||
include("test_hdf5plots.jl")
|
||||
include("test_pgfplotsx.jl")
|
||||
|
||||
reference_dir(args...) = joinpath(homedir(), ".julia", "dev", "PlotReferenceImages", args...)
|
||||
|
||||
function reference_file(backend, i, version)
|
||||
refdir = reference_dir("Plots", string(backend))
|
||||
fn = "ref$i.png"
|
||||
versions = sort(VersionNumber.(readdir(refdir)), rev=true)
|
||||
|
||||
reffn = joinpath(refdir, string(version), fn)
|
||||
for v in versions
|
||||
tmpfn = joinpath(refdir, string(v), fn)
|
||||
if isfile(tmpfn)
|
||||
reffn = tmpfn
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Utils" begin
|
||||
zipped = (
|
||||
[(1, 2)],
|
||||
[("a", "b")],
|
||||
[(1, "a"), (2, "b")],
|
||||
[(1, 2), (3, 4)],
|
||||
[(1, 2, 3), (3, 4, 5)],
|
||||
[(1, 2, 3, 4), (3, 4, 5, 6)],
|
||||
[(1, 2.0), (missing, missing)],
|
||||
[(1, missing), (missing, "a")],
|
||||
[(missing, missing)],
|
||||
[(missing, missing, missing), ("a", "b", "c")],
|
||||
)
|
||||
for z in zipped
|
||||
@test isequal(collect(zip(Plots.RecipesPipeline.unzip(z)...)), z)
|
||||
@test isequal(
|
||||
collect(zip(Plots.RecipesPipeline.unzip(GeometryBasics.Point.(z))...)),
|
||||
z,
|
||||
)
|
||||
return reffn
|
||||
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)
|
||||
|
||||
@test (==)(
|
||||
Plots.texmath2unicode(
|
||||
raw"Equation $y = \alpha \cdot x + \beta$ and eqn $y = \sin(x)^2$",
|
||||
),
|
||||
raw"Equation y = α ⋅ x + β and eqn y = sin(x)²",
|
||||
)
|
||||
reference_path(backend, version) = reference_dir("Plots", string(backend), string(version))
|
||||
|
||||
@test Plots.isvector([1, 2])
|
||||
@test !Plots.isvector(nothing)
|
||||
@test Plots.ismatrix([1 2; 3 4])
|
||||
@test !Plots.ismatrix(nothing)
|
||||
@test Plots.isscalar(1.0)
|
||||
@test !Plots.isscalar(nothing)
|
||||
@test Plots.tovec([]) isa AbstractVector
|
||||
@test Plots.tovec(nothing) isa AbstractVector
|
||||
@test Plots.anynan(1, 3, (1, NaN, 3))
|
||||
@test Plots.allnan(1, 2, (NaN, NaN, 1))
|
||||
@test Plots.makevec([]) isa AbstractVector
|
||||
@test Plots.makevec(1) isa AbstractVector
|
||||
@test Plots.maketuple(1) == (1, 1)
|
||||
@test Plots.maketuple((1, 1)) == (1, 1)
|
||||
@test Plots.ok(1, 2)
|
||||
@test !Plots.ok(1, 2, NaN)
|
||||
@test Plots.ok((1, 2, 3))
|
||||
@test !Plots.ok((1, 2, NaN))
|
||||
@test Plots.nansplit([1, 2, NaN, 3, 4]) == [[1.0, 2.0], [3.0, 4.0]]
|
||||
@test Plots.nanvcat([1, NaN]) |> length == 4
|
||||
if !isdir(reference_dir())
|
||||
mkpath(reference_dir())
|
||||
LibGit2.clone("https://github.com/JuliaPlots/PlotReferenceImages.jl.git", reference_dir())
|
||||
end
|
||||
|
||||
@test Plots.nop() === nothing
|
||||
@test_throws ErrorException Plots.notimpl()
|
||||
include("imgcomp.jl")
|
||||
# don't actually show the plots
|
||||
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
|
||||
|
||||
@test Plots.inch2px(1) isa AbstractFloat
|
||||
@test Plots.px2inch(1) isa AbstractFloat
|
||||
@test Plots.inch2mm(1) isa AbstractFloat
|
||||
@test Plots.mm2inch(1) isa AbstractFloat
|
||||
@test Plots.px2mm(1) isa AbstractFloat
|
||||
@test Plots.mm2px(1) isa AbstractFloat
|
||||
## Uncomment the following lines to update reference images for different backends
|
||||
|
||||
# @testset "GR" begin
|
||||
# image_comparison_facts(:gr, tol=IMG_TOL, skip = Plots._backend_skips[:gr])
|
||||
# end
|
||||
#
|
||||
# plotly()
|
||||
# @testset "Plotly" begin
|
||||
# image_comparison_facts(:plotly, tol=IMG_TOL, skip = Plots._backend_skips[:plotlyjs])
|
||||
# end
|
||||
#
|
||||
# pyplot()
|
||||
# @testset "PyPlot" begin
|
||||
# image_comparison_facts(:pyplot, tol=IMG_TOL, skip = Plots._backend_skips[:pyplot])
|
||||
# end
|
||||
#
|
||||
# pgfplotsx()
|
||||
# @testset "PGFPlotsX" begin
|
||||
# image_comparison_facts(:pgfplotsx, tol=IMG_TOL, skip = Plots._backend_skips[:pgfplotsx])
|
||||
# end
|
||||
|
||||
# 10 Histogram2D
|
||||
|
||||
##
|
||||
|
||||
@testset "Backends" begin
|
||||
|
||||
@testset "GR" begin
|
||||
ENV["PLOTS_TEST"] = "true"
|
||||
ENV["GKSwstype"] = "100"
|
||||
@test gr() == Plots.GRBackend()
|
||||
@test backend() == Plots.GRBackend()
|
||||
|
||||
@static if haskey(ENV, "APPVEYOR")
|
||||
@info "Skipping GR image comparison tests on AppVeyor"
|
||||
else
|
||||
image_comparison_facts(:gr, tol=IMG_TOL, skip=Plots._backend_skips[:gr])
|
||||
end
|
||||
end
|
||||
|
||||
@testset "UnicodePlots" begin
|
||||
@test unicodeplots() == Plots.UnicodePlotsBackend()
|
||||
@test backend() == Plots.UnicodePlotsBackend()
|
||||
|
||||
# lets just make sure it runs without error
|
||||
p = plot(rand(10))
|
||||
@test isa(p, Plots.Plot) == true
|
||||
@test isa(display(p), Nothing) == true
|
||||
p = bar(randn(10))
|
||||
@test isa(p, Plots.Plot) == true
|
||||
@test isa(display(p), Nothing) == true
|
||||
p = plot([1, 2], [3, 4])
|
||||
annotate!(p, [(1.5, 3.2, Plots.text("Test", :red, :center))])
|
||||
hline!(p, [3.1])
|
||||
@test isa(p, Plots.Plot) == true
|
||||
@test isa(display(p), Nothing) == true
|
||||
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
|
||||
hline!(p, [3.1])
|
||||
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
|
||||
@test isa(p, Plots.Plot) == true
|
||||
@test isa(display(p), Nothing) == true
|
||||
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
|
||||
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, :auto)])
|
||||
hline!(p, [3.1])
|
||||
@test isa(p, Plots.Plot) == true
|
||||
@test isa(display(p), Nothing) == true
|
||||
end
|
||||
|
||||
@testset "PlotlyJS" begin
|
||||
@test 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
|
||||
p = plot()
|
||||
@test xlims() isa Tuple
|
||||
@test ylims() isa Tuple
|
||||
@test zlims() isa Tuple
|
||||
axis = p.subplots[1][:xaxis]
|
||||
@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 axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1)
|
||||
|
||||
Plots.makekw(foo = 1, bar = 2) isa Dict
|
||||
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
|
||||
|
||||
@test_throws ErrorException Plots.inline()
|
||||
@test_throws ErrorException Plots._do_plot_show(plot(), :inline)
|
||||
@test_throws ErrorException Plots.dumpcallstack()
|
||||
@testset "NoFail" begin
|
||||
#ensure backend with tested display
|
||||
@test unicodeplots() == Plots.UnicodePlotsBackend()
|
||||
@test backend() == Plots.UnicodePlotsBackend()
|
||||
|
||||
Plots.debugplots(true)
|
||||
Plots.debugplots(false)
|
||||
Plots.debugshow(devnull, nothing)
|
||||
Plots.debugshow(devnull, [1])
|
||||
@testset "Plot" begin
|
||||
plots = [histogram([1, 0, 0, 0, 0, 0]),
|
||||
plot([missing]),
|
||||
plot([missing; 1:4]),
|
||||
plot([fill(missing, 10); 1:4]),
|
||||
plot([1 1; 1 missing]),
|
||||
plot(["a" "b"; missing "d"], [1 2; 3 4])]
|
||||
for plt in plots
|
||||
display(plt)
|
||||
end
|
||||
@test_nowarn plot(x -> x^2, 0, 2)
|
||||
end
|
||||
|
||||
p = plot(1)
|
||||
push!(p, 1.5)
|
||||
push!(p, 1, 1.5)
|
||||
# append!(p, [1., 2.])
|
||||
append!(p, 1, 2.5, 2.5)
|
||||
push!(p, (1.5, 2.5))
|
||||
push!(p, 1, (1.5, 2.5))
|
||||
append!(p, (1.5, 2.5))
|
||||
append!(p, 1, (1.5, 2.5))
|
||||
@testset "Bar" begin
|
||||
p = bar([3,2,1], [1,2,3]);
|
||||
@test isa(p, Plots.Plot)
|
||||
@test isa(display(p), Nothing) == true
|
||||
end
|
||||
end
|
||||
|
||||
p = plot([1, 2, 3], [4, 5, 6])
|
||||
@test Plots.xmin(p) == 1
|
||||
@test Plots.xmax(p) == 3
|
||||
@test Plots.ignorenan_extrema(p) == (1, 3)
|
||||
|
||||
@test Plots.get_attr_symbol(:x, "lims") == :xlims
|
||||
@test Plots.get_attr_symbol(:x, :lims) == :xlims
|
||||
@testset "EmptyAnim" begin
|
||||
anim = @animate for i in []
|
||||
end
|
||||
|
||||
@test_throws ArgumentError gif(anim)
|
||||
end
|
||||
|
||||
@testset "NaN-separated Segments" begin
|
||||
segments(args...) = collect(iter_segments(args...))
|
||||
@ -150,334 +210,19 @@ end
|
||||
@test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10]
|
||||
@test segments([nan10; 1:15], [1:15; nan10]) == [11:15]
|
||||
end
|
||||
|
||||
@testset "Utils" begin
|
||||
zipped = ([(1, 2)], [("a", "b")], [(1, "a"),(2, "b")],
|
||||
[(1, 2),(3, 4)], [(1, 2, 3),(3, 4, 5)], [(1, 2, 3, 4),(3, 4, 5, 6)],
|
||||
[(1, 2.0),(missing, missing)], [(1, missing),(missing, "a")],
|
||||
[(missing, missing)], [(missing, missing, missing),("a", "b", "c")])
|
||||
for z in zipped
|
||||
@test isequal(collect(zip(Plots.unzip(z)...)), z)
|
||||
@test isequal(collect(zip(Plots.unzip(GeometryBasics.Point.(z))...)), z)
|
||||
end
|
||||
|
||||
@testset "Axes" begin
|
||||
p = plot()
|
||||
axis = p.subplots[1][:xaxis]
|
||||
@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 axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1)
|
||||
|
||||
Plots.discrete_value!(axis, ["x$i" for i in 1:5])
|
||||
Plots.discrete_value!(axis, ["x$i" for i in 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()
|
||||
|
||||
dsp = TextDisplay(IOContext(IOBuffer(), :color => true))
|
||||
|
||||
@testset "plot" begin
|
||||
for plt in [
|
||||
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]),
|
||||
]
|
||||
display(dsp, plt)
|
||||
end
|
||||
@test_nowarn plot(x -> x^2, 0, 2)
|
||||
end
|
||||
|
||||
@testset "bar" begin
|
||||
p = bar([3, 2, 1], [1, 2, 3])
|
||||
@test p isa Plots.Plot
|
||||
@test display(dsp, p) isa Nothing
|
||||
end
|
||||
|
||||
@testset "gui" begin
|
||||
open(tempname(), "w") do io
|
||||
redirect_stdout(io) do
|
||||
gui(plot())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Coverage" begin
|
||||
@testset "themes" begin
|
||||
p = showtheme(:dark)
|
||||
@test p isa Plots.Plot
|
||||
end
|
||||
|
||||
@testset "plotattr" begin
|
||||
tmp = tempname()
|
||||
open(tmp, "w") do io
|
||||
redirect_stdout(io) do
|
||||
plotattr("seriestype")
|
||||
plotattr(:Plot)
|
||||
plotattr()
|
||||
end
|
||||
end
|
||||
str = join(readlines(tmp), "")
|
||||
@test occursin("seriestype", str)
|
||||
@test occursin("Plot attributes", str)
|
||||
end
|
||||
|
||||
@testset "legend" begin
|
||||
@test isa(
|
||||
Plots.legend_pos_from_angle(20, 0.0, 0.5, 1.0, 0.0, 0.5, 1.0),
|
||||
NTuple{2,<:AbstractFloat},
|
||||
)
|
||||
@test Plots.legend_anchor_index(-1) == 1
|
||||
@test Plots.legend_anchor_index(+0) == 2
|
||||
@test Plots.legend_anchor_index(+1) == 3
|
||||
|
||||
@test Plots.legend_angle(:foo_bar) == (45, :inner)
|
||||
@test Plots.legend_angle(20.0) ==
|
||||
Plots.legend_angle((20.0, :inner)) ==
|
||||
(20.0, :inner)
|
||||
@test Plots.legend_angle((20.0, 10.0)) == (20.0, 10.0)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Output" begin
|
||||
@test Plots.defaultOutputFormat(plot()) == "png"
|
||||
@test Plots.addExtension("foo", "bar") == "foo.bar"
|
||||
|
||||
fn = tempname()
|
||||
gr()
|
||||
let p = plot()
|
||||
Plots.png(p, fn)
|
||||
Plots.png(fn)
|
||||
savefig(p, "$fn.png")
|
||||
savefig("$fn.png")
|
||||
|
||||
Plots.pdf(p, fn)
|
||||
Plots.pdf(fn)
|
||||
savefig(p, "$fn.pdf")
|
||||
savefig("$fn.pdf")
|
||||
|
||||
Plots.ps(p, fn)
|
||||
Plots.ps(fn)
|
||||
savefig(p, "$fn.ps")
|
||||
savefig("$fn.ps")
|
||||
|
||||
Plots.svg(p, fn)
|
||||
Plots.svg(fn)
|
||||
savefig(p, "$fn.svg")
|
||||
savefig("$fn.svg")
|
||||
end
|
||||
|
||||
if Sys.islinux()
|
||||
pgfplotsx()
|
||||
let p = plot()
|
||||
Plots.tex(p, fn)
|
||||
Plots.tex(fn)
|
||||
savefig(p, "$fn.tex")
|
||||
savefig("$fn.tex")
|
||||
end
|
||||
end
|
||||
|
||||
unicodeplots()
|
||||
let p = plot()
|
||||
Plots.txt(p, fn)
|
||||
Plots.txt(fn)
|
||||
savefig(p, "$fn.txt")
|
||||
savefig("$fn.txt")
|
||||
end
|
||||
|
||||
plotlyjs()
|
||||
let p = plot()
|
||||
Plots.html(p, fn)
|
||||
Plots.html(fn)
|
||||
savefig(p, "$fn.html")
|
||||
savefig("$fn.html")
|
||||
|
||||
if Sys.islinux()
|
||||
Plots.eps(p, fn)
|
||||
Plots.eps(fn)
|
||||
savefig(p, "$fn.eps")
|
||||
savefig("$fn.eps")
|
||||
end
|
||||
end
|
||||
|
||||
@test_throws ErrorException savefig("$fn.foo")
|
||||
end
|
||||
|
||||
gr() # reset to default backend
|
||||
|
||||
for fn in (
|
||||
"test_args.jl",
|
||||
"test_defaults.jl",
|
||||
"test_pipeline.jl",
|
||||
"test_axes.jl",
|
||||
"test_layouts.jl",
|
||||
"test_contours.jl",
|
||||
"test_axis_letter.jl",
|
||||
"test_components.jl",
|
||||
"test_shorthands.jl",
|
||||
"integration_dates.jl",
|
||||
"test_recipes.jl",
|
||||
"test_hdf5plots.jl",
|
||||
"test_pgfplotsx.jl",
|
||||
"test_plotly.jl",
|
||||
"test_animations.jl",
|
||||
)
|
||||
@testset "$fn" begin
|
||||
include(fn)
|
||||
end
|
||||
end
|
||||
|
||||
reference_dir(args...) =
|
||||
joinpath(homedir(), ".julia", "dev", "PlotReferenceImages", args...)
|
||||
|
||||
function reference_file(backend, i, version)
|
||||
refdir = reference_dir("Plots", string(backend))
|
||||
fn = "ref$i.png"
|
||||
versions = sort(VersionNumber.(readdir(refdir)), rev = true)
|
||||
reffn = joinpath(refdir, string(version), fn)
|
||||
for v in versions
|
||||
tmpfn = joinpath(refdir, string(v), fn)
|
||||
if isfile(tmpfn)
|
||||
reffn = tmpfn
|
||||
break
|
||||
end
|
||||
end
|
||||
return reffn
|
||||
end
|
||||
|
||||
reference_path(backend, version) = reference_dir("Plots", string(backend), string(version))
|
||||
|
||||
if !isdir(reference_dir())
|
||||
mkpath(reference_dir())
|
||||
LibGit2.clone(
|
||||
"https://github.com/JuliaPlots/PlotReferenceImages.jl.git",
|
||||
reference_dir(),
|
||||
)
|
||||
end
|
||||
|
||||
include("imgcomp.jl")
|
||||
Random.seed!(PLOTS_SEED)
|
||||
|
||||
default(show = false, reuse = true) # don't actually show the plots
|
||||
|
||||
is_ci() = get(ENV, "CI", "false") == "true"
|
||||
const PLOTS_IMG_TOL = parse(
|
||||
Float64,
|
||||
get(ENV, "PLOTS_IMG_TOL", is_ci() ? Sys.iswindows() ? "2e-4" : "1e-4" : "1e-5"),
|
||||
)
|
||||
|
||||
## Uncomment the following lines to update reference images for different backends
|
||||
|
||||
# @testset "GR" begin
|
||||
# image_comparison_facts(:gr, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:gr])
|
||||
# end
|
||||
#
|
||||
# plotly()
|
||||
# @testset "Plotly" begin
|
||||
# image_comparison_facts(:plotly, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:plotlyjs])
|
||||
# end
|
||||
#
|
||||
# pyplot()
|
||||
# @testset "PyPlot" begin
|
||||
# image_comparison_facts(:pyplot, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:pyplot])
|
||||
# end
|
||||
#
|
||||
# pgfplotsx()
|
||||
# @testset "PGFPlotsX" begin
|
||||
# image_comparison_facts(:pgfplotsx, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:pgfplotsx])
|
||||
# end
|
||||
|
||||
##
|
||||
|
||||
@testset "Examples" begin
|
||||
if Sys.islinux()
|
||||
backends = (
|
||||
:unicodeplots,
|
||||
:pgfplotsx,
|
||||
:inspectdr,
|
||||
:plotlyjs,
|
||||
:gaston,
|
||||
# :pyplot, # FIXME: fails with system matplotlib
|
||||
)
|
||||
only = setdiff(
|
||||
1:length(Plots._examples),
|
||||
(Plots._backend_skips[be] for be in backends)...,
|
||||
)
|
||||
for be in backends
|
||||
@info be
|
||||
for (i, p) in Plots.test_examples(be, only = only, disp = false)
|
||||
fn = tempname() * ".png"
|
||||
png(p, fn)
|
||||
@test filesize(fn) > 1_000
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Backends" begin
|
||||
@testset "UnicodePlots" begin
|
||||
@test unicodeplots() == Plots.UnicodePlotsBackend()
|
||||
@test backend() == Plots.UnicodePlotsBackend()
|
||||
|
||||
io = IOContext(IOBuffer(), :color => true)
|
||||
|
||||
# lets just make sure it runs without error
|
||||
p = plot(rand(10))
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = bar(randn(10))
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = plot([1, 2], [3, 4])
|
||||
annotate!(p, [(1.5, 3.2, Plots.text("Test", :red, :center))])
|
||||
hline!(p, [3.1])
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
|
||||
hline!(p, [3.1])
|
||||
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
|
||||
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, :auto)])
|
||||
hline!(p, [3.1])
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
|
||||
p = plot((plot(i) for i in 1:4)..., layout = (2, 2))
|
||||
@test p isa Plots.Plot
|
||||
@test show(io, p) isa Nothing
|
||||
end
|
||||
|
||||
@testset "GR" begin
|
||||
ENV["PLOTS_TEST"] = "true"
|
||||
ENV["GKSwstype"] = "100"
|
||||
@test gr() == Plots.GRBackend()
|
||||
@test backend() == Plots.GRBackend()
|
||||
|
||||
@static if haskey(ENV, "APPVEYOR")
|
||||
@info "Skipping GR image comparison tests on AppVeyor"
|
||||
else
|
||||
image_comparison_facts(
|
||||
:gr,
|
||||
tol = PLOTS_IMG_TOL,
|
||||
skip = Plots._backend_skips[:gr],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "PlotlyJS" begin
|
||||
@test plotlyjs() == Plots.PlotlyJSBackend()
|
||||
@test backend() == Plots.PlotlyJSBackend()
|
||||
|
||||
p = plot(rand(10))
|
||||
@test p isa Plots.Plot
|
||||
@test_broken display(p) isa Nothing
|
||||
end
|
||||
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
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
|
||||
@testset "Empty anim" begin
|
||||
anim = @animate for i in []
|
||||
end
|
||||
@test_throws ArgumentError gif(anim)
|
||||
end
|
||||
|
||||
@userplot CirclePlot
|
||||
@recipe function f(cp::CirclePlot)
|
||||
x, y, i = cp.args
|
||||
n = length(x)
|
||||
inds = circshift(1:n, 1 - i)
|
||||
linewidth --> range(0, 10, length = n)
|
||||
seriesalpha --> range(0, 1, length = n)
|
||||
aspect_ratio --> 1
|
||||
label --> false
|
||||
x[inds], y[inds]
|
||||
end
|
||||
|
||||
@testset "Circle plot" begin
|
||||
n = 10
|
||||
t = range(0, 2π, length = n)
|
||||
x = sin.(t)
|
||||
y = cos.(t)
|
||||
|
||||
anim = @animate for i in 1:n
|
||||
circleplot(x, y, i)
|
||||
end
|
||||
@test filesize(gif(anim).filename) > 10_000
|
||||
@test filesize(mov(anim).filename) > 10_000
|
||||
@test filesize(mp4(anim).filename) > 10_000
|
||||
@test filesize(webm(anim).filename) > 10_000
|
||||
|
||||
@gif for i in 1:n
|
||||
circleplot(x, y, i, line_z = 1:n, cbar = false, framestyle = :zerolines)
|
||||
end every 5
|
||||
end
|
||||
|
||||
@testset "html" begin
|
||||
p = plot([sin, cos], zeros(0), leg = false, xlims = (0, 2π), ylims = (-1, 1))
|
||||
anim = Animation()
|
||||
for x in range(0, stop = 2π, length = 10)
|
||||
push!(p, x, Float64[sin(x), cos(x)])
|
||||
frame(anim)
|
||||
end
|
||||
|
||||
agif = gif(anim)
|
||||
html = tempname() * ".html"
|
||||
open(html, "w") do io
|
||||
show(io, MIME("text/html"), agif)
|
||||
end
|
||||
@test filesize(html) > 10_000
|
||||
@test showable(MIME("image/gif"), agif)
|
||||
|
||||
agif = mp4(anim)
|
||||
html = tempname() * ".html"
|
||||
open(html, "w") do io
|
||||
show(io, MIME("text/html"), agif)
|
||||
end
|
||||
@test filesize(html) > 10_000
|
||||
end
|
||||
@ -1,27 +0,0 @@
|
||||
using Plots, Test
|
||||
|
||||
@testset "Series Attributes" begin
|
||||
pl = plot([[1, 2, 3], [2, 3, 4]], lw = 5)
|
||||
@test hline!(deepcopy(pl), [1.75])[1].series_list[3][:label] ==
|
||||
hline!(deepcopy(pl), [1.75], z_order = :front)[1].series_list[3][:label] ==
|
||||
"y3"
|
||||
@test hline!(deepcopy(pl), [1.75], z_order = :back)[1].series_list[1][:label] == "y3"
|
||||
@test hline!(deepcopy(pl), [1.75], z_order = 2)[1].series_list[2][:label] == "y3"
|
||||
end
|
||||
|
||||
@testset "Axis Attributes" begin
|
||||
pl = @test_nowarn plot(; tickfont = font(10, "Times"))
|
||||
for axis in (:xaxis, :yaxis, :zaxis)
|
||||
@test pl[1][axis][:tickfontsize] == 10
|
||||
@test pl[1][axis][:tickfontfamily] == "Times"
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Permute recipes" begin
|
||||
pl = bar(["a", "b", "c"], [1, 2, 3])
|
||||
ppl = bar(["a", "b", "c"], [1, 2, 3], permute = (:x, :y))
|
||||
@test xticks(ppl) == yticks(pl)
|
||||
@test yticks(ppl) == xticks(pl)
|
||||
@test filter(isfinite, pl[1][1][:x]) == filter(isfinite, ppl[1][1][:y])
|
||||
@test filter(isfinite, pl[1][1][:y]) == filter(isfinite, ppl[1][1][:x])
|
||||
end
|
||||
@ -21,102 +21,3 @@ end # testset
|
||||
@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
|
||||
|
||||
@testset "axis-aliases" begin
|
||||
@test haskey(Plots._keyAliases, :xguideposition)
|
||||
@test haskey(Plots._keyAliases, :x_guide_position)
|
||||
@test !haskey(Plots._keyAliases, :xguide_position)
|
||||
p = plot(1:2, xl = "x label")
|
||||
@test p[1][:xaxis][:guide] === "x label"
|
||||
p = plot(1:2, xrange = (0, 3))
|
||||
@test xlims(p) === (0, 3)
|
||||
p = plot(1:2, xtick = [1.25, 1.5, 1.75])
|
||||
@test p[1][:xaxis][:ticks] == [1.25, 1.5, 1.75]
|
||||
p = plot(1:2, xlabelfontsize = 4)
|
||||
@test p[1][:xaxis][:guidefontsize] == 4
|
||||
p = plot(1:2, xgα = 0.07)
|
||||
@test p[1][:xaxis][:gridalpha] ≈ 0.07
|
||||
p = plot(1:2, xgridls = :dashdot)
|
||||
@test p[1][:xaxis][:gridstyle] === :dashdot
|
||||
p = plot(1:2, xgridcolor = :red)
|
||||
@test p[1][:xaxis][:foreground_color_grid] === RGBA{Float64}(1.0, 0.0, 0.0, 1.0)
|
||||
p = plot(1:2, xminorgridcolor = :red)
|
||||
@test p[1][:xaxis][:foreground_color_minor_grid] === RGBA{Float64}(1.0, 0.0, 0.0, 1.0)
|
||||
p = plot(1:2, xgrid_lw = 0.01)
|
||||
@test p[1][:xaxis][:gridlinewidth] ≈ 0.01
|
||||
p = plot(1:2, xminorgrid_lw = 0.01)
|
||||
@test p[1][:xaxis][:minorgridlinewidth] ≈ 0.01
|
||||
p = plot(1:2, xtickor = :out)
|
||||
@test p[1][:xaxis][:tick_direction] === :out
|
||||
end
|
||||
|
||||
@testset "aliases" begin
|
||||
compare(p::Plots.Plot, s::Symbol, val, op) =
|
||||
op(p[1][:xaxis][s], val) && op(p[1][:yaxis][s], val) && op(p[1][:zaxis][s], val)
|
||||
p = plot(1:2, guide = "all labels")
|
||||
@test compare(p, :guide, "all labels", ===)
|
||||
p = plot(1:2, label = "test")
|
||||
@test compare(p, :guide, "", ===)
|
||||
p = plot(1:2, lim = (0, 3))
|
||||
@test xlims(p) === ylims(p) === zlims(p) === (0, 3)
|
||||
p = plot(1:2, tick = [1.25, 1.5, 1.75])
|
||||
@test compare(p, :ticks, [1.25, 1.5, 1.75], ==)
|
||||
p = plot(1:2, labelfontsize = 4)
|
||||
@test compare(p, :guidefontsize, 4, ==)
|
||||
p = plot(1:2, gα = 0.07)
|
||||
@test compare(p, :gridalpha, 0.07, ≈)
|
||||
p = plot(1:2, gridls = :dashdot)
|
||||
@test compare(p, :gridstyle, :dashdot, ===)
|
||||
p = plot(1:2, gridcolor = :red)
|
||||
@test compare(p, :foreground_color_grid, RGBA{Float64}(1.0, 0.0, 0.0, 1.0), ===)
|
||||
p = plot(1:2, minorgridcolor = :red)
|
||||
@test compare(p, :foreground_color_minor_grid, RGBA{Float64}(1.0, 0.0, 0.0, 1.0), ===)
|
||||
p = plot(1:2, grid_lw = 0.01)
|
||||
@test compare(p, :gridlinewidth, 0.01, ≈)
|
||||
p = plot(1:2, minorgrid_lw = 0.01)
|
||||
@test compare(p, :minorgridlinewidth, 0.01, ≈)
|
||||
p = plot(1:2, tickor = :out)
|
||||
@test compare(p, :tick_direction, :out, ===)
|
||||
end
|
||||
|
||||
@ -9,15 +9,12 @@ using Plots, Test
|
||||
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}}
|
||||
@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")
|
||||
@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"
|
||||
|
||||
@ -1,15 +1,6 @@
|
||||
using Plots, Test
|
||||
|
||||
@testset "Shapes" begin
|
||||
@testset "Type" begin
|
||||
square = Shape([(0, 0.0), (1, 0.0), (1, 1.0), (0, 1.0)])
|
||||
@test Plots.get_xs(square) == [0, 1, 1, 0]
|
||||
@test Plots.get_ys(square) == [0, 0, 1, 1]
|
||||
@test Plots.vertices(square) == [(0, 0), (1, 0), (1, 1), (0, 1)]
|
||||
@test isa(square, Shape{Int64,Float64})
|
||||
@test 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)
|
||||
@ -51,35 +42,6 @@ using Plots, Test
|
||||
@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 in 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
|
||||
|
||||
@testset "Misc" begin
|
||||
@test Plots.weave([1, 3], [2, 4]) == collect(1:4)
|
||||
@test Plots.makeshape(3) isa Plots.Shape
|
||||
@test Plots.makestar(3) isa Plots.Shape
|
||||
@test Plots.makecross() isa Plots.Shape
|
||||
@test Plots.makearrowhead(10.0) isa Plots.Shape
|
||||
|
||||
@test Plots.rotate(1.0, 2.0, 5.0, (0, 0)) isa Tuple
|
||||
|
||||
star = Plots.makestar(3)
|
||||
star_scaled = Plots.scale(star, 0.5)
|
||||
|
||||
Plots.scale!(star, 0.5)
|
||||
@test Plots.get_xs(star) == Plots.get_xs(star_scaled)
|
||||
@test Plots.get_ys(star) == Plots.get_ys(star_scaled)
|
||||
|
||||
@test Plots.extrema_plus_buffer([1, 2], 0.1) == (0.9, 2.1)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Brush" begin
|
||||
@ -104,52 +66,11 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Text" begin
|
||||
t = Plots.PlotText("foo")
|
||||
f = Plots.font()
|
||||
|
||||
@test Plots.PlotText(nothing).str == "nothing"
|
||||
@test length(t) == 3
|
||||
@test text(t).str == "foo"
|
||||
@test text(t, f).str == "foo"
|
||||
@test text("bar", f).str == "bar"
|
||||
@test text(true).str == "true"
|
||||
end
|
||||
|
||||
@testset "Annotations" begin
|
||||
ann = Plots.series_annotations(missing)
|
||||
|
||||
@test Plots.series_annotations(["1" "2"; "3" "4"]) isa AbstractMatrix
|
||||
@test Plots.series_annotations(10).strs[1].str == "10"
|
||||
@test Plots.series_annotations(nothing) === nothing
|
||||
@test Plots.series_annotations(ann) == ann
|
||||
|
||||
@test Plots.annotations(["1" "2"; "3" "4"]) isa AbstractMatrix
|
||||
@test Plots.annotations(ann) == ann
|
||||
@test Plots.annotations([ann]) == [ann]
|
||||
@test Plots.annotations(nothing) == []
|
||||
|
||||
t = Plots.text("foo")
|
||||
sp = plot(1)[1]
|
||||
@test Plots.locate_annotation(sp, 1, 2, t) == (1, 2, t)
|
||||
@test Plots.locate_annotation(sp, 1, 2, 3, t) == (1, 2, 3, t)
|
||||
@test Plots.locate_annotation(sp, (0.1, 0.2), t) isa Tuple
|
||||
@test Plots.locate_annotation(sp, (0.1, 0.2, 0.3), t) isa Tuple
|
||||
end
|
||||
|
||||
@testset "Fonts" begin
|
||||
@testset "Scaling" begin
|
||||
sizesToCheck = [
|
||||
:titlefontsize,
|
||||
:legendfontsize,
|
||||
:legendtitlefontsize,
|
||||
:xtickfontsize,
|
||||
:ytickfontsize,
|
||||
:ztickfontsize,
|
||||
:xguidefontsize,
|
||||
:yguidefontsize,
|
||||
:zguidefontsize,
|
||||
]
|
||||
sizesToCheck = [:titlefontsize, :legendfontsize, :legendtitlefontsize,
|
||||
:xtickfontsize, :ytickfontsize, :ztickfontsize,
|
||||
:xguidefontsize, :yguidefontsize, :zguidefontsize,]
|
||||
# get inital font sizes
|
||||
initialSizes = [Plots.default(s) for s in sizesToCheck ]
|
||||
|
||||
@ -171,51 +92,20 @@ end
|
||||
end
|
||||
|
||||
@testset "Series Annotations" begin
|
||||
square = Shape([(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)])
|
||||
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"],
|
||||
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
|
||||
),
|
||||
)
|
||||
:triangle # pass an incorrect argument
|
||||
))
|
||||
sa = p.series_list[1].plotattributes[:series_annotations]
|
||||
@test only(sa.strs).str == "a"
|
||||
@test sa.strs == ["a"]
|
||||
@test sa.font.family == "courier"
|
||||
@test sa.baseshape == square
|
||||
@test sa.scalefactor == (1,4)
|
||||
end
|
||||
spl = scatter(
|
||||
4.53 .* [1 / 1 1 / 2 1 / 3 1 / 4 1 / 5],
|
||||
[0 0 0 0 0],
|
||||
layout = (5, 1),
|
||||
ylims = (-1.1, 1.1),
|
||||
xlims = (0, 5),
|
||||
series_annotations = permutedims([["1/1"], ["1/2"], ["1/3"], ["1/4"], ["1/5"]]),
|
||||
)
|
||||
for i in 1:5
|
||||
@test only(spl.series_list[i].plotattributes[:series_annotations].strs).str ==
|
||||
"1/$i"
|
||||
end
|
||||
|
||||
p = plot([1, 2], annotations = (1.5, 2, text("foo", :left)))
|
||||
x, y, txt = only(p.subplots[end][:annotations])
|
||||
@test (x, y) == (1.5, 2)
|
||||
@test txt.str == "foo"
|
||||
|
||||
p = plot([1, 2], annotations = ((0.1, 0.5), :auto))
|
||||
pos, txt = only(p.subplots[end][:annotations])
|
||||
@test pos == (0.1, 0.5)
|
||||
@test txt.str == "(a)"
|
||||
end
|
||||
|
||||
@testset "Bezier" begin
|
||||
curve = Plots.BezierCurve([Plots.P2(0.0, 0.0), Plots.P2(0.5, 1.0), Plots.P2(1.0, 0.0)])
|
||||
@test curve(0.75) == Plots.P2(0.75, 0.375)
|
||||
@test length(coords(curve, 10)) == 10
|
||||
end
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
using Plots, Test
|
||||
import RecipesPipeline
|
||||
|
||||
@testset "Contours" begin
|
||||
@testset "check_contour_levels" begin
|
||||
@test Plots.check_contour_levels(2) === nothing
|
||||
@test Plots.check_contour_levels(-1.0:0.2:10.0) === nothing
|
||||
@test Plots.check_contour_levels([-100, -2, -1, 0, 1, 2, 100]) === nothing
|
||||
@test_throws ArgumentError Plots.check_contour_levels(1.0)
|
||||
@test_throws ArgumentError Plots.check_contour_levels((1, 2, 3))
|
||||
@test_throws ArgumentError Plots.check_contour_levels(-3)
|
||||
end
|
||||
|
||||
@testset "RecipesPipeline.preprocess_attributes!" begin
|
||||
function equal_after_pipeline(kw)
|
||||
kw′ = deepcopy(kw)
|
||||
RecipesPipeline.preprocess_attributes!(kw′)
|
||||
kw == kw′
|
||||
end
|
||||
|
||||
@test equal_after_pipeline(KW(:levels => 1))
|
||||
@test equal_after_pipeline(KW(:levels => 1:10))
|
||||
@test equal_after_pipeline(KW(:levels => [1.0, 3.0, 5.0]))
|
||||
@test_throws ArgumentError RecipesPipeline.preprocess_attributes!(
|
||||
KW(:levels => 1.0),
|
||||
)
|
||||
@test_throws ArgumentError RecipesPipeline.preprocess_attributes!(
|
||||
KW(:levels => (1, 2, 3)),
|
||||
)
|
||||
@test_throws ArgumentError RecipesPipeline.preprocess_attributes!(KW(:levels => -3))
|
||||
end
|
||||
|
||||
@testset "contour[f]" begin
|
||||
x = (-2π):0.1:(2π)
|
||||
y = (-π):0.1:π
|
||||
z = cos.(y) .* sin.(x')
|
||||
|
||||
@testset "Incorrect input" begin
|
||||
@test_throws ArgumentError contour(x, y, z, levels = 1.0)
|
||||
@test_throws ArgumentError contour(x, y, z, levels = (1, 2, 3))
|
||||
@test_throws ArgumentError contour(x, y, z, levels = -3)
|
||||
end
|
||||
|
||||
@testset "Default number" begin
|
||||
@test contour(x, y, z)[1][1].plotattributes[:levels] ==
|
||||
Plots._series_defaults[:levels]
|
||||
end
|
||||
|
||||
@testset "Number" begin
|
||||
@testset "$n contours" for n in (2, 5, 100)
|
||||
p = contour(x, y, z, levels = n)
|
||||
attr = p[1][1].plotattributes
|
||||
@test attr[:seriestype] == :contour
|
||||
@test attr[:levels] == n
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Range" begin
|
||||
levels = -1:0.5:1
|
||||
@test contour(x, y, z, levels = levels)[1][1].plotattributes[:levels] == levels
|
||||
end
|
||||
|
||||
@testset "Set of levels" begin
|
||||
levels = [-1, 0.25, 0, 0.25, 1]
|
||||
@test contour(x, y, z, levels = levels)[1][1].plotattributes[:levels] == levels
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,101 +1,11 @@
|
||||
using Plots, Test, Plots.Colors
|
||||
using Plots, Test
|
||||
|
||||
const PLOTS_DEFAULTS = Dict(:theme => :wong2, :fontfamily => :palantino)
|
||||
const PLOTS_DEFAULTS = Dict(:theme => :wong2)
|
||||
Plots.__init__()
|
||||
|
||||
@testset "Loading theme" begin
|
||||
pl = plot(1:5)
|
||||
@test pl[1][1][:seriescolor] == RGBA(colorant"black")
|
||||
@test Plots.guidefont(pl[1][:xaxis]).family == "palantino"
|
||||
@test plot(1:5)[1][1][:seriescolor] == RGBA(colorant"black")
|
||||
end
|
||||
|
||||
empty!(PLOTS_DEFAULTS)
|
||||
Plots.__init__()
|
||||
|
||||
@testset "default" begin
|
||||
default(fillrange = 0)
|
||||
@test Plots._series_defaults[:fillrange] == 0
|
||||
pl = plot(1:5)
|
||||
@test pl[1][1][:fillrange] == 0
|
||||
default()
|
||||
end
|
||||
|
||||
@testset "Legend defaults" begin
|
||||
p = plot()
|
||||
@test p[1][:legend_font_family] == "sans-serif"
|
||||
@test p[1][:legend_font_pointsize] == 8
|
||||
@test p[1][:legend_font_halign] == :hcenter
|
||||
@test p[1][:legend_font_valign] == :vcenter
|
||||
@test p[1][:legend_font_rotation] == 0.0
|
||||
@test p[1][:legend_font_color] == RGB{Colors.N0f8}(0.0, 0.0, 0.0)
|
||||
@test p[1][:legend_position] == :best
|
||||
@test p[1][:legend_title] == nothing
|
||||
@test p[1][:legend_title_font_family] == "sans-serif"
|
||||
@test p[1][:legend_title_font_pointsize] == 11
|
||||
@test p[1][:legend_title_font_halign] == :hcenter
|
||||
@test p[1][:legend_title_font_valign] == :vcenter
|
||||
@test p[1][:legend_title_font_rotation] == 0.0
|
||||
@test p[1][:legend_title_font_color] == RGB{Colors.N0f8}(0.0, 0.0, 0.0)
|
||||
@test p[1][:legend_background_color] == RGBA{Float64}(1.0, 1.0, 1.0, 1.0)
|
||||
@test p[1][:legend_foreground_color] == RGB{Colors.N0f8}(0.0, 0.0, 0.0)
|
||||
end # testset
|
||||
|
||||
@testset "Legend API" begin
|
||||
p = plot(;
|
||||
legendfontfamily = "serif",
|
||||
legendfontsize = 12,
|
||||
legendfonthalign = :left,
|
||||
legendfontvalign = :top,
|
||||
legendfontrotation = 1,
|
||||
legendfontcolor = :red,
|
||||
legend = :outertopleft,
|
||||
legendtitle = "The legend",
|
||||
legendtitlefontfamily = "helvetica",
|
||||
legendtitlefontsize = 3,
|
||||
legendtitlefonthalign = :right,
|
||||
legendtitlefontvalign = :bottom,
|
||||
legendtitlefontrotation = -5.2,
|
||||
legendtitlefontcolor = :blue,
|
||||
background_color_legend = :cyan,
|
||||
foreground_color_legend = :green,
|
||||
)
|
||||
@test p[1][:legend_font_family] == "serif"
|
||||
@test p[1][:legend_font_pointsize] == 12
|
||||
@test p[1][:legend_font_halign] == :left
|
||||
@test p[1][:legend_font_valign] == :top
|
||||
@test p[1][:legend_font_rotation] == 1.0
|
||||
@test p[1][:legend_font_color] == :red
|
||||
@test p[1][:legend_position] == :outertopleft
|
||||
@test p[1][:legend_title] == "The legend"
|
||||
@test p[1][:legend_title_font_family] == "helvetica"
|
||||
@test p[1][:legend_title_font_pointsize] == 3
|
||||
@test p[1][:legend_title_font_halign] == :right
|
||||
@test p[1][:legend_title_font_valign] == :bottom
|
||||
@test p[1][:legend_title_font_rotation] == -5.2
|
||||
@test p[1][:legend_title_font_color] == :blue
|
||||
@test p[1][:legend_background_color] == RGBA{Float64}(0.0, 1.0, 1.0, 1.0)
|
||||
@test p[1][:legend_foreground_color] == RGBA{Float64}(0.0, 0.5019607843137255, 0.0, 1.0)
|
||||
|
||||
#remember settings
|
||||
plot(legend_font_pointsize = 20)
|
||||
sp = plot!(label = "R")[1]
|
||||
@test Plots.legendfont(sp).pointsize == 20
|
||||
|
||||
#setting whole font
|
||||
sp = plot(
|
||||
1:5,
|
||||
legendfont = font(12),
|
||||
legend_font_halign = :left,
|
||||
foreground_color_subplot = :red,
|
||||
)[1]
|
||||
@test Plots.legendfont(sp).pointsize == 12
|
||||
@test Plots.legendfont(sp).halign == :left
|
||||
# match mechanism
|
||||
@test sp[:legend_font_color] == sp[:foreground_color_subplot]
|
||||
@test Plots.legendfont(sp).color == sp[:foreground_color_subplot]
|
||||
|
||||
# magic invocation
|
||||
@test_nowarn sp = plot(; legendfont = 12)[1]
|
||||
@test sp[:legend_font_pointsize] == 12
|
||||
@test Plots.legendfont(sp).pointsize == 12
|
||||
end # testset
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
using Plots, HDF5
|
||||
|
||||
|
||||
@testset "HDF5_Plots" begin
|
||||
fname = "tmpplotsave.hdf5"
|
||||
hdf5()
|
||||
|
||||
x = 1:10
|
||||
psrc = plot(x, x .* x) #Create some plot
|
||||
psrc=plot(x, x.*x); #Create some plot
|
||||
Plots.hdf5plot_write(psrc, fname)
|
||||
|
||||
#Read back file:
|
||||
|
||||
@ -1,98 +0,0 @@
|
||||
using Plots, Test
|
||||
|
||||
@testset "Subplot sclicing" begin
|
||||
pl = @test_nowarn plot(
|
||||
rand(4, 8),
|
||||
layout = 4,
|
||||
yscale = [:identity :identity :log10 :log10],
|
||||
)
|
||||
@test pl[1][:yaxis][:scale] == :identity
|
||||
@test pl[2][:yaxis][:scale] == :identity
|
||||
@test pl[3][:yaxis][:scale] == :log10
|
||||
@test pl[4][:yaxis][:scale] == :log10
|
||||
end
|
||||
|
||||
@testset "Plot title" begin
|
||||
pl = plot(rand(4, 8), layout = 4, plot_title = "My title")
|
||||
@test pl[:plot_title] == "My title"
|
||||
@test pl[:plot_titleindex] == 5
|
||||
|
||||
plot!(pl)
|
||||
@test pl[:plot_title] == "My title"
|
||||
@test pl[:plot_titleindex] == 5
|
||||
|
||||
plot!(pl, plot_title = "My new title")
|
||||
@test pl[:plot_title] == "My new title"
|
||||
@test pl[:plot_titleindex] == 5
|
||||
end
|
||||
|
||||
@testset "Plots.jl/issues/4083" begin
|
||||
p = plot(plot(1:2), plot(1:2); border = :grid, plot_title = "abc")
|
||||
@test p[1][:framestyle] === :grid
|
||||
@test p[2][:framestyle] === :grid
|
||||
@test p[3][:framestyle] === :none
|
||||
end
|
||||
|
||||
@testset "Coverage" begin
|
||||
p = plot((plot(i) for i in 1:4)..., layout = (2, 2))
|
||||
|
||||
sp = p[end]
|
||||
@test sp isa Plots.Subplot
|
||||
@test size(sp) == (1, 1)
|
||||
@test length(sp) == 1
|
||||
@test sp[1, 1] == sp
|
||||
@test Plots.get_subplot(p, UInt32(4)) == sp
|
||||
@test Plots.series_list(sp) |> first |> Plots.get_subplot isa Plots.Subplot
|
||||
@test Plots.get_subplot(p, keys(p.spmap) |> first) isa Plots.Subplot
|
||||
|
||||
gl = p[2, 2]
|
||||
@test gl isa Plots.GridLayout
|
||||
@test length(gl) == 1
|
||||
@test size(gl) == (1, 1)
|
||||
@test Plots.layout_args(gl) == (gl, 1)
|
||||
|
||||
@test size(p, 1) == 2
|
||||
@test size(p, 2) == 2
|
||||
@test size(p) === (2, 2)
|
||||
@test ndims(p) == 2
|
||||
|
||||
@test p[1][end] isa Plots.Series
|
||||
show(devnull, p[1])
|
||||
|
||||
@test Plots.getplot(p) == p
|
||||
@test Plots.getattr(p) == p.attr
|
||||
@test Plots.backend_object(p) == p.o
|
||||
@test occursin("Plot", string(p))
|
||||
print(devnull, p)
|
||||
|
||||
@test Plots.to_pixels(1Plots.mm) isa AbstractFloat
|
||||
@test Plots.ispositive(1Plots.mm)
|
||||
@test size(Plots.defaultbox) == (0Plots.mm, 0Plots.mm)
|
||||
show(devnull, Plots.defaultbox)
|
||||
show(devnull, p.layout)
|
||||
|
||||
@test Plots.make_measure_hor(1Plots.mm) == 1Plots.mm
|
||||
@test Plots.make_measure_vert(1Plots.mm) == 1Plots.mm
|
||||
|
||||
@test Plots.parent(p.layout) isa Plots.RootLayout
|
||||
show(devnull, Plots.parent_bbox(p.layout))
|
||||
|
||||
rl = Plots.RootLayout()
|
||||
show(devnull, rl)
|
||||
@test parent(rl) === nothing
|
||||
@test Plots.parent_bbox(rl) == Plots.defaultbox
|
||||
@test Plots.bbox(rl) == Plots.defaultbox
|
||||
|
||||
el = Plots.EmptyLayout()
|
||||
@test Plots.update_position!(el) === nothing
|
||||
@test size(el) == (0, 0)
|
||||
@test length(el) == 0
|
||||
@test el[1, 1] === nothing
|
||||
|
||||
@test Plots.left(el) == 0Plots.mm
|
||||
@test Plots.top(el) == 0Plots.mm
|
||||
@test Plots.right(el) == 0Plots.mm
|
||||
@test Plots.bottom(el) == 0Plots.mm
|
||||
|
||||
@test_throws ErrorException Plots.layout_args(nothing)
|
||||
end
|
||||
@ -21,19 +21,16 @@ end
|
||||
@test !haskey(axis.contents[1].options.dict, "fill")
|
||||
|
||||
@testset "Legends" begin
|
||||
legends_plot = plot(rand(5, 2), lab = ["1" ""], arrow = true)
|
||||
legends_plot = plot(rand(5, 2), lab = ["1" ""])
|
||||
scatter!(legends_plot, rand(5))
|
||||
Plots._update_plot_object(legends_plot)
|
||||
axis_contents = Plots.pgfx_axes(legends_plot.o)[1].contents
|
||||
leg_entries = filter(x -> x isa PGFPlotsX.LegendEntry, axis_contents)
|
||||
series = filter(x -> x isa PGFPlotsX.Plot, axis_contents)
|
||||
@test length(leg_entries) == 2
|
||||
@test length(series) == 5
|
||||
@test !haskey(series[1].options.dict, "forget plot")
|
||||
@test haskey(series[2].options.dict, "forget plot")
|
||||
@test haskey(series[3].options.dict, "forget plot")
|
||||
@test haskey(series[4].options.dict, "forget plot")
|
||||
@test !haskey(series[5].options.dict, "forget plot")
|
||||
@test !haskey(series[3].options.dict, "forget plot")
|
||||
end # testset
|
||||
|
||||
@testset "3D docs example" begin
|
||||
@ -85,7 +82,8 @@ end
|
||||
marker = axis.contents[15]
|
||||
@test marker isa PGFPlotsX.Plot
|
||||
@test marker.options["mark"] == "*"
|
||||
@test marker.options["mark options"]["color"] == RGBA{Float64}(colorant"green", 0.8)
|
||||
@test marker.options["mark options"]["color"] ==
|
||||
RGBA{Float64}(colorant"green", 0.8)
|
||||
@test marker.options["mark options"]["line width"] == 0.75 # 1px is 0.75pt
|
||||
end # testset
|
||||
@testset "Plot in pieces" begin
|
||||
@ -172,8 +170,8 @@ end
|
||||
histogram2d(randn(10000), randn(10000), nbins = 20)
|
||||
end # testset
|
||||
@testset "Heatmap-like" begin
|
||||
xs = [string("x", i) for i in 1:10]
|
||||
ys = [string("y", i) for i in 1:4]
|
||||
xs = [string("x", i) for i = 1:10]
|
||||
ys = [string("y", i) for i = 1:4]
|
||||
z = float((1:4) * reshape(1:10, 1, :))
|
||||
pgfx_plot = heatmap(xs, ys, z, aspect_ratio = 1)
|
||||
Plots._update_plot_object(pgfx_plot)
|
||||
@ -207,9 +205,15 @@ end
|
||||
x = t .* cos.(θ)
|
||||
y = t .* sin.(θ)
|
||||
p1 = plot(x, y, line_z = t, linewidth = 3, legend = false)
|
||||
p2 = scatter(x, y, marker_z = ((x, y) -> begin
|
||||
p2 = scatter(
|
||||
x,
|
||||
y,
|
||||
marker_z = ((x, y) -> begin
|
||||
x + y
|
||||
end), color = :bwr, legend = false)
|
||||
end),
|
||||
color = :bwr,
|
||||
legend = false,
|
||||
)
|
||||
plot(p1, p2)
|
||||
end # testset
|
||||
@testset "Framestyles" begin
|
||||
@ -241,8 +245,11 @@ end
|
||||
end # testset
|
||||
@testset "Annotations" begin
|
||||
y = rand(10)
|
||||
pgfx_plot =
|
||||
plot(y, annotations = (3, y[3], Plots.text("this is \\#3", :left)), leg = false)
|
||||
pgfx_plot = plot(
|
||||
y,
|
||||
annotations = (3, y[3], Plots.text("this is \\#3", :left)),
|
||||
leg = false,
|
||||
)
|
||||
Plots._update_plot_object(pgfx_plot)
|
||||
axis_content = Plots.pgfx_axes(pgfx_plot.o)[1].contents
|
||||
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
|
||||
@ -307,7 +314,8 @@ end
|
||||
bb = rand(10)
|
||||
cc = rand(10)
|
||||
conf = [aa - cc bb - cc]
|
||||
ribbon_plot = plot(collect(1:10), fill(1, 10), ribbon = (conf[:, 1], conf[:, 2]))
|
||||
ribbon_plot =
|
||||
plot(collect(1:10), fill(1, 10), ribbon = (conf[:, 1], conf[:, 2]))
|
||||
Plots._update_plot_object(ribbon_plot)
|
||||
axis = Plots.pgfx_axes(ribbon_plot.o)[1]
|
||||
plots = filter(x -> x isa PGFPlotsX.Plot, axis.contents)
|
||||
@ -330,22 +338,6 @@ end
|
||||
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
|
||||
@ -376,8 +368,12 @@ end # testset
|
||||
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)
|
||||
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)
|
||||
@ -404,7 +400,11 @@ end # testset
|
||||
@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))
|
||||
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
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
using Plots, Test
|
||||
using RecipesPipeline
|
||||
|
||||
@testset "plot" begin
|
||||
pl = plot(1:5)
|
||||
pl2 = plot(pl, tex_output_standalone = true)
|
||||
@test pl[:tex_output_standalone] == false
|
||||
@test pl2[:tex_output_standalone] == true
|
||||
plot!(pl, tex_output_standalone = true)
|
||||
@test pl[:tex_output_standalone] == true
|
||||
end
|
||||
|
||||
@testset "get_axis_limits" begin
|
||||
x = [0.1, 5]
|
||||
p1 = plot(x, [5, 0.1], yscale = :log10)
|
||||
p2 = plot!(identity)
|
||||
@test all(RecipesPipeline.get_axis_limits(p1, :x) .== x)
|
||||
@test all(RecipesPipeline.get_axis_limits(p2, :x) .== x)
|
||||
end
|
||||
|
||||
@testset "Slicing" begin
|
||||
@test plot(1:5, fillrange = 0)[1][1][:fillrange] == 0
|
||||
data4 = rand(4, 4)
|
||||
mat = reshape(1:8, 2, 4)
|
||||
for i in axes(data4, 1)
|
||||
for attribute in (:fillrange, :ribbon)
|
||||
@test plot(data4; NamedTuple{tuple(attribute)}(0)...)[1][i][attribute] == 0
|
||||
@test plot(data4; NamedTuple{tuple(attribute)}(Ref([1, 2]))...)[1][i][attribute] ==
|
||||
[1.0, 2.0]
|
||||
@test plot(data4; NamedTuple{tuple(attribute)}(Ref([1 2]))...)[1][i][attribute] ==
|
||||
(iseven(i) ? 2 : 1)
|
||||
@test plot(data4; NamedTuple{tuple(attribute)}(Ref(mat))...)[1][i][attribute] ==
|
||||
[2(i - 1) + 1, 2i]
|
||||
end
|
||||
@test plot(data4, ribbon = (mat, mat))[1][i][:ribbon] ==
|
||||
([2(i - 1) + 1, 2i], [2(i - 1) + 1, 2i])
|
||||
end
|
||||
end
|
||||
@ -1,64 +0,0 @@
|
||||
using Plots, Test
|
||||
|
||||
@testset "Plotly" begin
|
||||
@testset "Basic" begin
|
||||
@test plotly() == Plots.PlotlyBackend()
|
||||
@test backend() == Plots.PlotlyBackend()
|
||||
|
||||
p = plot(rand(10))
|
||||
@test isa(p, Plots.Plot) == true
|
||||
@test_nowarn Plots.plotly_series(plot())
|
||||
end
|
||||
|
||||
@testset "Contours" begin
|
||||
x = (-2π):0.1:(2π)
|
||||
y = (-π):0.1:π
|
||||
z = cos.(y) .* sin.(x')
|
||||
|
||||
@testset "Contour numbers" begin
|
||||
@testset "Default" begin
|
||||
@test Plots.plotly_series(contour(x, y, z))[1][:ncontours] ==
|
||||
Plots._series_defaults[:levels] + 2
|
||||
end
|
||||
@testset "Specified number" begin
|
||||
@test Plots.plotly_series(contour(x, y, z, levels = 10))[1][:ncontours] ==
|
||||
12
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Contour values" begin
|
||||
@testset "Range" begin
|
||||
levels = -1:0.5:1
|
||||
p = contour(x, y, z, levels = levels)
|
||||
@test p[1][1].plotattributes[:levels] == levels
|
||||
@test Plots.plotly_series(p)[1][:contours][:start] == first(levels)
|
||||
@test Plots.plotly_series(p)[1][:contours][:end] == last(levels)
|
||||
@test Plots.plotly_series(p)[1][:contours][:size] == step(levels)
|
||||
end
|
||||
|
||||
@testset "Set of contours" begin
|
||||
levels = [-1, -0.25, 0, 0.25, 1]
|
||||
levels_range =
|
||||
range(first(levels), stop = last(levels), length = length(levels))
|
||||
p = contour(x, y, z, levels = levels)
|
||||
@test p[1][1].plotattributes[:levels] == levels
|
||||
series_dict = @test_logs (
|
||||
:warn,
|
||||
"setting arbitrary contour levels with Plotly backend " *
|
||||
"is not supported; use a range to set equally-spaced contours or an " *
|
||||
"integer to set the approximate number of contours with the keyword " *
|
||||
"`levels`. Setting levels to -1.0:0.5:1.0",
|
||||
) Plots.plotly_series(p)
|
||||
@test series_dict[1][:contours][:start] == first(levels_range)
|
||||
@test series_dict[1][:contours][:end] == last(levels_range)
|
||||
@test series_dict[1][:contours][:size] == step(levels_range)
|
||||
end
|
||||
end
|
||||
end
|
||||
@testset "Extra kwargs" begin
|
||||
pl = plot(1:5, test = "me")
|
||||
@test Plots.plotly_series(pl)[1][:test] == "me"
|
||||
pl = plot(1:5, test = "me", extra_kwargs = :plot)
|
||||
@test Plots.plotly_layout(pl)[:test] == "me"
|
||||
end
|
||||
end
|
||||
@ -1,18 +1,6 @@
|
||||
using Plots, Test
|
||||
using OffsetArrays
|
||||
|
||||
@testset "User recipes" begin
|
||||
struct LegendPlot end
|
||||
@recipe function f(plot::LegendPlot)
|
||||
legend --> :topleft
|
||||
(1:3, 1:3)
|
||||
end
|
||||
pl = plot(LegendPlot(); legend = :right)
|
||||
@test pl[1][:legend_position] == :right
|
||||
pl = plot(LegendPlot())
|
||||
@test pl[1][:legend_position] == :topleft
|
||||
end
|
||||
|
||||
@testset "lens!" begin
|
||||
pl = plot(1:5)
|
||||
lens!(pl, [1,2], [1,2], inset = (1, bbox(0.0,0.0,0.2,0.2)), colorbar = false)
|
||||
|
||||
@ -7,132 +7,42 @@ using Plots, Test
|
||||
xlims!((1,20))
|
||||
@test xlims(p) == (1,20)
|
||||
|
||||
xlims!(p, (1, 21))
|
||||
@test xlims(p) == (1, 21)
|
||||
|
||||
ylims!((-1,1))
|
||||
@test ylims(p) == (-1,1)
|
||||
|
||||
ylims!(p, (-2, 2))
|
||||
@test ylims(p) == (-2, 2)
|
||||
|
||||
zlims!((-1,1))
|
||||
@test zlims(p) == (-1,1)
|
||||
|
||||
zlims!(p, (-2, 2))
|
||||
@test zlims(p) == (-2, 2)
|
||||
|
||||
xlims!(-1,11)
|
||||
@test xlims(p) == (-1,11)
|
||||
|
||||
xlims!(p, -2, 12)
|
||||
@test xlims(p) == (-2, 12)
|
||||
|
||||
ylims!((-10,10))
|
||||
@test ylims(p) == (-10,10)
|
||||
|
||||
ylims!(p, (-11, 9))
|
||||
@test ylims(p) == (-11, 9)
|
||||
|
||||
zlims!((-10,10))
|
||||
@test zlims(p) == (-10,10)
|
||||
|
||||
zlims!(p, (-9, 8))
|
||||
@test zlims(p) == (-9, 8)
|
||||
end
|
||||
|
||||
@testset "Set Title / Labels" begin
|
||||
p = plot()
|
||||
title!(p, "Foo")
|
||||
sp = p[1]
|
||||
@test sp[:title] == "Foo"
|
||||
xlabel!(p, "xlabel")
|
||||
@test sp[:xaxis][:guide] == "xlabel"
|
||||
ylabel!(p, "ylabel")
|
||||
@test sp[:yaxis][:guide] == "ylabel"
|
||||
end
|
||||
|
||||
@testset "Misc" begin
|
||||
p = plot()
|
||||
sp = p[1]
|
||||
|
||||
xflip!(p)
|
||||
@test sp[:xaxis][:flip]
|
||||
|
||||
yflip!(p)
|
||||
@test sp[:yaxis][:flip]
|
||||
|
||||
xgrid!(p, true)
|
||||
@test sp[:xaxis][:grid]
|
||||
|
||||
xgrid!(p, false)
|
||||
@test !sp[:xaxis][:grid]
|
||||
|
||||
ygrid!(p, true)
|
||||
@test sp[:yaxis][:grid]
|
||||
|
||||
ygrid!(p, false)
|
||||
@test !sp[:yaxis][:grid]
|
||||
|
||||
ann = [(7, 3, "(7,3)"), (3, 7, text("hey", 14, :left, :top, :green))]
|
||||
annotate!(p, ann)
|
||||
annotate!(p, ann...)
|
||||
|
||||
xaxis!(p, true)
|
||||
@test sp[:xaxis][:showaxis]
|
||||
|
||||
xaxis!(p, false)
|
||||
@test !sp[:xaxis][:showaxis]
|
||||
|
||||
yaxis!(p, true)
|
||||
@test sp[:yaxis][:showaxis]
|
||||
|
||||
yaxis!(p, false)
|
||||
@test !sp[:yaxis][:showaxis]
|
||||
|
||||
p = plot3d([1, 2], [1, 2], [1, 2])
|
||||
plot3d!(p, [3, 4], [3, 4], [3, 4])
|
||||
@test Plots.series_list(p[1])[1][:seriestype] == :path3d
|
||||
end
|
||||
|
||||
@testset "Set Ticks" begin
|
||||
p = plot([0,2,3,4,5,6,7,8,9,10])
|
||||
sp = p[1]
|
||||
|
||||
xticks = 2:6
|
||||
xticks!(xticks)
|
||||
@test sp.attr[:xaxis][:ticks] == xticks
|
||||
|
||||
xticks = 1:5
|
||||
xticks!(p, xticks)
|
||||
@test sp.attr[:xaxis][:ticks] == xticks
|
||||
@test Plots.get_subplot(current(),1).attr[:xaxis][:ticks] == xticks
|
||||
|
||||
yticks = 0.2:0.1:0.7
|
||||
yticks!(yticks)
|
||||
@test sp.attr[:yaxis][:ticks] == yticks
|
||||
|
||||
yticks = 0.1:0.5
|
||||
yticks!(p, yticks)
|
||||
@test sp.attr[:yaxis][:ticks] == yticks
|
||||
@test Plots.get_subplot(current(),1).attr[:yaxis][:ticks] == yticks
|
||||
|
||||
xticks = [5,6,7.5]
|
||||
xlabels = ["a","b","c"]
|
||||
|
||||
xticks!(xticks, xlabels)
|
||||
@test sp.attr[:xaxis][:ticks] == (xticks, xlabels)
|
||||
@test Plots.get_subplot(current(),1).attr[:xaxis][:ticks] == (xticks, xlabels)
|
||||
|
||||
xticks = [5, 2]
|
||||
xlabels = ["b", "a"]
|
||||
xticks!(p, xticks, xlabels)
|
||||
@test sp.attr[:xaxis][:ticks] == (xticks, xlabels)
|
||||
|
||||
yticks = [0.5, 0.6, 0.75]
|
||||
yticks = [.5,.6,.75]
|
||||
ylabels = ["z","y","x"]
|
||||
yticks!(yticks, ylabels)
|
||||
@test sp.attr[:yaxis][:ticks] == (yticks, ylabels)
|
||||
|
||||
yticks = [0.5, 0.1]
|
||||
ylabels = ["z", "y"]
|
||||
yticks!(p, yticks, ylabels)
|
||||
@test sp.attr[:yaxis][:ticks] == (yticks, ylabels)
|
||||
@test Plots.get_subplot(current(),1).attr[:yaxis][:ticks] == (yticks, ylabels)
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user