Compare commits
155 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4bc6412b46 | |||
| 798de8b17c | |||
| b0ff0e58b3 | |||
| 5cca5e9148 | |||
| 90e0074f44 | |||
| 3e14a47e17 | |||
| 5d608d1e77 | |||
| 20e24cfa8d | |||
| 2d0191cd70 | |||
| 12d5accf0a | |||
| c02dbca31d | |||
| 0e25767cd3 | |||
| 5d935d29c5 | |||
| f5e6ae9f98 | |||
| 4a18098944 | |||
| 3994e47d3c | |||
| 39d52a5c57 | |||
| 91e91ac821 | |||
| e9949251a6 | |||
| 16e41f0690 | |||
| 6f4400411e | |||
| 1bba6afde5 | |||
| 909ad3314a | |||
| 68a56fee91 | |||
| 9f4e32aa4d | |||
| 434e189f1e | |||
| c9f7c6b45d | |||
| e58fdf970f | |||
| c97900f7ee | |||
| 1b881619e3 | |||
| fbd5d79d49 | |||
| db7420fd5f | |||
| 09356ee3b5 | |||
| 0122d70640 | |||
| 5974d0ac31 | |||
| 81170b4342 | |||
| ee316e2913 | |||
| ef93aa87be | |||
| 88ebb8152d | |||
| 124d2d6aa3 | |||
| cdbafd60c8 | |||
| 5eb62abb25 | |||
| 3f110d6a6c | |||
| 293b43013b | |||
| 3536acbcc8 | |||
| 0ca5bc9124 | |||
| 14b38354da | |||
| 06c551ba51 | |||
| f63ee6d79e | |||
| b3f698c460 | |||
| 829860fa2d | |||
| 1523ef67d5 | |||
| e049b082f3 | |||
| f78899a1ef | |||
| e42b4ad34d | |||
| a7c629f775 | |||
| 1ddc673201 | |||
| bba971f7ea | |||
| 3f9105054c | |||
| a64ae3d13c | |||
| 7b0066c433 | |||
| d657c0cb33 | |||
| 50f63cf1eb | |||
| 2b22dae757 | |||
| 7ca32b5edd | |||
| 3f5a1287be | |||
| 990e0f3f7f | |||
| 849d31d57f | |||
| cfe5ba24a6 | |||
| be1c263df9 | |||
| 203af856cd | |||
| 019a742c84 | |||
| 5330776040 | |||
| fcdb3c1c0d | |||
| cc290818d7 | |||
| 14b3852060 | |||
| 387f918080 | |||
| d0d95c6cc7 | |||
| d51059f0e9 | |||
| 4723c513be | |||
| d1373d8b89 | |||
| 9f51b96269 | |||
| 601df0c9a9 | |||
| 700b5782ec | |||
| 6a62d96751 | |||
| 25b57cfb55 | |||
| fb390d1872 | |||
| 5fafddb995 | |||
| 697e5a87cf | |||
| 77ba81de19 | |||
| e43f3ee373 | |||
| 8f055fef3d | |||
| ce530ef518 | |||
| 827462dc21 | |||
| 1ecec912a1 | |||
| ca8e775b83 | |||
| c0e50588d3 | |||
| de7717b85f | |||
| a1311e5c60 | |||
| 4069b73563 | |||
| a7d6e93af3 | |||
| 058983165e | |||
| 97036e689e | |||
| d3589db840 | |||
| 15bd9c537d | |||
| 27764bbc67 | |||
| 788e28d18a | |||
| d544647b1b | |||
| 3cb81d6d04 | |||
| 61f2d825b6 | |||
| 5df64bd45b | |||
| 7e997da6bd | |||
| 35658bf4fe | |||
| f355ff9904 | |||
| 8893782b13 | |||
| 78f7db138f | |||
| 23567964e7 | |||
| 0c7f7ba011 | |||
| 4731477920 | |||
| 57ba6aa5a9 | |||
| 3c472f24b5 | |||
| 5a4651a0ec | |||
| 7bb2132b18 | |||
| fd50469e20 | |||
| e3d13aa17a | |||
| 476de3d2a2 | |||
| c986bfa1e6 | |||
| dfd8fada9d | |||
| d4298bf1cc | |||
| 02437562a7 | |||
| 8cf268a390 | |||
| fbf3878ca5 | |||
| e449d3221c | |||
| a359f21325 | |||
| 9da550ba3b | |||
| 0a7035979f | |||
| 6376d40ae2 | |||
| 67f4d79c4a | |||
| 50adb6cd9c | |||
| 64f3d589b6 | |||
| 07b05e075e | |||
| 1ceb3a561f | |||
| e1e0f8d1c9 | |||
| f39ba03da5 | |||
| 7d7212ba3e | |||
| 17a942998d | |||
| 6a829e2b1a | |||
| 011591ff55 | |||
| c56654c6cf | |||
| 90255913a4 | |||
| 67d7b4d771 | |||
| 3051ce9e57 | |||
| 09e90c0ca6 | |||
| dbe9a2c52b | |||
| 9ad3654d4f |
@@ -28,5 +28,5 @@ inspectdr | | |
|
||||
### Versions
|
||||
|
||||
Plots.jl version:
|
||||
Backend version (`]st -m`):
|
||||
Backend version (`]st -m <backend(s)>`):
|
||||
Output of `versioninfo()`:
|
||||
|
||||
@@ -71,7 +71,10 @@ jobs:
|
||||
|
||||
# Run tests
|
||||
- name: Run Graphical test
|
||||
run: $TESTCMD --project -e 'using Pkg; Pkg.test(coverage=true);'
|
||||
run: |
|
||||
$TESTCMD --project -e 'using Pkg; Pkg.test(coverage=true);'
|
||||
$TESTCMD -e 'using Pkg; Pkg.activate(tempdir()); Pkg.develop(path=abspath(".")); Pkg.add("StatsPlots"); Pkg.test("StatsPlots");'
|
||||
$TESTCMD -e 'using Pkg; Pkg.activate(tempdir()); Pkg.develop(path=abspath(".")); Pkg.add("GraphRecipes"); Pkg.test("GraphRecipes");'
|
||||
|
||||
- name: Codecov
|
||||
uses: julia-actions/julia-uploadcodecov@latest
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
name: docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags: '*'
|
||||
|
||||
jobs:
|
||||
Build_docs:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: JuliaPlots/PlotDocs.jl
|
||||
- uses: julia-actions/setup-julia@v1
|
||||
- name: Cache artifacts
|
||||
uses: actions/cache@v1
|
||||
env:
|
||||
cache-name: cache-artifacts
|
||||
with:
|
||||
path: ~/.julia/artifacts
|
||||
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-test-${{ env.cache-name }}-
|
||||
${{ runner.os }}-test-
|
||||
${{ runner.os }}-
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y qt5-default \
|
||||
ttf-mscorefonts-installer \
|
||||
poppler-utils \
|
||||
pdf2svg \
|
||||
texlive-latex-base \
|
||||
texlive-binaries \
|
||||
texlive-pictures \
|
||||
texlive-latex-extra \
|
||||
texlive-luatex \
|
||||
ghostscript-x \
|
||||
libgconf2-4
|
||||
sudo fc-cache -vr
|
||||
|
||||
- name: build documentation
|
||||
env:
|
||||
PYTHON: ""
|
||||
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
|
||||
run: |
|
||||
xvfb-run julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.add(PackageSpec(name="Plots", rev=split(ENV["GITHUB_REF"], "/", limit=3)[3])); Pkg.instantiate()'
|
||||
xvfb-run julia --color=yes --project=docs/ -e 'withenv("GITHUB_REPOSITORY" => "JuliaPlots/PlotDocs.jl") do; include("docs/make.jl"); end'
|
||||
@@ -12,3 +12,4 @@ dev/
|
||||
test/tmpplotsave.hdf5
|
||||
/.benchmarkci
|
||||
/benchmark/*.json
|
||||
.vscode/
|
||||
|
||||
+698
@@ -0,0 +1,698 @@
|
||||
{
|
||||
"title": "Plots.jl",
|
||||
"license": "MIT",
|
||||
"creators": [
|
||||
{
|
||||
"affiliation": "Elemental Cognition",
|
||||
"name": "Tom Breloff"
|
||||
}
|
||||
],
|
||||
"contributors":[
|
||||
{
|
||||
"affiliation": "TU Wien",
|
||||
"name": "Daniel Schwabeneder",
|
||||
"orcid": "0000-0002-0412-0777",
|
||||
"type": "ProjectLeader"
|
||||
},
|
||||
{
|
||||
"affiliation": "GLOBE Institute, 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",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "david-macmahon",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Fredrik Ekre",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Maaz Bin Tahir Saeed",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Kristoffer Carlsson",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Will Kearney",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Niklas Korsbo",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Miles Lucas",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@Godisemo",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Florian Oswald",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Diego Javier Zea",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@WillRam",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Fedor Bezrukov",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Spencer Lyon",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Darwin Darakananda",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Lukas Hauertmann",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Huckleberry Febbo",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@H-M-H",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Josh Day",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@wfgra",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Sheehan Olver",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jerry Ling",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jks Liu",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Seth Axen",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@o01eg",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Micluța-Câmpeanu",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Tim Holy",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Tony Kelman",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Antoine Levitt",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Iblis Lin",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Harry Scholes",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@djsegal",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Goran Nakerst",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Felix Hagemann",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Matthieu Gomez",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@biggsbiggsby",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Anderson",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Michael Kraus",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Carlo Lucibello",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Robin Deits",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Misha Mkhasenko",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Benoît Legat",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Steven G. Johnson",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "John Verzani",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Mattias Fält",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Rashika Karki",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Morten Piibeleht",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Filippo Vicentini",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "David Anthoff",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Leon Wabeke",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Yusuke Kominami",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Oscar Dowson",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Max G",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Fabian Greimel",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jérémy",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Pearl Li",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "David P. Sanders",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Asbjørn Nilsen Riseth",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jan Weidner",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@jakkor2",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Pablo Zubieta",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Hamza Yusuf Çakır",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "John Rinehart",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Martin Biel",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Moritz Schauer",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Moesè Giodano",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@olegshtch",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Leon Shen",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jeff Fessler",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@hustf",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Asim H Dar",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@8uurg",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Abel Siqueira",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Adrian Dawid",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Alberto Lusiani",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Balázs Mezei",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Ben Ide",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Lungwitz",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"affiliation": "University of Graz",
|
||||
"name": "Bernd Riederer",
|
||||
"type": "Other",
|
||||
"orcid": "0000-0001-8390-0087"
|
||||
},
|
||||
{
|
||||
"name": "Christina Lee",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Christof Stocker",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Christoph Finkensiep",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@Cornelius-G",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Daniel Høegh",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Denny Biasiolli",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Dieter Castel",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Elliot Saba",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Fengyang Wang",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Fons van der Plas",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Fredrik Bagge Carlson",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Graham Smith",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Hayato Ikoma",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Hessam Mehr",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@InfiniteChai",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jack Dunn",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jeff Bezanson",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jeff Eldredge",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Jinay Jain",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Johan Blåbäck",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@jmert",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Lakshya Khatri",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Lia Siegelmann",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@marekkukan-tw",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"affiliation": "ETH Zurich",
|
||||
"name": "Mauro Werder",
|
||||
"type": "Other",
|
||||
"orcid": "0000-0003-0137-9377"
|
||||
},
|
||||
{
|
||||
"name": "Maxim Grechkin",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Michael Cawte",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@milesfrain",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Nicholas Bauer",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Nicolau Leal Werneck",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@nilshg",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Oliver Evans",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Peter Gagarinov",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Páll Haraldsson",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Rik Huijzer",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Romain Franconville",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Ronan Pigott",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Roshan Shariff",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Scott Thomas",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Rollén",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Seth Bromberger",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Siva Swaminathan",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Tim DuBois",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Travis DePrato",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Will Thompson",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Yakir Luc Gagnon",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Chislett",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@hhaensel",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@improbable22",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Fleck",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Peter Czaban",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@innerlee",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Mats Cronqvist",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "Shi Pengcheng",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@wg030",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"affiliation": "University of Cambridge",
|
||||
"name": "Will Tebbutt",
|
||||
"type": "Other"
|
||||
},
|
||||
{
|
||||
"name": "@t-bltg",
|
||||
"type": "Other"
|
||||
}
|
||||
{
|
||||
"name": "Fred Callaway",
|
||||
"type": "Other"
|
||||
}
|
||||
],
|
||||
"upload_type": "software"
|
||||
}
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
name = "Plots"
|
||||
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
author = ["Tom Breloff (@tbreloff)"]
|
||||
version = "1.11.2"
|
||||
version = "1.19.0"
|
||||
|
||||
[deps]
|
||||
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||
@@ -36,10 +36,10 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
Contour = "0.5"
|
||||
FFMPEG = "0.2, 0.3, 0.4"
|
||||
FixedPointNumbers = "0.6, 0.7, 0.8"
|
||||
GR = "0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.57"
|
||||
GR = "0.53, 0.54, 0.55, 0.57"
|
||||
GeometryBasics = "0.2, 0.3.1"
|
||||
JSON = "0.21, 1"
|
||||
Latexify = "0.14"
|
||||
Latexify = "0.14, 0.15"
|
||||
Measures = "0.3"
|
||||
NaNMath = "0.3"
|
||||
PlotThemes = "2"
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
[![][docs-img]][docs-url]
|
||||
[](https://codecov.io/gh/JuliaPlots/Plots.jl)
|
||||
|
||||
[](https://doi.org/10.5281/zenodo.4725317)
|
||||
This is the DOI for all Versions, please follow the link to get the DOI for a specific version.
|
||||
|
||||
|
||||
#### Created by Tom Breloff (@tbreloff)
|
||||
|
||||
#### Maintained by the [JuliaPlots members](https://github.com/orgs/JuliaPlots/people)
|
||||
|
||||
+80
-64
@@ -76,12 +76,13 @@ function _precompile_()
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}, Vector{Float64}},Tuple{Int64, Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(_make_hist)),NamedTuple{(:normed, :weights), Tuple{Bool, Vector{Int64}}},typeof(_make_hist),Tuple{Vector{Float64}},Symbol})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:flip,), Tuple{Bool}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{Symbol}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:formatter,), Tuple{typeof(datetimeformatter)}},typeof(attr!),Axis})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(attr!)),NamedTuple{(:grid, :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,), Tuple{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{(: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})
|
||||
@@ -90,84 +91,92 @@ 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{(:halign, :valign, :rotation, :color), Tuple{Symbol, Symbol, Int64, RGBA{Float64}}},typeof(gr_set_font),Font,Subplot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(hline!)),Any,typeof(hline!),Any})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{GRBackend},Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Vector{GeometryBasics.Point2{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:annotation,), Tuple{Vector{Tuple{Int64, Float64, PlotText}}}},typeof(plot!)})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:layout, :margin), Tuple{GridLayout, AbsoluteLength}},typeof(plot!),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(: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{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{GRBackend},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:line, :seriestype), Tuple{Tuple{Int64, Symbol, Float64, Matrix{Symbol}}, Symbol}},typeof(plot!),Plot{PlotlyBackend},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Function,Float64,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:lw, :color), Tuple{Int64, Symbol}},typeof(plot!),Plot{GRBackend},Function,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{GRBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(: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{(: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!),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},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!),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},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},Vector{Float64},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:xgrid,), Tuple{Tuple{Symbol, Symbol, Int64, Symbol, Float64}}},typeof(plot!),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis,), Tuple{Tuple{String, Symbol}}},typeof(plot!)})
|
||||
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!),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{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:annotations, :leg), Tuple{Tuple{Int64, Float64, PlotText}, Bool}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:arrow,), Tuple{Int64}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:aspect_ratio, :seriestype), Tuple{Int64, Symbol}},typeof(plot),Vector{String},Vector{String},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:bins, :weights, :seriestype), Tuple{Symbol, Vector{Int64}, Symbol}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:color, :line, :marker), Tuple{Matrix{Symbol}, Tuple{Symbol, Int64}, Tuple{Matrix{Symbol}, Int64, Float64, Stroke}}},typeof(plot),Vector{Vector{T} where T}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(: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{(:connections, :seriestype), Tuple{Tuple{Vector{Int64}, Vector{Int64}, Vector{Int64}}, 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{(:framestyle, :title, :color, :layout, :label, :markerstrokewidth, :ticks, :seriestype), Tuple{Matrix{Symbol}, Matrix{String}, Base.ReshapedArray{Int64, 2, UnitRange{Int64}, Tuple{}}, Int64, String, Int64, UnitRange{Int64}, Symbol}},typeof(plot),Vector{Vector{Float64}},Vector{Vector{Float64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:grid, :title), Tuple{Tuple{Symbol, Symbol, Symbol, Int64, Float64}, String}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:lab, :w, :palette, :fill, :α), Tuple{String, Int64, PlotUtils.ContinuousColorGradient, Int64, Float64}},typeof(plot),StepRange{Int64, Int64},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :title, :xlabel, :linewidth, :legend), Tuple{Matrix{String}, String, String, Int64, Symbol}},typeof(plot),Vector{Function},Float64,Vararg{Float64, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:label, :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{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, :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{GridLayout, AbsoluteLength}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :palette, :bg_inside), Tuple{Int64, Matrix{PlotUtils.ContinuousColorGradient}, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :t, :leg, :ticks, :border), Tuple{GridLayout, Matrix{Symbol}, Bool, Nothing, Symbol}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :title, :titlelocation, :left_margin, :bottom_margin, :xrotation), Tuple{GridLayout, Matrix{String}, Symbol, Matrix{AbsoluteLength}, AbsoluteLength, Int64}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xguide, :yguide, :xguidefonthalign, :yguidefontvalign, :xguideposition, :yguideposition, :ymirror, :xmirror, :legend, :seriestype), Tuple{Int64, String, String, Matrix{Symbol}, Matrix{Symbol}, Symbol, Matrix{Symbol}, Matrix{Bool}, Matrix{Bool}, Bool, Matrix{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xlims), Tuple{GridLayout, Tuple{Int64, Float64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout,), Tuple{Tuple{Int64, Int64}}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Bool}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{GRBackend},Plot{GRBackend},Vararg{Plot{GRBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:legend,), Tuple{Symbol}},typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:layout, :xlims), Tuple{GridLayout, 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{(:legend,), Tuple{Symbol}},typeof(plot),Vector{Tuple{Int64, Real}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :lab, :ms), Tuple{Tuple{Matrix{Symbol}, Int64}, Matrix{String}, Int64}},typeof(plot),Vector{Vector{T} where T},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :label, :legendtitle), Tuple{Tuple{Int64, Matrix{Symbol}}, Matrix{String}, String}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :leg, :fill), Tuple{Int64, Bool, Tuple{Int64, Symbol}}},typeof(plot),Function,Function,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:line, :marker, :bg, :fg, :xlim, :ylim, :leg), Tuple{Tuple{Int64, Symbol, Symbol}, Tuple{Shape, 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,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_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, :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{(:m, :markersize, :lab, :bg, :xlim, :ylim, :seriestype), Tuple{Matrix{Symbol}, Int64, Matrix{String}, Symbol, Tuple{Int64, Int64}, Tuple{Int64, Int64}, Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker,), Tuple{Bool}},typeof(plot),Vector{Union{Missing, Int64}}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:marker_z, :color, :legend, :seriestype), Tuple{typeof(+), Symbol, Bool, Symbol}},typeof(plot),Vector{Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:markershape, :markersize, :marker_z, :line_z, :linewidth), Tuple{Matrix{Symbol}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}, Matrix{Int64}}},typeof(plot),Matrix{Float64}})
|
||||
@@ -175,29 +184,30 @@ 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},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{(: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{(:reg, :fill), Tuple{Bool, Tuple{Int64, Symbol}}},typeof(plot),Vector{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Int64}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{Tuple{LinRange{Float64}, LinRange{Float64}}}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:ribbon,), Tuple{typeof(sqrt)}},typeof(plot),UnitRange{Int64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color), Tuple{Matrix{Symbol}, Vector{Symbol}, Int64, Vector{Symbol}}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),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{OHLC}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},Vararg{Vector{Float64}, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(: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{(:title,), Tuple{String}},typeof(plot),Plot{GRBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title,), Tuple{String}},typeof(plot),Plot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:xaxis, :background_color, :leg), Tuple{Tuple{String, Tuple{Int64, Int64}, StepRange{Int64, Int64}, Symbol}, RGB{Float64}, Bool}},typeof(plot),Matrix{Float64}})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:yflip, :aspect_ratio), Tuple{Bool, Symbol}},typeof(plot),Vector{Float64},Vector{Int64},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:zcolor, :m, :leg, :cbar, :w), Tuple{StepRange{Int64, Int64}, Tuple{Int64, Float64, Symbol, Stroke}, Bool, Bool, Int64}},typeof(plot),Vector{Float64},Vector{Float64},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{Core.kwftype(typeof(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, 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}})
|
||||
@@ -233,11 +243,10 @@ function _precompile_()
|
||||
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),ColorPalette,Int64})
|
||||
Base.precompile(Tuple{typeof(_cycle),StepRange{Int64, Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},UnitRange{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Base.OneTo{Int64},Vector{Int64}})
|
||||
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},StepRange{Int64, 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}})
|
||||
@@ -247,17 +256,17 @@ function _precompile_()
|
||||
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})
|
||||
Base.precompile(Tuple{typeof(contour),Any,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(build_layout),GridLayout,Int64,Vector{Plot}})
|
||||
Base.precompile(Tuple{typeof(convert_to_polar),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Int64, Float64}})
|
||||
Base.precompile(Tuple{typeof(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(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),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
|
||||
@@ -267,13 +276,18 @@ function _precompile_()
|
||||
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Float64},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(get_ticks),Symbol,Vector{Float64},Vector{Any},Tuple{Int64, Int64},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(get_ticks),UnitRange{Int64},Vector{Float64},Vector{Any},Tuple{Float64, Float64},Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(get_xy),OHLC{Float64},Int64,Float64})
|
||||
Base.precompile(Tuple{typeof(get_xy),Vector{OHLC}})
|
||||
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Float64, Float64, Float64, Int64, Float64, Float64, Float64, Float64}},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_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_colorbar),GRColorbar,Subplot{GRBackend},Tuple{Float64, Float64},Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_heatmap),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Float64,Float64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Shape{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Int64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
|
||||
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_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}})
|
||||
@@ -282,14 +296,16 @@ function _precompile_()
|
||||
Base.precompile(Tuple{typeof(gr_draw_shapes),Series,Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Vector{Float64},Tuple{Float64, Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_fill_viewport),Vector{Float64},RGBA{Float64}})
|
||||
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Float64}, Vector{String}},Int64})
|
||||
Base.precompile(Tuple{typeof(gr_get_ticks_size),Tuple{Vector{Int64}, Vector{String}},Int64})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
|
||||
Base.precompile(Tuple{typeof(gr_label_ticks),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_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}}})
|
||||
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Float64, Float64, Float64, Int64, Float64, Float64, Float64, Float64}}})
|
||||
Base.precompile(Tuple{typeof(gr_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),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})
|
||||
@@ -299,35 +315,44 @@ function _precompile_()
|
||||
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(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(ohlc),Any})
|
||||
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(plot),Any,Any,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(partialcircle),Int64,Float64,Int64})
|
||||
Base.precompile(Tuple{typeof(plot),Any,Any})
|
||||
Base.precompile(Tuple{typeof(plot),Any})
|
||||
Base.precompile(Tuple{typeof(processGridArg!),DefaultsDict,Bool,Symbol})
|
||||
Base.precompile(Tuple{typeof(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{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
|
||||
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},Matrix{Symbol}})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},RGBA{Float64}})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Shape})
|
||||
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},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(processMinorGridArg!),Dict{Symbol, Any},Bool,Symbol})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
|
||||
Base.precompile(Tuple{typeof(process_annotation),Subplot{PlotlyBackend},Int64,Float64,PlotText})
|
||||
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol})
|
||||
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol})
|
||||
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}})
|
||||
Base.precompile(Tuple{typeof(resetfontsizes)})
|
||||
Base.precompile(Tuple{typeof(scalefontsizes),Float64})
|
||||
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(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})
|
||||
@@ -338,12 +363,8 @@ function _precompile_()
|
||||
Base.precompile(Tuple{typeof(vline!),Any})
|
||||
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any, N} where N})
|
||||
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
|
||||
Base.precompile(Tuple{typeof(yaxis!),Any,Any})
|
||||
let fbody = try __lookup_kwbody__(which(gr_polyline, (Vector{Float64},Vector{Float64},typeof(GR.fillarea),))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Symbol,Symbol,typeof(gr_polyline),Vector{Float64},Vector{Float64},typeof(GR.fillarea),))
|
||||
end
|
||||
end
|
||||
isdefined(Plots, Symbol("#add_major_or_minor_segments#126")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#126")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64}},Float64,Bool})
|
||||
isdefined(Plots, Symbol("#add_major_or_minor_segments#127")) && Base.precompile(Tuple{getfield(Plots, Symbol("#add_major_or_minor_segments#127")),Vector{Float64},Bool,Segments{Tuple{Float64, Float64, Float64}},Float64,Bool})
|
||||
let fbody = try __lookup_kwbody__(which(plot!, (Any,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(plot!),Any,))
|
||||
@@ -364,11 +385,6 @@ function _precompile_()
|
||||
precompile(fbody, (Any,typeof(plot),Any,Vararg{Any, N} where N,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(plot, (Plot,Plot,Vararg{Plot, N} where N,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Any,typeof(plot),Plot,Plot,Vararg{Plot, N} where N,))
|
||||
end
|
||||
end
|
||||
let fbody = try __lookup_kwbody__(which(text, (String,Int64,Vararg{Any, N} where N,))) catch missing end
|
||||
if !ismissing(fbody)
|
||||
precompile(fbody, (Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}},typeof(text),String,Int64,Vararg{Any, N} where N,))
|
||||
|
||||
+2
-2
@@ -137,8 +137,8 @@ end
|
||||
# -----------------------------------------------
|
||||
|
||||
function _animate(forloop::Expr, args...; callgif = false)
|
||||
if forloop.head != :for
|
||||
error("@animate macro expects a for-block. got: $(forloop.head)")
|
||||
if forloop.head ∉ (:for, :while)
|
||||
error("@animate macro expects a for- or while-block. got: $(forloop.head)")
|
||||
end
|
||||
|
||||
# add the call to frame to the end of each iteration
|
||||
|
||||
+20
-5
@@ -53,7 +53,8 @@ const _arg_desc = KW(
|
||||
:colorbar_entry => "Bool. Include this series in the color bar? Set to `false` to exclude.",
|
||||
|
||||
# plot args
|
||||
:plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)",
|
||||
: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)",
|
||||
: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.",
|
||||
@@ -115,7 +116,13 @@ const _arg_desc = KW(
|
||||
:colorbar_formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.",
|
||||
:legendfont => "Font. Font of legend items.",
|
||||
:legendtitlefont => "Font. Font of the legend title.",
|
||||
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
|
||||
: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.",
|
||||
: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.",
|
||||
@@ -131,7 +138,12 @@ 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]",
|
||||
:lims => """
|
||||
NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example).
|
||||
`:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]
|
||||
`:symmetric` sets the limits to be symmetric around zero.
|
||||
Set widen=true to widen the specified limits (as occurs when lims are not specified).
|
||||
""",
|
||||
:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
|
||||
:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`",
|
||||
:rotation => "Number. Degrees rotation of tick labels.",
|
||||
@@ -165,8 +177,11 @@ 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` or `:out`",
|
||||
:tick_direction => "Symbol. Direction of the ticks. `:in`, `:out` or `:none`",
|
||||
:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`",
|
||||
:widen => "Bool. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders. Defaults to `true`.",
|
||||
:widen => """
|
||||
Bool or :auto. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders.
|
||||
Defaults to `:auto`, which widens unless limits were manually set.
|
||||
""",
|
||||
:draw_arrow => "Bool. Draw arrow at the end of the axis.",
|
||||
)
|
||||
|
||||
+14
-3
@@ -331,13 +331,15 @@ const _series_defaults = KW(
|
||||
|
||||
const _plot_defaults = KW(
|
||||
:plot_title => "",
|
||||
:plot_titleindex => 0,
|
||||
:plot_titlefontsize => 16,
|
||||
:plot_title_location => :center, # also :left or :right
|
||||
:plot_titlelocation => :center, # also :left or :right
|
||||
:plot_titlefontfamily => :match,
|
||||
:plot_titlefonthalign => :hcenter,
|
||||
:plot_titlefontvalign => :vcenter,
|
||||
:plot_titlefontrotation => 0.0,
|
||||
:plot_titlefontcolor => :match,
|
||||
:plot_titlevspan => 0.05, # vertical span of the plot title, here 5%
|
||||
:background_color => colorant"white", # default for all backgrounds,
|
||||
:background_color_outside => :match, # background outside grid,
|
||||
:foreground_color => :auto, # default for all foregrounds, and title color,
|
||||
@@ -408,6 +410,12 @@ const _subplot_defaults = KW(
|
||||
:legendtitlefontrotation => 0.0,
|
||||
:legendtitlefontcolor => :match,
|
||||
:annotations => [], # annotation tuples... list of (x,y,annotation)
|
||||
:annotationfontfamily => :match,
|
||||
:annotationfontsize => 14,
|
||||
:annotationhalign => :hcenter,
|
||||
:annotationvalign => :vcenter,
|
||||
:annotationrotation => 0.0,
|
||||
:annotationcolor => :match,
|
||||
:projection => :none, # can also be :polar or :3d
|
||||
:aspect_ratio => :auto, # choose from :none or :equal
|
||||
:margin => 1mm,
|
||||
@@ -470,7 +478,7 @@ const _axis_defaults = KW(
|
||||
:minorticks => false,
|
||||
:minorgrid => false,
|
||||
:showaxis => true,
|
||||
:widen => true,
|
||||
:widen => :auto,
|
||||
:draw_arrow => false,
|
||||
)
|
||||
|
||||
@@ -519,6 +527,7 @@ const _initial_axis_defaults = deepcopy(_axis_defaults)
|
||||
const _initial_fontsizes = Dict(:titlefontsize => _subplot_defaults[:titlefontsize],
|
||||
:legendfontsize => _subplot_defaults[:legendfontsize],
|
||||
:legendtitlefontsize => _subplot_defaults[:legendtitlefontsize],
|
||||
:annotationfontsize => _subplot_defaults[:annotationfontsize],
|
||||
:tickfontsize => _axis_defaults[:tickfontsize],
|
||||
:guidefontsize => _axis_defaults[:guidefontsize])
|
||||
|
||||
@@ -1132,7 +1141,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
|
||||
RecipesPipeline.reset_kw!(plotattributes, :marker)
|
||||
if haskey(plotattributes, :markershape)
|
||||
plotattributes[:markershape] = _replace_markershape(plotattributes[:markershape])
|
||||
if plotattributes[:markershape] == :none && plotattributes[:seriestype] in (:scatter, :scatterbins, :scatterhist, :scatter3d) #the default should be :auto, not :none, so that :none can be set explicitly and would be respected
|
||||
if plotattributes[:markershape] == :none && get(plotattributes, :seriestype, :path) in (:scatter, :scatterbins, :scatterhist, :scatter3d) #the default should be :auto, not :none, so that :none can be set explicitly and would be respected
|
||||
plotattributes[:markershape] = :circle
|
||||
end
|
||||
elseif anymarker
|
||||
@@ -1359,6 +1368,8 @@ const _match_map = KW(
|
||||
:plot_titlefontcolor => :foreground_color,
|
||||
:tickfontcolor => :foreground_color_text,
|
||||
:guidefontcolor => :foreground_color_guide,
|
||||
:annotationfontfamily => :fontfamily_subplot,
|
||||
:annotationcolor => :foreground_color_subplot,
|
||||
)
|
||||
|
||||
# these can match values from the parent container (axis --> subplot --> plot)
|
||||
|
||||
+187
-121
@@ -172,8 +172,9 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
||||
scaled_ticks = optimize_ticks(
|
||||
sf(amin),
|
||||
sf(amax);
|
||||
k_min = 4, # minimum number of ticks
|
||||
k_min = scale ∈ _logScales ? 2 : 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(
|
||||
@@ -185,6 +186,7 @@ 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
|
||||
@@ -235,6 +237,66 @@ 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[Symbol(s, :axis)])
|
||||
get_ticks(p::Plot, s::Symbol) = [get_ticks(sp, s) for sp in p.subplots]
|
||||
|
||||
function get_ticks(ticks::Symbol, cvals::T, dvals, args...) where T
|
||||
if ticks === :none
|
||||
return T[], String[]
|
||||
@@ -271,30 +333,48 @@ _transform_ticks(ticks::AbstractArray{T}) where T <: Dates.TimeType = Dates.valu
|
||||
_transform_ticks(ticks::NTuple{2, Any}) = (_transform_ticks(ticks[1]), ticks[2])
|
||||
|
||||
function get_minor_ticks(sp, axis, ticks)
|
||||
axis[:minorticks] in (:none, nothing, false) && !axis[:minorgrid] && return nothing
|
||||
axis[:minorticks] ∈ (:none, nothing, false) && !axis[:minorgrid] && return nothing
|
||||
ticks = ticks[1]
|
||||
length(ticks) < 2 && return nothing
|
||||
|
||||
amin, amax = axis_limits(sp, axis[:letter])
|
||||
#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
|
||||
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]
|
||||
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]
|
||||
else
|
||||
sub = 1 # unused
|
||||
ratio = length(ticks) > 2 ? (ticks[3] - ticks[2]) / (ticks[2] - ticks[1]) : 1
|
||||
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])
|
||||
for (i, hi) ∈ enumerate(ticks[2:end])
|
||||
lo = ticks[i]
|
||||
if isfinite(lo) && isfinite(hi) && hi > lo
|
||||
append!(minorticks,collect(lo + (hi-lo)/n :(hi-lo)/n: hi - (hi-lo)/2n))
|
||||
if log_scaled
|
||||
for e ∈ 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
|
||||
end
|
||||
end
|
||||
minorticks[amin .<= minorticks .<= amax]
|
||||
@@ -432,35 +512,38 @@ end
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# push the limits out slightly
|
||||
function widen(lmin, lmax, scale = :identity)
|
||||
function widen(lmin, lmax, scale=:identity)
|
||||
f, invf = RecipesPipeline.scale_func(scale), RecipesPipeline.inverse_scale_func(scale)
|
||||
span = f(lmax) - f(lmin)
|
||||
# eps = NaNMath.max(1e-16, min(1e-2span, 1e-10))
|
||||
eps = NaNMath.max(1e-16, 0.03span)
|
||||
invf(f(lmin)-eps), invf(f(lmax)+eps)
|
||||
invf(f(lmin) - eps), invf(f(lmax) + eps)
|
||||
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)
|
||||
|
||||
function default_should_widen(axis::Axis)
|
||||
should_widen = false
|
||||
if !(is_2tuple(axis[:lims]) || axis[:lims] == :round)
|
||||
for sp in axis.sps
|
||||
for series in series_list(sp)
|
||||
if series.plotattributes[:seriestype] in _widen_seriestypes
|
||||
should_widen = true
|
||||
end
|
||||
if axis[:widen] isa Bool
|
||||
return axis[:widen]
|
||||
end
|
||||
# automatic behavior: widen if limits aren't specified and series type is appropriate
|
||||
(is_2tuple(axis[:lims]) || axis[:lims] == :round) && return false
|
||||
for sp in axis.sps
|
||||
for series in series_list(sp)
|
||||
if series.plotattributes[:seriestype] in _widen_seriestypes
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
should_widen
|
||||
false
|
||||
end
|
||||
|
||||
function round_limits(amin,amax)
|
||||
scale = 10^(1-round(log10(amax - amin)))
|
||||
amin = floor(amin*scale)/scale
|
||||
amax = ceil(amax*scale)/scale
|
||||
function round_limits(amin, amax, scale)
|
||||
base = get(_logScaleBases, scale, 10.)
|
||||
factor = base^(1 - round(log(base, amax - amin)))
|
||||
amin = floor(amin * factor) / factor
|
||||
amax = ceil(amax * factor) / factor
|
||||
amin, amax
|
||||
end
|
||||
|
||||
@@ -473,13 +556,20 @@ function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(l
|
||||
has_user_lims = (isa(lims, Tuple) || isa(lims, AVec)) && length(lims) == 2
|
||||
if has_user_lims
|
||||
lmin, lmax = lims
|
||||
if lmin != :auto && isfinite(lmin)
|
||||
if lmin == :auto
|
||||
elseif isfinite(lmin)
|
||||
amin = lmin
|
||||
end
|
||||
if lmax != :auto && isfinite(lmax)
|
||||
if lmax == :auto
|
||||
elseif 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
|
||||
@@ -490,20 +580,23 @@ function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(l
|
||||
if axis[:letter] == :x
|
||||
amin, amax = 0, 2pi
|
||||
elseif lims == :auto
|
||||
#widen max radius so ticks dont overlap with theta axis
|
||||
# widen max radius so ticks dont overlap with theta axis
|
||||
0, amax + 0.1 * abs(amax - amin)
|
||||
else
|
||||
amin, amax
|
||||
end
|
||||
elseif should_widen && axis[:widen]
|
||||
elseif should_widen
|
||||
widen(amin, amax, axis[:scale])
|
||||
elseif lims == :round
|
||||
round_limits(amin,amax)
|
||||
round_limits(amin, amax, axis[:scale])
|
||||
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
|
||||
@@ -634,60 +727,48 @@ function axis_drawing_info(sp, letter)
|
||||
)
|
||||
end
|
||||
end
|
||||
if !(ax[:ticks] in (:none, nothing, false))
|
||||
if ax[:ticks] ∉ (:none, nothing, false)
|
||||
f = RecipesPipeline.scale_func(oax[:scale])
|
||||
invf = RecipesPipeline.inverse_scale_func(oax[:scale])
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.012 * (f(oamax) - f(oamin)))
|
||||
(-t, t)
|
||||
else
|
||||
ticks_in = ax[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(oa1) + 0.012 * (f(oa2) - f(oa1)) * ticks_in)
|
||||
(oa1, t)
|
||||
end
|
||||
|
||||
for tick in ticks[1]
|
||||
if ax[:showaxis]
|
||||
push!(
|
||||
tick_segments,
|
||||
reverse_if((tick, tick_start), isy),
|
||||
reverse_if((tick, tick_stop), isy),
|
||||
)
|
||||
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, t)
|
||||
else
|
||||
ticks_in = ax[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(oa1) + factor * (f(oa2) - f(oa1)) * ticks_in)
|
||||
(oa1, t)
|
||||
end
|
||||
end
|
||||
if ax[:grid]
|
||||
push!(
|
||||
grid_segments,
|
||||
reverse_if((tick, oamin), isy),
|
||||
reverse_if((tick, oamax), isy),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
if !(ax[:minorticks] in (:none, nothing, false)) || ax[:minorgrid]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.006 * (f(oamax) - f(oamin)))
|
||||
(-t, t)
|
||||
else
|
||||
t = invf(f(oa1) + 0.006 * (f(oa2) - f(oa1)) * ticks_in)
|
||||
(oa1, t)
|
||||
end
|
||||
for tick in minor_ticks
|
||||
if ax[:showaxis]
|
||||
for tick in ticks
|
||||
if ax[:showaxis] && cond
|
||||
push!(
|
||||
tick_segments,
|
||||
reverse_if((tick, tick_start), isy),
|
||||
reverse_if((tick, tick_stop), isy),
|
||||
)
|
||||
end
|
||||
if ax[:minorgrid]
|
||||
if grid
|
||||
push!(
|
||||
minorgrid_segments,
|
||||
segments,
|
||||
reverse_if((tick, oamin), isy),
|
||||
reverse_if((tick, oamax), isy),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# add major grid segments
|
||||
add_major_or_minor_segments(ticks[1], ax[:grid], grid_segments, 0.012, ax[:tick_direction] !== :none)
|
||||
|
||||
# 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)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -770,72 +851,57 @@ function axis_drawing_info_3d(sp, letter)
|
||||
)
|
||||
end
|
||||
end
|
||||
# TODO this can be simplified, we do almost the same thing twice for grid and minorgrid
|
||||
if !(ax[:ticks] in (:none, nothing, false))
|
||||
|
||||
if ax[:ticks] ∉ (:none, nothing, false)
|
||||
f = RecipesPipeline.scale_func(nax[:scale])
|
||||
invf = RecipesPipeline.inverse_scale_func(nax[:scale])
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.012 * (f(namax) - f(namin)))
|
||||
(-t, t)
|
||||
else
|
||||
ticks_in = ax[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(na0) + 0.012 * (f(na1) - f(na0)) * ticks_in)
|
||||
(na0, t)
|
||||
end
|
||||
|
||||
ga0, ga1 = sp[:framestyle] in (:origin, :zerolines) ? (namin, namax) : (na0, na1)
|
||||
for tick in ticks[1]
|
||||
if ax[:showaxis]
|
||||
push!(
|
||||
tick_segments,
|
||||
sort_3d_axes(tick, tick_start, fa0, letter),
|
||||
sort_3d_axes(tick, tick_stop, fa0, letter),
|
||||
)
|
||||
end
|
||||
if ax[:grid]
|
||||
push!(
|
||||
grid_segments,
|
||||
sort_3d_axes(tick, ga0, fa0, letter),
|
||||
sort_3d_axes(tick, ga1, fa0, letter),
|
||||
)
|
||||
push!(
|
||||
grid_segments,
|
||||
sort_3d_axes(tick, ga1, fa0, letter),
|
||||
sort_3d_axes(tick, ga1, fa1, letter),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
if !(ax[:minorticks] in (:none, nothing, false)) || ax[:minorgrid]
|
||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||
t = invf(f(0) + 0.006 * (f(namax) - f(namin)))
|
||||
(-t, t)
|
||||
else
|
||||
t = invf(f(na0) + 0.006 * (f(na1) - f(na0)) * ticks_in)
|
||||
(na0, t)
|
||||
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, t)
|
||||
else
|
||||
ticks_in = ax[:tick_direction] == :out ? -1 : 1
|
||||
t = invf(f(na0) + factor * (f(na1) - f(na0)) * ticks_in)
|
||||
(na0, t)
|
||||
end
|
||||
end
|
||||
for tick in minor_ticks
|
||||
if ax[:showaxis]
|
||||
|
||||
for tick in ticks
|
||||
if ax[:showaxis] && cond
|
||||
push!(
|
||||
tick_segments,
|
||||
sort_3d_axes(tick, tick_start, fa0, letter),
|
||||
sort_3d_axes(tick, tick_stop, fa0, letter),
|
||||
)
|
||||
end
|
||||
if ax[:minorgrid]
|
||||
if grid
|
||||
fa0_, fa1_ = reverse_if((fa0, fa1), ax[:mirror])
|
||||
ga0_, ga1_ = reverse_if((ga0, ga1), ax[:mirror])
|
||||
push!(
|
||||
minorgrid_segments,
|
||||
sort_3d_axes(tick, ga0, fa0, letter),
|
||||
sort_3d_axes(tick, ga1, fa0, letter),
|
||||
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),
|
||||
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)
|
||||
|
||||
# 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)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -256,6 +256,7 @@ end
|
||||
@init_backend PGFPlotsX
|
||||
@init_backend InspectDR
|
||||
@init_backend HDF5
|
||||
@init_backend Gaston
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@@ -352,6 +353,7 @@ const _gr_seriestype = [
|
||||
:scatter3d,
|
||||
:surface,
|
||||
:wireframe,
|
||||
:mesh3d,
|
||||
:volume,
|
||||
:shape,
|
||||
]
|
||||
@@ -574,6 +576,92 @@ const _pyplot_style = [:auto, :solid, :dash, :dot, :dashdot]
|
||||
const _pyplot_marker = vcat(_allMarkers, :pixel)
|
||||
const _pyplot_scale = [:identity, :ln, :log2, :log10]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Gaston
|
||||
|
||||
function _initialize_backend(::GastonBackend)
|
||||
@eval Main begin
|
||||
import Gaston
|
||||
export Gaston
|
||||
end
|
||||
end
|
||||
|
||||
const _gaston_attr = merge_with_base_supported([
|
||||
# :annotations,
|
||||
# :background_color_legend,
|
||||
# :background_color_inside,
|
||||
# :background_color_outside,
|
||||
# :foreground_color_legend,
|
||||
# :foreground_color_grid, :foreground_color_axis,
|
||||
# :foreground_color_text, :foreground_color_border,
|
||||
:label,
|
||||
# :seriescolor, :seriesalpha,
|
||||
:linecolor, :linestyle, :linewidth, :linealpha,
|
||||
:markershape, :markercolor, :markersize, :markeralpha,
|
||||
# :markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :markerstrokestyle,
|
||||
# :fillrange, :fillcolor, :fillalpha,
|
||||
# :bins,
|
||||
# :bar_width, :bar_edges,
|
||||
# :title,
|
||||
# :window_title,
|
||||
:guide,
|
||||
# :guide_position,
|
||||
:lims, :ticks, :scale, # :flip, :rotation,
|
||||
:tickfont, :guidefont,
|
||||
# :legendfont,
|
||||
# :grid, :legend,
|
||||
# :colorbar, :colorbar_title,
|
||||
# :fill_z, :line_z, :marker_z, :levels,
|
||||
# :ribbon, :quiver, :arrow,
|
||||
# :orientation,
|
||||
# :overwrite_figure,
|
||||
# :polar,
|
||||
# :normalize, :weights, :contours,
|
||||
# :aspect_ratio,
|
||||
:tick_direction,
|
||||
# :framestyle,
|
||||
# :camera,
|
||||
# :contour_labels,
|
||||
])
|
||||
const _gaston_seriestype = [:path,
|
||||
# :path3d,
|
||||
:scatter,
|
||||
:steppre,
|
||||
# :stepmid,
|
||||
:steppost,
|
||||
# :histogram2d,
|
||||
# :ysticks, :xsticks,
|
||||
# :contour,
|
||||
:shape,
|
||||
# :straightline,
|
||||
]
|
||||
|
||||
const _gaston_style = [:auto,
|
||||
:solid,
|
||||
:dash,
|
||||
:dot,
|
||||
:dashdot,
|
||||
:dashdotdot
|
||||
]
|
||||
|
||||
const _gaston_marker = [:none,
|
||||
# :auto,
|
||||
:circle,
|
||||
:rect,
|
||||
:diamond,
|
||||
:utriangle,
|
||||
:dtriangle,
|
||||
:pentagon,
|
||||
:x,
|
||||
:+
|
||||
] #vcat(_allMarkers, Shape)
|
||||
|
||||
const _gaston_scale = [:identity,
|
||||
# :ln,
|
||||
# :log2,
|
||||
:log10,
|
||||
]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# unicodeplots
|
||||
|
||||
|
||||
@@ -0,0 +1,331 @@
|
||||
# https://github.com/mbaz/Gaston.
|
||||
const G = Gaston
|
||||
const GastonSubplot = G.Plot
|
||||
const GASTON_MARKER_SCALING = 1.3 / 5.0
|
||||
const GNUPLOT_DPI = 72 # Compensate for DPI with increased resolution
|
||||
|
||||
#
|
||||
# --------------------------------------------
|
||||
# These functions are called by Plots
|
||||
# --------------------------------------------
|
||||
#
|
||||
# Create the window/figure for this backend.
|
||||
function _create_backend_figure(plt::Plot{GastonBackend})
|
||||
xsize = plt.attr[:size][1]
|
||||
ysize = plt.attr[:size][2]
|
||||
G.set(termopts="""size $xsize,$ysize""")
|
||||
|
||||
state_handle = G.nexthandle() # for now all the figures will be kept
|
||||
plt.o = G.newfigure(state_handle)
|
||||
end
|
||||
|
||||
|
||||
function _before_layout_calcs(plt::Plot{GastonBackend})
|
||||
# Initialize all the subplots first
|
||||
plt.o.subplots = G.SubPlot[]
|
||||
grid = size(plt.layout)
|
||||
plt.o.layout = grid
|
||||
|
||||
|
||||
for sp in plt.subplots
|
||||
gaston_init_subplot(plt, sp)
|
||||
end
|
||||
|
||||
# Then add the series (curves in gaston)
|
||||
for series in plt.series_list
|
||||
gaston_add_series(plt, series)
|
||||
end
|
||||
end
|
||||
|
||||
function _update_min_padding!(sp::Subplot{GastonBackend})
|
||||
sp.minpad = (20mm, 5mm, 2mm, 10mm)
|
||||
end
|
||||
|
||||
function _update_plot_object(plt::Plot{GastonBackend})
|
||||
end
|
||||
|
||||
for (mime, term) in (
|
||||
"application/eps" => "epscairo", # NEED fixing TODO
|
||||
"image/eps" => "epslatex", # NEED fixing TODO
|
||||
"application/pdf" => "pdfcairo", # NEED fixing TODO
|
||||
"application/postscript" => "postscript", # NEED fixing TODO
|
||||
"image/svg+xml" => "svg",
|
||||
"text/latex" => "tikz", # NEED fixing TODO
|
||||
"application/x-tex" => "epslatex", # NEED fixing TODO
|
||||
"text/plain" => "dumb", # NEED fixing TODO
|
||||
)
|
||||
@eval function _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{GastonBackend})
|
||||
xsize = plt.attr[:size][1]
|
||||
ysize = plt.attr[:size][2]
|
||||
termopts="""size $xsize,$ysize"""
|
||||
|
||||
tmpfile = G.tempname() * "." * $term
|
||||
|
||||
G.save(
|
||||
term = $term,
|
||||
output = tmpfile,
|
||||
handle = plt.o.handle,
|
||||
saveopts = termopts
|
||||
)
|
||||
while !isfile(tmpfile) end # avoid race condition with read in next line
|
||||
write(io, read(tmpfile))
|
||||
rm(tmpfile, force=true)
|
||||
nothing
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function _show(io::IO, mime::MIME{Symbol("image/png")},
|
||||
plt::Plot{GastonBackend},)
|
||||
scaling = plt.attr[:dpi] / GNUPLOT_DPI
|
||||
xsize = plt.attr[:size][1] * scaling
|
||||
ysize = plt.attr[:size][2] * scaling
|
||||
|
||||
# Scale all plot elements to match Plots.jl DPI standard
|
||||
termopts="""size $xsize,$ysize fontscale $scaling lw $scaling dl $scaling ps $scaling"""
|
||||
|
||||
tmpfile = G.tempname()
|
||||
|
||||
G.save(
|
||||
term = "pngcairo",
|
||||
output = tmpfile,
|
||||
handle = plt.o.handle,
|
||||
saveopts = termopts
|
||||
)
|
||||
while !isfile(tmpfile) end # avoid race condition with read in next line
|
||||
write(io, read(tmpfile))
|
||||
rm(tmpfile, force=true)
|
||||
nothing
|
||||
end
|
||||
|
||||
|
||||
function _display(plt::Plot{GastonBackend})
|
||||
display(plt.o)
|
||||
end
|
||||
#
|
||||
# --------------------------------------------
|
||||
# These functions are gaston specific
|
||||
# --------------------------------------------
|
||||
#
|
||||
function gaston_init_subplot(plt::Plot{GastonBackend}, sp::Subplot{GastonBackend})
|
||||
dims = RecipesPipeline.is3d(sp) ? 3 : 2
|
||||
|
||||
axesconf = gaston_parse_axes_args(plt, sp) # Gnuplot string
|
||||
sp.o = GastonSubplot(dims=dims, axesconf = axesconf, curves = [])
|
||||
push!(plt.o.subplots, sp.o)
|
||||
|
||||
end
|
||||
|
||||
function gaston_add_series(plt::Plot{GastonBackend}, series::Series)
|
||||
# Gaston.Curve = Plots.Series
|
||||
sp = series[:subplot]
|
||||
g_sp = sp.o # Gaston subplot object
|
||||
|
||||
seriesconf = gaston_parse_series_args(series) # Gnuplot string
|
||||
c = G.Curve(series[:x], series[:y], nothing, nothing, seriesconf )
|
||||
|
||||
isfirst = length(g_sp.curves) == 0 ? true : false
|
||||
push!(g_sp.curves, c)
|
||||
G.write_data(c, g_sp.dims, g_sp.datafile, append = isfirst ? false : true)
|
||||
end
|
||||
|
||||
function gaston_parse_series_args(series::Series)
|
||||
curveconf = String[]
|
||||
st = series[:seriestype]
|
||||
|
||||
if st == :scatter
|
||||
pt = gaston_marker(series[:markershape])
|
||||
ps = series[:markersize] * GASTON_MARKER_SCALING
|
||||
lc = gaston_color(series[:markercolor])
|
||||
# alpha = series[:markeralpha] # TODO merge alpha with rgb color
|
||||
push!(curveconf, """with points pt $pt ps $ps lc $lc""")
|
||||
elseif st == :path
|
||||
lc = gaston_color(series[:linecolor])
|
||||
dt = gaston_linestyle(series[:linestyle])
|
||||
lw = series[:linewidth]
|
||||
# alpha = series[:linealpha] # TODO merge alpha with rgb color
|
||||
if series[:markershape] == :none # simplepath
|
||||
push!(curveconf, """with lines lc $lc dt $dt lw $lw""")
|
||||
else
|
||||
pt = gaston_marker(series[:markershape])
|
||||
ps = series[:markersize] * GASTON_MARKER_SCALING
|
||||
push!(curveconf, """with lp lc $lc dt $dt lw $lw pt $pt ps $ps""")
|
||||
end
|
||||
elseif st == :shape
|
||||
fc = gaston_color(series[:fillcolor])
|
||||
fs = "solid"
|
||||
lc = gaston_color(series[:linecolor])
|
||||
push!(curveconf, """with filledcurves fc $fc fs $fs border lc $lc""")
|
||||
elseif st == :steppre
|
||||
push!(curveconf, """with steps""")
|
||||
elseif st == :steppost
|
||||
push!(curveconf, """with fsteps""") # Not sure if not the other way
|
||||
end
|
||||
|
||||
# label
|
||||
push!(curveconf, """title "$(series[:label])" """)
|
||||
|
||||
return join(curveconf, " ")
|
||||
end
|
||||
|
||||
function gaston_parse_axes_args(plt::Plot{GastonBackend}, sp::Subplot{GastonBackend})
|
||||
axesconf = String[]
|
||||
# Standard 2d axis
|
||||
if !ispolar(sp) && !RecipesPipeline.is3d(sp)
|
||||
# TODO
|
||||
# configure grid, axis spines, thickness
|
||||
end
|
||||
|
||||
for letter in (:x, :y, :z)
|
||||
axis_attr = sp.attr[Symbol(letter, :axis)]
|
||||
# label names
|
||||
push!(axesconf, """set $(letter)label "$(axis_attr[:guide])" """)
|
||||
push!(axesconf, """set $(letter)label font "$(axis_attr[:guidefontfamily]), $(axis_attr[:guidefontsize])" """)
|
||||
|
||||
# Handle ticks
|
||||
# ticksyle
|
||||
push!(axesconf, """set $(letter)tics font "$(axis_attr[:tickfontfamily]), $(axis_attr[:tickfontsize])" """)
|
||||
push!(axesconf, """set $(letter)tics textcolor rgb "#$(hex(axis_attr[:tickfontcolor], :rrggbb))" """)
|
||||
push!(axesconf, """set $(letter)tics $(axis_attr[:tick_direction])""")
|
||||
|
||||
mirror = axis_attr[:mirror] ? "mirror" : "nomirror"
|
||||
push!(axesconf, """set $(letter)tics $(mirror) """)
|
||||
|
||||
logscale = if axis_attr[:scale] == :identity
|
||||
"nologscale"
|
||||
elseif axis_attr[:scale] == :log10
|
||||
"logscale"
|
||||
end
|
||||
push!(axesconf, """set $logscale $(letter)""")
|
||||
|
||||
# tick locations
|
||||
if axis_attr[:ticks] != :native
|
||||
# axis limits
|
||||
from, to = axis_limits(sp, letter)
|
||||
push!(axesconf, """set $(letter)range [$from:$to]""")
|
||||
|
||||
ticks = get_ticks(sp, axis_attr)
|
||||
gaston_set_ticks!(axesconf, ticks, letter)
|
||||
end
|
||||
# set title {"<title-text>"} {offset <offset>} {font "<font>{,<size>}"}{{textcolor | tc} {<colorspec> | default}} {{no}enhanced}1
|
||||
end
|
||||
gaston_set_legend!(axesconf, sp) # Set legend params
|
||||
|
||||
if sp[:title] != nothing
|
||||
push!(axesconf, """set title '$(sp[:title])' """)
|
||||
push!(axesconf, """set title font '$(sp[:titlefontfamily]), $(sp[:titlefontsize])' """)
|
||||
end
|
||||
|
||||
return join(axesconf, "\n")
|
||||
end
|
||||
|
||||
function gaston_set_ticks!(axesconf, ticks, letter)
|
||||
|
||||
ticks == :auto && return
|
||||
if ticks == :none || ticks === nothing || ticks == false
|
||||
push!(axesconf, """unset $(letter)tics """)
|
||||
return
|
||||
end
|
||||
|
||||
ttype = ticksType(ticks)
|
||||
if ttype == :ticks
|
||||
tick_locations = @view ticks[:]
|
||||
gaston_tick_string = []
|
||||
for i in eachindex(tick_locations)
|
||||
lac = tick_locations[i]
|
||||
push!(gaston_tick_string, "$loc")
|
||||
end
|
||||
push!(
|
||||
axesconf,
|
||||
"set $(letter)tics (" * join(gaston_tick_string, ", ") * ")"
|
||||
)
|
||||
|
||||
elseif ttype == :ticks_and_labels
|
||||
tick_locations = @view ticks[1][:]
|
||||
tick_labels = @view ticks[2][:]
|
||||
gaston_tick_string = []
|
||||
for i in eachindex(tick_locations)
|
||||
loc = tick_locations[i]
|
||||
lab = gaston_enclose_tick_string(tick_labels[i])
|
||||
push!(gaston_tick_string, "'$lab' $loc")
|
||||
end
|
||||
push!(
|
||||
axesconf,
|
||||
"set $(letter)tics (" * join(gaston_tick_string, ", ") * ")"
|
||||
)
|
||||
|
||||
else
|
||||
error("Invalid input for $(letter)ticks: $ticks")
|
||||
end
|
||||
end
|
||||
|
||||
function gaston_set_legend!(axesconf, sp)
|
||||
leg = sp[:legend]
|
||||
if !(sp[:legend] in(:none, :inline))
|
||||
if leg == :best
|
||||
leg = :topright
|
||||
end
|
||||
|
||||
if occursin("outer", string(leg))
|
||||
push!(axesconf, "set key outside")
|
||||
else
|
||||
push!(axesconf, "set key inside")
|
||||
end
|
||||
positions = ["top", "bottom", "left", "right"]
|
||||
for position in positions
|
||||
if occursin(position, string(leg))
|
||||
push!(axesconf, "set key $position")
|
||||
end
|
||||
end
|
||||
if sp[:legendtitle] != nothing
|
||||
push!(axesconf, "set key title '$(sp[:legendtitle])'")
|
||||
end
|
||||
push!(axesconf, "set key box linewidth 1")
|
||||
push!(axesconf, "set key opaque")
|
||||
|
||||
push!(axesconf, "set border back")
|
||||
push!(axesconf, """set key font "$(sp[:legendfontfamily]), $(sp[:legendfontsize])" """)
|
||||
else
|
||||
push!(axesconf, "set key off")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function gaston_marker(marker)
|
||||
marker == :none && return -1
|
||||
marker == :circle && return 7
|
||||
marker == :rect && return 5
|
||||
marker == :diamond && return 28
|
||||
marker == :utriangle && return 9
|
||||
marker == :dtriangle && return 11
|
||||
marker == :+ && return 1
|
||||
marker == :x && return 2
|
||||
marker == :star5 && return 3
|
||||
marker == :pentagon && return 15
|
||||
marker == :pixel && return 0
|
||||
|
||||
@warn("Unsupported marker $marker")
|
||||
return 1
|
||||
end
|
||||
|
||||
gaston_color(color) = """rgb "#$(hex(color, :rrggbb))" """
|
||||
|
||||
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)
|
||||
if findfirst("^", tick_string) == nothing
|
||||
return tick_string
|
||||
end
|
||||
|
||||
|
||||
base, power = split(tick_string, "^")
|
||||
power = string("{", power, "}")
|
||||
return string(base, "^", power)
|
||||
end
|
||||
+116
-46
@@ -355,9 +355,9 @@ end
|
||||
|
||||
# draw ONE symbol marker
|
||||
function gr_draw_marker(series, xi, yi, clims, i, msize, strokewidth, shape::Symbol)
|
||||
GR.setborderwidth(strokewidth);
|
||||
gr_set_bordercolor(get_markerstrokecolor(series, i));
|
||||
gr_set_markercolor(get_markercolor(series, clims, i));
|
||||
GR.setborderwidth(strokewidth)
|
||||
gr_set_bordercolor(get_markerstrokecolor(series, i))
|
||||
gr_set_markercolor(get_markercolor(series, clims, i))
|
||||
gr_set_transparency(get_markeralpha(series, i))
|
||||
GR.setmarkertype(gr_markertype(shape))
|
||||
GR.setmarkersize(0.3msize / gr_nominal_size(series))
|
||||
@@ -401,7 +401,7 @@ end
|
||||
|
||||
function gr_nans_to_infs!(z)
|
||||
for (i,zi) in enumerate(z)
|
||||
if zi == NaN
|
||||
if isnan(zi)
|
||||
z[i] = Inf
|
||||
end
|
||||
end
|
||||
@@ -524,7 +524,7 @@ function gr_draw_colorbar(cbar::GRColorbar, sp::Subplot, clims, viewport_plotare
|
||||
levels = _cbar_unique(contour_levels.(series, Ref(clims)), "levels")
|
||||
# GR implicitly uses the maximal z value as the highest level
|
||||
if levels[end] < clims[2]
|
||||
@warn("GR: highest contour level less than maximal z value is not supported.")
|
||||
@warn "GR: highest contour level less than maximal z value is not supported."
|
||||
# replace levels, rather than assign to levels[end], to ensure type
|
||||
# promotion in case levels is an integer array
|
||||
levels = [levels[1:end-1]; clims[2]]
|
||||
@@ -651,12 +651,17 @@ end
|
||||
|
||||
function gr_set_tickfont(sp, letter)
|
||||
axis = sp[Symbol(letter, :axis)]
|
||||
|
||||
# invalidate alignment changes for small rotations (|θ| < 45°)
|
||||
trigger(rot) = abs(sind(rot)) < abs(cosd(rot)) ? 0 : sign(rot)
|
||||
|
||||
rot = axis[:rotation]
|
||||
if letter === :x || (RecipesPipeline.is3d(sp) && letter === :y)
|
||||
halign = (:left, :hcenter, :right)[sign(axis[:rotation]) + 2]
|
||||
valign = (axis[:mirror] ? :bottom : :top)
|
||||
halign = (:left, :hcenter, :right)[trigger(rot) + 2]
|
||||
valign = (axis[:mirror] ? :bottom : :top, :vcenter)[trigger(abs(rot)) + 1]
|
||||
else
|
||||
halign = (axis[:mirror] ? :left : :right)
|
||||
valign = (:top, :vcenter, :bottom)[sign(axis[:rotation]) + 2]
|
||||
halign = (axis[:mirror] ? :left : :right, :hcenter)[trigger(abs(rot)) + 1]
|
||||
valign = (:top, :vcenter, :bottom)[trigger(rot) + 2]
|
||||
end
|
||||
gr_set_font(
|
||||
tickfont(axis),
|
||||
@@ -1157,25 +1162,25 @@ function gr_legend_pos(theta::Real, leg, viewport_plotarea; axisclearance=nothin
|
||||
end
|
||||
|
||||
function gr_get_legend_geometry(viewport_plotarea, sp)
|
||||
legendn = 0
|
||||
legendw = 0
|
||||
legendn = legendw = dy = 0
|
||||
if sp[:legend] != :none
|
||||
GR.savestate()
|
||||
GR.selntran(0)
|
||||
GR.setscale(0)
|
||||
if sp[:legendtitle] !== nothing
|
||||
gr_set_font(legendtitlefont(sp), sp)
|
||||
legendn += 1
|
||||
tbx, tby = gr_inqtext(0, 0, string(sp[:legendtitle]))
|
||||
legendw = tbx[3] - tbx[1]
|
||||
legendn += 1
|
||||
dy = tby[3] - tby[1]
|
||||
end
|
||||
gr_set_font(legendfont(sp), sp)
|
||||
for series in series_list(sp)
|
||||
should_add_to_legend(series) || continue
|
||||
legendn += 1
|
||||
lab = series[:label]
|
||||
tbx, tby = gr_inqtext(0, 0, string(lab))
|
||||
tbx, tby = gr_inqtext(0, 0, string(series[:label]))
|
||||
legendw = max(legendw, tbx[3] - tbx[1]) # Holds text width right now
|
||||
dy = max(dy, tby[3] - tby[1])
|
||||
end
|
||||
|
||||
GR.setscale(1)
|
||||
@@ -1192,7 +1197,8 @@ function gr_get_legend_geometry(viewport_plotarea, sp)
|
||||
x_legend_offset = (viewport_plotarea[2] - viewport_plotarea[1]) / 30
|
||||
y_legend_offset = (viewport_plotarea[4] - viewport_plotarea[3]) / 30
|
||||
|
||||
dy = gr_point_mult(sp) * sp[:legendfontsize] * 1.75
|
||||
dy *= get(sp[:extra_kwargs], :legend_hfactor, 1)
|
||||
|
||||
legendh = dy * legendn
|
||||
|
||||
return (
|
||||
@@ -1282,12 +1288,22 @@ function gr_set_window(sp, viewport_plotarea)
|
||||
gr_set_viewport_polar(viewport_plotarea)
|
||||
else
|
||||
xmin, xmax, ymin, ymax = gr_xy_axislims(sp)
|
||||
needs_3d = needs_any_3d_axes(sp)
|
||||
if needs_3d
|
||||
zmin, zmax = gr_z_axislims(sp)
|
||||
zok = zmax > zmin
|
||||
else
|
||||
zok = true
|
||||
end
|
||||
|
||||
scaleop = 0
|
||||
if xmax > xmin && ymax > ymin
|
||||
sp[:xaxis][:scale] == :log10 && (scaleop |= GR.OPTION_X_LOG)
|
||||
sp[:yaxis][:scale] == :log10 && (scaleop |= GR.OPTION_Y_LOG)
|
||||
sp[:xaxis][:flip] && (scaleop |= GR.OPTION_FLIP_X)
|
||||
sp[:yaxis][:flip] && (scaleop |= GR.OPTION_FLIP_Y)
|
||||
if xmax > xmin && ymax > ymin && zok
|
||||
sp[:xaxis][:scale] == :log10 && (scaleop |= GR.OPTION_X_LOG)
|
||||
sp[:yaxis][:scale] == :log10 && (scaleop |= GR.OPTION_Y_LOG)
|
||||
needs_3d && sp[:zaxis][:scale] == :log10 && (scaleop |= GR.OPTION_Z_LOG)
|
||||
sp[:xaxis][:flip] && (scaleop |= GR.OPTION_FLIP_X)
|
||||
sp[:yaxis][:flip] && (scaleop |= GR.OPTION_FLIP_Y)
|
||||
needs_3d && sp[:zaxis][:flip] && (scaleop |= GR.OPTION_FLIP_Z)
|
||||
# NOTE: setwindow sets the "data coordinate" limits of the current "viewport"
|
||||
GR.setwindow(xmin, xmax, ymin, ymax)
|
||||
GR.setscale(scaleop)
|
||||
@@ -1310,8 +1326,14 @@ function gr_draw_axes(sp, viewport_plotarea)
|
||||
if RecipesPipeline.is3d(sp)
|
||||
# set space
|
||||
xmin, xmax, ymin, ymax = gr_xy_axislims(sp)
|
||||
zmin, zmax = axis_limits(sp, :z)
|
||||
GR.setspace(zmin, zmax, round.(Int, sp[:camera])...)
|
||||
zmin, zmax = gr_z_axislims(sp)
|
||||
|
||||
camera = round.(Int, sp[:camera])
|
||||
|
||||
warn_invalid(val) = if val < 0 || val > 90 @warn "camera: $(val)° ∉ [0°, 90°]" end
|
||||
warn_invalid.(camera)
|
||||
|
||||
GR.setspace(zmin, zmax, camera...)
|
||||
|
||||
# fill the plot area
|
||||
gr_set_fill(plot_color(sp[:background_color_inside]))
|
||||
@@ -1322,7 +1344,7 @@ function gr_draw_axes(sp, viewport_plotarea)
|
||||
GR.fillarea(x_bg, y_bg)
|
||||
|
||||
for letter in (:x, :y, :z)
|
||||
gr_draw_axis_3d(sp, letter)
|
||||
gr_draw_axis_3d(sp, letter, viewport_plotarea)
|
||||
end
|
||||
elseif ispolar(sp)
|
||||
r = gr_set_viewport_polar(viewport_plotarea)
|
||||
@@ -1352,7 +1374,7 @@ function gr_draw_axis(sp, letter, viewport_plotarea)
|
||||
gr_label_axis(sp, letter, viewport_plotarea)
|
||||
end
|
||||
|
||||
function gr_draw_axis_3d(sp, letter)
|
||||
function gr_draw_axis_3d(sp, letter, viewport_plotarea)
|
||||
ax = axis_drawing_info_3d(sp, letter)
|
||||
axis = sp[Symbol(letter, :axis)]
|
||||
|
||||
@@ -1364,8 +1386,10 @@ function gr_draw_axis_3d(sp, letter)
|
||||
gr_draw_ticks(sp, axis, ax.tick_segments, gr_polyline3d)
|
||||
|
||||
# labels
|
||||
GR.setscale(0)
|
||||
gr_label_ticks_3d(sp, letter, ax.ticks)
|
||||
gr_label_axis_3d(sp, letter)
|
||||
gr_set_window(sp, viewport_plotarea)
|
||||
end
|
||||
|
||||
function gr_draw_grid(sp, axis, segments, func = gr_polyline)
|
||||
@@ -1440,13 +1464,14 @@ function gr_label_ticks(sp, letter, ticks)
|
||||
oamin, oamax = axis_limits(sp, oletter)
|
||||
gr_set_tickfont(sp, letter)
|
||||
out_factor = ifelse(axis[:tick_direction] === :out, 1.5, 1)
|
||||
x_offset = isy ? (axis[:mirror] ? 1 : -1) * 1.5e-2 * out_factor : 0
|
||||
y_offset = isy ? 0 : (axis[:mirror] ? 1 : -1) * 8e-3 * out_factor
|
||||
x_offset = isy ? -1.5e-2 * out_factor : 0
|
||||
y_offset = isy ? 0 : -8e-3 * out_factor
|
||||
|
||||
ov = sp[:framestyle] == :origin ? 0 : xor(oaxis[:flip], axis[:mirror]) ? oamax : oamin
|
||||
sgn = axis[:mirror] ? -1 : 1
|
||||
for (cv, dv) in zip(ticks...)
|
||||
x, y = GR.wctondc(reverse_if((cv, ov), isy)...)
|
||||
gr_text(x + x_offset, y + y_offset, dv)
|
||||
gr_text(x + sgn * x_offset, y + sgn * y_offset, dv)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1478,8 +1503,8 @@ function gr_label_ticks_3d(sp, letter, ticks)
|
||||
xax, yax, zax = getindex.(Ref(sp), asyms)
|
||||
|
||||
gr_set_tickfont(sp, letter)
|
||||
nt = sp[:framestyle] == :origin ? 0 : xor(ax[:mirror], nax[:flip]) ? n1 : n0
|
||||
ft = sp[:framestyle] == :origin ? 0 : xor(ax[:mirror], fax[:flip]) ? famax : famin
|
||||
nt = sp[:framestyle] == :origin ? 0 : ax[:mirror] ? n1 : n0
|
||||
ft = sp[:framestyle] == :origin ? 0 : ax[:mirror] ? famax : famin
|
||||
|
||||
xoffset = if letter === :x
|
||||
(sp[:yaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:xaxis][:tick_direction] == :out ? 1.5 : 1)
|
||||
@@ -1496,7 +1521,10 @@ function gr_label_ticks_3d(sp, letter, ticks)
|
||||
0
|
||||
end
|
||||
|
||||
for (cv, dv) in zip(ticks...)
|
||||
cvs, dvs = ticks
|
||||
ax[:flip] && reverse!(cvs)
|
||||
|
||||
for (cv, dv) in zip((cvs, dvs)...)
|
||||
xi, yi = gr_w3tondc(sort_3d_axes(cv, nt, ft, letter)...)
|
||||
gr_text(xi + xoffset, yi + yoffset, dv)
|
||||
end
|
||||
@@ -1510,8 +1538,10 @@ function gr_label_axis(sp, letter, viewport_plotarea)
|
||||
GR.savestate()
|
||||
gr_set_font(guidefont(axis), sp)
|
||||
guide_position = axis[:guide_position]
|
||||
angle = float(axis[:guidefontrotation]) # github.com/JuliaPlots/Plots.jl/issues/3089
|
||||
if letter === :y
|
||||
GR.setcharup(-1, 0)
|
||||
angle += 180. # default angle = 0. should yield GR.setcharup(-1, 0) i.e. 180°
|
||||
GR.setcharup(cosd(angle), sind(angle))
|
||||
ypos = gr_view_yposition(viewport_plotarea, position(axis[:guidefontvalign]))
|
||||
yalign = alignment(axis[:guidefontvalign])
|
||||
if guide_position === :right || (guide_position == :auto && mirror)
|
||||
@@ -1522,6 +1552,8 @@ function gr_label_axis(sp, letter, viewport_plotarea)
|
||||
xpos = viewport_plotarea[1] - 0.03 - !mirror * gr_axis_width(sp, axis)
|
||||
end
|
||||
else
|
||||
angle += 90. # default angle = 0. should yield GR.setcharup(0, 1) i.e. 90°
|
||||
GR.setcharup(cosd(angle), sind(angle))
|
||||
xpos = gr_view_xposition(viewport_plotarea, position(axis[:guidefonthalign]))
|
||||
xalign = alignment(axis[:guidefonthalign])
|
||||
if guide_position === :top || (guide_position == :auto && mirror)
|
||||
@@ -1561,8 +1593,8 @@ function gr_label_axis_3d(sp, letter)
|
||||
# color = ax[:guidefontcolor],
|
||||
)
|
||||
ag = (amin + amax) / 2
|
||||
ng = xor(ax[:mirror], nax[:flip]) ? n1 : n0
|
||||
fg = xor(ax[:mirror], fax[:flip]) ? famax : famin
|
||||
ng = ax[:mirror] ? n1 : n0
|
||||
fg = ax[:mirror] ? famax : famin
|
||||
x, y = gr_w3tondc(sort_3d_axes(ag, ng, fg, letter)...)
|
||||
if letter in (:x, :y)
|
||||
h = gr_axis_height(sp, ax)
|
||||
@@ -1573,7 +1605,8 @@ function gr_label_axis_3d(sp, letter)
|
||||
y_offset = 0
|
||||
end
|
||||
letter === :z && GR.setcharup(-1, 0)
|
||||
gr_text(x + x_offset, y + y_offset, ax[:guide])
|
||||
sgn = ax[:mirror] ? -1 : 1
|
||||
gr_text(x + sgn * x_offset, y + sgn * y_offset, ax[:guide])
|
||||
GR.restorestate()
|
||||
end
|
||||
end
|
||||
@@ -1649,7 +1682,7 @@ function gr_add_series(sp, series)
|
||||
end
|
||||
elseif st === :contour
|
||||
gr_draw_contour(series, x, y, z, clims)
|
||||
elseif st in (:surface, :wireframe)
|
||||
elseif st in (:surface, :wireframe, :mesh3d)
|
||||
gr_draw_surface(series, x, y, z, clims)
|
||||
elseif st === :volume
|
||||
sp[:legend] = :none
|
||||
@@ -1691,7 +1724,7 @@ end
|
||||
function gr_draw_segments(series, x, y, fillrange, clims)
|
||||
st = series[:seriestype]
|
||||
if x !== nothing && length(x) > 1
|
||||
segments = series_segments(series, st)
|
||||
segments = series_segments(series, st; check=true)
|
||||
# do area fill
|
||||
if fillrange !== nothing
|
||||
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
||||
@@ -1728,7 +1761,7 @@ end
|
||||
function gr_draw_segments_3d(series, x, y, z, clims)
|
||||
if series[:seriestype] === :path3d && length(x) > 1
|
||||
lz = series[:line_z]
|
||||
segments = series_segments(series, :path3d)
|
||||
segments = series_segments(series, :path3d; check=true)
|
||||
for segment in segments
|
||||
i, rng = segment.attr_index, segment.range
|
||||
lc = get_linecolor(series, clims, i)
|
||||
@@ -1805,7 +1838,7 @@ function gr_draw_contour(series, x, y, z, clims)
|
||||
h = gr_contour_levels(series, clims)
|
||||
if series[:fillrange] !== nothing
|
||||
if series[:fillcolor] != series[:linecolor] && !is_lc_black
|
||||
@warn("GR: filled contour only supported with black contour lines")
|
||||
@warn "GR: filled contour only supported with black contour lines"
|
||||
end
|
||||
GR.contourf(x, y, h, z, series[:contour_labels] == true ? 1 : 0)
|
||||
else
|
||||
@@ -1815,22 +1848,59 @@ function gr_draw_contour(series, x, y, z, clims)
|
||||
end
|
||||
|
||||
function gr_draw_surface(series, x, y, z, clims)
|
||||
|
||||
if series[:seriestype] === :surface
|
||||
e_kwargs = series[:extra_kwargs]
|
||||
st = series[:seriestype]
|
||||
if st === :surface
|
||||
fillalpha = get_fillalpha(series)
|
||||
fillcolor = get_fillcolor(series)
|
||||
if length(x) == length(y) == length(z)
|
||||
x, y, z = GR.gridit(x, y, z, 200, 200)
|
||||
# NOTE: setting nx = 0 or ny = 0 disables GR.gridit interpolation
|
||||
nx, ny = get(e_kwargs, :nx, 200), get(e_kwargs, :ny, 200)
|
||||
if length(x) == length(y) == length(z) && nx > 0 && ny > 0
|
||||
x, y, z = GR.gridit(x, y, z, nx, ny)
|
||||
end
|
||||
d_opt = get(e_kwargs, :display_option, GR.OPTION_COLORED_MESH)
|
||||
if (!isnothing(fillalpha) && fillalpha < 1) || alpha(first(fillcolor)) < 1
|
||||
gr_set_transparency(fillcolor, fillalpha)
|
||||
GR.surface(x, y, z, GR.OPTION_COLORED_MESH)
|
||||
GR.surface(x, y, z, d_opt)
|
||||
else
|
||||
GR.gr3.surface(x, y, z, GR.OPTION_COLORED_MESH)
|
||||
GR.gr3.surface(x, y, z, d_opt)
|
||||
end
|
||||
else # wireframe
|
||||
elseif st === :wireframe
|
||||
GR.setfillcolorind(0)
|
||||
GR.surface(x, y, z, GR.OPTION_FILLED_MESH)
|
||||
GR.surface(x, y, z, get(e_kwargs, :display_option, GR.OPTION_FILLED_MESH))
|
||||
elseif st === :mesh3d
|
||||
@warn "GR: mesh3d is experimental (no face colors)"
|
||||
conn = series[:connections]
|
||||
if typeof(conn) <: Tuple{Array, Array, Array}
|
||||
ci, cj, ck = conn
|
||||
if !(length(ci) == length(cj) == length(ck))
|
||||
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
|
||||
end
|
||||
else
|
||||
throw(ArgumentError("Argument connections has to be a tuple of three arrays."))
|
||||
end
|
||||
X = zeros(eltype(x), 4length(ci))
|
||||
Y = zeros(eltype(y), 4length(cj))
|
||||
Z = zeros(eltype(z), 4length(ck))
|
||||
@inbounds for I ∈ 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
|
||||
gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series), series)
|
||||
GR.polyline3d(X, Y, Z)
|
||||
else
|
||||
throw(ArgumentError("Not handled !"))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+18
-18
@@ -363,37 +363,37 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
||||
a.title = sp[:title]
|
||||
a.xlabel = xaxis[:guide]; a.ylabels = [yaxis[:guide]]
|
||||
|
||||
l = plot.layout
|
||||
#IMPORTANT: Don't forget to actually register changes
|
||||
#(TODO: need to find a better way to set layout properties)
|
||||
l[:frame_canvas].fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
|
||||
l[:frame_canvas] = l[:frame_canvas] #register changes
|
||||
l[:frame_data].fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
|
||||
l[:frame_data] = l[:frame_data] #register changes
|
||||
|
||||
l[:frame_data].line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
|
||||
l[:frame_data] = l[:frame_data] #register changes
|
||||
l[:font_title] = InspectDR.Font(sp[:titlefontfamily],
|
||||
#Modify base layout of new object:
|
||||
l = plot.layout.defaults = deepcopy(InspectDR.defaults.plotlayout)
|
||||
#IMPORTANT: Must deepcopy to ensure we don't change layouts of other plots.
|
||||
#Works because plot uses defaults (not user-overwritten `layout.values`)
|
||||
l.frame_canvas.fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
|
||||
l.frame_data.fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
|
||||
l.frame_data.line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
|
||||
l.font_title = InspectDR.Font(sp[:titlefontfamily],
|
||||
_inspectdr_mapptsize(sp[:titlefontsize]),
|
||||
color = _inspectdr_mapcolor(sp[:titlefontcolor])
|
||||
)
|
||||
#Cannot independently control fonts of axes with InspectDR:
|
||||
l[:font_axislabel] = InspectDR.Font(xaxis[:guidefontfamily],
|
||||
l.font_axislabel = InspectDR.Font(xaxis[:guidefontfamily],
|
||||
_inspectdr_mapptsize(xaxis[:guidefontsize]),
|
||||
color = _inspectdr_mapcolor(xaxis[:guidefontcolor])
|
||||
)
|
||||
l[:font_ticklabel] = InspectDR.Font(xaxis[:tickfontfamily],
|
||||
l.font_ticklabel = InspectDR.Font(xaxis[:tickfontfamily],
|
||||
_inspectdr_mapptsize(xaxis[:tickfontsize]),
|
||||
color = _inspectdr_mapcolor(xaxis[:tickfontcolor])
|
||||
)
|
||||
l[:enable_legend] = (sp[:legend] != :none)
|
||||
#l[:halloc_legend] = 150 #TODO: compute???
|
||||
l[:font_legend] = InspectDR.Font(sp[:legendfontfamily],
|
||||
l.enable_legend = (sp[:legend] != :none)
|
||||
#l.halloc_legend = 150 #TODO: compute???
|
||||
l.font_legend = InspectDR.Font(sp[:legendfontfamily],
|
||||
_inspectdr_mapptsize(sp[:legendfontsize]),
|
||||
color = _inspectdr_mapcolor(sp[:legendfontcolor])
|
||||
)
|
||||
l[:frame_legend].fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
|
||||
l[:frame_legend] = l[:frame_legend] #register changes
|
||||
l.frame_legend.fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
|
||||
|
||||
#_round!() ensures values use integer spacings (looks better on screen):
|
||||
InspectDR._round!(InspectDR.autofit2font!(l, legend_width=10.0)) #10 "em"s wide
|
||||
return
|
||||
end
|
||||
|
||||
# called just before updating layout bounding boxes... in case you need to prep
|
||||
|
||||
+99
-56
@@ -82,6 +82,7 @@ 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)
|
||||
@@ -117,11 +118,22 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
end
|
||||
|
||||
for sp in plt.subplots
|
||||
bb1 = sp.plotarea
|
||||
bb2 = bbox(sp)
|
||||
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)
|
||||
dx, dy = bb2.x0
|
||||
lpad = leftpad(sp) + sp[:left_margin]
|
||||
rpad = rightpad(sp) + sp[:right_margin]
|
||||
tpad = toppad(sp) + sp[:top_margin]
|
||||
@@ -130,10 +142,6 @@ 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]
|
||||
@@ -142,7 +150,6 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
axis_opt = PGFPlotsX.Options(
|
||||
"point meta max" => get_clims(sp)[2],
|
||||
"point meta min" => get_clims(sp)[1],
|
||||
"legend cell align" => "left",
|
||||
"title" => sp[:title],
|
||||
"title style" => PGFPlotsX.Options(
|
||||
pgfx_get_title_pos(title_loc)...,
|
||||
@@ -154,22 +161,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
"draw opacity" => title_a,
|
||||
"rotate" => sp[:titlefontrotation],
|
||||
),
|
||||
"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]),
|
||||
),
|
||||
"legend style" => pgfx_get_legend_style(sp),
|
||||
"axis background/.style" => PGFPlotsX.Options(
|
||||
"fill" => bgc_inside,
|
||||
"opacity" => bgc_inside_a,
|
||||
@@ -183,8 +175,6 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
|
||||
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)
|
||||
@@ -225,16 +215,22 @@ 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
|
||||
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
|
||||
push!(colorbar_style,
|
||||
"ytick" => string("{", join(cticks, ","), "}"),
|
||||
"yticklabel style" => pgfx_get_colorbar_ticklabel_style(sp),
|
||||
)
|
||||
end
|
||||
push!(
|
||||
@@ -242,6 +238,8 @@ 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]
|
||||
@@ -339,9 +337,9 @@ end
|
||||
|
||||
function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, opt)
|
||||
# treat segments
|
||||
segments = collect(series_segments(series, series[:seriestype]))
|
||||
segments = collect(series_segments(series, series[:seriestype]; check=true))
|
||||
sf = opt[:fillrange]
|
||||
for segment in segments
|
||||
for (k, segment) in enumerate(segments)
|
||||
i, rng = segment.attr_index, segment.range
|
||||
segment_opt = PGFPlotsX.Options()
|
||||
segment_opt = merge(segment_opt, pgfx_linestyle(opt, i))
|
||||
@@ -397,7 +395,7 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
|
||||
)
|
||||
end
|
||||
end
|
||||
if i == 1 &&
|
||||
if k == 1 &&
|
||||
series[:subplot][:legend] != :none && pgfx_should_add_to_legend(series)
|
||||
pgfx_filllegend!(series_opt, opt)
|
||||
end
|
||||
@@ -464,7 +462,7 @@ function pgfx_add_series!(::Val{:path}, axis, series_opt, series, series_func, o
|
||||
),
|
||||
)
|
||||
end
|
||||
pgfx_add_legend!(axis, series, opt, i)
|
||||
pgfx_add_legend!(axis, series, opt, k)
|
||||
end # for segments
|
||||
# get that last marker
|
||||
if !isnothing(opt[:y]) && !any(isnan, opt[:y]) && opt[:markershape] isa AVec
|
||||
@@ -492,13 +490,14 @@ 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(opt[:x]),
|
||||
"mesh/cols" => length(opt[:y]),
|
||||
"mesh/rows" => length(unique(opt[:x])), # unique if its all vectors
|
||||
"mesh/cols" => length(unique(opt[:y])),
|
||||
"z buffer" => "sort",
|
||||
"opacity" => get_fillalpha(series),
|
||||
"opacity" => alpha === nothing ? 1.0 : alpha,
|
||||
)
|
||||
pgfx_add_series!(axis, series_opt, series, series_func, opt)
|
||||
end
|
||||
@@ -791,6 +790,31 @@ 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[:background_color_legend])
|
||||
a = alpha(cstr)
|
||||
fg_alpha = alpha(plot_color(sp[:foreground_color_legend]))
|
||||
legfont = legendfont(sp)
|
||||
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]),
|
||||
"cells" => PGFPlotsX.Options("anchor" => get((left = "west", right = "east", hcenter = "center"), legfont.halign, "west")),
|
||||
pgfx_get_legend_pos(sp[:legend])...,
|
||||
)
|
||||
end
|
||||
|
||||
pgfx_get_colorbar_pos(s) =
|
||||
get((left = " left", bottom = " horizontal", top = " horizontal"), s, "")
|
||||
pgfx_get_colorbar_pos(b::Bool) = ""
|
||||
@@ -809,15 +833,23 @@ function pgfx_get_ticklabel_style(sp, axis)
|
||||
return PGFPlotsX.Options(
|
||||
"font" => pgfx_font(
|
||||
axis[:tickfontsize], pgfx_thickness_scaling(sp)
|
||||
),
|
||||
"color" => cstr,
|
||||
), "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[]
|
||||
@@ -848,6 +880,7 @@ 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
|
||||
@@ -866,7 +899,7 @@ function pgfx_framestyle(style::Symbol)
|
||||
return style
|
||||
else
|
||||
default_style = get((semi = :box,), style, :axes)
|
||||
@warn( "Framestyle :$style is not (yet) supported by the PGFPlotsX backend. :$default_style was cosen instead.",)
|
||||
@warn "Framestyle :$style is not (yet) supported by the PGFPlotsX backend. :$default_style was chosen instead."
|
||||
default_style
|
||||
end
|
||||
end
|
||||
@@ -976,24 +1009,27 @@ function pgfx_marker(plotattributes, i = 1)
|
||||
)
|
||||
end
|
||||
|
||||
function pgfx_add_annotation!(o, x, y, val, thickness_scaling = 1)
|
||||
function pgfx_add_annotation!(o, x, y, val, thickness_scaling = 1; cs = "axis cs:", options = PGFPlotsX.Options())
|
||||
# Construct the style string.
|
||||
cstr = val.font.color
|
||||
a = alpha(cstr)
|
||||
push!(
|
||||
o,
|
||||
[
|
||||
join([
|
||||
"\\node",
|
||||
PGFPlotsX.Options(
|
||||
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),
|
||||
),
|
||||
" at (axis cs:$x, $y) {$(val.str)};",
|
||||
],
|
||||
sprint(PGFPlotsX.print_tex, merge(
|
||||
PGFPlotsX.Options(
|
||||
get((hcenter = "", 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, "};"),
|
||||
]),
|
||||
)
|
||||
end
|
||||
|
||||
@@ -1058,7 +1094,7 @@ 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))
|
||||
fillrange_opt = merge(fillrange_opt, pgfx_marker(series, i))
|
||||
push!(fillrange_opt, "mark" => "none") # no markers on fillranges
|
||||
push!(fillrange_opt, "forget plot" => nothing)
|
||||
opt = series.plotattributes
|
||||
args = RecipesPipeline.is3d(series) ? (opt[:x][rng], opt[:y][rng], opt[:z][rng]) :
|
||||
@@ -1261,11 +1297,18 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
|
||||
else
|
||||
push!(opt, string(letter, "ticklabels") => "{}")
|
||||
end
|
||||
push!(
|
||||
opt,
|
||||
string(letter, "tick align") =>
|
||||
(axis[:tick_direction] == :out ? "outside" : "inside"),
|
||||
)
|
||||
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)
|
||||
)
|
||||
|
||||
+10
-10
@@ -7,7 +7,7 @@ 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 cosen instead.")
|
||||
@warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was chosen instead.")
|
||||
default_style
|
||||
end
|
||||
end
|
||||
@@ -143,7 +143,8 @@ function plotly_axis(axis, sp, anchor = nothing, domain = nothing)
|
||||
:zerolinecolor => rgba_string(axis[:foreground_color_axis]),
|
||||
:showline => framestyle in (:box, :axes) && axis[:showaxis],
|
||||
:linecolor => rgba_string(plot_color(axis[:foreground_color_axis])),
|
||||
:ticks => axis[:tick_direction] == :out ? "outside" : "inside",
|
||||
:ticks => axis[:tick_direction] === :out ? "outside" :
|
||||
axis[:tick_direction] === :in ? "inside" : "",
|
||||
:mirror => framestyle == :box,
|
||||
:showticklabels => axis[:showaxis],
|
||||
)
|
||||
@@ -662,7 +663,7 @@ function plotly_series(plt::Plot, series::Series)
|
||||
end
|
||||
|
||||
function plotly_series_shapes(plt::Plot, series::Series, clims)
|
||||
segments = collect(series_segments(series))
|
||||
segments = series_segments(series; check=true)
|
||||
plotattributes_outs = Vector{KW}(undef, length(segments))
|
||||
|
||||
# TODO: create a plotattributes_out for each polygon
|
||||
@@ -681,7 +682,7 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
|
||||
for (letter, data) in zip((:x, :y), shape_data(series, 100))
|
||||
)
|
||||
|
||||
for segment in segments
|
||||
for (k, segment) in enumerate(segments)
|
||||
i, rng = segment.attr_index, segment.range
|
||||
length(rng) < 2 && continue
|
||||
|
||||
@@ -701,10 +702,10 @@ function plotly_series_shapes(plt::Plot, series::Series, clims)
|
||||
:dash => string(get_linestyle(series, i)),
|
||||
)
|
||||
end
|
||||
plotattributes_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
|
||||
plotattributes_out[:showlegend] = k==1 ? should_add_to_legend(series) : false
|
||||
plotly_polar!(plotattributes_out, series)
|
||||
plotly_hover!(plotattributes_out, _cycle(series[:hover], i))
|
||||
plotattributes_outs[i] = plotattributes_out
|
||||
plotattributes_outs[k] = plotattributes_out
|
||||
end
|
||||
if series[:fill_z] !== nothing
|
||||
push!(plotattributes_outs, plotly_colorbar_hack(series, plotattributes_base, :fill))
|
||||
@@ -952,8 +953,7 @@ function plotly_html_body(plt, style = nothing)
|
||||
<div id=\"$(uuid)\" style=\"$(style)\"></div>
|
||||
<script>
|
||||
$(requirejs_prefix)
|
||||
PLOT = document.getElementById('$(uuid)');
|
||||
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
|
||||
$(js_body(plt, uuid))
|
||||
$(requirejs_suffix)
|
||||
</script>
|
||||
"""
|
||||
@@ -962,7 +962,7 @@ end
|
||||
|
||||
function js_body(plt::Plot, uuid)
|
||||
js = """
|
||||
PLOT = document.getElementById('$(uuid)');
|
||||
var PLOT = document.getElementById('$(uuid)');
|
||||
Plotly.plot(PLOT, $(plotly_series_json(plt)), $(plotly_layout_json(plt)));
|
||||
"""
|
||||
end
|
||||
@@ -986,7 +986,7 @@ end
|
||||
|
||||
|
||||
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
|
||||
write(io, standalone_html(plt))
|
||||
write(io, embeddable_html(plt))
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ _show(io::IO, mime::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBack
|
||||
html_head(plt::Plot{PlotlyJSBackend}) = plotly_html_head(plt)
|
||||
html_body(plt::Plot{PlotlyJSBackend}) = plotly_html_body(plt)
|
||||
|
||||
_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, standalone_html(plt))
|
||||
_show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, embeddable_html(plt))
|
||||
|
||||
_display(plt::Plot{PlotlyJSBackend}) = display(plotlyjs_syncplot(plt))
|
||||
|
||||
|
||||
+19
-11
@@ -442,7 +442,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
||||
# end
|
||||
# push!(handles, handle)
|
||||
# else
|
||||
for (k, segment) in enumerate(series_segments(series, st))
|
||||
for (k, segment) in enumerate(series_segments(series, st; check=true))
|
||||
i, rng = segment.attr_index, segment.range
|
||||
handle = ax."plot"((arg[rng] for arg in xyargs)...;
|
||||
label = k == 1 ? series[:label] : "",
|
||||
@@ -759,7 +759,7 @@ function py_surround_latextext(latexstring, env)
|
||||
end
|
||||
|
||||
|
||||
function py_set_ticks(ax, ticks, letter, env)
|
||||
function py_set_ticks(sp, ax, ticks, letter, env)
|
||||
ticks == :auto && return
|
||||
axis = getproperty(ax, Symbol(letter,"axis"))
|
||||
if ticks == :none || ticks === nothing || ticks == false
|
||||
@@ -777,7 +777,7 @@ function py_set_ticks(ax, ticks, letter, env)
|
||||
elseif ttype == :ticks_and_labels
|
||||
axis."set_ticks"(ticks[1])
|
||||
|
||||
if pyrcparams["text.usetex"]
|
||||
if get(sp[:extra_kwargs], :rawticklabels, false)
|
||||
tick_labels = ticks[2]
|
||||
else
|
||||
tick_labels = [py_surround_latextext(ticklabel, env) for ticklabel in ticks[2]]
|
||||
@@ -1009,7 +1009,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
||||
ticks_letter=:y
|
||||
end
|
||||
py_set_scale(cb.ax, sp, sp[:colorbar_scale], ticks_letter)
|
||||
sp[:colorbar_ticks] == :native ? nothing : py_set_ticks(cb.ax, ticks, ticks_letter, env)
|
||||
sp[:colorbar_ticks] == :native ? nothing : py_set_ticks(sp, cb.ax, ticks, ticks_letter, env)
|
||||
|
||||
for lab in cbar_axis."get_ticklabels"()
|
||||
lab."set_fontsize"(py_thickness_scale(plt, sp[:colorbar_tickfontsize]))
|
||||
@@ -1022,7 +1022,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
||||
cbar_axis."set_tick_params"(
|
||||
direction = axis[:tick_direction] == :out ? "out" : "in",
|
||||
width=py_thickness_scale(plt, intensity),
|
||||
length= 5 * py_thickness_scale(plt, intensity)
|
||||
length = axis[:tick_direction] == :none ? 0 : 5 * py_thickness_scale(plt, intensity)
|
||||
)
|
||||
|
||||
|
||||
@@ -1063,8 +1063,14 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
||||
ax.spines["left"]."set_position"("zero")
|
||||
end
|
||||
elseif sp[:framestyle] in (:grid, :none, :zerolines)
|
||||
for (loc, spine) in ax.spines
|
||||
spine."set_visible"(false)
|
||||
if PyPlot.version >= v"3.4.1" # that is one where it worked, the API change may have some other value
|
||||
for spine in ax.spines
|
||||
ax.spines[string(spine)]."set_visible"(false)
|
||||
end
|
||||
else
|
||||
for (loc, spine) in ax.spines
|
||||
spine."set_visible"(false)
|
||||
end
|
||||
end
|
||||
if sp[:framestyle] == :zerolines
|
||||
ax."axhline"(y = 0, color = py_color(sp[:xaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75))
|
||||
@@ -1131,13 +1137,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
||||
# workaround to set mathtext.fontspec per Text element
|
||||
env = "\\mathregular" # matches the outer fonts https://matplotlib.org/tutorials/text/mathtext.html
|
||||
|
||||
axis[:ticks] == :native ? nothing : py_set_ticks(ax, ticks, letter, env)
|
||||
axis[:ticks] == :native ? nothing : py_set_ticks(sp, ax, ticks, letter, env)
|
||||
# Tick marks
|
||||
intensity = 0.5 # This value corresponds to scaling of other grid elements
|
||||
pyaxis."set_tick_params"(
|
||||
direction = axis[:tick_direction] == :out ? "out" : "in",
|
||||
width=py_thickness_scale(plt, intensity),
|
||||
length= 5 * py_thickness_scale(plt, intensity)
|
||||
length = axis[:tick_direction] == :none ? 0 : 5 * py_thickness_scale(plt, intensity)
|
||||
)
|
||||
|
||||
getproperty(ax, Symbol("set_", letter, "label"))(axis[:guide])
|
||||
@@ -1176,7 +1182,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
||||
pyaxis."set_tick_params"(
|
||||
which = "minor",
|
||||
direction = axis[:tick_direction] == :out ? "out" : "in",
|
||||
width=py_thickness_scale(plt, intensity))
|
||||
length = axis[:tick_direction] == :none ? 0 : py_thickness_scale(plt, intensity),
|
||||
)
|
||||
end
|
||||
|
||||
if axis[:minorgrid]
|
||||
@@ -1186,7 +1193,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
||||
pyaxis."set_tick_params"(
|
||||
which = "minor",
|
||||
direction = axis[:tick_direction] == :out ? "out" : "in",
|
||||
width=py_thickness_scale(plt, intensity))
|
||||
length = axis[:tick_direction] == :none ? 0 : py_thickness_scale(plt, intensity)
|
||||
)
|
||||
|
||||
pyaxis."grid"(true,
|
||||
which = "minor",
|
||||
|
||||
@@ -19,6 +19,10 @@ function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr
|
||||
"""
|
||||
end
|
||||
|
||||
function embeddable_html(plt::AbstractPlot)
|
||||
html_head(plt) * html_body(plt)
|
||||
end
|
||||
|
||||
function open_browser_window(filename::AbstractString)
|
||||
@static if Sys.isapple()
|
||||
return run(`open $(filename)`)
|
||||
|
||||
+42
-13
@@ -9,9 +9,9 @@ compute_angle(v::P2) = (angle = atan(v[2], v[1]); angle < 0 ? 2π - angle : angl
|
||||
|
||||
# -------------------------------------------------------------
|
||||
|
||||
struct Shape
|
||||
x::Vector{Float64}
|
||||
y::Vector{Float64}
|
||||
struct Shape{X<:Number, Y<:Number}
|
||||
x::Vector{X}
|
||||
y::Vector{Y}
|
||||
# function Shape(x::AVec, y::AVec)
|
||||
# # if x[1] != x[end] || y[1] != y[end]
|
||||
# # new(vcat(x, x[1]), vcat(y, y[1]))
|
||||
@@ -43,7 +43,7 @@ function coords(shape::Shape)
|
||||
end
|
||||
|
||||
#coords(shapes::AVec{Shape}) = unzip(map(coords, shapes))
|
||||
function coords(shapes::AVec{Shape})
|
||||
function coords(shapes::AVec{<:Shape})
|
||||
c = map(coords, shapes)
|
||||
x = [q[1] for q in c]
|
||||
y = [q[2] for q in c]
|
||||
@@ -52,7 +52,7 @@ end
|
||||
|
||||
"get an array of tuples of points on a circle with radius `r`"
|
||||
function partialcircle(start_θ, end_θ, n = 20, r=1)
|
||||
Tuple{Float64,Float64}[(r*cos(u),r*sin(u)) for u in range(start_θ, stop=end_θ, length=n)]
|
||||
[(r*cos(u), r*sin(u)) for u in range(start_θ, stop=end_θ, length=n)]
|
||||
end
|
||||
|
||||
"interleave 2 vectors into each other (like a zipper's teeth)"
|
||||
@@ -205,9 +205,12 @@ function rotate!(shape::Shape, Θ::Real, c = center(shape))
|
||||
end
|
||||
|
||||
"rotate an object in space"
|
||||
function rotate(shape::Shape, Θ::Real, c = center(shape))
|
||||
shapecopy = deepcopy(shape)
|
||||
rotate!(shapecopy, Θ, c)
|
||||
function rotate(shape::Shape, θ::Real, c = center(shape))
|
||||
x, y = coords(shape)
|
||||
cx, cy = c
|
||||
x_new = rotate_x.(x, y, θ, cx, cy)
|
||||
y_new = rotate_y.(x, y, θ, cx, cy)
|
||||
Shape(x_new, y_new)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
@@ -285,7 +288,7 @@ function font(args...;kw...)
|
||||
|
||||
for symbol in keys(kw)
|
||||
if symbol == :family
|
||||
family = kw[:family]
|
||||
family = string(kw[:family])
|
||||
elseif symbol == :pointsize
|
||||
pointsize = kw[:pointsize]
|
||||
elseif symbol == :halign
|
||||
@@ -471,6 +474,11 @@ mutable struct SeriesAnnotations
|
||||
baseshape::Union{Shape, AbstractVector{Shape}, Nothing}
|
||||
scalefactor::Tuple
|
||||
end
|
||||
|
||||
series_annotations(scalar) = series_annotations([scalar])
|
||||
function series_annotations(anns::AMat)
|
||||
map(series_annotations, anns)
|
||||
end
|
||||
function series_annotations(strs::AbstractVector, args...)
|
||||
fnt = font()
|
||||
shp = nothing
|
||||
@@ -567,16 +575,27 @@ end
|
||||
|
||||
annotations(::Nothing) = []
|
||||
annotations(anns::AVec) = anns
|
||||
annotations(anns::AMat) = map(annotations, anns)
|
||||
annotations(anns) = Any[anns]
|
||||
annotations(sa::SeriesAnnotations) = sa
|
||||
|
||||
# Expand arrays of coordinates, positions and labels into induvidual annotations
|
||||
# and make sure labels are of type PlotText
|
||||
function process_annotation(sp::Subplot, xs, ys, labs, font = font())
|
||||
function process_annotation(sp::Subplot, xs, ys, labs, font = nothing)
|
||||
anns = []
|
||||
labs = makevec(labs)
|
||||
xlength = length(methods(length, (typeof(xs),))) == 0 ? 1 : length(xs)
|
||||
ylength = length(methods(length, (typeof(ys),))) == 0 ? 1 : length(ys)
|
||||
if isnothing(font)
|
||||
font = Plots.font(;
|
||||
family=sp[:annotationfontfamily],
|
||||
pointsize=sp[:annotationfontsize],
|
||||
halign=sp[:annotationhalign],
|
||||
valign=sp[:annotationvalign],
|
||||
rotation=sp[:annotationrotation],
|
||||
color=sp[:annotationcolor],
|
||||
)
|
||||
end
|
||||
for i in 1:max(xlength, ylength, length(labs))
|
||||
x, y, lab = _cycle(xs, i), _cycle(ys, i), _cycle(labs, i)
|
||||
x = typeof(x) <: TimeType ? Dates.value(x) : x
|
||||
@@ -585,14 +604,24 @@ function process_annotation(sp::Subplot, xs, ys, labs, font = font())
|
||||
alphabet = "abcdefghijklmnopqrstuvwxyz"
|
||||
push!(anns, (x, y, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
|
||||
else
|
||||
push!(anns, (x, y, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab...) : text(lab, font)))
|
||||
push!(anns, (x, y, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab[1], font, lab[2:end]...) : text(lab, font)))
|
||||
end
|
||||
end
|
||||
anns
|
||||
end
|
||||
function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, labs, font = font())
|
||||
function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, labs, font = nothing)
|
||||
anns = []
|
||||
positions, labs = makevec(positions), makevec(labs)
|
||||
if isnothing(font)
|
||||
font = Plots.font(;
|
||||
family=sp[:annotationfontfamily],
|
||||
pointsize=sp[:annotationfontsize],
|
||||
halign=sp[:annotationhalign],
|
||||
valign=sp[:annotationvalign],
|
||||
rotation=sp[:annotationrotation],
|
||||
color=sp[:annotationcolor],
|
||||
)
|
||||
end
|
||||
for i in 1:max(length(positions), length(labs))
|
||||
pos, lab = _cycle(positions, i), _cycle(labs, i)
|
||||
pos = get(_positionAliases, pos, pos)
|
||||
@@ -600,7 +629,7 @@ function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol},
|
||||
alphabet = "abcdefghijklmnopqrstuvwxyz"
|
||||
push!(anns, (pos, text(string("(", alphabet[sp[:subplot_index]], ")"), font)))
|
||||
else
|
||||
push!(anns, (pos, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab...) : text(lab, font)))
|
||||
push!(anns, (pos, isa(lab, PlotText) ? lab : isa(lab, Tuple) ? text(lab[1], font, lab[2:end]...) : text(lab, font)))
|
||||
end
|
||||
end
|
||||
anns
|
||||
|
||||
+101
-39
@@ -7,7 +7,7 @@ mutable struct PlotExample
|
||||
exprs::Vector{Expr}
|
||||
end
|
||||
|
||||
# the _examples we'll run for each
|
||||
# the _examples we'll run for each backend
|
||||
const _examples = PlotExample[
|
||||
PlotExample( # 1
|
||||
"Lines",
|
||||
@@ -115,7 +115,7 @@ const _examples = PlotExample[
|
||||
)
|
||||
vline!([5, 10])
|
||||
title!("TITLE")
|
||||
yaxis!("YLABEL", :log10)
|
||||
yaxis!("YLABEL", :log10, minorgrid = true)
|
||||
end
|
||||
),
|
||||
],
|
||||
@@ -241,14 +241,15 @@ const _examples = PlotExample[
|
||||
m -> m in Plots.supported_markers(),
|
||||
Plots._shape_keys,
|
||||
)
|
||||
markers = reshape(markers, 1, length(markers))
|
||||
markers = permutedims(markers)
|
||||
n = length(markers)
|
||||
x = range(0, stop = 10, length = n + 2)[2:(end - 1)]
|
||||
y = repeat(reshape(reverse(x), 1, :), n, 1)
|
||||
scatter(
|
||||
x,
|
||||
y,
|
||||
m = (8, :auto),
|
||||
m = markers,
|
||||
markersize = 8,
|
||||
lab = map(string, markers),
|
||||
bg = :linen,
|
||||
xlim = (0, 10),
|
||||
@@ -369,10 +370,19 @@ const _examples = PlotExample[
|
||||
"Annotations",
|
||||
"""
|
||||
The `annotations` keyword is used for text annotations in data-coordinates. Pass in a
|
||||
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.
|
||||
tuple `(x, y, text)`, or a vector of annotations, each of which is a tuple of `x`, `y`
|
||||
and `text`.
|
||||
`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.
|
||||
""",
|
||||
[
|
||||
:(
|
||||
@@ -384,11 +394,11 @@ const _examples = PlotExample[
|
||||
leg = false,
|
||||
)
|
||||
annotate!([
|
||||
(5, y[5], Plots.text("this is #5", 16, :red, :center)),
|
||||
(5, y[5], ("this is #5", 16, :red, :center)),
|
||||
(
|
||||
10,
|
||||
y[10],
|
||||
Plots.text("this is #10", :right, 20, "courier"),
|
||||
("this is #10", :right, 20, "courier"),
|
||||
),
|
||||
])
|
||||
scatter!(
|
||||
@@ -997,33 +1007,37 @@ const _examples = PlotExample[
|
||||
end]
|
||||
),
|
||||
PlotExample( # 47
|
||||
"Mesh3d",
|
||||
"""
|
||||
Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically.
|
||||
You can also specify the connections using the connections keyword.
|
||||
The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle,
|
||||
such that elements at the same position of these vectors form a triangle.
|
||||
""",
|
||||
[
|
||||
:(
|
||||
begin
|
||||
# specify the vertices
|
||||
x=[0, 1, 2, 0]
|
||||
y=[0, 0, 1, 2]
|
||||
z=[0, 2, 0, 1]
|
||||
"Mesh3d",
|
||||
"""
|
||||
Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically.
|
||||
You can also specify the connections using the connections keyword.
|
||||
The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle,
|
||||
such that elements at the same position of these vectors form a triangle.
|
||||
""",
|
||||
[
|
||||
:(
|
||||
begin
|
||||
# specify the vertices
|
||||
x=[0, 1, 2, 0]
|
||||
y=[0, 0, 1, 2]
|
||||
z=[0, 2, 0, 1]
|
||||
|
||||
# specify the triangles
|
||||
# every column is one triangle,
|
||||
# where the values denote the indices of the vertices of the triangle
|
||||
i=[0, 0, 0, 1]
|
||||
j=[1, 2, 3, 2]
|
||||
k=[2, 3, 1, 3]
|
||||
# specify the triangles
|
||||
# every column is one triangle,
|
||||
# where the values denote the indices of the vertices of the triangle
|
||||
i=[0, 0, 0, 1]
|
||||
j=[1, 2, 3, 2]
|
||||
k=[2, 3, 1, 3]
|
||||
|
||||
# the four triangles gives above give a tetrahedron
|
||||
mesh3d(x,y,z;connections=(i,j,k))
|
||||
end
|
||||
),
|
||||
],
|
||||
# the four triangles gives above give a tetrahedron
|
||||
mesh3d(
|
||||
x, y, z; connections=(i, j, k),
|
||||
title="triangles", xlabel="x", ylabel="y", zlabel="z",
|
||||
legend=:none, margin=2Plots.mm
|
||||
)
|
||||
end
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 48
|
||||
"Vectors of markershapes and segments",
|
||||
@@ -1162,15 +1176,61 @@ const _examples = PlotExample[
|
||||
),
|
||||
],
|
||||
),
|
||||
PlotExample( # 55
|
||||
"3D axis flip / mirror",
|
||||
"",
|
||||
[
|
||||
:(
|
||||
begin
|
||||
using LinearAlgebra
|
||||
scalefontsizes(.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 ∈ (:x, :y, :z)
|
||||
push!(plots, wireframe(
|
||||
args...,
|
||||
title = "wire-flip-$ax",
|
||||
xflip = ax == :x,
|
||||
yflip = ax == :y,
|
||||
zflip = ax == :z;
|
||||
kwargs...,
|
||||
))
|
||||
end
|
||||
|
||||
for ax ∈ (: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
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
# Some constants for PlotDocs and PlotReferenceImages
|
||||
_animation_examples = [2, 31]
|
||||
_backend_skips = Dict(
|
||||
:gr => [25, 30, 47],
|
||||
:pyplot => [2, 25, 30, 31, 47, 49],
|
||||
:plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51],
|
||||
:plotly => [2, 21, 24, 25, 30, 31, 49, 51],
|
||||
:gr => [25, 30],
|
||||
:pyplot => [2, 25, 30, 31, 47, 49, 55],
|
||||
:plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51, 55],
|
||||
:plotly => [2, 21, 24, 25, 30, 31, 49, 50, 51, 55],
|
||||
:pgfplotsx => [
|
||||
2, # animation
|
||||
6, # images
|
||||
@@ -1181,6 +1241,8 @@ _backend_skips = Dict(
|
||||
49, # polar heatmap
|
||||
51, # image with custom axes
|
||||
],
|
||||
:inspectdr => [4, 6, 10, 22, 24, 28, 30, 38, 43, 45, 47, 48, 49, 50, 51, 55],
|
||||
:unicodeplots => [6, 10, 22, 24, 28, 38, 43, 45, 47, 49, 50, 51, 55],
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -70,6 +70,11 @@ 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()
|
||||
|
||||
+35
-58
@@ -406,7 +406,7 @@ end
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
calc_num_subplots(layout::AbstractLayout) = 1
|
||||
calc_num_subplots(layout::AbstractLayout) = get(layout.attr, :blank, false) ? 0 : 1
|
||||
function calc_num_subplots(layout::GridLayout)
|
||||
tot = 0
|
||||
for l in layout.grid
|
||||
@@ -494,34 +494,42 @@ layout_args(huh) = error("unhandled layout type $(typeof(huh)): $huh")
|
||||
|
||||
function build_layout(args...)
|
||||
layout, n = layout_args(args...)
|
||||
build_layout(layout, n)
|
||||
build_layout(layout, n, Array{Plot}(undef, 0))
|
||||
end
|
||||
|
||||
# # 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)
|
||||
# n is the number of subplots...
|
||||
function build_layout(layout::GridLayout, n::Integer, plts::AVec{Plot})
|
||||
nr, nc = size(layout)
|
||||
subplots = Subplot[]
|
||||
spmap = SubplotMap()
|
||||
empty = isempty(plts)
|
||||
i = 0
|
||||
for r=1:nr, c=1:nc
|
||||
l = layout[r,c]
|
||||
for r = 1:nr, c = 1:nc
|
||||
l = layout[r, c]
|
||||
if isa(l, EmptyLayout) && !get(l.attr, :blank, false)
|
||||
sp = Subplot(backend(), parent=layout)
|
||||
layout[r,c] = sp
|
||||
push!(subplots, sp)
|
||||
spmap[attr(l,:label,gensym())] = sp
|
||||
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 += 1
|
||||
i += inc
|
||||
elseif isa(l, GridLayout)
|
||||
# sub-grid
|
||||
if get(l.attr, :width, :auto) != :auto
|
||||
@@ -530,11 +538,11 @@ function build_layout(layout::GridLayout, n::Integer)
|
||||
if get(l.attr, :height, :auto) != :auto
|
||||
layout.heights[r] = attr(l,:height)
|
||||
end
|
||||
l, sps, m = build_layout(l, n-i)
|
||||
l, sps, m = build_layout(l, n - i, plts)
|
||||
append!(subplots, sps)
|
||||
merge!(spmap, m)
|
||||
i += length(sps)
|
||||
elseif isa(l, Subplot)
|
||||
elseif isa(l, Subplot) && empty
|
||||
error("Subplot exists. Cannot re-use existing layout. Please make a new one.")
|
||||
end
|
||||
i >= n && break # only add n subplots
|
||||
@@ -543,45 +551,6 @@ function build_layout(layout::GridLayout, n::Integer)
|
||||
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
|
||||
@@ -775,9 +744,17 @@ end
|
||||
|
||||
"Adds a new, empty subplot overlayed on top of `sp`, with a mirrored y-axis and linked x-axis."
|
||||
function twinx(sp::Subplot)
|
||||
sp[:right_margin] = max(sp[:right_margin], 30px)
|
||||
plot!(sp.plt, inset = (sp[:subplot_index], bbox(0,0,1,1)))
|
||||
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],
|
||||
)
|
||||
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])
|
||||
|
||||
+35
-3
@@ -141,7 +141,7 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::AKW)
|
||||
end
|
||||
|
||||
|
||||
RecipesPipeline.get_axis_limits(plt::Plot, letter) = axis_limits(plt[1], letter)
|
||||
RecipesPipeline.get_axis_limits(plt::Plot, letter) = axis_limits(plt[1], letter, false)
|
||||
|
||||
|
||||
## Plot recipes
|
||||
@@ -262,6 +262,7 @@ function _subplot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
|
||||
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
|
||||
@@ -274,12 +275,35 @@ 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]
|
||||
if plot_title != ""
|
||||
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
|
||||
# propagate arguments plt[:plot_titleXXX] --> subplot[:titleXXX]
|
||||
for sym ∈ filter(x -> startswith(string(x), "plot_title"), keys(_plot_defaults))
|
||||
subplot[Symbol(string(sym)[length("plot_") + 1:end])] = plt[sym]
|
||||
end
|
||||
plt[:force_minpad] = nothing, 0px, nothing, 0px
|
||||
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
|
||||
return nothing
|
||||
end
|
||||
|
||||
## Series recipes
|
||||
|
||||
@@ -313,7 +337,7 @@ function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where {T}
|
||||
st = _override_seriestype_check(plotattributes, st)
|
||||
|
||||
# change to a 3d projection for this subplot?
|
||||
if RecipesPipeline.needs_3d_axes(st)
|
||||
if RecipesPipeline.needs_3d_axes(st) || (st == :quiver && plotattributes[:z] !== nothing)
|
||||
sp.attr[:projection] = "3d"
|
||||
end
|
||||
|
||||
@@ -329,7 +353,7 @@ 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 !isa(z, Nothing) &&
|
||||
if z !== nothing &&
|
||||
(size(plotattributes[:x]) == size(plotattributes[:y]) == size(z))
|
||||
st = (st == :scatter ? :scatter3d : :path3d)
|
||||
plotattributes[:seriestype] = st
|
||||
@@ -338,6 +362,14 @@ 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
|
||||
|
||||
+50
-5
@@ -23,7 +23,38 @@ 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))
|
||||
Base.show(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
|
||||
|
||||
getplot(plt::Plot) = plt
|
||||
getattr(plt::Plot, idx::Int = 1) = plt.attr
|
||||
@@ -59,18 +90,20 @@ function plot(args...; kw...)
|
||||
end
|
||||
|
||||
# build a new plot from existing plots
|
||||
# note: we split into plt1 and plts_tail so we can dispatch correctly
|
||||
function plot(plt1::Plot, plts_tail::Plot...; kw...)
|
||||
# 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...)
|
||||
@nospecialize
|
||||
plotattributes = KW(kw)
|
||||
RecipesPipeline.preprocess_attributes!(plotattributes)
|
||||
|
||||
# build our plot vector from the args
|
||||
n = length(plts_tail) + 1
|
||||
n = length(plts_tail) + 2
|
||||
plts = Array{Plot}(undef, n)
|
||||
plts[1] = plt1
|
||||
plts[2] = plt2
|
||||
for (i,plt) in enumerate(plts_tail)
|
||||
plts[i+1] = plt
|
||||
plts[i+2] = plt
|
||||
end
|
||||
|
||||
# compute the layout
|
||||
@@ -127,6 +160,7 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...)
|
||||
cmdidx += 1
|
||||
end
|
||||
end
|
||||
_add_plot_title!(plt)
|
||||
|
||||
# first apply any args for the subplots
|
||||
for (idx,sp) in enumerate(plt.subplots)
|
||||
@@ -154,6 +188,7 @@ 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)
|
||||
@@ -191,6 +226,16 @@ 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 ∈ eachindex(plt.layout.grid)
|
||||
plt.layout.grid[i].minpad = Tuple(
|
||||
i === nothing ? j : i for (i, j) ∈ zip(force_minpad, plt.layout.grid[i].minpad)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# now another pass down, to update the bounding boxes
|
||||
update_child_bboxes!(plt.layout)
|
||||
|
||||
|
||||
+31
-3
@@ -165,16 +165,44 @@ 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
|
||||
|
||||
|
||||
@@ -1400,9 +1428,9 @@ 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
|
||||
# For backwards compatibility, column vectors of segmenting attributes are
|
||||
# interpreted as having one element per shape
|
||||
for attr in union(_segmenting_array_attributes, _segmenting_vector_attributes)
|
||||
v = get(plotattributes, attr, nothing)
|
||||
@@ -1415,7 +1443,7 @@ 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]))
|
||||
|
||||
+3
-1
@@ -453,12 +453,14 @@ Add annotations to an existing plot.
|
||||
# Arguments
|
||||
|
||||
- `anns`: An `AbstractVector` of tuples of the form `(x,y,text)`. The `text` object
|
||||
can be a `String` or `PlotText`.
|
||||
can be a `String`, `PlotText` PlotText (created with `text(args...)`),
|
||||
or a tuple of arguments to `text` (e.g., `("Label", 8, :red, :top)`).
|
||||
|
||||
# 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...)
|
||||
|
||||
+80
-60
@@ -57,7 +57,7 @@ struct SeriesSegment
|
||||
# indexes of this segement in series data vectors
|
||||
range::UnitRange
|
||||
# index into vector-valued attributes corresponding to this segment
|
||||
attr_index::Int
|
||||
attr_index::Int
|
||||
end
|
||||
|
||||
# -----------------------------------------------------
|
||||
@@ -75,27 +75,49 @@ function iter_segments(args...)
|
||||
NaNSegmentsIterator(tup, n1, n2)
|
||||
end
|
||||
|
||||
function series_segments(series::Series, seriestype::Symbol = :path)
|
||||
function series_segments(series::Series, seriestype::Symbol=:path; check=false)
|
||||
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...))
|
||||
|
||||
result = if has_attribute_segments(series)
|
||||
if check
|
||||
scales = :xscale, :yscale, :zscale
|
||||
for (n, s) ∈ enumerate(args)
|
||||
scale = get(series, scales[n], :identity)
|
||||
if scale ∈ _logScales
|
||||
for (i, v) ∈ 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)
|
||||
Iterators.flatten(map(nan_segments) do r
|
||||
if seriestype in (:scatter, :scatter3d)
|
||||
(SeriesSegment(i:i, i) for i in r)
|
||||
else
|
||||
(SeriesSegment(i:i+1, i) for i in first(r):last(r)-1)
|
||||
end
|
||||
end
|
||||
end)
|
||||
else
|
||||
(SeriesSegment(r, 1) for r in nan_segments)
|
||||
end
|
||||
end
|
||||
|
||||
seg_range = UnitRange(minimum(first(seg.range) for seg in result),
|
||||
maximum(last(seg.range) for seg in result))
|
||||
warn_on_attr_dim_mismatch(series, x, y, z, segments)
|
||||
return segments
|
||||
end
|
||||
|
||||
function warn_on_attr_dim_mismatch(series, x, y, z, segments)
|
||||
isempty(segments) && return
|
||||
seg_range = UnitRange(minimum(first(seg.range) for seg in segments),
|
||||
maximum(last(seg.range) for seg in segments))
|
||||
for attr in _segmenting_vector_attributes
|
||||
v = get(series, attr, nothing)
|
||||
if v isa AVec && eachindex(v) != seg_range
|
||||
@@ -103,7 +125,7 @@ function series_segments(series::Series, seriestype::Symbol = :path)
|
||||
if any(v -> !isnothing(v) && any(isnan, v), (x,y,z))
|
||||
@info """Data contains NaNs or missing values, and indices of `$attr` vector do not match data indices.
|
||||
If you intend elements of `$attr` to apply to individual NaN-separated segements in the data,
|
||||
pass each segment in a separate vector instead, and use a row vector for `$attr`. Legend entries
|
||||
pass each segment in a separate vector instead, and use a row vector for `$attr`. Legend entries
|
||||
may be suppressed by passing an empty label.
|
||||
For example,
|
||||
plot([1:2,1:3], [[4,5],[3,4,5]], label=["y" ""], $attr=[1 2])
|
||||
@@ -111,8 +133,6 @@ function series_segments(series::Series, seriestype::Symbol = :path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
# helpers to figure out if there are NaN values in a list of array types
|
||||
@@ -266,7 +286,7 @@ function heatmap_edges(x::AVec, xscale::Symbol, y::AVec, yscale::Symbol, z_size:
|
||||
or `size(z) == (length(y)+1, length(x)+1))` (x & y define edges).""")
|
||||
end
|
||||
x, y = heatmap_edges(x, xscale, isedges),
|
||||
heatmap_edges(y, yscale, isedges, ispolar) # special handle for `r` in polar plots
|
||||
heatmap_edges(y, yscale, isedges, ispolar) # special handle for `r` in polar plots
|
||||
return x, y
|
||||
end
|
||||
|
||||
@@ -935,67 +955,67 @@ ignorenan_extrema(plt::Plot) = (xmin(plt), xmax(plt))
|
||||
# ---------------------------------------------------------------
|
||||
# get fonts from objects:
|
||||
|
||||
plottitlefont(p::Plot) = font(
|
||||
p[:plot_titlefontfamily],
|
||||
p[:plot_titlefontsize],
|
||||
p[:plot_titlefontvalign],
|
||||
p[:plot_titlefonthalign],
|
||||
p[:plot_titlefontrotation],
|
||||
p[:plot_titlefontcolor],
|
||||
plottitlefont(p::Plot) = font(;
|
||||
family = p[:plot_titlefontfamily],
|
||||
pointsize = p[:plot_titlefontsize],
|
||||
valign = p[:plot_titlefontvalign],
|
||||
halign = p[:plot_titlefonthalign],
|
||||
rotation = p[:plot_titlefontrotation],
|
||||
color = p[:plot_titlefontcolor],
|
||||
)
|
||||
|
||||
colorbartitlefont(sp::Subplot) = font(
|
||||
sp[:colorbar_titlefontfamily],
|
||||
sp[:colorbar_titlefontsize],
|
||||
sp[:colorbar_titlefontvalign],
|
||||
sp[:colorbar_titlefonthalign],
|
||||
sp[:colorbar_titlefontrotation],
|
||||
sp[:colorbar_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],
|
||||
)
|
||||
|
||||
titlefont(sp::Subplot) = font(
|
||||
sp[:titlefontfamily],
|
||||
sp[:titlefontsize],
|
||||
sp[:titlefontvalign],
|
||||
sp[:titlefonthalign],
|
||||
sp[:titlefontrotation],
|
||||
sp[:titlefontcolor],
|
||||
titlefont(sp::Subplot) = font(;
|
||||
family = sp[:titlefontfamily],
|
||||
pointsize = sp[:titlefontsize],
|
||||
valign = sp[:titlefontvalign],
|
||||
halign = sp[:titlefonthalign],
|
||||
rotation = sp[:titlefontrotation],
|
||||
color = sp[:titlefontcolor],
|
||||
)
|
||||
|
||||
legendfont(sp::Subplot) = font(
|
||||
sp[:legendfontfamily],
|
||||
sp[:legendfontsize],
|
||||
sp[:legendfontvalign],
|
||||
sp[:legendfonthalign],
|
||||
sp[:legendfontrotation],
|
||||
sp[:legendfontcolor],
|
||||
legendfont(sp::Subplot) = font(;
|
||||
family = sp[:legendfontfamily],
|
||||
pointsize = sp[:legendfontsize],
|
||||
valign = sp[:legendfontvalign],
|
||||
halign = sp[:legendfonthalign],
|
||||
rotation = sp[:legendfontrotation],
|
||||
color = sp[:legendfontcolor],
|
||||
)
|
||||
|
||||
legendtitlefont(sp::Subplot) = font(
|
||||
sp[:legendtitlefontfamily],
|
||||
sp[:legendtitlefontsize],
|
||||
sp[:legendtitlefontvalign],
|
||||
sp[:legendtitlefonthalign],
|
||||
sp[:legendtitlefontrotation],
|
||||
sp[:legendtitlefontcolor],
|
||||
legendtitlefont(sp::Subplot) = font(;
|
||||
family = sp[:legendtitlefontfamily],
|
||||
pointsize = sp[:legendtitlefontsize],
|
||||
valign = sp[:legendtitlefontvalign],
|
||||
halign = sp[:legendtitlefonthalign],
|
||||
rotation = sp[:legendtitlefontrotation],
|
||||
color = sp[:legendtitlefontcolor],
|
||||
)
|
||||
|
||||
tickfont(ax::Axis) = font(
|
||||
ax[:tickfontfamily],
|
||||
ax[:tickfontsize],
|
||||
ax[:tickfontvalign],
|
||||
ax[:tickfonthalign],
|
||||
ax[:tickfontrotation],
|
||||
ax[:tickfontcolor],
|
||||
tickfont(ax::Axis) = font(;
|
||||
family = ax[:tickfontfamily],
|
||||
pointsize = ax[:tickfontsize],
|
||||
valign = ax[:tickfontvalign],
|
||||
halign = ax[:tickfonthalign],
|
||||
rotation = ax[:tickfontrotation],
|
||||
color = ax[:tickfontcolor],
|
||||
)
|
||||
|
||||
guidefont(ax::Axis) = font(
|
||||
ax[:guidefontfamily],
|
||||
ax[:guidefontsize],
|
||||
ax[:guidefontvalign],
|
||||
ax[:guidefonthalign],
|
||||
ax[:guidefontrotation],
|
||||
ax[:guidefontcolor],
|
||||
guidefont(ax::Axis) = font(;
|
||||
family = ax[:guidefontfamily],
|
||||
pointsize = ax[:guidefontsize],
|
||||
valign = ax[:guidefontvalign],
|
||||
halign = ax[:guidefonthalign],
|
||||
rotation = ax[:guidefontrotation],
|
||||
color = ax[:guidefontcolor],
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Plots: guidefont, series_annotations
|
||||
import ImageMagick
|
||||
using VisualRegressionTests
|
||||
using Plots
|
||||
@@ -29,6 +30,7 @@ end
|
||||
end # testset
|
||||
|
||||
include("test_defaults.jl")
|
||||
include("test_pipeline.jl")
|
||||
include("test_axes.jl")
|
||||
include("test_axis_letter.jl")
|
||||
include("test_components.jl")
|
||||
@@ -172,6 +174,8 @@ end
|
||||
@testset "Plot" begin
|
||||
plots = [histogram([1, 0, 0, 0, 0, 0]),
|
||||
plot([missing]),
|
||||
plot([missing, missing]),
|
||||
plot(fill(missing, 10)),
|
||||
plot([missing; 1:4]),
|
||||
plot([fill(missing, 10); 1:4]),
|
||||
plot([1 1; 1 missing]),
|
||||
|
||||
@@ -21,3 +21,45 @@ 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
|
||||
|
||||
+75
-35
@@ -1,52 +1,68 @@
|
||||
using Plots, Test
|
||||
|
||||
@testset "Shapes" begin
|
||||
@testset "Type" begin
|
||||
square = Shape([(0, 0.0), (1, 0.0), (1, 1.0), (0, 1.0)])
|
||||
@test isa(square, Shape{Int64,Float64})
|
||||
@test coords(square) isa Tuple{Vector{S},Vector{T}} where {T,S}
|
||||
end
|
||||
|
||||
@testset "Copy" begin
|
||||
square = Shape([(0,0),(1,0),(1,1),(0,1)])
|
||||
square = Shape([(0, 0), (1, 0), (1, 1), (0, 1)])
|
||||
square2 = Shape(square)
|
||||
@test square2.x == square.x
|
||||
@test square2.y == square.y
|
||||
end
|
||||
|
||||
@testset "Center" begin
|
||||
square = Shape([(0,0),(1,0),(1,1),(0,1)])
|
||||
@test Plots.center(square) == (0.5,0.5)
|
||||
square = Shape([(0, 0), (1, 0), (1, 1), (0, 1)])
|
||||
@test Plots.center(square) == (0.5, 0.5)
|
||||
end
|
||||
|
||||
@testset "Translate" begin
|
||||
square = Shape([(0,0),(1,0),(1,1),(0,1)])
|
||||
squareUp = Shape([(0,1),(1,1),(1,2),(0,2)])
|
||||
squareUpRight = Shape([(1,1),(2,1),(2,2),(1,2)])
|
||||
square = Shape([(0, 0), (1, 0), (1, 1), (0, 1)])
|
||||
squareUp = Shape([(0, 1), (1, 1), (1, 2), (0, 2)])
|
||||
squareUpRight = Shape([(1, 1), (2, 1), (2, 2), (1, 2)])
|
||||
|
||||
@test Plots.translate(square,0,1).x == squareUp.x
|
||||
@test Plots.translate(square,0,1).y == squareUp.y
|
||||
@test Plots.translate(square, 0, 1).x == squareUp.x
|
||||
@test Plots.translate(square, 0, 1).y == squareUp.y
|
||||
|
||||
@test Plots.center(translate!(square,1)) == (1.5,1.5)
|
||||
@test Plots.center(translate!(square, 1)) == (1.5, 1.5)
|
||||
end
|
||||
|
||||
@testset "Rotate" begin
|
||||
# 2 radians rotation matrix
|
||||
R2 = [cos(2) sin(2); -sin(2) cos(2)]
|
||||
coords = [0 0; 1 0; 1 1; 0 1]'
|
||||
coordsRotated2 = R2*(coords.-0.5).+0.5
|
||||
coordsRotated2 = R2 * (coords .- 0.5) .+ 0.5
|
||||
|
||||
square = Shape([(0,0),(1,0),(1,1),(0,1)])
|
||||
square = Shape([(0, 0), (1, 0), (1, 1), (0, 1)])
|
||||
|
||||
# make a new, rotated square
|
||||
square2 = Plots.rotate(square, -2)
|
||||
@test square2.x ≈ coordsRotated2[1,:]
|
||||
@test square2.y ≈ coordsRotated2[2,:]
|
||||
@test square2.x ≈ coordsRotated2[1, :]
|
||||
@test square2.y ≈ coordsRotated2[2, :]
|
||||
|
||||
# unrotate the new square in place
|
||||
rotate!(square2, 2)
|
||||
@test square2.x ≈ coords[1,:]
|
||||
@test square2.y ≈ coords[2,:]
|
||||
@test square2.x ≈ coords[1, :]
|
||||
@test square2.y ≈ coords[2, :]
|
||||
end
|
||||
|
||||
@testset "Plot" begin
|
||||
ang = range(0, 2π, length = 60)
|
||||
ellipse(x, y, w, h) = Shape(w * sin.(ang) .+ x, h * cos.(ang) .+ y)
|
||||
myshapes = [ellipse(x, rand(), rand(), rand()) for x = 1:4]
|
||||
@test coords(myshapes) isa Tuple{Vector{Vector{S}},Vector{Vector{T}}} where {T,S}
|
||||
local p
|
||||
@test_nowarn p = plot(myshapes)
|
||||
@test p[1][1][:seriestype] == :shape
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Brush" begin
|
||||
@testset "Colors" begin
|
||||
baseline = brush(1, RGB(0,0,0))
|
||||
baseline = brush(1, RGB(0, 0, 0))
|
||||
@test brush(:black) == baseline
|
||||
@test brush("black") == baseline
|
||||
end
|
||||
@@ -60,7 +76,7 @@ end
|
||||
end
|
||||
@testset "Bad Argument" begin
|
||||
# using test_logs because test_warn seems to not work anymore
|
||||
@test_logs (:warn,"Unused brush arg: nothing (Nothing)") begin
|
||||
@test_logs (:warn, "Unused brush arg: nothing (Nothing)") begin
|
||||
brush(nothing)
|
||||
end
|
||||
end
|
||||
@@ -68,44 +84,68 @@ 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 ]
|
||||
initialSizes = [Plots.default(s) for s in sizesToCheck]
|
||||
|
||||
#scale up font sizes
|
||||
scalefontsizes(2)
|
||||
|
||||
# get inital font sizes
|
||||
doubledSizes = [Plots.default(s) for s in sizesToCheck ]
|
||||
doubledSizes = [Plots.default(s) for s in sizesToCheck]
|
||||
|
||||
@test doubledSizes == initialSizes*2
|
||||
@test doubledSizes == initialSizes * 2
|
||||
|
||||
# reset font sizes
|
||||
resetfontsizes()
|
||||
|
||||
finalSizes = [Plots.default(s) for s in sizesToCheck ]
|
||||
finalSizes = [Plots.default(s) for s in sizesToCheck]
|
||||
|
||||
@test finalSizes == initialSizes
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Series Annotations" begin
|
||||
square = Shape([(0,0),(1,0),(1,1),(0,1)])
|
||||
@test_logs (:warn,"Unused SeriesAnnotations arg: triangle (Symbol)") begin
|
||||
p = plot([1,2,3],
|
||||
series_annotations=(["a"],
|
||||
2, # pass a scale factor
|
||||
(1,4), # pass two scale factors (overwrites first one)
|
||||
square, # pass a shape
|
||||
font(:courier), # pass an annotation font
|
||||
:triangle # pass an incorrect argument
|
||||
))
|
||||
square = Shape([(0, 0), (1, 0), (1, 1), (0, 1)])
|
||||
@test_logs (:warn, "Unused SeriesAnnotations arg: triangle (Symbol)") begin
|
||||
p = plot(
|
||||
[1, 2, 3],
|
||||
series_annotations = (
|
||||
["a"],
|
||||
2, # pass a scale factor
|
||||
(1, 4), # pass two scale factors (overwrites first one)
|
||||
square, # pass a shape
|
||||
font(:courier), # pass an annotation font
|
||||
:triangle, # pass an incorrect argument
|
||||
),
|
||||
)
|
||||
sa = p.series_list[1].plotattributes[:series_annotations]
|
||||
@test sa.strs == ["a"]
|
||||
@test sa.font.family == "courier"
|
||||
@test sa.baseshape == square
|
||||
@test sa.scalefactor == (1,4)
|
||||
@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"]]),
|
||||
)
|
||||
@test spl.series_list[1].plotattributes[:series_annotations].strs == ["1/1"]
|
||||
@test spl.series_list[2].plotattributes[:series_annotations].strs == ["1/2"]
|
||||
@test spl.series_list[3].plotattributes[:series_annotations].strs == ["1/3"]
|
||||
@test spl.series_list[4].plotattributes[:series_annotations].strs == ["1/4"]
|
||||
@test spl.series_list[5].plotattributes[:series_annotations].strs == ["1/5"]
|
||||
end
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using Plots, Test
|
||||
|
||||
const PLOTS_DEFAULTS = Dict(:theme => :wong2)
|
||||
const PLOTS_DEFAULTS = Dict(:theme => :wong2, :fontfamily => :palantino)
|
||||
Plots.__init__()
|
||||
|
||||
@testset "Loading theme" begin
|
||||
@test plot(1:5)[1][1][:seriescolor] == RGBA(colorant"black")
|
||||
pl = plot(1:5)
|
||||
@test pl[1][1][:seriescolor] == RGBA(colorant"black")
|
||||
@test guidefont(pl[1][:xaxis]).family == "palantino"
|
||||
end
|
||||
|
||||
empty!(PLOTS_DEFAULTS)
|
||||
|
||||
@@ -338,6 +338,16 @@ 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
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
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 = [.1, 5]
|
||||
p1 = plot(x, [5, .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
|
||||
Reference in New Issue
Block a user