Compare commits

..

4 Commits

Author SHA1 Message Date
Daniel Schwabeneder 9df1ef0d4d update and enable precompiles 2020-04-04 17:38:38 +02:00
Daniel Schwabeneder e851dcded2 move remaining user recipes in series.jl to recipes.jl 2020-04-04 17:32:45 +02:00
Daniel Schwabeneder 79f8402483 extract the recipe pipeline into separate submodule 2020-04-04 17:30:04 +02:00
Daniel Schwabeneder f86b324200 rename some functions 2020-04-02 20:12:03 +02:00
50 changed files with 3350 additions and 2122 deletions
-32
View File
@@ -1,32 +0,0 @@
---
name: Bug report
about: Create a bug report
title: "[BUG]"
labels: bug
assignees: ''
---
<!-- Please search existing issues to avoid duplicates. -->
## Details
### Backends
This bug occurs on ( insert `x` below )
Backend | yes | no | untested
-------------|-----|-----|---------
gr (default) | | |
pyplot | | |
plotly | | |
plotlyjs | | |
pgfplotsx | | |
inspectdr | | |
### Versions
Plots.jl version:
Backend version (`]st -m`):
Output of `versioninfo()`:
-10
View File
@@ -1,10 +0,0 @@
---
name: Feature request
about: Suggest a feature or enhancement
title: "[FR]"
labels: feature request
assignees: ''
---
Please search existing issues to avoid duplicates.
-86
View File
@@ -1,86 +0,0 @@
name: ci
on:
push:
pull_request:
defaults:
run:
shell: bash
jobs:
CI:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
env:
GKS_ENCODING: "utf8"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
julia_version:
- 'nightly'
- '1'
- '1.0'
os:
- ubuntu-latest
- windows-latest
- macos-latest
arch:
- x64
# - x32
steps:
# Setup environment
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.julia_version }}
- name: Cache artifacts
uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
# OS Dependencies
# - name: Ubuntu OS dependencies
# if: startsWith(matrix.os,'ubuntu')
# run: |
# ./test/install_wkhtmltoimage.sh
# at-spi2-core, libgtk-3-dev, libgtk-3-0, and xvfb are already installed: https://github.com/actions/virtual-environments/blob/master/images/linux/scripts/installers/basic.sh
# TESTCMD
- name: Default TESTCMD
run: echo ::set-env name=TESTCMD::"julia"
- name: Ubuntu TESTCMD
if: startsWith(matrix.os,'ubuntu')
run: echo ::set-env name=TESTCMD::"xvfb-run julia"
# Julia Deoendencies
- name: Install Julia dependencies
uses: julia-actions/julia-buildpkg@latest
# Run tests
- name: Run Graphical test
run: $TESTCMD --project -e 'using Pkg; Pkg.test(coverage=true);'
- name: Codecov
uses: julia-actions/julia-uploadcodecov@latest
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Skip:
if: "contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- name: Skip CI 🚫
run: echo skip ci
+1 -1
View File
@@ -4,7 +4,7 @@
.DS_Store
examples/.ipynb_checkpoints/*
examples/meetup/.ipynb_checkpoints/*
deps/plotly-*
deps/plotly-latest.min.js
deps/build.log
deps/deps.jl
Manifest.toml
+44
View File
@@ -0,0 +1,44 @@
# Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
os:
- linux
# - osx
julia:
- 1.0
- 1
- nightly
matrix:
allow_failures:
- julia: nightly
addons:
apt:
packages:
- at-spi2-core
- libgtk-3-dev
- xauth
- xvfb
env:
- GKS_ENCODING="utf8"
cache:
directories:
- $HOME/.julia/artifacts
sudo: required
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then pwd ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./test/install_wkhtmltoimage.sh ; fi
notifications:
email: true
after_success:
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())'
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- if [[ `uname` = "Linux" ]]; then TESTCMD="xvfb-run julia"; else TESTCMD="julia"; fi
- $TESTCMD -e 'using Pkg; Pkg.build(); Pkg.test(coverage=true)'
+13 -12
View File
@@ -1,7 +1,7 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "1.4.2"
version = "0.29.9"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
@@ -15,13 +15,13 @@ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Measures = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
RecipesPipeline = "01d81517-befc-4cb6-b9ec-a95719d0359c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
@@ -34,24 +34,24 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
Contour = "0.5"
FFMPEG = "0.2, 0.3"
FixedPointNumbers = "0.6, 0.7, 0.8"
GR = "0.46, 0.47, 0.48, 0.49, 0.50"
GR = "0.46, 0.47, 0.48"
GeometryTypes = "0.7, 0.8"
JSON = "0.21"
Measures = "0.3"
NaNMath = "0.3"
PGFPlotsX = "1.2.0 - 1.2.6"
PlotThemes = "2"
PlotUtils = "1"
RecipesBase = "1"
RecipesPipeline = "0.1.7"
PGFPlotsX = "1.2.0"
PlotThemes = "1"
PlotUtils = "0.6.5"
RecipesBase = "0.8"
Reexport = "0.2"
Requires = "1"
Requires = "0.5, 1"
Showoff = "0.3.1"
StatsBase = "0.32, 0.33"
julia = "1.4"
StatsBase = "0.32"
julia = "1"
[extras]
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44"
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
@@ -60,6 +60,7 @@ LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
@@ -67,4 +68,4 @@ UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"
[targets]
test = ["FileIO", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "HDF5", "RDatasets", "StaticArrays", "StatsPlots", "Test", "UnicodePlots", "VisualRegressionTests"]
test = ["FileIO", "GeometryTypes", "Gtk", "ImageMagick", "Images", "LibGit2", "OffsetArrays", "PGFPlotsX", "HDF5", "Random", "RDatasets", "StaticArrays", "StatsPlots", "Test", "UnicodePlots", "VisualRegressionTests"]
+8 -4
View File
@@ -1,7 +1,10 @@
# Plots
[gh-ci-img]: https://github.com/JuliaPlots/Plots.jl/workflows/ci/badge.svg?branch=master
[gh-ci-url]: https://github.com/JuliaPlots/Plots.jl/actions?query=workflow%3Aci
[travis-img]: https://img.shields.io/travis/JuliaPlots/Plots.jl?logo=travis
[travis-url]: https://travis-ci.org/JuliaPlots/Plots.jl
[appveyor-img]: https://ci.appveyor.com/api/projects/status/github/juliaplots/plots.jl?branch=master&svg=true
[appveyor-url]: https://ci.appveyor.com/project/mkborregaard/plots-jl
[pkgeval-img]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/P/Plots.svg
[pkgeval-url]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/report.html
@@ -12,9 +15,10 @@
[docs-img]: https://img.shields.io/badge/docs-stable-blue.svg
[docs-url]: http://docs.juliaplots.org/latest/
[![][gh-ci-img]][gh-ci-url]
[![][travis-img]][travis-url]
[![][appveyor-img]][appveyor-url]
[![][pkgeval-img]][pkgeval-url]
[![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://julialang.zulipchat.com/#narrow/stream/236493-plots)
[![][gitter-img]][gitter-url]
[![][docs-img]][docs-url]
[![Codecov](https://codecov.io/gh/JuliaPlots/Plots.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaPlots/Plots.jl)
+46
View File
@@ -0,0 +1,46 @@
environment:
matrix:
- julia_version: 1.0
- julia_version: 1
- julia_version: nightly
platform:
- x86 # 32-bit
- x64 # 64-bit
# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
matrix:
allow_failures:
- julia_version: nightly
branches:
only:
- master
- /release-.*/
cache:
- '%USERPROFILE%\.julia\artifacts'
notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false
install:
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
build_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
test_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
+4 -4
View File
@@ -1,12 +1,12 @@
#TODO: download https://cdn.plot.ly/plotly-1.54.2.min.js to deps/ if it doesn't exist
#TODO: download https://cdn.plot.ly/plotly-latest.min.js to deps/ if it doesn't exist
file_path = ""
if get(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL", "false") == "true"
global file_path
local_fn = joinpath(dirname(@__FILE__), "plotly-1.54.2.min.js")
local_fn = joinpath(dirname(@__FILE__), "plotly-latest.min.js")
if !isfile(local_fn)
@info("Cannot find deps/plotly-1.54.2.min.js... downloading latest version.")
download("https://cdn.plot.ly/plotly-1.54.2.min.js", local_fn)
@info("Cannot find deps/plotly-latest.min.js... downloading latest version.")
download("https://cdn.plot.ly/plotly-latest.min.js", local_fn)
isfile(local_fn) && (file_path = local_fn)
else
file_path = local_fn
-2
View File
@@ -44,9 +44,7 @@ blacklist = [
# the following are not visible to Plots, only its dependencies
"CategoricalArrays",
"FixedPointNumbers",
"OffsetArrays",
"SparseArrays",
"StaticArrays",
r"#{1,2}[^\"#]+#{1,2}\d+",
]
+7 -18
View File
@@ -1,16 +1,12 @@
module Plots
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optlevel"))
@eval Base.Experimental.@optlevel 1
end
const _current_plots_version = VersionNumber(split(first(filter(line -> occursin("version", line), readlines(normpath(@__DIR__, "..", "Project.toml")))), "\"")[2])
using Reexport
import GeometryTypes
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random
import SparseArrays: AbstractSparseMatrix, findnz
import SparseArrays: findnz
using FFMPEG
@@ -108,7 +104,6 @@ export
gif,
mov,
mp4,
webm,
animate,
@animate,
@gif,
@@ -124,11 +119,7 @@ export
center,
BezierCurve,
plotattr,
scalefontsize,
scalefontsizes,
resetfontsizes
plotattr
# ---------------------------------------------------------
@@ -172,8 +163,9 @@ using .PlotMeasures
import .PlotMeasures: Length, AbsoluteLength, Measure, width, height
# ---------------------------------------------------------
import RecipesPipeline
import RecipesPipeline: SliceIt,
include("RecipePipeline/RecipePipeline.jl")
import .RecipePipeline
import .RecipePipeline: SliceIt,
DefaultsDict,
Formatted,
AbstractSurface,
@@ -182,15 +174,12 @@ import RecipesPipeline: SliceIt,
is3d,
is_surface,
needs_3d_axes,
group_as_matrix, # for StatsPlots
group_as_matrix,
reset_kw!,
pop_kw!,
scale_func,
inverse_scale_func,
unzip,
dateformatter,
datetimeformatter,
timeformatter
unzip
include("types.jl")
include("utils.jl")
+97
View File
@@ -0,0 +1,97 @@
module RecipePipeline
import RecipesBase
import RecipesBase: @recipe, @series, RecipeData, is_explicit
import PlotUtils # tryrange and adapted_grid
export recipe_pipeline!
# Plots relies on these:
export SliceIt,
DefaultsDict,
Formatted,
AbstractSurface,
Surface,
Volume,
is3d,
is_surface,
needs_3d_axes,
group_as_matrix,
reset_kw!,
pop_kw!,
scale_func,
inverse_scale_func,
unzip
# API
export warn_on_recipe_aliases,
splittable_attribute,
split_attribute,
process_userrecipe!,
get_axis_limits,
is_axis_attribute,
type_alias,
plot_setup!,
slice_series_attributes!
include("api.jl")
include("utils.jl")
include("series.jl")
include("group.jl")
include("user_recipe.jl")
include("type_recipe.jl")
include("plot_recipe.jl")
include("series_recipe.jl")
"""
recipe_pipeline!(plt, plotattributes, args)
Recursively apply user recipes, type recipes, plot recipes and series recipes to build a
list of `Dict`s, each corresponding to a series. At the beginning `plotattributes`
contains only the keyword arguments passed in by the user. Add all series to the plot
bject `plt` and return it.
"""
function recipe_pipeline!(plt, plotattributes, args)
plotattributes[:plot_object] = plt
# --------------------------------
# "USER RECIPES"
# --------------------------------
# process user and type recipes
kw_list = _process_userrecipes!(plt, plotattributes, args)
# --------------------------------
# "PLOT RECIPES"
# --------------------------------
# The "Plot recipe" acts like a series type, and is processed before the plot layout
# is created, which allows for setting layouts and other plot-wide attributes.
# We get inputs which have been fully processed by "user recipes" and "type recipes",
# so we can expect standard vectors, surfaces, etc. No defaults have been set yet.
kw_list = _process_plotrecipes!(plt, kw_list)
# --------------------------------
# Plot/Subplot/Layout setup
# --------------------------------
plot_setup!(plt, plotattributes, kw_list)
# At this point, `kw_list` is fully decomposed into individual series... one KW per
# series. The next step is to recursively apply series recipes until the backend
# supports that series type.
# --------------------------------
# "SERIES RECIPES"
# --------------------------------
_process_seriesrecipes!(plt, kw_list)
# --------------------------------
# Return processed plot object
# --------------------------------
return plt
end
end
+142
View File
@@ -0,0 +1,142 @@
## Warnings
"""
warn_on_recipe_aliases!(plt, plotattributes, recipe_type, args...)
Warn if an alias is dedected in `plotattributes` after a recipe of type `recipe_type` is
applied to 'args'. `recipe_type` is either `:user`, `:type`, `:plot` or `:series`.
"""
function warn_on_recipe_aliases!(plt, plotattributes, recipe_type, args...) end
## Grouping
"""
splittable_attribute(plt, key, val, len)
Returns `true` if the attribute `key` with the value `val` can be split into groups with
group provided as a vector of length `len`, `false` otherwise.
"""
splittable_attribute(plt, key, val, len) = false
splittable_attribute(plt, key, val::AbstractArray, len) =
!(key in (:group, :color_palette)) && length(axes(val, 1)) == len
splittable_attribute(plt, key, val::Tuple, n) = all(splittable_attribute.(key, val, len))
"""
split_attribute(plt, key, val, indices)
Select the proper indices from `val` for attribute `key`.
"""
split_attribute(plt, key, val::AbstractArray, indices) =
val[indices, fill(Colon(), ndims(val) - 1)...]
split_attribute(plt, key, val::Tuple, indices) =
Tuple(split_attribute(key, v, indices) for v in val)
## Preprocessing attributes
"""
preprocess_attributes!(plt, plotattributes)
Any plotting package specific preprocessing of user or recipe input happens here.
For example, Plots replaces aliases and expands magic arguments.
"""
function preprocess_attributes!(plt, plotattributes) end
# TODO: should the Plots version be defined as fallback in RecipePipeline?
"""
is_subplot_attribute(plt, attr)
Returns `true` if `attr` is a subplot attribute, otherwise `false`.
"""
is_subplot_attribute(plt, attr) = false
# TODO: should the Plots version be defined as fallback in RecipePipeline?
"""
is_axis_attribute(plt, attr)
Returns `true` if `attr` is an axis attribute, i.e. it applies to `xattr`, `yattr` and
`zattr`, otherwise `false`.
"""
is_axis_attribute(plt, attr) = false
## User recipes
"""
process_userrecipe!(plt, attributes_list, attributes)
Do plotting package specific post-processing and add series attributes to attributes_list.
For example, Plots increases the number of series in `plt`, sets `:series_plotindex` in
attributes and possible adds new series attributes for errorbars or smooth.
"""
function process_userrecipe!(plt, attributes_list, attributes)
push!(attributes_list, attributes)
end
"""
get_axis_limits(plt, letter)
Get the limits for the axis specified by `letter` (`:x`, `:y` or `:z`) in `plt`. If it
errors, `tryrange` from PlotUtils is used.
"""
get_axis_limits(plt, letter) = ErrorException("Axis limits not defined.")
## Plot recipes
"""
type_alias(plt, st)
Return the seriestype alias for `st`.
"""
type_alias(plt, st) = st
## Plot setup
"""
plot_setup!(plt, plotattributes, kw_list)
Setup plot, subplots and layouts.
For example, Plots creates the backend figure, initializes subplots, expands extrema and
links subplot axes.
"""
function plot_setup!(plt, plotattributes, kw_list) end
## Series recipes
"""
slice_series_attributes!(plt, kw_list, kw)
For attributes given as vector with one element per series, only select the value for
current series.
"""
function slice_series_attributes!(plt, kw_list, kw) end
"""
series_defaults(plt)
Returns a `Dict` storing the defaults for series attributes.
"""
series_defaults(plt) = Dict{Symbol, Any}()
# TODO: Add a more sensible fallback including e.g. path, scatter, ...
"""
is_seriestype_supported(plt, st)
Check if the plotting package natively supports the seriestype `st`.
"""
is_seriestype_supported(plt, st) = false
"""
add_series!(plt, kw)
Adds the series defined by `kw` to the plot object.
For example Plots updates the current subplot arguments, expands extrema and pushes the
the series to the series_list of `plt`.
"""
function add_series!(plt, kw) end
+122
View File
@@ -0,0 +1,122 @@
"A special type that will break up incoming data into groups, and allow for easier creation of grouped plots"
mutable struct GroupBy
group_labels::Vector # length == numGroups
group_indices::Vector{Vector{Int}} # list of indices for each group
end
# this is when given a vector-type of values to group by
function _extract_group_attributes(v::AVec, args...; legend_entry = string)
group_labels = sort(collect(unique(v)))
n = length(group_labels)
if n > 100
@warn("You created n=$n groups... Is that intended?")
end
group_indices = Vector{Int}[filter(i -> v[i] == glab, eachindex(v)) for glab in group_labels]
GroupBy(map(legend_entry, group_labels), group_indices)
end
legend_entry_from_tuple(ns::Tuple) = join(ns, ' ')
# this is when given a tuple of vectors of values to group by
function _extract_group_attributes(vs::Tuple, args...)
isempty(vs) && return GroupBy([""], [axes(args[1],1)])
v = map(tuple, vs...)
_extract_group_attributes(v, args...; legend_entry = legend_entry_from_tuple)
end
# allow passing NamedTuples for a named legend entry
legend_entry_from_tuple(ns::NamedTuple) =
join(["$k = $v" for (k, v) in pairs(ns)], ", ")
function _extract_group_attributes(vs::NamedTuple, args...)
isempty(vs) && return GroupBy([""], [axes(args[1],1)])
v = map(NamedTuple{keys(vs)}tuple, values(vs)...)
_extract_group_attributes(v, args...; legend_entry = legend_entry_from_tuple)
end
# expecting a mapping of "group label" to "group indices"
function _extract_group_attributes(idxmap::Dict{T,V}, args...) where {T, V<:AVec{Int}}
group_labels = sortedkeys(idxmap)
group_indices = Vector{Int}[collect(idxmap[k]) for k in group_labels]
GroupBy(group_labels, group_indices)
end
filter_data(v::AVec, idxfilter::AVec{Int}) = v[idxfilter]
filter_data(v, idxfilter) = v
function filter_data!(plotattributes::AKW, idxfilter)
for s in (:x, :y, :z)
plotattributes[s] = filter_data(get(plotattributes, s, nothing), idxfilter)
end
end
function _filter_input_data!(plotattributes::AKW)
idxfilter = pop!(plotattributes, :idxfilter, nothing)
if idxfilter !== nothing
filter_data!(plotattributes, idxfilter)
end
end
function groupedvec2mat(x_ind, x, y::AbstractArray, groupby, def_val = y[1])
y_mat = Array{promote_type(eltype(y), typeof(def_val))}(
undef,
length(keys(x_ind)),
length(groupby.group_labels),
)
fill!(y_mat, def_val)
for i in eachindex(groupby.group_labels)
xi = x[groupby.group_indices[i]]
yi = y[groupby.group_indices[i]]
y_mat[getindex.(Ref(x_ind), xi), i] = yi
end
return y_mat
end
groupedvec2mat(x_ind, x, y::Tuple, groupby) =
Tuple(groupedvec2mat(x_ind, x, v, groupby) for v in y)
group_as_matrix(t) = false
# split the group into 1 series per group, and set the label and idxfilter for each
@recipe function f(groupby::GroupBy, args...)
plt = plotattributes[:plot_object]
group_length = maximum(union(groupby.group_indices...))
if !(group_as_matrix(args[1]))
for (i, glab) in enumerate(groupby.group_labels)
@series begin
label --> string(glab)
idxfilter --> groupby.group_indices[i]
for (key, val) in plotattributes
if splittable_attribute(plt, key, val, group_length)
:($key) := split_attribute(plt, key, val, groupby.group_indices[i])
end
end
args
end
end
else
g = args[1]
if length(g.args) == 1
x = zeros(Int, group_length)
for indexes in groupby.group_indices
x[indexes] = eachindex(indexes)
end
last_args = g.args
else
x = g.args[1]
last_args = g.args[2:end]
end
x_u = unique(sort(x))
x_ind = Dict(zip(x_u, eachindex(x_u)))
for (key, val) in plotattributes
if splittable_kw(key, val, group_length)
:($key) := groupedvec2mat(x_ind, x, val, groupby)
end
end
label --> reshape(groupby.group_labels, 1, :)
typeof(g)((
x_u,
(groupedvec2mat(x_ind, x, arg, groupby, NaN) for arg in last_args)...,
))
end
end
+46
View File
@@ -0,0 +1,46 @@
"""
_process_plotrecipes!(plt, kw_list)
Grab the first in line to be processed and pass it through `apply_recipe` to generate a
list of `RecipeData` objects.
If we applied a "plot recipe" without error, then add the returned datalist's KWs,
otherwise we just add the original KW.
"""
function _process_plotrecipes!(plt, kw_list)
still_to_process = kw_list
kw_list = KW[]
while !isempty(still_to_process)
next_kw = popfirst!(still_to_process)
_process_plotrecipe(plt, next_kw, kw_list, still_to_process)
end
return kw_list
end
function _process_plotrecipe(plt, kw, kw_list, still_to_process)
if !isa(get(kw, :seriestype, nothing), Symbol)
# seriestype was never set, or it's not a Symbol, so it can't be a plot recipe
push!(kw_list, kw)
return
end
try
st = kw[:seriestype]
st = kw[:seriestype] = type_alias(plt, st)
datalist = RecipesBase.apply_recipe(kw, Val{st}, plt)
warn_on_recipe_aliases!(plt, datalist, :plot, st)
for data in datalist
preprocess_attributes!(plt, data.plotattributes)
if data.plotattributes[:seriestype] == st
error("Plot recipe $st returned the same seriestype: $(data.plotattributes)")
end
push!(still_to_process, data.plotattributes)
end
catch err
if isa(err, MethodError)
push!(kw_list, kw)
else
rethrow()
end
end
return
end
+170
View File
@@ -0,0 +1,170 @@
const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}}
const MaybeNumber = Union{Number, Missing}
const MaybeString = Union{AbstractString, Missing}
const DataPoint = Union{MaybeNumber, MaybeString}
_prepare_series_data(x) = error("Cannot convert $(typeof(x)) to series data for plotting")
_prepare_series_data(::Nothing) = nothing
_prepare_series_data(t::Tuple{T, T}) where {T <: Number} = t
_prepare_series_data(f::Function) = f
_prepare_series_data(ar::AbstractRange{<:Number}) = ar
function _prepare_series_data(a::AbstractArray{<:MaybeNumber})
f = isimmutable(a) ? replace : replace!
a = f(x -> ismissing(x) || isinf(x) ? NaN : x, map(float, a))
end
_prepare_series_data(a::AbstractArray{<:Missing}) = fill(NaN, axes(a))
_prepare_series_data(a::AbstractArray{<:MaybeString}) =
replace(x -> ismissing(x) ? "" : x, a)
_prepare_series_data(s::Surface{<:AMat{<:MaybeNumber}}) =
Surface(_prepare_series_data(s.surf))
_prepare_series_data(s::Surface) = s # non-numeric Surface, such as an image
_prepare_series_data(v::Volume) =
Volume(_prepare_series_data(v.v), v.x_extents, v.y_extents, v.z_extents)
# default: assume x represents a single series
_series_data_vector(x, plotattributes) = [_prepare_series_data(x)]
# fixed number of blank series
_series_data_vector(n::Integer, plotattributes) = [zeros(0) for i in 1:n]
# vector of data points is a single series
_series_data_vector(v::AVec{<:DataPoint}, plotattributes) = [_prepare_series_data(v)]
# list of things (maybe other vectors, functions, or something else)
function _series_data_vector(v::AVec, plotattributes)
if all(x -> x isa MaybeNumber, v)
_series_data_vector(Vector{MaybeNumber}(v), plotattributes)
elseif all(x -> x isa MaybeString, v)
_series_data_vector(Vector{MaybeString}(v), plotattributes)
else
vcat((_series_data_vector(vi, plotattributes) for vi in v)...)
end
end
# Matrix is split into columns
function _series_data_vector(v::AMat{<:DataPoint}, plotattributes)
if is3d(plotattributes)
[_prepare_series_data(Surface(v))]
else
[_prepare_series_data(v[:, i]) for i in axes(v, 2)]
end
end
# --------------------------------------------------------------------
# Fillranges & ribbons
_process_fillrange(range::Number, plotattributes) = [range]
_process_fillrange(range, plotattributes) = _series_data_vector(range, plotattributes)
_process_ribbon(ribbon::Number, plotattributes) = [ribbon]
_process_ribbon(ribbon, plotattributes) = _series_data_vector(ribbon, plotattributes)
# ribbon as a tuple: (lower_ribbons, upper_ribbons)
_process_ribbon(ribbon::Tuple{S, T}, plotattributes) where {S, T} = collect(zip(
_series_data_vector(ribbon[1], plotattributes),
_series_data_vector(ribbon[2], plotattributes),
))
# --------------------------------------------------------------------
_compute_x(x::Nothing, y::Nothing, z) = axes(z, 1)
_compute_x(x::Nothing, y, z) = axes(y, 1)
_compute_x(x::Function, y, z) = map(x, y)
_compute_x(x, y, z) = x
_compute_y(x::Nothing, y::Nothing, z) = axes(z, 2)
_compute_y(x, y::Function, z) = map(y, x)
_compute_y(x, y, z) = y
_compute_z(x, y, z::Function) = map(z, x, y)
_compute_z(x, y, z::AbstractMatrix) = Surface(z)
_compute_z(x, y, z::Nothing) = nothing
_compute_z(x, y, z) = z
_nobigs(v::AVec{BigFloat}) = map(Float64, v)
_nobigs(v::AVec{BigInt}) = map(Int64, v)
_nobigs(v) = v
@noinline function _compute_xyz(x, y, z)
x = _compute_x(x, y, z)
y = _compute_y(x, y, z)
z = _compute_z(x, y, z)
_nobigs(x), _nobigs(y), _nobigs(z)
end
# not allowed
_compute_xyz(x::Nothing, y::FuncOrFuncs{F}, z) where {F <: Function} =
error("If you want to plot the function `$y`, you need to define the x values!")
_compute_xyz(x::Nothing, y::Nothing, z::FuncOrFuncs{F}) where {F <: Function} =
error("If you want to plot the function `$z`, you need to define x and y values!")
_compute_xyz(x::Nothing, y::Nothing, z::Nothing) = error("x/y/z are all nothing!")
# --------------------------------------------------------------------
# we are going to build recipes to do the processing and splitting of the args
# --------------------------------------------------------------------
# The catch-all SliceIt recipe
# --------------------------------------------------------------------
# ensure we dispatch to the slicer
struct SliceIt end
# TODO: Should ribbon and fillrange be handled by the plotting package?
# The `SliceIt` recipe finishes user and type recipe processing.
# It splits processed data into individual series data, stores in copied `plotattributes`
# for each series and returns no arguments.
@recipe function f(::Type{SliceIt}, x, y, z)
# handle data with formatting attached
if typeof(x) <: Formatted
xformatter := x.formatter
x = x.data
end
if typeof(y) <: Formatted
yformatter := y.formatter
y = y.data
end
if typeof(z) <: Formatted
zformatter := z.formatter
z = z.data
end
xs = _series_data_vector(x, plotattributes)
ys = _series_data_vector(y, plotattributes)
zs = _series_data_vector(z, plotattributes)
fr = pop!(plotattributes, :fillrange, nothing)
fillranges = _process_fillrange(fr, plotattributes)
mf = length(fillranges)
rib = pop!(plotattributes, :ribbon, nothing)
ribbons = _process_ribbon(rib, plotattributes)
mr = length(ribbons)
mx = length(xs)
my = length(ys)
mz = length(zs)
if mx > 0 && my > 0 && mz > 0
for i in 1:max(mx, my, mz)
# add a new series
di = copy(plotattributes)
xi, yi, zi = xs[mod1(i, mx)], ys[mod1(i, my)], zs[mod1(i, mz)]
di[:x], di[:y], di[:z] = _compute_xyz(xi, yi, zi)
# handle fillrange
fr = fillranges[mod1(i, mf)]
di[:fillrange] = isa(fr, Function) ? map(fr, di[:x]) : fr
# handle ribbons
rib = ribbons[mod1(i, mr)]
di[:ribbon] = isa(rib, Function) ? map(rib, di[:x]) : rib
push!(series_list, RecipeData(di, ()))
end
end
nothing # don't add a series for the main block
end
+62
View File
@@ -0,0 +1,62 @@
"""
_process_seriesrecipes!(plt, kw_list)
Recursively apply series recipes until the backend supports the seriestype
"""
function _process_seriesrecipes!(plt, kw_list)
for kw in kw_list
# in series attributes given as vector with one element per series,
# select the value for current series
slice_series_attributes!(plt, kw_list, kw)
series_attr = DefaultsDict(kw, series_defaults(plt))
# now we have a fully specified series, with colors chosen. we must recursively
# handle series recipes, which dispatch on seriestype. If a backend does not
# natively support a seriestype, we check for a recipe that will convert that
# series type into one made up of lower-level components.
# For example, a histogram is just a bar plot with binned data, a bar plot is
# really a filled step plot, and a step plot is really just a path. So any backend
# that supports drawing a path will implicitly be able to support step, bar, and
# histogram plots (and any recipes that use those components).
_process_seriesrecipe(plt, series_attr)
end
end
# this method recursively applies series recipes when the seriestype is not supported
# natively by the backend
function _process_seriesrecipe(plt, plotattributes)
# replace seriestype aliases
st = Symbol(plotattributes[:seriestype])
st = plotattributes[:seriestype] = type_alias(plt, st)
# shapes shouldn't have fillrange set
if plotattributes[:seriestype] == :shape
plotattributes[:fillrange] = nothing
end
# if it's natively supported, finalize processing and pass along to the backend,
# otherwise recurse
if is_seriestype_supported(plt, st)
add_series!(plt, plotattributes)
else
# get a sub list of series for this seriestype
x, y, z = plotattributes[:x], plotattributes[:y], plotattributes[:z]
datalist = RecipesBase.apply_recipe(plotattributes, Val{st}, x, y, z)
warn_on_recipe_aliases!(plt, datalist, :series, st)
# assuming there was no error, recursively apply the series recipes
for data in datalist
if isa(data, RecipeData)
preprocess_attributes!(plt, data.plotattributes)
if data.plotattributes[:seriestype] == st
error("The seriestype didn't change in series recipe $st. This will cause a StackOverflow.")
end
_process_seriesrecipe(plt, data.plotattributes)
else
@warn("Unhandled recipe: $(data)")
break
end
end
end
nothing
end
+94
View File
@@ -0,0 +1,94 @@
# this is the default "type recipe"... just pass the object through
@recipe f(::Type{T}, v::T) where {T} = v
# this should catch unhandled "series recipes" and error with a nice message
@recipe f(::Type{V}, x, y, z) where {V <: Val} =
error("The backend must not support the series type $V, and there isn't a series recipe defined.")
"""
_apply_type_recipe(plotattributes, v::T, letter)
Apply the type recipe with signature `(::Type{T}, ::T)`.
"""
function _apply_type_recipe(plotattributes, v, letter)
_preprocess_axis_args!(plotattributes, letter)
rdvec = RecipesBase.apply_recipe(plotattributes, typeof(v), v)
warn_on_recipe_aliases!(plotattributes[:plot_object], plotattributes, :type, typeof(v))
_postprocess_axis_args!(plotattributes, letter)
return rdvec[1].args[1]
end
# Handle type recipes when the recipe is defined on the elements.
# This sort of recipe should return a pair of functions... one to convert to number,
# and one to format tick values.
function _apply_type_recipe(plotattributes, v::AbstractArray, letter)
plt = plotattributes[:plot_object]
_preprocess_axis_args!(plotattributes, letter)
# First we try to apply an array type recipe.
w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1]
warn_on_recipe_aliases!(plt, plotattributes, :type, typeof(v))
# If the type did not change try it element-wise
if typeof(v) == typeof(w)
isempty(skipmissing(v)) && return Float64[]
x = first(skipmissing(v))
args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args
warn_on_recipe_aliases!(plt, plotattributes, :type, typeof(x))
_postprocess_axis_args!(plotattributes, letter)
if length(args) == 2 && all(arg -> arg isa Function, args)
numfunc, formatter = args
return Formatted(map(numfunc, v), formatter)
else
return v
end
end
_postprocess_axis_args!(plotattributes, letter)
return w
end
# special handling for Surface... need to properly unwrap and re-wrap
_apply_type_recipe(plotattributes, v::Surface{<:AMat{<:DataPoint}}) = v
function _apply_type_recipe(plotattributes, v::Surface)
ret = _apply_type_recipe(plotattributes, v.surf)
if typeof(ret) <: Formatted
Formatted(Surface(ret.data), ret.formatter)
else
Surface(ret.data)
end
end
# don't do anything for datapoints or nothing
_apply_type_recipe(plotattributes, v::AbstractArray{<:DataPoint}, letter) = v
_apply_type_recipe(plotattributes, v::Nothing, letter) = v
# axis args before type recipes should still be mapped to all axes
function _preprocess_axis_args!(plotattributes)
plt = plotattributes[:plot_object]
for (k, v) in plotattributes
if is_axis_attribute(plt, k)
pop!(plotattributes, k)
for l in (:x, :y, :z)
lk = Symbol(l, k)
haskey(plotattributes, lk) || (plotattributes[lk] = v)
end
end
end
end
function _preprocess_axis_args!(plotattributes, letter)
plotattributes[:letter] = letter
_preprocess_axis_args!(plotattributes)
end
# axis args in type recipes should only be applied to the current axis
function _postprocess_axis_args!(plotattributes, letter)
plt = plotattributes[:plot_object]
pop!(plotattributes, :letter)
if letter in (:x, :y, :z)
for (k, v) in plotattributes
if is_axis_attribute(plt, k)
pop!(plotattributes, k)
lk = Symbol(letter, k)
haskey(plotattributes, lk) || (plotattributes[lk] = v)
end
end
end
end
+330
View File
@@ -0,0 +1,330 @@
"""
_process_userrecipes(plt, plotattributes, args)
Wrap input arguments in a `RecipeData' vector and recursively apply user recipes and type
recipes on the first element. Prepend the returned `RecipeData` vector. If an element with
empy `args` is returned pop it from the vector, finish up, and it to vector of `Dict`s with
processed series. When all arguments are processed return the series `Dict`.
"""
function _process_userrecipes!(plt, plotattributes, args)
still_to_process = _recipedata_vector(plt, plotattributes, args)
# for plotting recipes, swap out the args and update the parameter dictionary
# we are keeping a stack of series that still need to be processed.
# each pass through the loop, we pop one off and apply the recipe.
# the recipe will return a list a Series objects... the ones that are
# finished (no more args) get added to the kw_list, the ones that are not
# are placed on top of the stack and are then processed further.
kw_list = KW[]
while !isempty(still_to_process)
# grab the first in line to be processed and either add it to the kw_list or
# pass it through apply_recipe to generate a list of RecipeData objects
# (data + attributes) for further processing.
next_series = popfirst!(still_to_process)
# recipedata should be of type RecipeData.
# if it's not then the inputs must not have been fully processed by recipes
if !(typeof(next_series) <: RecipeData)
error("Inputs couldn't be processed... expected RecipeData but got: $next_series")
end
if isempty(next_series.args)
_finish_userrecipe!(plt, kw_list, next_series)
else
rd_list =
RecipesBase.apply_recipe(next_series.plotattributes, next_series.args...)
warn_on_recipe_aliases!(plt, rd_list, :user, next_series.args...)
prepend!(still_to_process, rd_list)
end
end
# don't allow something else to handle it
plotattributes[:smooth] = false
kw_list
end
# TODO Move this to api.jl?
function _recipedata_vector(plt, plotattributes, args)
still_to_process = RecipeData[]
# the grouping mechanism is a recipe on a GroupBy object
# we simply add the GroupBy object to the front of the args list to allow
# the recipe to be applied
if haskey(plotattributes, :group)
args = (_extract_group_attributes(plotattributes[:group], args...), args...)
end
# if we were passed a vector/matrix of seriestypes and there's more than one row,
# we want to duplicate the inputs, once for each seriestype row.
if !isempty(args)
append!(still_to_process, _expand_seriestype_array(plotattributes, args))
end
# remove subplot and axis args from plotattributes...
# they will be passed through in the kw_list
if !isempty(args)
for (k, v) in plotattributes
if is_subplot_attribute(plt, k) || is_axis_attribute(plt, k)
reset_kw!(plotattributes, k)
end
end
end
still_to_process
end
function _expand_seriestype_array(plotattributes, args)
sts = get(plotattributes, :seriestype, :path)
if typeof(sts) <: AbstractArray
reset_kw!(plotattributes, :seriestype)
rd = Vector{RecipeData}(undef, size(sts, 1))
for r in axes(sts, 1)
dc = copy(plotattributes)
dc[:seriestype] = sts[r:r, :]
rd[r] = RecipeData(dc, args)
end
rd
else
RecipeData[RecipeData(copy(plotattributes), args)]
end
end
function _finish_userrecipe!(plt, kw_list, recipedata)
# when the arg tuple is empty, that means there's nothing left to recursively
# process... finish up and add to the kw_list
kw = recipedata.plotattributes
preprocess_attributes!(plt, kw)
# if there was a grouping, filter the data here
_filter_input_data!(kw)
process_userrecipe!(plt, kw_list, kw)
end
# --------------------------------
# Fallback user recipes
# --------------------------------
# These call `_apply_type_recipe` in type_recipe.jl and finally the `SliceIt` recipe in
# series.jl.
# handle "type recipes" by converting inputs, and then either re-calling or slicing
@recipe function f(x, y, z)
wrap_surfaces!(plotattributes, x, y, z)
did_replace = false
newx = _apply_type_recipe(plotattributes, x, :x)
x === newx || (did_replace = true)
newy = _apply_type_recipe(plotattributes, y, :y)
y === newy || (did_replace = true)
newz = _apply_type_recipe(plotattributes, z, :z)
z === newz || (did_replace = true)
if did_replace
newx, newy, newz
else
SliceIt, x, y, z
end
end
@recipe function f(x, y)
wrap_surfaces!(plotattributes, x, y)
did_replace = false
newx = _apply_type_recipe(plotattributes, x, :x)
x === newx || (did_replace = true)
newy = _apply_type_recipe(plotattributes, y, :y)
y === newy || (did_replace = true)
if did_replace
newx, newy
else
SliceIt, x, y, nothing
end
end
@recipe function f(y)
wrap_surfaces!(plotattributes, y)
newy = _apply_type_recipe(plotattributes, y, :y)
if y !== newy
newy
else
SliceIt, nothing, y, nothing
end
end
# if there's more than 3 inputs, it can't be passed directly to SliceIt
# so we'll apply_type_recipe to all of them
@recipe function f(v1, v2, v3, v4, vrest...)
did_replace = false
newargs = map(
v -> begin
newv = _apply_type_recipe(plotattributes, v, :unknown)
if newv !== v
did_replace = true
end
newv
end,
(v1, v2, v3, v4, vrest...),
)
if !did_replace
error("Couldn't process recipe args: $(map(typeof, (v1, v2, v3, v4, vrest...)))")
end
newargs
end
# helper function to ensure relevant attributes are wrapped by Surface
function wrap_surfaces!(plotattributes, args...) end
wrap_surfaces!(plotattributes, x::AMat, y::AMat, z::AMat) = wrap_surfaces!(plotattributes)
wrap_surfaces!(plotattributes, x::AVec, y::AVec, z::AMat) = wrap_surfaces!(plotattributes)
function wrap_surfaces!(plotattributes, x::AVec, y::AVec, z::Surface)
wrap_surfaces!(plotattributes)
end
function wrap_surfaces!(plotattributes)
if haskey(plotattributes, :fill_z)
v = plotattributes[:fill_z]
if !isa(v, Surface)
plotattributes[:fill_z] = Surface(v)
end
end
end
# --------------------------------
# Special Cases
# --------------------------------
# --------------------------------
# 1 argument
@recipe function f(n::Integer)
if is3d(plotattributes)
SliceIt, n, n, n
else
SliceIt, n, n, nothing
end
end
# return a surface if this is a 3d plot, otherwise let it be sliced up
@recipe function f(mat::AMat)
if is3d(plotattributes)
n, m = axes(mat)
m, n, Surface(mat)
else
nothing, mat, nothing
end
end
# if a matrix is wrapped by Formatted, do similar logic, but wrap data with Surface
@recipe function f(fmt::Formatted{<:AMat})
if is3d(plotattributes)
mat = fmt.data
n, m = axes(mat)
m, n, Formatted(Surface(mat), fmt.formatter)
else
nothing, fmt, nothing
end
end
# assume this is a Volume, so construct one
@recipe function f(vol::AbstractArray{<:MaybeNumber, 3}, args...)
seriestype := :volume
SliceIt, nothing, Volume(vol, args...), nothing
end
# Dicts: each entry is a data point (x,y)=(key,value)
@recipe f(d::AbstractDict) = collect(keys(d)), collect(values(d))
# function without range... use the current range of the x-axis
@recipe function f(f::FuncOrFuncs{F}) where {F <: Function}
plt = plotattributes[:plot_object]
xmin, xmax = if haskey(plotattributes, :xlims)
plotattributes[:xlims]
else
try
get_axis_limits(plt, :x)
catch
xinv = inverse_scale_func(get(plotattributes, :xscale, :identity))
xm = PlotUtils.tryrange(f, xinv.([-5, -1, 0, 0.01]))
xm, PlotUtils.tryrange(f, filter(x -> x > xm, xinv.([5, 1, 0.99, 0, -0.01])))
end
end
f, xmin, xmax
end
# --------------------------------
# 2 arguments
# if functions come first, just swap the order (not to be confused with parametric
# functions... as there would be more than one function passed in)
@recipe function f(f::FuncOrFuncs{F}, x) where {F <: Function}
F2 = typeof(x)
@assert !(F2 <: Function || (F2 <: AbstractArray && F2.parameters[1] <: Function))
# otherwise we'd hit infinite recursion here
x, f
end
# --------------------------------
# 3 arguments
# surface-like... function
@recipe function f(x::AVec, y::AVec, zf::Function)
x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported
end
# surface-like... matrix grid
@recipe function f(x::AVec, y::AVec, z::AMat)
if !is_surface(plotattributes)
plotattributes[:seriestype] = :contour
end
x, y, Surface(z)
end
# parametric functions
# special handling... xmin/xmax with parametric function(s)
@recipe function f(f::Function, xmin::Number, xmax::Number)
xscale, yscale = [get(plotattributes, sym, :identity) for sym in (:xscale, :yscale)]
_scaled_adapted_grid(f, xscale, yscale, xmin, xmax)
end
@recipe function f(fs::AbstractArray{F}, xmin::Number, xmax::Number) where {F <: Function}
xscale, yscale = [get(plotattributes, sym, :identity) for sym in (:xscale, :yscale)]
unzip(_scaled_adapted_grid.(fs, xscale, yscale, xmin, xmax))
end
@recipe f(
fx::FuncOrFuncs{F},
fy::FuncOrFuncs{G},
u::AVec,
) where {F <: Function, G <: Function} = _map_funcs(fx, u), _map_funcs(fy, u)
@recipe f(
fx::FuncOrFuncs{F},
fy::FuncOrFuncs{G},
umin::Number,
umax::Number,
n = 200,
) where {F <: Function, G <: Function} = fx, fy, range(umin, stop = umax, length = n)
function _scaled_adapted_grid(f, xscale, yscale, xmin, xmax)
(xf, xinv), (yf, yinv) = ((scale_func(s), inverse_scale_func(s)) for s in (xscale, yscale))
xs, ys = PlotUtils.adapted_grid(yf f xinv, xf.((xmin, xmax)))
xinv.(xs), yinv.(ys)
end
# special handling... 3D parametric function(s)
@recipe function f(
fx::FuncOrFuncs{F},
fy::FuncOrFuncs{G},
fz::FuncOrFuncs{H},
u::AVec,
) where {F <: Function, G <: Function, H <: Function}
_map_funcs(fx, u), _map_funcs(fy, u), _map_funcs(fz, u)
end
@recipe function f(
fx::FuncOrFuncs{F},
fy::FuncOrFuncs{G},
fz::FuncOrFuncs{H},
umin::Number,
umax::Number,
numPoints = 200,
) where {F <: Function, G <: Function, H <: Function}
fx, fy, fz, range(umin, stop = umax, length = numPoints)
end
# list of tuples
@recipe f(v::AVec{<:Tuple}) = unzip(v)
@recipe f(tup::Tuple) = [tup]
+220
View File
@@ -0,0 +1,220 @@
const AVec = AbstractVector
const AMat = AbstractMatrix
const KW = Dict{Symbol, Any}
const AKW = AbstractDict{Symbol, Any}
# --------------------------------
# DefaultsDict
# --------------------------------
struct DefaultsDict <: AbstractDict{Symbol, Any}
explicit::KW
defaults::KW
end
function Base.getindex(dd::DefaultsDict, k)
return haskey(dd.explicit, k) ? dd.explicit[k] : dd.defaults[k]
end
Base.haskey(dd::DefaultsDict, k) = haskey(dd.explicit, k) || haskey(dd.defaults, k)
Base.get(dd::DefaultsDict, k, default) = haskey(dd, k) ? dd[k] : default
function Base.get!(dd::DefaultsDict, k, default)
v = if haskey(dd, k)
dd[k]
else
dd.defaults[k] = default
end
return v
end
function Base.delete!(dd::DefaultsDict, k)
haskey(dd.explicit, k) && delete!(dd.explicit, k)
haskey(dd.defaults, k) && delete!(dd.defaults, k)
end
Base.length(dd::DefaultsDict) = length(union(keys(dd.explicit), keys(dd.defaults)))
function Base.iterate(dd::DefaultsDict)
exp_keys = keys(dd.explicit)
def_keys = setdiff(keys(dd.defaults), exp_keys)
key_list = collect(Iterators.flatten((exp_keys, def_keys)))
iterate(dd, (key_list, 1))
end
function Base.iterate(dd::DefaultsDict, (key_list, i))
i > length(key_list) && return nothing
k = key_list[i]
(k => dd[k], (key_list, i + 1))
end
Base.copy(dd::DefaultsDict) = DefaultsDict(copy(dd.explicit), dd.defaults)
RecipesBase.is_explicit(dd::DefaultsDict, k) = haskey(dd.explicit, k)
isdefault(dd::DefaultsDict, k) = !is_explicit(dd, k) && haskey(dd.defaults, k)
Base.setindex!(dd::DefaultsDict, v, k) = dd.explicit[k] = v
# Reset to default value and return dict
reset_kw!(dd::DefaultsDict, k) = is_explicit(dd, k) ? delete!(dd.explicit, k) : dd
# Reset to default value and return old value
pop_kw!(dd::DefaultsDict, k) = is_explicit(dd, k) ? pop!(dd.explicit, k) : dd.defaults[k]
pop_kw!(dd::DefaultsDict, k, default) =
is_explicit(dd, k) ? pop!(dd.explicit, k) : get(dd.defaults, k, default)
# Fallbacks for dicts without defaults
reset_kw!(d::AKW, k) = delete!(d, k)
pop_kw!(d::AKW, k) = pop!(d, k)
pop_kw!(d::AKW, k, default) = pop!(d, k, default)
# --------------------------------
# 3D types
# --------------------------------
abstract type AbstractSurface end
"represents a contour or surface mesh"
struct Surface{M <: AMat} <: AbstractSurface
surf::M
end
Surface(f::Function, x, y) = Surface(Float64[f(xi, yi) for yi in y, xi in x])
Base.Array(surf::Surface) = surf.surf
for f in (:length, :size, :axes)
@eval Base.$f(surf::Surface, args...) = $f(surf.surf, args...)
end
Base.copy(surf::Surface) = Surface(copy(surf.surf))
Base.eltype(surf::Surface{T}) where {T} = eltype(T)
struct Volume{T}
v::Array{T, 3}
x_extents::Tuple{T, T}
y_extents::Tuple{T, T}
z_extents::Tuple{T, T}
end
default_extents(::Type{T}) where {T} = (zero(T), one(T))
function Volume(
v::Array{T, 3},
x_extents = default_extents(T),
y_extents = default_extents(T),
z_extents = default_extents(T),
) where {T}
Volume(v, x_extents, y_extents, z_extents)
end
Base.Array(vol::Volume) = vol.v
for f in (:length, :size)
@eval Base.$f(vol::Volume, args...) = $f(vol.v, args...)
end
Base.copy(vol::Volume{T}) where {T} =
Volume{T}(copy(vol.v), vol.x_extents, vol.y_extents, vol.z_extents)
Base.eltype(vol::Volume{T}) where {T} = T
# --------------------------------
# Formatting
# --------------------------------
"Represents data values with formatting that should apply to the tick labels."
struct Formatted{T}
data::T
formatter::Function
end
# -------------------------------
# 3D seriestypes
# -------------------------------
# TODO: Move to RecipesBase?
"""
is3d(::Type{Val{:myseriestype}})
Returns `true` if `myseriestype` represents a 3D series, `false` otherwise.
"""
is3d(st) = false
for st in (
:contour,
:contourf,
:contour3d,
:heatmap,
:image,
:path3d,
:scatter3d,
:surface,
:volume,
:wireframe,
)
@eval is3d(::Type{Val{Symbol($(string(st)))}}) = true
end
is3d(st::Symbol) = is3d(Val{st})
is3d(plt, stv::AbstractArray) = all(st -> is3d(plt, st), stv)
is3d(plotattributes::AbstractDict) = is3d(get(plotattributes, :seriestype, :path))
"""
is_surface(::Type{Val{:myseriestype}})
Returns `true` if `myseriestype` represents a surface series, `false` otherwise.
"""
is_surface(st) = false
for st in (:contour, :contourf, :contour3d, :image, :heatmap, :surface, :wireframe)
@eval is_surface(::Type{Val{Symbol($(string(st)))}}) = true
end
is_surface(st::Symbol) = is_surface(Val{st})
is_surface(plt, stv::AbstractArray) = all(st -> is_surface(plt, st), stv)
is_surface(plotattributes::AbstractDict) =
is_surface(get(plotattributes, :seriestype, :path))
"""
needs_3d_axes(::Type{Val{:myseriestype}})
Returns `true` if `myseriestype` needs 3d axes, `false` otherwise.
"""
needs_3d_axes(st) = false
for st in (
:contour3d,
:path3d,
:scatter3d,
:surface,
:volume,
:wireframe,
)
@eval needs_3d_axes(::Type{Val{Symbol($(string(st)))}}) = true
end
needs_3d_axes(st::Symbol) = needs_3d_axes(Val{st})
needs_3d_axes(plt, stv::AbstractArray) = all(st -> needs_3d_axes(plt, st), stv)
needs_3d_axes(plotattributes::AbstractDict) =
needs_3d_axes(get(plotattributes, :seriestype, :path))
# --------------------------------
# Scales
# --------------------------------
const SCALE_FUNCTIONS = Dict{Symbol, Function}(:log10 => log10, :log2 => log2, :ln => log)
const INVERSE_SCALE_FUNCTIONS =
Dict{Symbol, Function}(:log10 => exp10, :log2 => exp2, :ln => exp)
scale_func(scale::Symbol) = x -> get(SCALE_FUNCTIONS, scale, identity)(Float64(x))
inverse_scale_func(scale::Symbol) =
x -> get(INVERSE_SCALE_FUNCTIONS, scale, identity)(Float64(x))
# --------------------------------
# Unzip
# --------------------------------
for i in 2:4
@eval begin
unzip(v::AVec{<:Tuple{Vararg{T, $i} where T}}) =
$(Expr(:tuple, (:([t[$j] for t in v]) for j in 1:i)...))
end
end
# --------------------------------
# Map functions on vectors
# --------------------------------
_map_funcs(f::Function, u::AVec) = map(f, u)
_map_funcs(fs::AVec{F}, u::AVec) where {F <: Function} = [map(f, u) for f in fs]
+2 -4
View File
@@ -24,7 +24,6 @@ end
giffn() = (isijulia() ? "tmp.gif" : tempname()*".gif")
movfn() = (isijulia() ? "tmp.mov" : tempname()*".mov")
mp4fn() = (isijulia() ? "tmp.mp4" : tempname()*".mp4")
webmfn() = (isijulia() ? "tmp.webm" : tempname()*".webm")
mutable struct FrameIterator
itr
@@ -64,7 +63,6 @@ file_extension(fn) = Base.Filesystem.splitext(fn)[2][2:end]
gif(anim::Animation, fn = giffn(); kw...) = buildanimation(anim, fn; kw...)
mov(anim::Animation, fn = movfn(); kw...) = buildanimation(anim, fn, false; kw...)
mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim, fn, false; kw...)
webm(anim::Animation, fn = webmfn(); kw...) = buildanimation(anim, fn, false; kw...)
ffmpeg_framerate(fps) = "$fps"
ffmpeg_framerate(fps::Rational) = "$(fps.num)/$(fps.den)"
@@ -112,8 +110,8 @@ function Base.show(io::IO, ::MIME"text/html", agif::AnimatedGif)
ext = file_extension(agif.filename)
if ext == "gif"
html = "<img src=\"data:image/gif;base64," * base64encode(read(agif.filename)) * "\" />"
elseif ext in ("mov", "mp4","webm")
mimetype = ext == "mov" ? "video/quicktime" : "video/$ext"
elseif ext in ("mov", "mp4")
mimetype = ext == "mov" ? "video/quicktime" : "video/mp4"
html = "<video controls><source src=\"data:$mimetype;base64," *
base64encode(read(agif.filename)) *
"\" type = \"$mimetype\"></video>"
+4 -6
View File
@@ -70,13 +70,12 @@ const _arg_desc = KW(
:dpi => "Number. Dots Per Inch of output figures",
:thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.",
:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.",
:extra_kwargs => "Either one of (`:plot`, `:subplot`, `:series`) to specify for which element extra keyword args are collected or a KW (Dict{Symbol,Any}) to pass a map of extra keyword args which may be specific to a backend. Default: `:series`.\n Example: `pgfplotsx(); scatter(1:5, extra_kwargs=Dict(:subplot=>Dict(\"axis line shift\" => \"10pt\"))`",
:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.",
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",
:warn_on_unsupported => "Bool. Warn on unsupported attributes, series types and marker shapes",
# subplot args
:title => "String. Subplot title.",
:titlelocation => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`",
:title_location => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`",
:titlefontfamily => "String or Symbol. Font family of subplot title.",
:titlefontsize => "Integer. Font pointsize of subplot title.",
:titlefonthalign => "Symbol. Font horizontal alignment of subplot title: :hcenter, :left, :right or :center",
@@ -90,14 +89,13 @@ const _arg_desc = KW(
:foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.",
:foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.",
:color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.",
:legend => "Bool (show the legend?) or (x,y) tuple or Symbol (legend position). Bottom left corner of legend is placed at (x,y). Symbol values: `:none`; `:best`; `:inline`; `:inside`; `:legend`; any valid combination of `:(outer ?)(top/bottom ?)(right/left ?)`, i.e.: `:top`, `:topright`, `:outerleft`, `:outerbottomright` ... (note: only some may be supported in each backend)",
:legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` , `:inline` (note: only some may be supported in each backend)",
:legendfontfamily => "String or Symbol. Font family of legend entries.",
:legendfontsize => "Integer. Font pointsize of legend entries.",
:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center",
:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center",
:legendfontrotation => "Real. Font rotation of legend entries",
:legendfontcolor => "Color Type. Font color of legend entries",
:legendtitle => "String. Legend title.",
:legendtitlefontfamily => "String or Symbol. Font family of the legend title.",
:legendtitlefontsize => "Integer. Font pointsize the legend title.",
:legendtitlefonthalign => "Symbol. Font horizontal alignment of the legend title: :hcenter, :left, :right or :center",
@@ -105,7 +103,7 @@ const _arg_desc = KW(
:legendtitlefontrotation => "Real. Font rotation of the legend title",
:legendtitlefontcolor => "Color Type. Font color of the legend title",
:colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)",
:clims => "`:auto`, NTuple{2,Number}, or a function that takes series data in and returns NTuple{2,Number}. Fixes the limits of the colorbar.",
:clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.",
:legendfont => "Font. Font of legend items.",
:legendtitlefont => "Font. Font of the legend title.",
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",
+42 -83
View File
@@ -20,14 +20,7 @@ function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol})
end
end
function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol}, args::Vector{Symbol})
for arg in args
s = string(arg)
if '_' in s
aliases[Symbol(replace(s, "_" => ""))] = arg
end
end
end
# ------------------------------------------------------------
const _allAxes = [:auto, :left, :right]
@@ -93,10 +86,10 @@ const _surface_like = [:contour, :contourf, :contour3d, :heatmap, :surface, :wir
like_histogram(seriestype::Symbol) = seriestype in _histogram_like
like_line(seriestype::Symbol) = seriestype in _line_like
like_surface(seriestype::Symbol) = RecipesPipeline.is_surface(seriestype)
like_surface(seriestype::Symbol) = is_surface(seriestype)
RecipesPipeline.is3d(series::Series) = RecipesPipeline.is3d(series.plotattributes)
RecipesPipeline.is3d(sp::Subplot) = string(sp.attr[:projection]) == "3d"
is3d(series::Series) = is3d(series.plotattributes)
is3d(sp::Subplot) = string(sp.attr[:projection]) == "3d"
ispolar(sp::Subplot) = string(sp.attr[:projection]) == "polar"
ispolar(series::Series) = ispolar(series.plotattributes[:subplot])
@@ -271,7 +264,6 @@ const _series_defaults = KW(
:bar_edges => false,
:xerror => nothing,
:yerror => nothing,
:zerror => nothing,
:ribbon => nothing,
:quiver => nothing,
:arrow => nothing, # allows for adding arrows to line/path... call `arrow(args...)`
@@ -288,7 +280,6 @@ const _series_defaults = KW(
# one logical series to be broken up (path and markers, for example)
:hover => nothing, # text to display when hovering over the data points
:stride => (1,1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride.
:extra_kwargs => Dict()
)
@@ -300,7 +291,7 @@ const _plot_defaults = KW(
:fontfamily => "sans-serif",
:size => (600,400),
:pos => (0,0),
:window_title => "Plots.jl",
:window_title => "Plots.jl",
:show => false,
:layout => 1,
:link => :none,
@@ -312,15 +303,13 @@ const _plot_defaults = KW(
:dpi => DPI, # dots per inch for images, etc
:thickness_scaling => 1,
:display_type => :auto,
:warn_on_unsupported => true,
:extra_plot_kwargs => Dict(),
:extra_kwargs => :series, # directs collection of extra_kwargs
:extra_kwargs => KW(),
)
const _subplot_defaults = KW(
:title => "",
:titlelocation => :center, # also :left or :right
:title_location => :center, # also :left or :right
:fontfamily_subplot => :match,
:titlefontfamily => :match,
:titlefontsize => 14,
@@ -363,7 +352,6 @@ const _subplot_defaults = KW(
:colorbar_title => "",
:framestyle => :axes,
:camera => (30,30),
:extra_kwargs => Dict()
)
const _axis_defaults = KW(
@@ -491,7 +479,10 @@ is_default_attribute(k) = k in _internal_args || k in _all_args || is_axis_attr_
makeplural(s::Symbol) = Symbol(string(s,"s"))
autopick_ignore_none_auto(arr::AVec, idx::Integer) = _cycle(setdiff(arr, [:none, :auto]), idx)
autopick(arr::AVec, idx::Integer) = arr[mod1(idx,length(arr))]
autopick(notarr, idx::Integer) = notarr
autopick_ignore_none_auto(arr::AVec, idx::Integer) = autopick(setdiff(arr, [:none, :auto]), idx)
autopick_ignore_none_auto(notarr, idx::Integer) = notarr
function aliasesAndAutopick(plotattributes::AKW, sym::Symbol, aliases::Dict{Symbol,Symbol}, options::AVec, plotIndex::Int)
@@ -509,13 +500,6 @@ end
# -----------------------------------------------------------------------------
# margin
add_aliases(:left_margin , :leftmargin )
add_aliases(:top_margin , :topmargin)
add_aliases(:bottom_margin , :bottommargin)
add_aliases(:right_margin ,:rightmargin)
# colors
add_aliases(:seriescolor, :c, :color, :colour)
add_aliases(:linecolor, :lc, :lcolor, :lcolour, :linecolour)
@@ -581,23 +565,21 @@ add_aliases(:bins, :bin, :nbin, :nbins, :nb)
add_aliases(:ribbon, :rib)
add_aliases(:annotations, :ann, :anns, :annotate, :annotation)
add_aliases(:xguide, :xlabel, :xlab, :xl)
add_aliases(:xlims, :xlim, :xlimit, :xlimits, :xrange)
add_aliases(:xlims, :xlim, :xlimit, :xlimits)
add_aliases(:xticks, :xtick)
add_aliases(:xrotation, :xrot, :xr)
add_aliases(:yguide, :ylabel, :ylab, :yl)
add_aliases(:ylims, :ylim, :ylimit, :ylimits, :yrange)
add_aliases(:ylims, :ylim, :ylimit, :ylimits)
add_aliases(:yticks, :ytick)
add_aliases(:yrotation, :yrot, :yr)
add_aliases(:zguide, :zlabel, :zlab, :zl)
add_aliases(:zlims, :zlim, :zlimit, :zlimits)
add_aliases(:zticks, :ztick)
add_aliases(:zrotation, :zrot, :zr)
add_aliases(:guidefontsize, :labelfontsize)
add_aliases(:fill_z, :fillz, :fz, :surfacecolor, :surfacecolour, :sc, :surfcolor, :surfcolour)
add_aliases(:legend, :leg, :key)
add_aliases(:legendtitle, :legend_title, :labeltitle, :label_title, :leg_title, :key_title)
add_aliases(:colorbar, :cb, :cbar, :colorkey)
add_aliases(:colorbar_title, :colorbartitle, :cb_title, :cbtitle, :cbartitle, :cbar_title, :colorkeytitle, :colorkey_title)
add_aliases(:clims, :clim, :cbarlims, :cbar_lims, :climits, :color_limits)
add_aliases(:smooth, :regression, :reg)
add_aliases(:levels, :nlevels, :nlev, :levs)
@@ -608,7 +590,6 @@ add_aliases(:color_palette, :palette)
add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse)
add_aliases(:xerror, :xerr, :xerrorbar)
add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar)
add_aliases(:zerror, :zerr, :zerrorbar)
add_aliases(:quiver, :velocity, :quiver2d, :gradient, :vectorfield)
add_aliases(:normalize, :norm, :normed, :normalized)
add_aliases(:show_empty_bins, :showemptybins, :showempty, :show_empty)
@@ -616,7 +597,7 @@ add_aliases(:aspect_ratio, :aspectratio, :axis_ratio, :axisratio, :ratio)
add_aliases(:match_dimensions, :transpose, :transpose_z)
add_aliases(:subplot, :sp, :subplt, :splt)
add_aliases(:projection, :proj)
add_aliases(:titlelocation, :title_location, :title_loc, :titleloc, :title_position, :title_pos, :titlepos, :titleposition, :title_align, :title_alignment)
add_aliases(:title_location, :title_loc, :titleloc, :title_position, :title_pos, :titlepos, :titleposition, :title_align, :title_alignment)
add_aliases(:series_annotations, :series_ann, :seriesann, :series_anns, :seriesanns, :series_annotation, :text, :txt, :texts, :txts)
add_aliases(:html_output_format, :format, :fmt, :html_format)
add_aliases(:orientation, :direction, :dir)
@@ -630,14 +611,13 @@ add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyl
add_aliases(:tick_direction, :tickdirection, :tick_dir, :tickdir, :tick_orientation, :tickorientation, :tick_or, :tickor)
add_aliases(:camera, :cam, :viewangle, :view_angle)
add_aliases(:contour_labels, :contourlabels, :clabels, :clabs)
add_aliases(:warn_on_unsupported, :warn)
# add all pluralized forms to the _keyAliases dict
for arg in keys(_series_defaults)
_keyAliases[makeplural(arg)] = arg
end
add_non_underscore_aliases!(_keyAliases)
# -----------------------------------------------------------------------------
@@ -674,7 +654,7 @@ function default(k::Symbol)
return _axis_defaults_byletter[letter][key]
end
k == :letter && return k # for type recipe processing
return missing
k in _suppress_warnings || error("Unknown key: ", k)
end
function default(k::Symbol, v)
@@ -697,12 +677,9 @@ function default(k::Symbol, v)
k in _suppress_warnings || error("Unknown key: ", k)
end
function default(; reset = true, kw...)
if reset && isempty(kw)
reset_defaults()
end
function default(; kw...)
kw = KW(kw)
RecipesPipeline.preprocess_attributes!(kw)
preprocess_attributes!(kw)
for (k,v) in kw
default(k, v)
end
@@ -955,13 +932,12 @@ function _add_markershape(plotattributes::AKW)
end
"Handle all preprocessing of args... break out colors/sizes/etc and replace aliases."
function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
function preprocess_attributes!(plotattributes::AKW)
replaceAliases!(plotattributes, _keyAliases)
# handle axis args common to all axis
args = wraptuple(RecipesPipeline.pop_kw!(plotattributes, :axis, ()))
showarg = wraptuple(RecipesPipeline.pop_kw!(plotattributes, :showaxis, ()))
for arg in wraptuple((args..., showarg...))
args = pop_kw!(plotattributes, :axis, ())
for arg in wraptuple(args)
for letter in (:x, :y, :z)
process_axis_arg!(plotattributes, arg, letter)
end
@@ -969,7 +945,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
# handle axis args
for letter in (:x, :y, :z)
asym = Symbol(letter, :axis)
args = RecipesPipeline.pop_kw!(plotattributes, asym, ())
args = pop_kw!(plotattributes, asym, ())
if !(typeof(args) <: Axis)
for arg in wraptuple(args)
process_axis_arg!(plotattributes, arg, letter)
@@ -987,7 +963,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end
# handle grid args common to all axes
args = RecipesPipeline.pop_kw!(plotattributes, :grid, ())
args = pop_kw!(plotattributes, :grid, ())
for arg in wraptuple(args)
for letter in (:x, :y, :z)
processGridArg!(plotattributes, arg, letter)
@@ -996,13 +972,13 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
# handle individual axes grid args
for letter in (:x, :y, :z)
gridsym = Symbol(letter, :grid)
args = RecipesPipeline.pop_kw!(plotattributes, gridsym, ())
args = pop_kw!(plotattributes, gridsym, ())
for arg in wraptuple(args)
processGridArg!(plotattributes, arg, letter)
end
end
# handle minor grid args common to all axes
args = RecipesPipeline.pop_kw!(plotattributes, :minorgrid, ())
args = pop_kw!(plotattributes, :minorgrid, ())
for arg in wraptuple(args)
for letter in (:x, :y, :z)
processMinorGridArg!(plotattributes, arg, letter)
@@ -1011,14 +987,14 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
# handle individual axes grid args
for letter in (:x, :y, :z)
gridsym = Symbol(letter, :minorgrid)
args = RecipesPipeline.pop_kw!(plotattributes, gridsym, ())
args = pop_kw!(plotattributes, gridsym, ())
for arg in wraptuple(args)
processMinorGridArg!(plotattributes, arg, letter)
end
end
# handle font args common to all axes
for fontname in (:tickfont, :guidefont)
args = RecipesPipeline.pop_kw!(plotattributes, fontname, ())
args = pop_kw!(plotattributes, fontname, ())
for arg in wraptuple(args)
for letter in (:x, :y, :z)
processFontArg!(plotattributes, Symbol(letter, fontname), arg)
@@ -1028,7 +1004,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
# handle individual axes font args
for letter in (:x, :y, :z)
for fontname in (:tickfont, :guidefont)
args = RecipesPipeline.pop_kw!(plotattributes, Symbol(letter, fontname), ())
args = pop_kw!(plotattributes, Symbol(letter, fontname), ())
for arg in wraptuple(args)
processFontArg!(plotattributes, Symbol(letter, fontname), arg)
end
@@ -1036,7 +1012,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
end
# handle axes args
for k in _axis_args
if haskey(plotattributes, k) && k !== :link
if haskey(plotattributes, k)
v = plotattributes[k]
for letter in (:x, :y, :z)
lk = Symbol(letter, k)
@@ -1049,14 +1025,14 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
# fonts
for fontname in (:titlefont, :legendfont, :legendtitlefont)
args = RecipesPipeline.pop_kw!(plotattributes, fontname, ())
args = pop_kw!(plotattributes, fontname, ())
for arg in wraptuple(args)
processFontArg!(plotattributes, fontname, arg)
end
end
# handle line args
for arg in wraptuple(RecipesPipeline.pop_kw!(plotattributes, :line, ()))
for arg in wraptuple(pop_kw!(plotattributes, :line, ()))
processLineArg(plotattributes, arg)
end
@@ -1070,7 +1046,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
processMarkerArg(plotattributes, arg)
anymarker = true
end
RecipesPipeline.reset_kw!(plotattributes, :marker)
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
@@ -1084,7 +1060,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
for arg in wraptuple(get(plotattributes, :fill, ()))
processFillArg(plotattributes, arg)
end
RecipesPipeline.reset_kw!(plotattributes, :fill)
reset_kw!(plotattributes, :fill)
# handle series annotations
if haskey(plotattributes, :series_annotations)
@@ -1143,26 +1119,20 @@ function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes)
empty!(_to_warn)
bend = backend_name(pkg)
already_warned = get!(_already_warned, bend, Set{Symbol}())
extra_kwargs = Dict{Symbol,Any}()
for k in keys(plotattributes)
is_attr_supported(pkg, k) && continue
k in _suppress_warnings && continue
default_value = default(k)
if ismissing(default_value)
extra_kwargs[k] = pop_kw!(plotattributes, k)
elseif plotattributes[k] != default(k)
if plotattributes[k] != default(k)
k in already_warned || push!(_to_warn, k)
end
end
if !isempty(_to_warn) &&
!get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported])
if !isempty(_to_warn)
for k in sort(collect(_to_warn))
push!(already_warned, k)
@warn("Keyword argument $k not supported with $pkg. Choose from: $(supported_attrs(pkg))")
end
end
return extra_kwargs
end
# _markershape_supported(pkg::AbstractBackend, shape::Symbol) = shape in supported_markers(pkg)
@@ -1170,9 +1140,6 @@ end
# _markershape_supported(pkg::AbstractBackend, shapes::AVec) = all([_markershape_supported(pkg, shape) for shape in shapes])
function warn_on_unsupported(pkg::AbstractBackend, plotattributes)
if !get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported])
return
end
if !is_seriestype_supported(pkg, plotattributes[:seriestype])
@warn("seriestype $(plotattributes[:seriestype]) is unsupported with $pkg. Choose from: $(supported_seriestypes(pkg))")
end
@@ -1185,9 +1152,6 @@ function warn_on_unsupported(pkg::AbstractBackend, plotattributes)
end
function warn_on_unsupported_scales(pkg::AbstractBackend, plotattributes::AKW)
if !get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported])
return
end
for k in (:xscale, :yscale, :zscale, :scale)
if haskey(plotattributes, k)
v = plotattributes[k]
@@ -1245,7 +1209,7 @@ function slice_arg!(plotattributes_in, plotattributes_out,
v
end
if remove_pair
RecipesPipeline.reset_kw!(plotattributes_in, k)
reset_kw!(plotattributes_in, k)
end
return
end
@@ -1429,7 +1393,8 @@ end
function _update_subplot_colors(sp::Subplot)
# background colors
color_or_nothing!(sp.attr, :background_color_subplot)
sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], 30)
bg = plot_color(sp[:background_color_subplot])
sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], bg, 30)
color_or_nothing!(sp.attr, :background_color_legend)
color_or_nothing!(sp.attr, :background_color_inside)
@@ -1505,7 +1470,7 @@ end
# update a subplots args and axes
function _update_subplot_args(plt::Plot, sp::Subplot, plotattributes_in, subplot_index::Int, remove_pair::Bool)
anns = RecipesPipeline.pop_kw!(sp.attr, :annotations)
anns = pop_kw!(sp.attr, :annotations)
# # grab those args which apply to this subplot
for k in keys(_subplot_defaults)
@@ -1532,9 +1497,9 @@ end
# and assigns a color automatically
function get_series_color(c, sp::Subplot, n::Int, seriestype)
if c == :auto
c = like_surface(seriestype) ? cgrad() : _cycle(sp[:color_palette], n)
c = like_surface(seriestype) ? cgrad() : autopick(sp[:color_palette], n)
elseif isa(c, Int)
c = _cycle(sp[:color_palette], c)
c = autopick(sp[:color_palette], c)
end
plot_color(c)
end
@@ -1544,13 +1509,7 @@ function get_series_color(c::AbstractArray, sp::Subplot, n::Int, seriestype)
end
function ensure_gradient!(plotattributes::AKW, csym::Symbol, asym::Symbol)
if plotattributes[csym] isa ColorPalette
α = nothing
if !(plotattributes[asym] isa AbstractVector)
α = plotattributes[asym]
end
plotattributes[csym] = cgrad(plotattributes[csym], categorical = true, alpha = α)
elseif !(plotattributes[csym] isa ColorGradient)
if !isa(plotattributes[csym], ColorGradient)
plotattributes[csym] = typeof(plotattributes[asym]) <: AbstractVector ? cgrad() : cgrad(alpha = plotattributes[asym])
end
end
+47 -29
View File
@@ -35,6 +35,7 @@ end
function process_axis_arg!(plotattributes::AKW, arg, letter = "")
T = typeof(arg)
arg = get(_scaleAliases, arg, arg)
if typeof(arg) <: Font
plotattributes[Symbol(letter,:tickfont)] = arg
plotattributes[Symbol(letter,:guidefont)] = arg
@@ -84,7 +85,7 @@ function attr!(axis::Axis, args...; kw...)
end
# then preprocess keyword arguments
RecipesPipeline.preprocess_attributes!(KW(kw))
preprocess_attributes!(KW(kw))
# then override for any keywords... only those keywords that already exists in plotattributes
for (k,v) in kw
@@ -128,7 +129,7 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
# scale the limits
scale = axis[:scale]
sf = RecipesPipeline.scale_func(scale)
sf = scale_func(scale)
# If the axis input was a Date or DateTime use a special logic to find
# "round" Date(Time)s as ticks
@@ -138,7 +139,7 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
# rather than on the input format
# TODO: maybe: non-trivial scale (:ln, :log2, :log10) for date/datetime
if ticks === nothing && scale == :identity
if axis[:formatter] == RecipesPipeline.dateformatter
if axis[:formatter] == dateformatter
# optimize_datetime_ticks returns ticks and labels(!) based on
# integers/floats corresponding to the DateTime type. Thus, the axes
# limits, which resulted from converting the Date type to integers,
@@ -149,7 +150,7 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
k_min = 2, k_max = 4)
# Now the ticks are converted back to floats corresponding to Dates.
return ticks / 864e5, labels
elseif axis[:formatter] == RecipesPipeline.datetimeformatter
elseif axis[:formatter] == datetimeformatter
return optimize_datetime_ticks(amin, amax; k_min = 2, k_max = 4)
end
end
@@ -173,18 +174,24 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
# chosen ticks is not too much bigger than amin - amax:
strict_span = false,
)
axis[:lims] = map(RecipesPipeline.inverse_scale_func(scale), (viewmin, viewmax))
axis[:lims] = map(inverse_scale_func(scale), (viewmin, viewmax))
else
scaled_ticks = map(sf, (filter(t -> amin <= t <= amax, ticks)))
end
unscaled_ticks = map(RecipesPipeline.inverse_scale_func(scale), scaled_ticks)
unscaled_ticks = map(inverse_scale_func(scale), scaled_ticks)
labels = if any(isfinite, unscaled_ticks)
formatter = axis[:formatter]
if formatter in (:auto, :plain, :scientific, :engineering)
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, formatter))
elseif formatter == :latex
map(x -> string("\$", replace(convert_sci_unicode(x), '×' => "\\times"), "\$"), Showoff.showoff(unscaled_ticks, :auto))
if formatter == :auto
# the default behavior is to make strings of the scaled values and then apply the labelfunc
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :auto))
elseif formatter == :plain
# Leave the numbers in plain format
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :plain))
elseif formatter == :scientific
Showoff.showoff(unscaled_ticks, :scientific)
elseif formatter == :latex
map(x -> string("\$", replace(convert_sci_unicode(x), '×' => "\\times"), "\$"), Showoff.showoff(unscaled_ticks, :auto))
else
# there was an override for the formatter... use that on the unscaled ticks
map(formatter, unscaled_ticks)
@@ -276,7 +283,7 @@ function get_minor_ticks(sp, axis, ticks)
minorticks = typeof(ticks[1])[]
for (i,hi) in enumerate(ticks[2:end])
lo = ticks[i]
if isfinite(lo) && isfinite(hi) && hi > lo
if isfinite(lo) && hi > lo
append!(minorticks,collect(lo + (hi-lo)/n :(hi-lo)/n: hi - (hi-lo)/2n))
end
end
@@ -371,7 +378,7 @@ function expand_extrema!(sp::Subplot, plotattributes::AKW)
if fr === nothing && plotattributes[:seriestype] == :bar
fr = 0.0
end
if fr !== nothing && !RecipesPipeline.is3d(plotattributes)
if fr !== nothing && !is3d(plotattributes)
axis = sp.attr[vert ? :yaxis : :xaxis]
if typeof(fr) <: Tuple
for fri in fr
@@ -416,7 +423,7 @@ end
# push the limits out slightly
function widen(lmin, lmax, scale = :identity)
f, invf = RecipesPipeline.scale_func(scale), RecipesPipeline.inverse_scale_func(scale)
f, invf = scale_func(scale), 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)
@@ -455,12 +462,11 @@ function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(l
lims = axis[:lims]
has_user_lims = (isa(lims, Tuple) || isa(lims, AVec)) && length(lims) == 2
if has_user_lims
lmin, lmax = lims
if lmin != :auto && isfinite(lmin)
amin = lmin
if isfinite(lims[1])
amin = lims[1]
end
if lmax != :auto && isfinite(lmax)
amax = lmax
if isfinite(lims[2])
amax = lims[2]
end
end
if amax <= amin && isfinite(amin)
@@ -486,7 +492,7 @@ function axis_limits(sp, letter, should_widen = default_should_widen(sp[Symbol(l
amin, amax
end
if !has_user_lims && consider_aspect && letter in (:x, :y) && !(sp[:aspect_ratio] in (:none, :auto) || RecipesPipeline.is3d(:sp))
if !has_user_lims && consider_aspect && letter in (:x, :y) && !(sp[:aspect_ratio] in (:none, :auto) || is3d(:sp))
aspect_ratio = isa(sp[:aspect_ratio], Number) ? sp[:aspect_ratio] : 1
plot_ratio = height(plotarea(sp)) / width(plotarea(sp))
dist = amax - amin
@@ -569,6 +575,18 @@ end
# -------------------------------------------------------------------------
function pie_labels(sp::Subplot, series::Series)
plotattributes = series.plotattributes
if haskey(plotattributes,:x_discrete_indices)
dvals = sp.attr[:xaxis].plotattributes[:discrete_values]
[dvals[idx] for idx in plotattributes[:x_discrete_indices]]
else
plotattributes[:x]
end
end
# -------------------------------------------------------------------------
# compute the line segments which should be drawn for this axis
function axis_drawing_info(sp::Subplot)
xaxis, yaxis = sp[:xaxis], sp[:yaxis]
@@ -608,8 +626,8 @@ function axis_drawing_info(sp::Subplot)
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2), (xmax, y2)) # top spine
end
if !(xaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(yaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(yaxis[:scale])
f = scale_func(yaxis[:scale])
invf = inverse_scale_func(yaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
(-t, t)
@@ -662,8 +680,8 @@ function axis_drawing_info(sp::Subplot)
sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (x2, ymin), (x2, ymax)) # right spine
end
if !(yaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(xaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(xaxis[:scale])
f = scale_func(xaxis[:scale])
invf = inverse_scale_func(xaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(xmax) - f(xmin)))
(-t, t)
@@ -754,8 +772,8 @@ function axis_drawing_info_3d(sp::Subplot)
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2, z2), (xmax, y2, z2)) # top spine
end
if !(xaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(yaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(yaxis[:scale])
f = scale_func(yaxis[:scale])
invf = inverse_scale_func(yaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
(-t, t)
@@ -829,8 +847,8 @@ function axis_drawing_info_3d(sp::Subplot)
sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (x2, ymin, z2), (x2, ymax, z2)) # right spine
end
if !(yaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(xaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(xaxis[:scale])
f = scale_func(xaxis[:scale])
invf = inverse_scale_func(xaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(xmax) - f(xmin)))
(-t, t)
@@ -904,8 +922,8 @@ function axis_drawing_info_3d(sp::Subplot)
sp[:framestyle] in (:semi, :box) && push!(zborder_segs, (x2, y2, zmin), (x2, y2, zmax))
end
if !(zaxis[:ticks] in (:none, nothing, false))
f = RecipesPipeline.scale_func(xaxis[:scale])
invf = RecipesPipeline.inverse_scale_func(xaxis[:scale])
f = scale_func(xaxis[:scale])
invf = inverse_scale_func(xaxis[:scale])
tick_start, tick_stop = if sp[:framestyle] == :origin
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
(-t, t)
+30 -92
View File
@@ -1,3 +1,5 @@
using Pkg
struct NoBackend <: AbstractBackend end
const _backendType = Dict{Symbol, DataType}(:none => NoBackend)
@@ -28,7 +30,7 @@ macro init_backend(s)
esc(quote
struct $T <: AbstractBackend end
export $sym
$sym(; kw...) = (default(; reset = false, kw...); backend($T()))
$sym(; kw...) = (default(; kw...); backend($T()))
backend_name(::$T) = Symbol($str)
backend_package_name(pkg::$T) = backend_package_name(Symbol($str))
push!(_backends, Symbol($str))
@@ -102,7 +104,7 @@ end
# Set the (left, top, right, bottom) minimum padding around the plot area
# to fit ticks, tick labels, guides, colorbars, etc.
function _update_min_padding!(sp::Subplot)
# TODO: something different when `RecipesPipeline.is3d(sp) == true`
# TODO: something different when `is3d(sp) == true`
leftpad = tick_padding(sp, sp[:yaxis]) + sp[:left_margin] + guide_padding(sp[:yaxis])
toppad = sp[:top_margin] + title_padding(sp)
rightpad = sp[:right_margin]
@@ -188,15 +190,11 @@ function backend(sym::Symbol)
end
end
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize, :pgfplots]
const _deprecated_backends = [:qwt, :winston, :bokeh, :gadfly, :immerse, :glvisualize]
function warn_on_deprecated_backend(bsym::Symbol)
if bsym in _deprecated_backends
if bsym == :pgfplots
@warn("Backend $bsym has been deprecated. Use pgfplotsx instead.")
else
@warn("Backend $bsym has been deprecated.")
end
@warn("Backend $bsym has been deprecated.")
end
end
@@ -213,7 +211,7 @@ const _base_supported_args = [
:seriestype,
:seriescolor, :seriesalpha,
:smooth,
:xerror, :yerror, :zerror,
:xerror, :yerror,
:subplot,
:x, :y, :z,
:show, :size,
@@ -343,18 +341,10 @@ const _gr_attr = merge_with_base_supported([
:contour_labels,
])
const _gr_seriestype = [
:path,
:scatter,
:straightline,
:heatmap,
:image,
:contour,
:path3d,
:scatter3d,
:surface,
:wireframe,
:volume,
:shape,
:path, :scatter, :straightline,
:heatmap, :pie, :image,
:contour, :path3d, :scatter3d, :surface, :wireframe, :volume,
:shape
]
const _gr_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
const _gr_marker = _allMarkers
@@ -388,7 +378,7 @@ const _plotly_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :markerstrokestyle,
:fillrange, :fillcolor, :fillalpha,
:bins,
:title, :titlelocation,
:title, :title_location,
:titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign,
:titlefontcolor,
:legendfontfamily, :legendfontsize, :legendfontcolor,
@@ -418,17 +408,9 @@ const _plotly_attr = merge_with_base_supported([
])
const _plotly_seriestype = [
:path,
:scatter,
:heatmap,
:contour,
:surface,
:wireframe,
:path3d,
:scatter3d,
:shape,
:scattergl,
:straightline,
:path, :scatter, :pie, :heatmap,
:contour, :surface, :wireframe, :path3d, :scatter3d, :shape, :scattergl,
:straightline
]
const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot]
const _plotly_marker = [
@@ -523,7 +505,7 @@ const _pyplot_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
:fillrange, :fillcolor, :fillalpha,
:bins, :bar_width, :bar_edges, :bar_position,
:title, :titlelocation, :titlefont,
:title, :title_location, :titlefont,
:window_title,
:guide, :guide_position, :lims, :ticks, :scale, :flip, :rotation,
:titlefontfamily, :titlefontsize, :titlefontcolor,
@@ -551,22 +533,12 @@ const _pyplot_attr = merge_with_base_supported([
:contour_labels,
])
const _pyplot_seriestype = [
:path,
:steppre,
:steppost,
:shape,
:straightline,
:scatter,
:hexbin,
:heatmap,
:image,
:contour,
:contour3d,
:path3d,
:scatter3d,
:surface,
:wireframe,
]
:path, :steppre, :steppost, :shape, :straightline,
:scatter, :hexbin, #:histogram2d, :histogram,
# :bar,
:heatmap, :pie, :image,
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
]
const _pyplot_style = [:auto, :solid, :dash, :dot, :dashdot]
const _pyplot_marker = vcat(_allMarkers, :pixel)
const _pyplot_scale = [:identity, :ln, :log2, :log10]
@@ -596,9 +568,6 @@ const _unicodeplots_style = [:auto, :solid]
const _unicodeplots_marker = [:none, :auto, :circle]
const _unicodeplots_scale = [:identity]
# Additional constants
const _canvas_type = Ref(:auto)
# ------------------------------------------------------------------------------
# hdf5
@@ -613,7 +582,7 @@ const _hdf5_attr = merge_with_base_supported([
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
:fillrange, :fillcolor, :fillalpha,
:bins, :bar_width, :bar_edges, :bar_position,
:title, :titlelocation, :titlefont,
:title, :title_location, :titlefont,
:window_title,
:guide, :lims, :ticks, :scale, :flip, :rotation,
:tickfont, :guidefont, :legendfont,
@@ -633,43 +602,16 @@ const _hdf5_attr = merge_with_base_supported([
:colorbar_title,
])
const _hdf5_seriestype = [
:path,
:steppre,
:steppost,
:shape,
:straightline,
:scatter,
:hexbin,
:heatmap,
:image,
:contour,
:contour3d,
:path3d,
:scatter3d,
:surface,
:wireframe,
]
:path, :steppre, :steppost, :shape, :straightline,
:scatter, :hexbin, #:histogram2d, :histogram,
# :bar,
:heatmap, :pie, :image,
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
]
const _hdf5_style = [:auto, :solid, :dash, :dot, :dashdot]
const _hdf5_marker = vcat(_allMarkers, :pixel)
const _hdf5_scale = [:identity, :ln, :log2, :log10]
# Additional constants
#Dict has problems using "Types" as keys. Initialize in "_initialize_backend":
const HDF5PLOT_MAP_STR2TELEM = Dict{String, Type}()
const HDF5PLOT_MAP_TELEM2STR = Dict{Type, String}()
#Don't really like this global variable... Very hacky
mutable struct HDF5Plot_PlotRef
ref::Union{Plot, Nothing}
end
const HDF5PLOT_PLOTREF = HDF5Plot_PlotRef(nothing)
#Simple sub-structures that can just be written out using _hdf5plot_gwritefields:
const HDF5PLOT_SIMPLESUBSTRUCT = Union{Font, BoundingBox,
GridLayout, RootLayout, ColorGradient, SeriesAnnotations, PlotText,
Shape,
}
# ------------------------------------------------------------------------------
# inspectdr
@@ -687,7 +629,7 @@ const _inspectdr_attr = merge_with_base_supported([
:markerstrokestyle, #Causes warning not to have it... what is this?
:fillcolor, :fillalpha, #:fillrange,
# :bins, :bar_width, :bar_edges, :bar_position,
:title, :titlelocation,
:title, :title_location,
:window_title,
:guide, :lims, :scale, #:ticks, :flip, :rotation,
:titlefontfamily, :titlefontsize, :titlefontcolor,
@@ -830,7 +772,6 @@ const _pgfplotsx_seriestype = [
:heatmap,
:contour,
:contour3d,
:quiver,
:shape,
:steppre,
:stepmid,
@@ -859,6 +800,3 @@ const _pgfplotsx_marker = [
]
const _pgfplotsx_scale = [:identity, :ln, :log2, :log10]
is_marker_supported(::PGFPlotsXBackend, shape::Shape) = true
# additional constants
const _pgfplotsx_series_ids = KW()
+366 -374
View File
File diff suppressed because it is too large Load Diff
+43 -16
View File
@@ -37,6 +37,33 @@ import FixedPointNumbers: N0f8 #In core Julia
struct HDF5PlotNative; end #Indentifies a data element that can natively be handled by HDF5
struct HDF5CTuple; end #Identifies a "complex" tuple structure
mutable struct HDF5Plot_PlotRef
ref::Union{Plot, Nothing}
end
#==Useful constants
===============================================================================#
const _hdf5_nullable{T} = Union{T, Nothing}
const _hdf5_plotroot = "plot"
const _hdf5_dataroot = "data" #TODO: Eventually move data to different root (easier to locate)?
const _hdf5plot_datatypeid = "TYPE" #Attribute identifying type
const _hdf5plot_countid = "COUNT" #Attribute for storing count
#Dict has problems using "Types" as keys. Initialize in "_initialize_backend":
const HDF5PLOT_MAP_STR2TELEM = Dict{String, Type}()
const HDF5PLOT_MAP_TELEM2STR = Dict{Type, String}()
#Don't really like this global variable... Very hacky
const HDF5PLOT_PLOTREF = HDF5Plot_PlotRef(nothing)
#Simple sub-structures that can just be written out using _hdf5plot_gwritefields:
const HDF5PLOT_SIMPLESUBSTRUCT = Union{Font, BoundingBox,
GridLayout, RootLayout, ColorGradient, SeriesAnnotations, PlotText,
Shape,
}
#==
===============================================================================#
is_marker_supported(::HDF5Backend, shape::Shape) = true
@@ -68,7 +95,7 @@ if length(HDF5PLOT_MAP_TELEM2STR) < 1
"AXIS" => Axis,
"SURFACE" => Surface,
"SUBPLOT" => Subplot,
"NULLABLE" => Union{Nothing, T} where T,
"NULLABLE" => _hdf5_nullable,
)
merge!(HDF5PLOT_MAP_STR2TELEM, telem2str)
merge!(HDF5PLOT_MAP_TELEM2STR, Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM))
@@ -78,8 +105,8 @@ end
#==Helper functions
===============================================================================#
_hdf5_plotelempath(subpath::String) = "plot/$subpath"
_hdf5_datapath(subpath::String) = "data/$subpath"
_hdf5_plotelempath(subpath::String) = "$_hdf5_plotroot/$subpath"
_hdf5_datapath(subpath::String) = "$_hdf5_dataroot/$subpath"
_hdf5_map_str2telem(k::String) = HDF5PLOT_MAP_STR2TELEM[k]
_hdf5_map_str2telem(v::Vector) = HDF5PLOT_MAP_STR2TELEM[v[1]]
@@ -174,38 +201,38 @@ end
function _hdf5plot_writetype(grp, k::String, tstr::Array{String})
d = HDF5.d_open(grp, k)
HDF5.a_write(d, "TYPE", tstr)
HDF5.a_write(d, _hdf5plot_datatypeid, tstr)
end
function _hdf5plot_writetype(grp, k::String, T::Type)
tstr = HDF5PLOT_MAP_TELEM2STR[T]
d = HDF5.d_open(grp, k)
HDF5.a_write(d, "TYPE", tstr)
HDF5.a_write(d, _hdf5plot_datatypeid, tstr)
end
function _hdf5plot_overwritetype(grp, k::String, T::Type)
tstr = HDF5PLOT_MAP_TELEM2STR[T]
d = HDF5.d_open(grp, k)
HDF5.a_delete(d, "TYPE")
HDF5.a_write(d, "TYPE", tstr)
HDF5.a_delete(d, _hdf5plot_datatypeid)
HDF5.a_write(d, _hdf5plot_datatypeid, tstr)
end
function _hdf5plot_writetype(grp, T::Type) #Write directly to group
tstr = HDF5PLOT_MAP_TELEM2STR[T]
HDF5.a_write(grp, "TYPE", tstr)
HDF5.a_write(grp, _hdf5plot_datatypeid, tstr)
end
function _hdf5plot_overwritetype(grp, T::Type) #Write directly to group
tstr = HDF5PLOT_MAP_TELEM2STR[T]
HDF5.a_delete(grp, "TYPE")
HDF5.a_write(grp, "TYPE", tstr)
HDF5.a_delete(grp, _hdf5plot_datatypeid)
HDF5.a_write(grp, _hdf5plot_datatypeid, tstr)
end
function _hdf5plot_writetype(grp, ::Type{Array{T}}) where T<:Any
tstr = HDF5PLOT_MAP_TELEM2STR[Array] #ANY
HDF5.a_write(grp, "TYPE", tstr)
HDF5.a_write(grp, _hdf5plot_datatypeid, tstr)
end
function _hdf5plot_writetype(grp, ::Type{T}) where T<:BoundingBox
tstr = HDF5PLOT_MAP_TELEM2STR[BoundingBox]
HDF5.a_write(grp, "TYPE", tstr)
HDF5.a_write(grp, _hdf5plot_datatypeid, tstr)
end
function _hdf5plot_writecount(grp, n::Int) #Write directly to group
HDF5.a_write(grp, "COUNT", n)
HDF5.a_write(grp, _hdf5plot_countid, n)
end
function _hdf5plot_gwritefields(grp, k::String, v)
grp = HDF5.g_create(grp, k)
@@ -345,7 +372,7 @@ function _hdf5plot_gwrite(grp, k::String, v::Surface)
_hdf5plot_writetype(grp, Surface)
end
# #TODO: "Properly" support Nullable using _hdf5plot_writetype?
# function _hdf5plot_gwrite(grp, k::String, v::Union{Nothing, T} where T)
# function _hdf5plot_gwrite(grp, k::String, v::_hdf5_nullable)
# if isnull(v)
# _hdf5plot_gwrite(grp, k, nothing)
# else
@@ -421,7 +448,7 @@ hdf5plot_write(path::AbstractString) = hdf5plot_write(current(), path)
===============================================================================#
function _hdf5plot_readcount(grp) #Read directly from group
return HDF5.a_read(grp, "COUNT")
return HDF5.a_read(grp, _hdf5plot_countid)
end
_hdf5plot_convert(T::Type{HDF5PlotNative}, v) = v
@@ -562,7 +589,7 @@ function _hdf5plot_read(grp, k::String, T::Type{Length}, dtid::Vector)
return Length{TU,T}(v)
end
function _hdf5plot_read(grp, k::String)
dtid = HDF5.a_read(grp[k], "TYPE")
dtid = HDF5.a_read(grp[k], _hdf5plot_datatypeid)
T = _hdf5_map_str2telem(dtid) #expect exception
return _hdf5plot_read(grp, k, T, dtid)
end
+16 -10
View File
@@ -429,23 +429,29 @@ end
# ----------------------------------------------------------------
const _inspectdr_mimeformats_dpi = Dict(
"image/png" => "png"
)
const _inspectdr_mimeformats_nodpi = Dict(
"image/svg+xml" => "svg",
"application/eps" => "eps",
"image/eps" => "eps",
# "application/postscript" => "ps", #TODO: support once Cairo supports PSSurface
"application/pdf" => "pdf"
)
_inspectdr_show(io::IO, mime::MIME, ::Nothing, w, h) =
throw(ErrorException("Cannot show(::IO, ...) plot - not yet generated"))
function _inspectdr_show(io::IO, mime::MIME, mplot, w, h)
InspectDR._show(io, mime, mplot, Float64(w), Float64(h))
end
function _show(io::IO, mime::MIME{Symbol("image/png")}, plt::Plot{InspectDRBackend})
dpi = plt[:dpi] # TODO: support
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
for (mime, fmt) in _inspectdr_mimeformats_dpi
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend})
dpi = plt[:dpi]#TODO: support
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
end
end
for (mime, fmt) in (
"image/svg+xml" => "svg",
"application/eps" => "eps",
"image/eps" => "eps",
# "application/postscript" => "ps", # TODO: support once Cairo supports PSSurface
"application/pdf" => "pdf",
)
for (mime, fmt) in _inspectdr_mimeformats_nodpi
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend})
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
end
+7 -6
View File
@@ -12,12 +12,13 @@ function plotlybase_syncplot(plt::Plot)
return plt.o
end
for (mime, fmt) in (
const _orca_mimeformats = Dict(
"application/pdf" => "pdf",
"image/png" => "png",
"image/svg+xml" => "svg",
"image/eps" => "eps",
"image/png" => "png",
"image/svg+xml" => "svg",
"image/eps" => "eps",
)
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyBackend}) =
ORCA.PlotlyBase.savefig(io, plotlybase_syncplot(plt), format = $fmt)
for (mime, fmt) in _orca_mimeformats
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyBackend}) = ORCA.PlotlyBase.savefig(io, plotlybase_syncplot(plt), format = $fmt)
end
@@ -166,7 +166,7 @@ function pgf_series(sp::Subplot, series::Series)
# function args
args = if st == :contour
plotattributes[:z].surf, plotattributes[:x], plotattributes[:y]
elseif RecipesPipeline.is3d(st)
elseif is3d(st)
plotattributes[:x], plotattributes[:y], plotattributes[:z]
elseif st == :straightline
straightline_data(series)
@@ -271,7 +271,7 @@ function pgf_fillrange_series(series, i, fillrange, args...)
push!(style, _pgf_series_extrastyle[st])
end
kw[:style] = join(style, ',')
func = RecipesPipeline.is3d(series) ? PGFPlots.Linear3 : PGFPlots.Linear
func = is3d(series) ? PGFPlots.Linear3 : PGFPlots.Linear
return func(pgf_fillrange_args(fillrange, args...)...; kw...)
end
@@ -444,7 +444,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
# add to style/kw for each axis
for letter in (:x, :y, :z)
if letter != :z || RecipesPipeline.is3d(sp)
if letter != :z || is3d(sp)
axisstyle, axiskw = pgf_axis(sp, letter)
append!(style, axisstyle)
merge!(kw, axiskw)
@@ -494,7 +494,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
if any(s[:seriestype] == :contour for s in series_list(sp))
kw[:view] = "{0}{90}"
kw[:colorbar] = !(sp[:colorbar] in (:none, :off, :hide, false))
elseif RecipesPipeline.is3d(sp)
elseif is3d(sp)
azim, elev = sp[:camera]
kw[:view] = "{$(azim)}{$(elev)}"
end
+180 -296
View File
@@ -86,16 +86,7 @@ end
function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
if !pgfx_plot.is_created || pgfx_plot.was_shown
pgfx_sanitize_plot!(plt)
# extract extra kwargs
extra_plot_opt = plt[:extra_plot_kwargs]
extra_plot = nothing
if haskey(extra_plot_opt, :add)
extra_plot = wraptuple(pop!(extra_plot_opt,:add))
end
the_plot = PGFPlotsX.TikzPicture(PGFPlotsX.Options(extra_plot_opt...))
if extra_plot !== nothing
push!(the_plot, extra_plot...)
end
the_plot = PGFPlotsX.TikzPicture(PGFPlotsX.Options())
bgc = plt.attr[:background_color_outside] == :match ?
plt.attr[:background_color] : plt.attr[:background_color_outside]
if bgc isa Colors.Colorant
@@ -113,35 +104,34 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
end
for sp in plt.subplots
bb1 = sp.plotarea
bb2 = bbox(sp)
sp_width = width(bb2)
sp_height = height(bb2)
dx, dy = bb2.x0
lpad = leftpad(sp) + sp[:left_margin]
rpad = rightpad(sp) + sp[:right_margin]
tpad = toppad(sp) + sp[:top_margin]
bpad = bottompad(sp) + sp[:bottom_margin]
dx += lpad
dy += tpad
axis_height = sp_height - (tpad + bpad)
axis_width = sp_width - (rpad + lpad)
bb = bbox(sp)
sp_width = width(bb)
sp_height = height(bb)
dx, dy = bb.x0
# TODO: does this hold at every scale?
if sp[:legend] in (:outertopright, nothing)
dx *= 1.2
end
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]
title_loc = sp[:title_location]
bgc_inside = plot_color(sp[:background_color_inside])
bgc_inside_a = alpha(bgc_inside)
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)...,
"at" => if title_loc == :left
"{(0,1)}"
elseif title_loc == :right
"{(1,1)}"
elseif title_loc isa Tuple
"{$(string(title_loc))}"
else
"{(0.5,1)}"
end,
"font" => pgfx_font(
sp[:titlefontsize],
pgfx_thickness_scaling(sp),
@@ -174,14 +164,23 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
"xshift" => string(dx),
"yshift" => string(-dy),
)
sp_width > 0 * mm ? push!(axis_opt, "width" => string(axis_width)) :
sp_width > 0 * mm ? push!(axis_opt, "width" => string(sp_width)) :
nothing
sp_height > 0 * mm ? push!(axis_opt, "height" => string(axis_height)) :
sp_height > 0 * mm ? push!(axis_opt, "height" => string(sp_height)) :
nothing
# legend position
push!(axis_opt["legend style"], pgfx_get_legend_pos(sp[:legend])...)
if sp[:legend] isa Tuple
x, y = sp[:legend]
push!(axis_opt["legend style"], "at={($x, $y)}")
else
push!(
axis_opt,
"legend pos" =>
get(_pgfplotsx_legend_pos, sp[:legend], "outer north east"),
)
end
for letter in (:x, :y, :z)
if letter != :z || RecipesPipeline.is3d(sp)
if letter != :z || is3d(sp)
pgfx_axis!(axis_opt, sp, letter)
end
end
@@ -196,49 +195,35 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
# As it is likely that all series within the same axis use the same
# colormap this should not cause any problem.
for series in series_list(sp)
if hascolorbar(series)
cg = get_colorgradient(series)
cm = pgfx_colormap(get_colorgradient(series))
PGFPlotsX.push_preamble!(
pgfx_plot.the_plot,
"""\\pgfplotsset{
colormap={plots$(sp.attr[:subplot_index])}{$cm},
}""",
)
push!(axis_opt, "colormap name" => "plots$(sp.attr[:subplot_index])")
if cg isa PlotUtils.CategoricalColorGradient
for col in (:markercolor, :fillcolor, :linecolor)
if typeof(series.plotattributes[col]) == ColorGradient
PGFPlotsX.push_preamble!(
pgfx_plot.the_plot,
"""\\pgfplotsset{
colormap={plots$(sp.attr[:subplot_index])}{$(pgfx_colormap(series.plotattributes[col]))},
}""",
)
push!(
axis_opt,
"colormap access" => "piecewise const",
"colorbar sampled" => nothing,
"colorbar" => nothing,
"colormap name" => "plots$(sp.attr[:subplot_index])",
)
# goto is needed to break out of col and series for
@goto colorbar_end
end
# goto is needed to break out of col and series for
@goto colorbar_end
end
end
@label colorbar_end
if hascolorbar(sp)
colorbar_style = PGFPlotsX.Options(
push!(
axis_opt,
"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",
"xticklabel pos" => "upper",
)
end
push!(
axis_opt,
string("colorbar", pgfx_get_colorbar_pos(sp[:colorbar])) => nothing,
"colorbar style" => colorbar_style,
)
end
if RecipesPipeline.is3d(sp)
"point meta max" => get_clims(sp)[2],
"point meta min" => get_clims(sp)[1],
),
)
if is3d(sp)
azim, elev = sp[:camera]
push!(axis_opt, "view" => (azim, elev))
end
@@ -249,25 +234,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
else
PGFPlotsX.Axis
end
extra_sp_opt = sp[:extra_kwargs]
extra_sp = nothing
if haskey(extra_sp_opt, :add)
extra_sp = wraptuple(pop!(extra_sp_opt,:add))
end
axis = axisf(merge(axis_opt, PGFPlotsX.Options(extra_sp_opt...)))
if extra_sp !== nothing
push!(axis, extra_sp...)
end
if sp[:legendtitle] !== nothing
push!(axis, PGFPlotsX.Options("\\addlegendimage{empty legend}" => nothing))
push!(
axis,
PGFPlotsX.LegendEntry(
string("\\hspace{-.6cm}{\\textbf{", sp[:legendtitle], "}}"),
false,
),
)
end
axis = axisf(axis_opt)
for (series_index, series) in enumerate(series_list(sp))
# give each series a uuid for fillbetween
series_id = uuid4()
@@ -279,13 +246,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
"color" => single_color(opt[:linecolor]),
"name path" => string(series_id),
)
extra_series_opt = series[:extra_kwargs]
extra_series = nothing
if haskey(extra_series_opt, :add)
extra_series = wraptuple(pop!(extra_series_opt,:add))
end
series_opt = merge(series_opt, PGFPlotsX.Options(extra_series_opt...))
if RecipesPipeline.is3d(series) || st in (:heatmap, :contour)
if is3d(series) || st == :heatmap
series_func = PGFPlotsX.Plot3
else
series_func = PGFPlotsX.Plot
@@ -294,7 +255,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
!isfilledcontour(series) && series[:ribbon] === nothing
push!(series_opt, "area legend" => nothing)
end
if st in (:heatmap, :contour)
if st == :heatmap
push!(axis.options, "view" => "{0}{90}")
end
# treat segments
@@ -339,13 +300,12 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
end
segment_opt = merge(segment_opt, pgfx_marker(opt, i))
end
if st == :shape
if st == :shape || isfilledcontour(series)
segment_opt = merge(segment_opt, pgfx_fillstyle(opt, i))
end
# add fillrange
if sf !== nothing &&
!isfilledcontour(series) &&
series[:ribbon] === nothing
!isfilledcontour(series) && series[:ribbon] === nothing
if sf isa Number || sf isa AVec
pgfx_fillrange_series!(
axis,
@@ -365,9 +325,6 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
pgfx_series_coordinates!(sp, series, segment_opt, opt, rng)
segment_plot =
series_func(merge(series_opt, segment_opt), coordinates)
if extra_series !== nothing
push!(segment_plot, extra_series...)
end
push!(axis, segment_plot)
# fill between functions
if sf isa Tuple && series[:ribbon] === nothing
@@ -395,6 +352,17 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
series_index,
)
end
# add series annotations
anns = series[:series_annotations]
for (xi, yi, str, fnt) in EachAnn(anns, series[:x], series[:y])
pgfx_add_annotation!(
axis,
xi,
yi,
PlotText(str, fnt),
pgfx_thickness_scaling(series),
)
end
# add to legend?
if sp[:legend] != :none
leg_entry = if opt[:label] isa AVec
@@ -420,26 +388,15 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
end
end
end # for segments
# add series annotations
anns = series[:series_annotations]
for (xi, yi, str, fnt) in EachAnn(anns, series[:x], series[:y])
# add subplot annotations
for ann in sp[:annotations]
pgfx_add_annotation!(
axis,
xi,
yi,
PlotText(str, fnt),
pgfx_thickness_scaling(series),
locate_annotation(sp, ann...)...,
pgfx_thickness_scaling(sp),
)
end
end # for series
# add subplot annotations
for ann in sp[:annotations]
pgfx_add_annotation!(
axis,
locate_annotation(sp, ann...)...,
pgfx_thickness_scaling(sp),
)
end
push!(the_plot, axis)
if length(plt.o.the_plot.elements) > 0
plt.o.the_plot.elements[1] = the_plot
@@ -448,7 +405,6 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
end
end # for subplots
pgfx_plot.is_created = true
pgfx_plot.was_shown = false
end # if
return pgfx_plot
end
@@ -460,7 +416,7 @@ end
opt[:x], opt[:y], Array(opt[:z])'
elseif st in (:heatmap, :surface, :wireframe)
surface_to_vecs(opt[:x], opt[:y], opt[:z])
elseif RecipesPipeline.is3d(st)
elseif is3d(st)
opt[:x], opt[:y], opt[:z]
elseif st == :straightline
straightline_data(series)
@@ -594,8 +550,8 @@ function pgfx_series_coordinates!(
xs, ys, zs = collect(args)
push!(
segment_opt,
"contour filled" => PGFPlotsX.Options(), # labels not supported
"patch type" => "bilinear",
"contour filled" => PGFPlotsX.Options("labels" => opt[:contour_labels]),
"point meta" => "explicit",
"shader" => "flat",
)
if opt[:levels] isa Number
@@ -604,115 +560,75 @@ function pgfx_series_coordinates!(
push!(segment_opt["contour filled"], "levels" => opt[:levels])
end
PGFPlotsX.Coordinates(args...)
cs = join(
[
join(["($x, $y) [$(zs[j, i])]" for (j, x) in enumerate(xs)], " ") for (i, y) in enumerate(ys)
],
"\n\n",
)
"""
coordinates {
$cs
};
"""
end
##
pgfx_get_linestyle(k) = get(
(
solid = "solid",
dash = "dashed",
dot = "dotted",
dashdot = "dashdotted",
dashdotdot = "dashdotdotted",
),
Symbol(k),
"solid",
const _pgfplotsx_linestyles = KW(
:solid => "solid",
:dash => "dashed",
:dot => "dotted",
:dashdot => "dashdotted",
:dashdotdot => "dashdotdotted",
)
pgfx_get_marker(k) = get(
(
none = "none",
cross = "+",
xcross = "x",
+ = "+",
x = "x",
utriangle = "triangle*",
dtriangle = "triangle*",
rtriangle = "triangle*",
ltriangle = "triangle*",
circle = "*",
rect = "square*",
star5 = "star",
star6 = "asterisk",
diamond = "diamond*",
pentagon = "pentagon*",
hline = "-",
vline = "|",
),
Symbol(k),
"*",
const _pgfplotsx_series_ids = KW()
const _pgfplotsx_markers = KW(
:none => "none",
:cross => "+",
:xcross => "x",
:+ => "+",
:x => "x",
:utriangle => "triangle*",
:dtriangle => "triangle*",
:rtriangle => "triangle*",
:ltriangle => "triangle*",
:circle => "*",
:rect => "square*",
:star5 => "star",
:star6 => "asterisk",
:diamond => "diamond*",
:pentagon => "pentagon*",
:hline => "-",
:vline => "|",
)
pgfx_get_xguide_pos(k) = get(
(
top = "at={(0.5,1)},above,",
right = "at={(ticklabel* cs:1.02)}, anchor=west,",
left = "at={(ticklabel* cs:-0.02)}, anchor=east,",
),
k,
"at={(ticklabel cs:0.5)}, anchor=near ticklabel"
const _pgfplotsx_legend_pos = KW(
:top => "north",
:bottom => "south",
:left => "west",
:right => "east",
:bottomleft => "south west",
:bottomright => "south east",
:topright => "north east",
:topleft => "north west",
:outertop => "north",
:outerbottom => "outer south",
:outerleft => "outer west",
:outerright => "outer east",
:outerbottomleft => "outer south west",
:outerbottomright => "outer south east",
:outertopright => "outer north east",
:outertopleft => "outer north west",
)
pgfx_get_yguide_pos(k) = get(
(
top = "at={(ticklabel* cs:1.02)}, anchor=south",
right = "at={(1,0.5)},below,",
bottom = "at={(ticklabel* cs:-0.02)}, anchor=north,",
),
k,
"at={(ticklabel cs:0.5)}, anchor=near ticklabel"
)
pgfx_get_legend_pos(k) = get(
(
top = ("at" => string((0.5, 0.98)), "anchor" => "north"),
bottom = ("at" => string((0.5, 0.02)), "anchor" => "south"),
left = ("at" => string((0.02, 0.5)), "anchor" => "west"),
right = ("at" => string((0.98, 0.5)), "anchor" => "east"),
bottomleft = ("at" => string((0.02, 0.02)), "anchor" => "south west"),
bottomright = ("at" => string((0.98, 0.02)), "anchor" => "south east"),
topright = ("at" => string((0.98, 0.98)), "anchor" => "north east"),
topleft = ("at" => string((0.02, 0.98)), "anchor" => "north west"),
outertop = ("at" => string((0.5, 1.02)), "anchor" => "south"),
outerbottom = ("at" => string((0.5, -0.02)), "anchor" => "north"),
outerleft = ("at" => string((-0.02, 0.5)), "anchor" => "east"),
outerright = ("at" => string((1.02, 0.5)), "anchor" => "west"),
outerbottomleft = ("at" => string((-0.02, -0.02)), "anchor" => "north east"),
outerbottomright = ("at" => string((1.02, -0.02)), "anchor" => "north west"),
outertopright = ("at" => string((1.02, 1)), "anchor" => "north west"),
outertopleft = ("at" => string((-0.02, 1)), "anchor" => "north east"),
),
Symbol(k),
("at" => string((1.02, 1)), "anchor" => "north west"),
)
pgfx_get_legend_pos(t::Tuple) = ("at" => "{$(string(t))}", "anchor" => "north west")
pgfx_get_legend_pos(nt::NamedTuple) = ("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
pgfx_get_colorbar_pos(s) =
get((left = " left", bottom = " horizontal", top = " horizontal"), s, "")
pgfx_get_colorbar_pos(b::Bool) = ""
pgfx_get_title_pos(s) =
get((
left = ("at" => "{(0,1)}", "anchor" => "south west"),
right = ("at" => "{(1,1)}", "anchor" => "south east"),
), s,
("at" => "{(0.5,1)}", "anchor" => "south"))
pgfx_get_title_pos(t::Tuple) = ("at" => "{$(string(t))}", "anchor" => "south")
pgfx_get_title_pos(nt::NamedTuple) = ("at" => "{$(string(nt.at))}", "anchor" => string(nt.anchor))
function pgfx_get_ticklabel_style(sp, axis)
cstr = plot_color(axis[:tickfontcolor])
return PGFPlotsX.Options(
"font" => pgfx_font(
axis[:tickfontsize], pgfx_thickness_scaling(sp)
),
"color" => cstr,
"draw opacity" => alpha(cstr),
"rotate" => axis[:tickfontrotation],
)
end
const _pgfx_framestyles = [:box, :axes, :origin, :zerolines, :grid, :none]
const _pgfx_framestyle_defaults = Dict(:semi => :box)
# we use the anchors to define orientations for example to align left
# one needs to use the right edge as anchor
const _pgfx_annotation_halign =
KW(:center => "", :left => "right", :right => "left")
## --------------------------------------------------------------------------------------
# Generates a colormap for pgfplots based on a ColorGradient
pgfx_arrow(::Nothing) = "every arrow/.append style={-}"
@@ -745,24 +661,22 @@ function pgfx_filllegend!(series_opt, opt)
}""")
end
pgfx_colormap(cl::PlotUtils.AbstractColorList) = pgfx_colormap(color_list(cl))
function pgfx_colormap(v::Vector{<:Colorant})
join(map(v) do c
function pgfx_colormap(grad::ColorGradient)
join(map(grad.colors) do c
@sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c), blue(c))
end, "\n")
end
function pgfx_colormap(cg::ColorGradient)
join(map(1:length(cg)) do i
@sprintf("rgb(%.8fcm)=(%.8f,%.8f,%.8f)", cg.values[i], red(cg.colors[i]), green(cg.colors[i]), blue(cg.colors[i]))
function pgfx_colormap(grad::Vector{<:Colorant})
join(map(grad) do c
@sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c), blue(c))
end, "\n")
end
function pgfx_framestyle(style::Symbol)
if style in (:box, :axes, :origin, :zerolines, :grid, :none)
if style in _pgfx_framestyles
return style
else
default_style = get((semi = :box,), style, :axes)
default_style = get(_pgfx_framestyle_defaults, style, :axes)
@warn( "Framestyle :$style is not (yet) supported by the PGFPlotsX backend. :$default_style was cosen instead.",)
default_style
end
@@ -781,14 +695,14 @@ function pgfx_fillstyle(plotattributes, i = 1)
PGFPlotsX.Options("fill" => cstr, "fill opacity" => a)
end
function pgfx_linestyle(linewidth::Real, color, α = 1, linestyle = :solid)
function pgfx_linestyle(linewidth::Real, color, α = 1, linestyle = "solid")
cstr = plot_color(color, α)
a = alpha(cstr)
return PGFPlotsX.Options(
"color" => cstr,
"draw opacity" => a,
"line width" => linewidth,
pgfx_get_linestyle(linestyle) => nothing,
get(_pgfplotsx_linestyles, linestyle, "solid") => nothing,
)
end
@@ -818,6 +732,7 @@ function pgfx_should_add_to_legend(series::Series)
:contourf,
:contour3d,
:heatmap,
:pie,
:image,
)
)
@@ -825,8 +740,10 @@ end
function pgfx_marker(plotattributes, i = 1)
shape = _cycle(plotattributes[:markershape], i)
cstr =
plot_color(get_markercolor(plotattributes, i), get_markeralpha(plotattributes, i))
cstr = plot_color(
get_markercolor(plotattributes, i),
get_markeralpha(plotattributes, i),
)
a = alpha(cstr)
cstr_stroke = plot_color(
get_markerstrokecolor(plotattributes, i),
@@ -835,10 +752,11 @@ function pgfx_marker(plotattributes, i = 1)
a_stroke = alpha(cstr_stroke)
mark_size =
pgfx_thickness_scaling(plotattributes) *
0.75 *
0.5 *
_cycle(plotattributes[:markersize], i)
return PGFPlotsX.Options(
"mark" => shape isa Shape ? "PlotsShape$i" : pgfx_get_marker(shape),
"mark" =>
shape isa Shape ? "PlotsShape$i" : get(_pgfplotsx_markers, shape, "*"),
"mark size" => "$mark_size pt",
"mark options" => PGFPlotsX.Options(
"color" => cstr_stroke,
@@ -847,7 +765,6 @@ function pgfx_marker(plotattributes, i = 1)
"fill opacity" => a,
"line width" =>
pgfx_thickness_scaling(plotattributes) *
0.75 *
_cycle(plotattributes[:markerstrokewidth], i),
"rotate" => if shape == :dtriangle
180
@@ -858,7 +775,11 @@ function pgfx_marker(plotattributes, i = 1)
else
0
end,
pgfx_get_linestyle(_cycle(plotattributes[:markerstrokestyle], i)) => nothing,
get(
_pgfplotsx_linestyles,
_cycle(plotattributes[:markerstrokestyle], i),
"solid",
) => nothing,
),
)
end
@@ -872,8 +793,7 @@ function pgfx_add_annotation!(o, x, y, val, thickness_scaling = 1)
[
"\\node",
PGFPlotsX.Options(
get((center = "", left = "right", right = "left"), val.font.halign, "") =>
nothing,
get(_pgfx_annotation_halign, val.font.halign, "") => nothing,
"color" => cstr,
"draw opacity" => convert(Float16, a),
"rotate" => val.font.rotation,
@@ -948,7 +868,7 @@ function pgfx_fillrange_series!(axis, series, series_func, i, fillrange, rng)
fillrange_opt = merge(fillrange_opt, pgfx_marker(series, i))
push!(fillrange_opt, "forget plot" => nothing)
opt = series.plotattributes
args = RecipesPipeline.is3d(series) ? (opt[:x][rng], opt[:y][rng], opt[:z][rng]) :
args = is3d(series) ? (opt[:x][rng], opt[:y][rng], opt[:z][rng]) :
(opt[:x][rng], opt[:y][rng])
push!(
axis,
@@ -980,16 +900,6 @@ function pgfx_sanitize_string(s::AbstractString)
s = replace(s, r"\\?\%" => "\\%")
s = replace(s, r"\\?\_" => "\\_")
s = replace(s, r"\\?\&" => "\\&")
s = replace(s, r"\\?\{" => "\\{")
s = replace(s, r"\\?\}" => "\\}")
end
@require LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" begin
using .LaTeXStrings
function pgfx_sanitize_string(s::LaTeXString)
s = replace(s, r"\\?\#" => "\\#")
s = replace(s, r"\\?\%" => "\\%")
return LaTeXString(s)
end
end
function pgfx_sanitize_plot!(plt)
for (key, value) in plt.attr
@@ -1054,10 +964,10 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
# axis label position
labelpos = ""
if letter == :x
labelpos = pgfx_get_xguide_pos(axis[:guide_position])
elseif letter == :y
labelpos = pgfx_get_yguide_pos(axis[:guide_position])
if letter == :x && axis[:guide_position] == :top
labelpos = "at={(0.5,1)},above,"
elseif letter == :y && axis[:guide_position] == :right
labelpos = "at={(1,0.5)},below,"
end
# Add label font
@@ -1088,8 +998,6 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
# ticks on or off
if axis[:ticks] in (nothing, false, :none) || framestyle == :none
push!(opt, "$(letter)majorticks" => "false")
elseif framestyle in (:grid, :zerolines)
push!(opt, "$letter tick style" => PGFPlotsX.Options("draw" => "none"))
end
# grid on or off
@@ -1105,7 +1013,6 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
push!(opt, string(letter, :min) => lims[1], string(letter, :max) => lims[2])
if !(axis[:ticks] in (nothing, false, :none, :native)) && framestyle != :none
# ticks
ticks = get_ticks(sp, axis)
#pgf plot ignores ticks with angle below 90 when xmin = 90 so shift values
tick_values =
@@ -1150,8 +1057,17 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
string(letter, "tick align") =>
(axis[:tick_direction] == :out ? "outside" : "inside"),
)
cstr = plot_color(axis[:tickfontcolor])
α = alpha(cstr)
push!(
opt, string(letter, "ticklabel style") => pgfx_get_ticklabel_style(sp, axis)
opt,
string(letter, "ticklabel style") => PGFPlotsX.Options(
"font" =>
pgfx_font(axis[:tickfontsize], pgfx_thickness_scaling(sp)),
"color" => cstr,
"draw opacity" => α,
"rotate" => axis[:tickfontrotation],
),
)
push!(
opt,
@@ -1162,37 +1078,6 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
axis[:gridstyle],
),
)
# minor ticks
# NOTE: PGFPlots would provide "minor x ticks num", but this only places minor ticks
# between major ticks and not outside first and last tick to the axis limits.
# Hence, we hack around with extra ticks. Unfortunately this conflicts with
# `:zerolines` framestyle hack. So minor ticks are not working with
# `:zerolines`.
minor_ticks = get_minor_ticks(sp, axis, ticks)
if minor_ticks !== nothing
minor_ticks =
ispolar(sp) && letter == :x ? [rad2deg.(minor_ticks)[3:end]..., 360, 405] :
minor_ticks
push!(
opt,
string("extra ", letter, " ticks") => string("{", join(minor_ticks, ","), "}"),
)
push!(opt, string("extra ", letter, " tick labels") => "")
push!(
opt,
string("extra ", letter, " tick style") => PGFPlotsX.Options(
"grid" => axis[:minorgrid] ? "major" : "none",
string(letter, " grid style") => pgfx_linestyle(
pgfx_thickness_scaling(sp) * axis[:minorgridlinewidth],
axis[:foreground_color_minor_grid],
axis[:minorgridalpha],
axis[:minorgridstyle],
),
"major tick length" => typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 || axis[:minorticks] ? "0.1cm" : "0"
),
)
end
end
# framestyle
@@ -1214,7 +1099,7 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
opt,
string("extra ", letter, " tick style") => PGFPlotsX.Options(
"grid" => "major",
string(letter, " grid style") => pgfx_linestyle(
"major grid style" => pgfx_linestyle(
pgfx_thickness_scaling(sp),
axis[:foreground_color_border],
1.0,
@@ -1239,18 +1124,17 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
)
end
end
# --------------------------------------------------------------------------------------
# display calls this and then _display, its called 3 times for plot(1:5)
# Set the (left, top, right, bottom) minimum padding around the plot area
# to fit ticks, tick labels, guides, colorbars, etc.
function _update_min_padding!(sp::Subplot{PGFPlotsXBackend})
leg = sp[:legend]
if leg in (:best, :outertopright, :outerright, :outerbottomright) || (leg isa Tuple && leg[1] >= 1)
sp.minpad = (0mm, 0mm, 5mm, 0mm)
else
sp.minpad = (0mm, 0mm, 0mm, 0mm)
end
# TODO: make padding more intelligent
# TODO: how to include margins properly?
# sp.minpad = (50mm + sp[:left_margin],
# 0mm + sp[:top_margin],
# 50mm + sp[:right_margin],
# 0mm + sp[:bottom_margin])
end
function _create_backend_figure(plt::Plot{PGFPlotsXBackend})
+72 -96
View File
@@ -3,11 +3,13 @@
is_subplot_supported(::PlotlyBackend) = true
# is_string_supported(::PlotlyBackend) = true
const _plotly_framestyles = [:box, :axes, :zerolines, :grid, :none]
const _plotly_framestyle_defaults = Dict(:semi => :box, :origin => :zerolines)
function _plotly_framestyle(style::Symbol)
if style in (:box, :axes, :zerolines, :grid, :none)
if style in _plotly_framestyles
return style
else
default_style = get((semi = :box, origin = :zerolines), style, :axes)
default_style = get(_plotly_framestyle_defaults, style, :axes)
@warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was cosen instead.")
default_style
end
@@ -15,11 +17,31 @@ end
# --------------------------------------------------------------------------------------
const plotly_remote_file_path = "https://cdn.plot.ly/plotly-latest.min.js"
# if isatom()
# import Atom
# Atom.@msg evaljs(_js_code)
# end
using UUIDs
# ----------------------------------------------------------------
const _plotly_legend_pos = KW(
:right => [1., 0.5],
:left => [0., 0.5],
:top => [0.5, 1.],
:bottom => [0.5, 0.],
:bottomleft => [0., 0.],
:bottomright => [1., 0.],
:topright => [1., 1.],
:topleft => [0., 1.]
)
plotly_legend_pos(pos::Symbol) = get(_plotly_legend_pos, pos, [1.,1.])
plotly_legend_pos(v::Tuple{S,T}) where {S<:Real, T<:Real} = v
function plotly_font(font::Font, color = font.color)
KW(
:family => font.family,
@@ -140,7 +162,7 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
if letter in (:x,:y)
ax[:domain] = plotly_domain(sp, letter)
if RecipesPipeline.is3d(sp)
if is3d(sp)
# don't link 3d axes for synchronized interactivity
x_idx = y_idx = sp[:subplot_index]
else
@@ -154,7 +176,7 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
lims = axis_limits(sp, letter)
if axis[:ticks] != :native || axis[:lims] != :auto
ax[:range] = map(RecipesPipeline.scale_func(axis[:scale]), lims)
ax[:range] = map(scalefunc(axis[:scale]), lims)
end
if !(axis[:ticks] in (nothing, :none, false))
@@ -223,7 +245,7 @@ function plotly_layout(plt::Plot)
# but vertically just below the top of the subplot bounding box
if sp[:title] != ""
bb = plotarea(sp)
tpos = sp[:titlelocation]
tpos = sp[:title_location]
xmm = if tpos == :left
left(bb)
elseif tpos == :right
@@ -241,8 +263,8 @@ function plotly_layout(plt::Plot)
# set to supported framestyle
sp[:framestyle] = _plotly_framestyle(sp[:framestyle])
# if any(RecipesPipeline.is3d, seriesargs)
if RecipesPipeline.is3d(sp)
# if any(is3d, seriesargs)
if is3d(sp)
azim = sp[:camera][1] - 90 #convert azimuthal to match GR behaviour
theta = 90 - sp[:camera][2] #spherical coordinate angle from z axis
plotattributes_out[:scene] = KW(
@@ -269,7 +291,18 @@ function plotly_layout(plt::Plot)
end
# legend
plotly_add_legend!(plotattributes_out, sp)
plotattributes_out[:showlegend] = sp[:legend] != :none
xpos,ypos = plotly_legend_pos(sp[:legend])
if sp[:legend] != :none
plotattributes_out[:legend] = KW(
:bgcolor => rgba_string(sp[:background_color_legend]),
:bordercolor => rgba_string(sp[:foreground_color_legend]),
:font => plotly_font(legendfont(sp)),
:tracegroupgap => 0,
:x => xpos,
:y => ypos
)
end
# annotations
for ann in sp[:annotations]
@@ -309,95 +342,38 @@ function plotly_layout(plt::Plot)
plotattributes_out[:hovermode] = "none"
end
plotattributes_out = recursive_merge(plotattributes_out, plt.attr[:extra_plot_kwargs])
plotattributes_out
end
function plotly_add_legend!(plotattributes_out::KW, sp::Subplot)
plotattributes_out[:showlegend] = sp[:legend] != :none
legend_position = plotly_legend_pos(sp[:legend])
if sp[:legend] != :none
plotattributes_out[:legend] = KW(
:bgcolor => rgba_string(sp[:background_color_legend]),
:bordercolor => rgba_string(sp[:foreground_color_legend]),
:borderwidth => 1,
:traceorder => "normal",
:xanchor => legend_position.xanchor,
:yanchor => legend_position.yanchor,
:font => plotly_font(legendfont(sp)),
:tracegroupgap => 0,
:x => legend_position.coords[1],
:y => legend_position.coords[2]
)
end
end
function plotly_legend_pos(pos::Symbol)
xleft = 0.07
ybot = 0.07
ycenter = 0.52
xcenter = 0.55
plotly_legend_position_mapping = (
right = (coords = [1.0, ycenter], xanchor = "right", yanchor = "middle"),
left = (coords = [xleft, ycenter], xanchor = "left", yanchor = "middle"),
top = (coords = [xcenter, 1.0], xanchor = "center", yanchor = "top"),
bottom = (coords = [xcenter, ybot], xanchor = "center", yanchor = "bottom"),
bottomleft = (coords = [xleft, ybot], xanchor = "left", yanchor = "bottom"),
bottomright = (coords = [1.0, ybot], xanchor = "right", yanchor = "bottom"),
topright = (coords = [1.0, 1.0], xanchor = "right", yanchor = "top"),
topleft = (coords = [xleft, 1.0], xanchor = "left", yanchor = "top"),
default = (coords = [1.02, 1.0], xanchor = "auto", yanchor = "auto")
)
legend_position = get(plotly_legend_position_mapping, pos, plotly_legend_position_mapping.default)
end
plotly_legend_pos(v::Tuple{S,T}) where {S<:Real, T<:Real} = (coords=v, xanchor="left", yanchor="top")
function plotly_layout_json(plt::Plot)
JSON.json(plotly_layout(plt), 4)
end
plotly_colorscale(cg::ColorGradient, α = nothing) =
[[v, rgba_string(plot_color(cg.colors[v], α))] for v in cg.values]
function plotly_colorscale(c::AbstractVector{<:Colorant}, α = nothing)
function plotly_colorscale(grad::ColorGradient, α)
[[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in eachindex(grad.colors)]
end
plotly_colorscale(c::Colorant,α) = plotly_colorscale(_as_gradient(c),α)
function plotly_colorscale(c::AbstractVector{<:RGBA}, α)
if length(c) == 1
return [
[0.0, rgba_string(plot_color(c[1], α))],
[1.0, rgba_string(plot_color(c[1], α))],
]
return [[0.0, rgba_string(plot_color(c[1], α))], [1.0, rgba_string(plot_color(c[1], α))]]
else
vals = range(0.0, stop = 1.0, length = length(c))
vals = range(0.0, stop=1.0, length=length(c))
return [[vals[i], rgba_string(plot_color(c[i], α))] for i in eachindex(c)]
end
end
function plotly_colorscale(cg::PlotUtils.CategoricalColorGradient, α = nothing)
n = length(cg)
cinds = repeat(1:n, inner = 2)
vinds = vcat((i:(i + 1) for i in 1:n)...)
return [
[cg.values[vinds[i]], rgba_string(plot_color(color_list(cg)[cinds[i]], α))]
for i in eachindex(cinds)
]
end
plotly_colorscale(c, α = nothing) = plotly_colorscale(_as_gradient(c), α)
# plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha)
get_plotly_marker(k, def) = get(
(
rect = "square",
xcross = "x",
x = "x",
utriangle = "triangle-up",
dtriangle = "triangle-down",
star5 = "star-triangle-up",
vline = "line-ns",
hline = "line-ew",
),
k,
def,
const _plotly_markers = KW(
:rect => "square",
:xcross => "x",
:x => "x",
:utriangle => "triangle-up",
:dtriangle => "triangle-down",
:star5 => "star-triangle-up",
:vline => "line-ns",
:hline => "line-ew",
)
# find indicies of axes to which the supblot links to
@@ -559,6 +535,12 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out[:showscale] = hascolorbar(sp)
end
elseif st == :pie
plotattributes_out[:type] = "pie"
plotattributes_out[:labels] = pie_labels(sp, series)
plotattributes_out[:values] = y
plotattributes_out[:hoverinfo] = "label+percent+name"
else
@warn("Plotly: seriestype $st isn't supported.")
return KW()
@@ -568,7 +550,7 @@ function plotly_series(plt::Plot, series::Series)
if hasmarker
inds = eachindex(x)
plotattributes_out[:marker] = KW(
:symbol => get_plotly_marker(series[:markershape], string(series[:markershape])),
:symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])),
# :opacity => series[:markeralpha],
:size => 2 * _cycle(series[:markersize], inds),
:color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))),
@@ -688,7 +670,7 @@ function plotly_series_segments(series::Series, plotattributes_base::KW, x, y, z
# add "marker"
if hasmarker
plotattributes_out[:marker] = KW(
:symbol => get_plotly_marker(_cycle(series[:markershape], i), string(_cycle(series[:markershape], i))),
:symbol => get(_plotly_markers, _cycle(series[:markershape], i), string(_cycle(series[:markershape], i))),
# :opacity => series[:markeralpha],
:size => 2 * _cycle(series[:markersize], i),
:color => rgba_string(plot_color(get_markercolor(series, clims, i), get_markeralpha(series, i))),
@@ -766,11 +748,11 @@ function plotly_colorbar_hack(series::Series, plotattributes_base::KW, sym::Symb
plotattributes_out = deepcopy(plotattributes_base)
cmin, cmax = get_clims(series[:subplot])
plotattributes_out[:showlegend] = false
plotattributes_out[:type] = RecipesPipeline.is3d(series) ? :scatter3d : :scatter
plotattributes_out[:type] = is3d(series) ? :scatter3d : :scatter
plotattributes_out[:hoverinfo] = :none
plotattributes_out[:mode] = :markers
plotattributes_out[:x], plotattributes_out[:y] = [series[:x][1]], [series[:y][1]]
if RecipesPipeline.is3d(series)
if is3d(series)
plotattributes_out[:z] = [series[:z][1]]
end
# zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line)
@@ -826,14 +808,8 @@ html_body(plt::Plot{PlotlyBackend}) = plotly_html_body(plt)
const ijulia_initialized = Ref(false)
function plotly_html_head(plt::Plot)
local_file = ("file:///" * plotly_local_file_path)
plotly =
use_local_dependencies[] ? local_file : "https://cdn.plot.ly/plotly-1.54.2.min.js"
include_mathjax = get(plt[:extra_plot_kwargs], :include_mathjax, "")
mathjax_file = include_mathjax != "cdn" ? ("file://" * include_mathjax) : "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"
mathjax_head = include_mathjax == "" ? "" : "<script src=\"$mathjax_file\"></script>\n\t\t"
local_file = ("file://" * plotly_local_file_path)
plotly = use_local_dependencies[] ? local_file : plotly_remote_file_path
if isijulia() && !ijulia_initialized[]
# using requirejs seems to be key to load a js depency in IJulia!
# https://requirejs.org/docs/start.html
@@ -847,7 +823,7 @@ function plotly_html_head(plt::Plot)
""")
ijulia_initialized[] = true
end
return "$mathjax_head<script src=$(repr(plotly))></script>"
return "<script src=$(repr(plotly))></script>"
end
function plotly_html_body(plt, style = nothing)
+8 -4
View File
@@ -19,12 +19,14 @@ end
# ------------------------------------------------------------------------------
for (mime, fmt) in (
const _plotlyjs_mimeformats = Dict(
"application/pdf" => "pdf",
"image/png" => "png",
"image/svg+xml" => "svg",
"image/eps" => "eps",
)
for (mime, fmt) in _plotlyjs_mimeformats
@eval _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plotlyjs_syncplot(plt), format = $fmt)
end
@@ -38,9 +40,11 @@ _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) = write(io, standal
_display(plt::Plot{PlotlyJSBackend}) = display(plotlyjs_syncplot(plt))
function PlotlyJS.WebIO.render(plt::Plot{PlotlyJSBackend})
plt_html = sprint(show, MIME("text/html"), plt)
return PlotlyJS.WebIO.render(PlotlyJS.WebIO.dom"div"(innerHTML=plt_html))
@require WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" begin
function WebIO.render(plt::Plot{PlotlyJSBackend})
plt_html = sprint(show, MIME("text/html"), plt)
return WebIO.render(dom"div"(innerHTML=plt_html))
end
end
function closeall(::PlotlyJSBackend)
+155 -210
View File
@@ -1,3 +1,6 @@
# Do "using PyPlot: PyCall, LaTeXStrings" without dependency warning:
const PyCall = PyPlot.PyCall
const LaTeXStrings = PyPlot.LaTeXStrings
# https://github.com/stevengj/PyPlot.jl
@@ -13,7 +16,6 @@ append!(Base.Multimedia.displays, otherdisplays)
pycolors = PyPlot.pyimport("matplotlib.colors")
pypath = PyPlot.pyimport("matplotlib.path")
mplot3d = PyPlot.pyimport("mpl_toolkits.mplot3d")
axes_grid1 = PyPlot.pyimport("mpl_toolkits.axes_grid1")
pypatches = PyPlot.pyimport("matplotlib.patches")
pyfont = PyPlot.pyimport("matplotlib.font_manager")
pyticker = PyPlot.pyimport("matplotlib.ticker")
@@ -33,7 +35,7 @@ else
end
# PyCall API changes in v1.90.0
if !isdefined(PyPlot.PyCall, :_setproperty!)
if !isdefined(PyCall, :_setproperty!)
@warn "Plots no longer supports PyCall < 1.90.0 and PyPlot < 2.8.0. Either update PyCall and PyPlot or pin Plots to a version <= 0.23.2."
end
@@ -62,23 +64,16 @@ end
py_color(s) = py_color(parse(Colorant, string(s)))
py_color(c::Colorant) = (red(c), green(c), blue(c), alpha(c))
py_color(cs::AVec) = map(py_color, cs)
py_color(grad::PlotUtils.AbstractColorList) = py_color(color_list(grad))
py_color(grad::ColorGradient) = py_color(grad.colors)
py_color(c::Colorant, α) = py_color(plot_color(c, α))
function py_colormap(cg::ColorGradient)
pyvals = collect(zip(cg.values, py_color(PlotUtils.color_list(cg))))
function py_colormap(grad::ColorGradient)
pyvals = [(z, py_color(grad[z])) for z in grad.values]
cm = pycolors."LinearSegmentedColormap"."from_list"("tmp", pyvals)
cm."set_bad"(color=(0,0,0,0.0), alpha=0.0)
cm
end
function py_colormap(cg::PlotUtils.CategoricalColorGradient)
r = range(0, stop = 1, length = 256)
pyvals = collect(zip(r, py_color(cg[r])))
cm = pycolors."LinearSegmentedColormap"."from_list"("tmp", pyvals)
cm."set_bad"(color=(0,0,0,0.0), alpha=0.0)
cm
end
py_colormap(c) = py_colormap(_as_gradient(c))
py_colormap(c::Colorant) = py_colormap(_as_gradient(c))
function py_shading(c, z)
@@ -110,6 +105,32 @@ function py_marker(marker::Shape)
pypath."Path"(mat)
end
const _path_MOVETO = UInt8(1)
const _path_LINETO = UInt8(2)
const _path_CLOSEPOLY = UInt8(79)
# # see http://matplotlib.org/users/path_tutorial.html
# # and http://matplotlib.org/api/path_api.html#matplotlib.path.Path
# function py_path(x, y)
# n = length(x)
# mat = zeros(n+1, 2)
# codes = zeros(UInt8, n+1)
# lastnan = true
# for i=1:n
# mat[i,1] = x[i]
# mat[i,2] = y[i]
# nan = !ok(x[i], y[i])
# codes[i] = if nan && i>1
# _path_CLOSEPOLY
# else
# lastnan ? _path_MOVETO : _path_LINETO
# end
# lastnan = nan
# end
# codes[n+1] = _path_CLOSEPOLY
# pypath["Path"](mat, codes)
# end
# get the marker shape
function py_marker(marker::Symbol)
marker == :none && return " "
@@ -176,19 +197,19 @@ end
function labelfunc(scale::Symbol, backend::PyPlotBackend)
if scale == :log10
x -> PyPlot.LaTeXStrings.latexstring("10^{$x}")
x -> LaTeXStrings.latexstring("10^{$x}")
elseif scale == :log2
x -> PyPlot.LaTeXStrings.latexstring("2^{$x}")
x -> LaTeXStrings.latexstring("2^{$x}")
elseif scale == :ln
x -> PyPlot.LaTeXStrings.latexstring("e^{$x}")
x -> LaTeXStrings.latexstring("e^{$x}")
else
x -> PyPlot.LaTeXStrings.latexstring(convert_sci_unicode(x))
string
end
end
function py_mask_nans(z)
# pynp["ma"][:masked_invalid](z)))
PyPlot.PyCall.pycall(pynp."ma"."masked_invalid", Any, z)
PyCall.pycall(pynp."ma"."masked_invalid", Any, z)
# pynp["ma"][:masked_where](pynp["isnan"](z),z)
end
@@ -208,6 +229,11 @@ function fix_xy_lengths!(plt::Plot{PyPlotBackend}, series::Series)
end
end
py_linecolor(series::Series) = py_color(series[:linecolor])
py_markercolor(series::Series) = py_color(series[:markercolor])
py_markerstrokecolor(series::Series) = py_color(series[:markerstrokecolor])
py_fillcolor(series::Series) = py_color(series[:fillcolor])
py_linecolormap(series::Series) = py_colormap(series[:linecolor])
py_markercolormap(series::Series) = py_colormap(series[:markercolor])
py_fillcolormap(series::Series) = py_colormap(series[:fillcolor])
@@ -422,7 +448,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
# :norm => pycolors["Normalize"](; extrakw...)
# )
# lz = _cycle(series[:line_z], 1:n)
# handle = if RecipesPipeline.is3d(st)
# handle = if is3d(st)
# line_segments = [[(x[j], y[j], z[j]) for j in rng] for rng in segments]
# lc = pyart3d["Line3DCollection"](line_segments; kw...)
# lc[:set_array](lz)
@@ -452,7 +478,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
# end
a = series[:arrow]
if a !== nothing && !RecipesPipeline.is3d(st) # TODO: handle 3d later
if a !== nothing && !is3d(st) # TODO: handle 3d later
if typeof(a) != Arrow
@warn("Unexpected type for arrow: $(typeof(a))")
else
@@ -460,8 +486,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
:arrowstyle => "simple,head_length=$(a.headlength),head_width=$(a.headwidth)",
:shrinkA => 0,
:shrinkB => 0,
:edgecolor => py_color(get_linecolor(series)),
:facecolor => py_color(get_linecolor(series)),
:edgecolor => py_linecolor(series),
:facecolor => py_linecolor(series),
:linewidth => py_thickness_scale(plt, get_linewidth(series)),
:linestyle => py_linestyle(st, get_linestyle(series)),
)
@@ -507,19 +533,16 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
handle = []
x,y = xyargs
shapes = series[:markershape]
msc = py_color(get_markerstrokecolor(series), get_markerstrokealpha(series))
msc = py_markerstrokecolor(series)
lw = py_thickness_scale(plt, series[:markerstrokewidth])
for i=eachindex(y)
if series[:marker_z] !== nothing
extrakw[:c] = [py_color(get_markercolor(series, i), get_markercoloralpha(series, i))]
end
extrakw[:c] = _cycle(markercolor, i)
push!(handle, ax."scatter"(_cycle(x,i), _cycle(y,i);
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
marker = py_marker(_cycle(shapes,i)),
s = py_thickness_scale(plt, _cycle(series[:markersize],i)).^ 2,
facecolors = py_color(get_markercolor(series, i), get_markercoloralpha(series, i)),
s = py_thickness_scale(plt, _cycle(series[:markersize],i) .^ 2),
edgecolors = msc,
linewidths = lw,
extrakw...
@@ -549,7 +572,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
push!(cur_y_list, _cycle(y,i))
push!(cur_color_list, _cycle(markercolor, i))
push!(cur_scale_list, py_thickness_scale(plt, _cycle(series[:markersize],i)).^ 2)
push!(cur_scale_list, py_thickness_scale(plt, _cycle(series[:markersize],i) .^ 2))
continue
end
@@ -559,7 +582,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
zorder = series[:series_plotindex] + 0.5,
marker = prev_marker,
s = cur_scale_list,
edgecolors = py_color(get_markerstrokecolor(series), get_markerstrokealpha(series)),
edgecolors = py_markerstrokecolor(series),
linewidths = py_thickness_scale(plt, series[:markerstrokewidth]),
facecolors = cur_color_list,
extrakw...
@@ -569,7 +592,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
cur_y_list = [_cycle(y,i)]
cur_color_list = [_cycle(markercolor, i)]
cur_scale_list = [py_thickness_scale(plt, _cycle(series[:markersize],i)) .^ 2]
cur_scale_list = [py_thickness_scale(plt, _cycle(series[:markersize],i) .^ 2)]
prev_marker = cur_marker
end
@@ -580,7 +603,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
zorder = series[:series_plotindex] + 0.5,
marker = prev_marker,
s = cur_scale_list,
edgecolors = py_color(get_markerstrokecolor(series), get_markerstrokealpha(series)),
edgecolors = py_markerstrokecolor(series),
linewidths = py_thickness_scale(plt, series[:markerstrokewidth]),
facecolors = cur_color_list,
extrakw...
@@ -590,18 +613,12 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
push!(handles, handle)
else
# do a normal scatter plot
# Add depthshade option for 3d plots
if RecipesPipeline.is3d(sp)
extrakw[:depthshade] = get(series[:extra_kwargs], :depthshade, false)
end
handle = ax."scatter"(xyargs...;
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
marker = py_marker(series[:markershape]),
s = py_thickness_scale(plt, series[:markersize]) .^2,
edgecolors = py_color(get_markerstrokecolor(series), get_markerstrokealpha(series)),
s = py_thickness_scale(plt, series[:markersize] .^ 2),
edgecolors = py_markerstrokecolor(series),
linewidths = py_thickness_scale(plt, series[:markerstrokewidth]),
extrakw...
)
@@ -610,16 +627,14 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
if st == :hexbin
handle = ax."hexbin"(x, y,
handle = ax."hexbin"(x, y;
label = series[:label],
C = series[:weights],
gridsize = series[:bins]==:auto ? 100 : series[:bins], # 100 is the default value
linewidths = py_thickness_scale(plt, series[:linewidth]),
edgecolors = py_color(get_linecolor(series)),
alpha = series[:fillalpha],
cmap = py_fillcolormap(series), # applies to the pcolorfast object
zorder = series[:series_plotindex],
# extrakw... # We are not supporting clims for hexbin as calculation of bins is not trivial
gridsize = series[:bins],
linewidths = py_thickness_scale(plt, series[:linewidth]),
edgecolors = py_linecolor(series),
cmap = py_fillcolormap(series), # applies to the pcolorfast object
extrakw...
)
push!(handles, handle)
end
@@ -652,7 +667,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
extrakw...
)
if series[:contour_labels] == true
ax."clabel"(handle, handle.levels)
PyPlot."clabel"(handle, handle.levels)
end
push!(handles, handle)
@@ -661,7 +676,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
handle = ax."contourf"(x, y, z, levelargs...;
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
alpha = series[:fillalpha],
extrakw...
)
push!(handles, handle)
@@ -691,7 +705,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
rstride = series[:stride][1],
cstride = series[:stride][2],
linewidth = py_thickness_scale(plt, series[:linewidth]),
edgecolor = py_color(get_linecolor(series)),
edgecolor = py_linecolor(series),
extrakw...
)
push!(handles, handle)
@@ -717,7 +731,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
zorder = series[:series_plotindex],
cmap = py_fillcolormap(series),
linewidth = py_thickness_scale(plt, series[:linewidth]),
edgecolor = py_color(get_linecolor(series)),
edgecolor = py_linecolor(series),
extrakw...
)
push!(handles, handle)
@@ -739,7 +753,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
handle = ax."imshow"(z;
zorder = series[:series_plotindex],
cmap = py_colormap(cgrad(plot_color([:black, :white]))),
cmap = py_colormap(cgrad([:black, :white])),
vmin = 0.0,
vmax = 1.0,
extent = (xmin-0.5, xmax+0.5, ymax+0.5, ymin-0.5)
@@ -794,6 +808,21 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
push!(handles, handle)
end
if st == :pie
handle = ax."pie"(y;
# colors = # a vector of colors?
labels = pie_labels(sp, series)
)[1]
push!(handles, handle)
# # expand extrema... get list of Wedge objects
# for wedge in handle
# path = wedge[:get_path]()
# for
lim = 1.1
expand_extrema!(sp, -lim, lim, -lim, lim)
end
series[:serieshandle] = handles
# # smoothing
@@ -910,7 +939,7 @@ function py_set_axis_colors(sp, ax, a::Axis)
spine."set_color"(py_color(a[:foreground_color_border]))
end
axissym = Symbol(a[:letter], :axis)
if PyPlot.PyCall.hasproperty(ax, axissym)
if PyCall.hasproperty(ax, axissym)
tickcolor = sp[:framestyle] in (:zerolines, :grid) ? py_color(plot_color(a[:foreground_color_grid], a[:gridalpha])) : py_color(a[:foreground_color_axis])
ax."tick_params"(axis=string(a[:letter]), which="both",
colors=tickcolor,
@@ -960,7 +989,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# title
if sp[:title] != ""
loc = lowercase(string(sp[:titlelocation]))
loc = lowercase(string(sp[:title_location]))
func = if loc == "left"
:_left_title
elseif loc == "right"
@@ -1005,53 +1034,12 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
end
kw[:spacing] = "proportional"
# create and store the colorbar object (handle) and the axis that it is drawn on.
# note: the colorbar axis is positioned independently from the subplot axis
fig = plt.o
if RecipesPipeline.is3d(sp)
cbax = fig."add_axes"([0.9, 0.1, 0.03, 0.8])
cb = fig."colorbar"(handle; cax=cbax, kw...)
else
# divider approach works only with 2d plots
divider = axes_grid1.make_axes_locatable(ax)
# width = axes_grid1.axes_size.AxesY(ax, aspect=1.0 / 3.5)
# pad = axes_grid1.axes_size.Fraction(0.5, width) # Colorbar is spaced 0.5 of its size away from the ax
# cbax = divider.append_axes("right", size=width, pad=pad) # This approach does not work well in subplots
colorbar_position = "right"
colorbar_pad = "2.5%"
colorbar_orientation="vertical"
if sp[:colorbar] == :left
colorbar_position = string(sp[:colorbar])
colorbar_pad = "5%"
elseif sp[:colorbar] == :top
colorbar_position = string(sp[:colorbar])
colorbar_pad = "2.5%"
colorbar_orientation="horizontal"
elseif sp[:colorbar] == :bottom
colorbar_position = string(sp[:colorbar])
colorbar_pad = "5%"
colorbar_orientation="horizontal"
end
cbax = divider.append_axes(colorbar_position, size="5%", pad=colorbar_pad) # Reasonable value works most of the usecases
cb = fig."colorbar"(handle; cax=cbax, orientation = colorbar_orientation, kw...)
if sp[:colorbar] == :left
cbax.yaxis.set_ticks_position("left")
elseif sp[:colorbar] == :top
cbax.xaxis.set_ticks_position("top")
elseif sp[:colorbar] == :bottom
cbax.xaxis.set_ticks_position("bottom")
end
end
cbax = fig."add_axes"([0.8,0.1,0.03,0.8], label = string(gensym()))
cb = fig."colorbar"(handle; cax = cbax, kw...)
cb."set_label"(sp[:colorbar_title],size=py_thickness_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor]))
# cb."formatter".set_useOffset(false) # This for some reason does not work, must be a pyplot bug, instead this is a workaround:
cb."formatter".set_powerlimits((-Inf, Inf))
cb."update_ticks"()
for lab in cb."ax"."yaxis"."get_ticklabels"()
lab."set_fontsize"(py_thickness_scale(plt, sp[:yaxis][:tickfontsize]))
lab."set_family"(sp[:yaxis][:tickfontfamily])
@@ -1062,7 +1050,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
end
# framestyle
if !ispolar(sp) && !RecipesPipeline.is3d(sp)
if !ispolar(sp) && !is3d(sp)
ax.spines["left"]."set_linewidth"(py_thickness_scale(plt, 1))
ax.spines["bottom"]."set_linewidth"(py_thickness_scale(plt, 1))
if sp[:framestyle] == :semi
@@ -1092,7 +1080,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# axis attributes
for letter in (:x, :y, :z)
axissym = Symbol(letter, :axis)
PyPlot.PyCall.hasproperty(ax, axissym) || continue
PyCall.hasproperty(ax, axissym) || continue
axis = sp[axissym]
pyaxis = getproperty(ax, axissym)
if axis[:mirror] && letter != :z
@@ -1115,27 +1103,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
ticks[2][ticks[1] .== 0] .= ""
end
axis[:ticks] != :native ? py_set_ticks(ax, ticks, letter) : nothing
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))
pyaxis."set_tick_params"(direction = axis[:tick_direction] == :out ? "out" : "in")
getproperty(ax, Symbol("set_", letter, "label"))(axis[:guide])
if get(axis.plotattributes, :flip, false)
getproperty(ax, Symbol("invert_", letter, "axis"))()
end
pyaxis."label"."set_fontsize"(py_thickness_scale(plt, axis[:guidefontsize]))
pyaxis."label"."set_family"(axis[:guidefontfamily])
if (RecipesPipeline.is3d(sp))
pyaxis."set_rotate_label"(false)
end
if (letter == :y && !RecipesPipeline.is3d(sp))
pyaxis."label"."set_rotation"(axis[:guidefontrotation] + 90)
else
pyaxis."label"."set_rotation"(axis[:guidefontrotation])
end
for lab in getproperty(ax, Symbol("get_", letter, "ticklabels"))()
lab."set_fontsize"(py_thickness_scale(plt, axis[:tickfontsize]))
lab."set_family"(axis[:tickfontfamily])
@@ -1152,35 +1126,6 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
else
pyaxis."grid"(false)
end
#
if axis[:minorticks] > 1
pyaxis."set_minor_locator"(PyPlot.matplotlib.ticker.AutoMinorLocator(axis[:minorticks]))
pyaxis."set_tick_params"(
which = "minor",
direction = axis[:tick_direction] == :out ? "out" : "in",
width=py_thickness_scale(plt, intensity))
end
if axis[:minorgrid]
if !(axis[:minorticks] > 1) # Check if ticks were already configured
ax."minorticks_on"()
end
pyaxis."set_tick_params"(
which = "minor",
direction = axis[:tick_direction] == :out ? "out" : "in",
width=py_thickness_scale(plt, intensity))
pyaxis."grid"(true,
which = "minor",
color = fgcolor,
linestyle = py_linestyle(:line, axis[:minorgridstyle]),
linewidth = py_thickness_scale(plt, axis[:minorgridlinewidth]),
alpha = axis[:minorgridalpha])
end
py_set_axis_colors(sp, ax, axis)
end
@@ -1216,7 +1161,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
end
#camera/view angle
if RecipesPipeline.is3d(sp)
if is3d(sp)
#convert azimuthal to match GR behaviour
#view_init(elevation, azimuthal) so reverse :camera args
ax."view_init"((sp[:camera].-(90,0))[end:-1:1]...)
@@ -1263,7 +1208,7 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend})
# optionally add the width of colorbar labels and colorbar to rightpad
if haskey(sp.attr, :cbar_ax)
bb = py_bbox(sp.attr[:cbar_handle]."ax"."get_yticklabels"())
sp.attr[:cbar_width] = _cbar_width + width(bb) + (sp[:colorbar_title] == "" ? 0px : 30px)
sp.attr[:cbar_width] = _cbar_width + width(bb) + 2.3mm + (sp[:colorbar_title] == "" ? 0px : 30px)
rightpad = rightpad + sp.attr[:cbar_width]
end
@@ -1304,44 +1249,43 @@ end
# -----------------------------------------------------------------
py_legend_pos(pos::Symbol) = get(
(
right = "right",
left = "center left",
top = "upper center",
bottom = "lower center",
bottomleft = "lower left",
bottomright = "lower right",
topright = "upper right",
topleft = "upper left",
outerright = "center left",
outerleft = "right",
outertop = "lower center",
outerbottom = "upper center",
outerbottomleft = "lower right",
outerbottomright = "lower left",
outertopright = "upper left",
outertopleft = "upper right",
),
pos,
"best",
const _pyplot_legend_pos = KW(
:right => "right",
:left => "center left",
:top => "upper center",
:bottom => "lower center",
:bottomleft => "lower left",
:bottomright => "lower right",
:topright => "upper right",
:topleft => "upper left"
)
const _pyplot_legend_pos_outer = KW(
:outerright => "center left",
:outerleft => "right",
:outertop => "lower center",
:outerbottom => "upper center",
:outerbottomleft => "lower right",
:outerbottomright => "lower left",
:outertopright => "upper left",
:outertopleft => "upper right"
)
py_legend_pos(pos::Symbol) = get(_pyplot_legend_pos, pos, get(_pyplot_legend_pos_outer, pos, "best"))
py_legend_pos(pos) = "lower left"
py_legend_bbox(pos::Symbol) = get(
(
outerright = (1.0, 0.5, 0.0, 0.0),
outerleft = (-0.15, 0.5, 0.0, 0.0),
outertop = (0.5, 1.0, 0.0, 0.0),
outerbottom = (0.5, -0.15, 0.0, 0.0),
outerbottomleft = (-0.15, 0.0, 0.0, 0.0),
outerbottomright = (1.0, 0.0, 0.0, 0.0),
outertopright = (1.0, 1.0, 0.0, 0.0),
outertopleft = (-0.15, 1.0, 0.0, 0.0),
),
pos,
(0.0, 0.0, 1.0, 1.0),
const _pyplot_legend_bbox_outer = KW(
:outerright => (1.0, 0.5, 0.0, 0.0),
:outerleft => (-0.15, 0.5, 0.0, 0.0),
:outertop => (0.5, 1.0, 0.0, 0.0),
:outerbottom => (0.5, -0.15, 0.0, 0.0),
:outerbottomleft => (-0.15, 0.0, 0.0, 0.0),
:outerbottomright => (1.0, 0.0, 0.0, 0.0),
:outertopright => (1.0, 1.0, 0.0, 0.0),
:outertopleft => (-0.15, 1.0, 0.0, 0.0)
)
py_legend_bbox(pos::Symbol) = get(_pyplot_legend_bbox_outer, pos, (0.0, 0.0, 1.0, 1.0))
py_legend_bbox(pos) = pos
function py_add_legend(plt::Plot, sp::Subplot, ax)
@@ -1354,30 +1298,25 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
if should_add_to_legend(series)
clims = get_clims(sp, series)
# add a line/marker and a label
push!(handles,
if series[:seriestype] == :shape || series[:fillrange] !== nothing
pypatches."Patch"(
edgecolor = py_color(single_color(get_linecolor(series, clims)), get_linealpha(series)),
facecolor = py_color(single_color(get_fillcolor(series, clims)), get_fillalpha(series)),
linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)),
linestyle = py_linestyle(series[:seriestype], get_linestyle(series))
)
elseif series[:seriestype] in (:path, :straightline, :scatter, :steppre, :steppost)
hasline = get_linewidth(series) > 0
PyPlot.plt."Line2D"((0,1),(0,0),
color = py_color(single_color(get_linecolor(series, clims)), get_linealpha(series)),
linewidth = py_thickness_scale(plt, hasline * sp[:legendfontsize] / 8),
linestyle = py_linestyle(:path, get_linestyle(series)),
marker = py_marker(_cycle(series[:markershape], 1)),
markersize = py_thickness_scale(plt, 0.8 * sp[:legendfontsize]),
markeredgecolor = py_color(single_color(get_markerstrokecolor(series)), get_markerstrokealpha(series)),
markerfacecolor = py_color(single_color(get_markercolor(series, clims)), get_markeralpha(series)),
markeredgewidth = py_thickness_scale(plt, 0.8 * get_markerstrokewidth(series) * sp[:legendfontsize] / first(series[:markersize])) # retain the markersize/markerstroke ratio from the markers on the plot
)
else
series[:serieshandle][1]
end
)
push!(handles, if series[:seriestype] == :shape || series[:fillrange] !== nothing
pypatches."Patch"(
edgecolor = py_color(single_color(get_linecolor(series, clims)), get_linealpha(series)),
facecolor = py_color(single_color(get_fillcolor(series, clims)), get_fillalpha(series)),
linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)),
linestyle = py_linestyle(series[:seriestype], get_linestyle(series))
)
elseif series[:seriestype] in (:path, :straightline, :scatter)
PyPlot.plt."Line2D"((0,1),(0,0),
color = py_color(single_color(get_linecolor(series, clims)), get_linealpha(series)),
linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)),
linestyle = py_linestyle(:path, get_linestyle(series)),
marker = py_marker(first(series[:markershape])),
markeredgecolor = py_color(single_color(get_markerstrokecolor(series)), get_markerstrokealpha(series)),
markerfacecolor = py_color(single_color(get_markercolor(series, clims)), get_markeralpha(series))
)
else
series[:serieshandle][1]
end)
push!(labels, series[:label])
end
end
@@ -1393,7 +1332,6 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
facecolor = py_color(sp[:background_color_legend]),
edgecolor = py_color(sp[:foreground_color_legend]),
framealpha = alpha(plot_color(sp[:background_color_legend])),
fancybox = false # makes the legend box square
)
frame = leg."get_frame"()
frame."set_linewidth"(py_thickness_scale(plt, 1))
@@ -1424,10 +1362,13 @@ function _update_plot_object(plt::Plot{PyPlotBackend})
pcts = bbox_to_pcts(sp.plotarea, figw, figh)
ax."set_position"(pcts)
if haskey(sp.attr, :cbar_ax) && RecipesPipeline.is3d(sp) # 2D plots are completely handled by axis dividers
# set the cbar position if there is one
if haskey(sp.attr, :cbar_ax)
cbw = sp.attr[:cbar_width]
# this is the bounding box of just the colors of the colorbar (not labels)
cb_bbox = BoundingBox(right(sp.bbox)-cbw - 2mm, top(sp.bbox) + 2mm, _cbar_width-1mm, height(sp.bbox) - 4mm)
ex = sp[:zaxis][:extrema]
has_toplabel = !(1e-7 < max(abs(ex.emax), abs(ex.emin)) < 1e7)
cb_bbox = BoundingBox(right(sp.bbox)-cbw+1mm, top(sp.bbox) + (has_toplabel ? 4mm : 2mm), _cbar_width-1mm, height(sp.bbox) - (has_toplabel ? 6mm : 4mm))
pcts = bbox_to_pcts(cb_bbox, figw, figh)
sp.attr[:cbar_ax]."set_position"(pcts)
end
@@ -1441,7 +1382,8 @@ end
_display(plt::Plot{PyPlotBackend}) = plt.o."show"()
for (mime, fmt) in (
const _pyplot_mimeformats = Dict(
"application/eps" => "eps",
"image/eps" => "eps",
"application/pdf" => "pdf",
@@ -1450,6 +1392,9 @@ for (mime, fmt) in (
"image/svg+xml" => "svg",
"application/x-tex" => "pgf"
)
for (mime, fmt) in _pyplot_mimeformats
@eval function _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PyPlotBackend})
fig = plt.o
fig."canvas"."print_figure"(
+10 -8
View File
@@ -3,17 +3,19 @@
# don't warn on unsupported... there's just too many warnings!!
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
warnOnUnsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
# --------------------------------------------------------------------------------------
const _canvas_type = Ref(:auto)
function _canvas_map()
(
braille = UnicodePlots.BrailleCanvas,
ascii = UnicodePlots.AsciiCanvas,
block = UnicodePlots.BlockCanvas,
dot = UnicodePlots.DotCanvas,
density = UnicodePlots.DensityCanvas,
KW(
:braille => UnicodePlots.BrailleCanvas,
:ascii => UnicodePlots.AsciiCanvas,
:block => UnicodePlots.BlockCanvas,
:dot => UnicodePlots.DotCanvas,
:density => UnicodePlots.DensityCanvas,
)
end
@@ -124,7 +126,7 @@ function addUnicodeSeries!(o, plotattributes, addlegend::Bool, xlim, ylim)
color = plotattributes[:linecolor] in UnicodePlots.color_cycle ? plotattributes[:linecolor] : :auto
# add the series
x, y = RecipesPipeline.unzip(collect(Base.Iterators.filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y))))
x, y = Plots.unzip(collect(Base.Iterators.filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y))))
func(o, x, y; color = color, name = label)
end
+10 -28
View File
@@ -29,7 +29,7 @@ end
Construct a polygon to be plotted
"""
Shape(verts::AVec) = Shape(RecipesPipeline.unzip(verts)...)
Shape(verts::AVec) = Shape(unzip(verts)...)
Shape(s::Shape) = deepcopy(s)
get_xs(shape::Shape) = shape.x
@@ -358,15 +358,9 @@ end
Scales all **current** font sizes by `factor`. For example `scalefontsizes(1.1)` increases all current font sizes by 10%. To reset to initial sizes, use `scalefontsizes()`
"""
function scalefontsizes(factor::Number)
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize)
scalefontsize(k, factor)
end
for letter in (:x,:y,:z)
for k in (:guidefontsize, :tickfontsize)
scalefontsize(Symbol(letter, k), factor)
end
end
end
"""
@@ -375,27 +369,15 @@ end
Resets font sizes to initial default values.
"""
function scalefontsizes()
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
f = default(k)
if k in keys(_initial_fontsizes)
factor = f / _initial_fontsizes[k]
scalefontsize(k, 1.0/factor)
end
end
for letter in (:x,:y,:z)
for k in (:guidefontsize, :tickfontsize)
if k in keys(_initial_fontsizes)
f = default(Symbol(letter, k))
factor = f / _initial_fontsizes[k]
scalefontsize(Symbol(letter, k), 1.0/factor)
end
end
end
for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize)
f = default(k)
if k in keys(_initial_fontsizes)
factor = f / _initial_fontsizes[k]
scalefontsize(k, 1.0/factor)
end
end
end
resetfontsizes() = scalefontsizes()
"Wrap a string with font info"
struct PlotText
str::AbstractString
@@ -770,7 +752,7 @@ end
@deprecate curve_points coords
coords(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, Base.range(first(range), stop=last(range), length=n))
coords(curve::BezierCurve, n::Integer = 30; range = [0,1]) = map(curve, Base.range(range..., length=n))
# build a BezierCurve which leaves point p vertically upwards and arrives point q vertically upwards.
# may create a loop if necessary. Assumes the view is [0,1]
+12 -66
View File
@@ -74,7 +74,7 @@ const _examples = PlotExample[
rand(11, 4),
lab = "lines",
w = 3,
palette = cgrad(:grays),
palette = :grays,
fill = 0,
α = 0.6,
)
@@ -322,7 +322,7 @@ const _examples = PlotExample[
plot(
Plots.fakedata(100, 10),
layout = 4,
palette = cgrad.([:grays :blues :heat :lightrainbow]),
palette = [:grays :blues :heat :lightrainbow],
bg_inside = [:orange :pink :darkblue :black],
)
end
@@ -586,7 +586,7 @@ const _examples = PlotExample[
rand(100, 6),
layout = @layout([a b; c]),
title = ["A" "B" "C"],
titlelocation = :left,
title_location = :left,
left_margin = [20mm 0mm],
bottom_margin = 10px,
xrotation = 60,
@@ -934,77 +934,23 @@ const _examples = PlotExample[
end,
],
),
PlotExample(
"Linked axes",
"",
[
quote
begin
x = -5:0.1:5
plot(plot(x, x->x^2), plot(x, x->sin(x)), layout = 2, link = :y)
end
end,
],
),
PlotExample(
"Error bars and array type recipes",
"",
[
quote
begin
struct Measurement <: Number
val::Float64
err::Float64
end
value(m::Measurement) = m.val
uncertainty(m::Measurement) = m.err
@recipe function f(::Type{T}, m::T) where T <: AbstractArray{<:Measurement}
if !(get(plotattributes, :seriestype, :path) in [:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image])
error_sym = Symbol(plotattributes[:letter], :error)
plotattributes[error_sym] = uncertainty.(m)
end
value.(m)
end
x = Measurement.(10sort(rand(10)), rand(10))
y = Measurement.(10sort(rand(10)), rand(10))
z = Measurement.(10sort(rand(10)), rand(10))
surf = Measurement.((1:10) .* (1:10)', rand(10,10))
plot(
scatter(x, [x y], msw = 0),
scatter(x, y, z, msw = 0),
heatmap(x, y, surf),
wireframe(x, y, surf),
legend = :topleft
)
end
end,
],
),
]
# Some constants for PlotDocs and PlotReferenceImages
_animation_examples = [2, 31]
_animation_examples = [2, 30]
_backend_skips = Dict(
:gr => [25, 30],
:pyplot => [2, 25, 30, 31],
:pyplot => [25, 30],
:plotlyjs => [2, 21, 24, 25, 30, 31],
:plotly => [2, 21, 24, 25, 30, 31],
:pgfplots => [2, 5, 6, 10, 16, 20, 22, 23, 25, 28, 30, 31, 34, 37, 38, 39],
:pgfplotsx => [
2, # animation
6, # images
10, # histogram2d
16, # pgfplots thinks the upper panel is too small
25, # @df
30, # @df
31, # animation
32, # spy
38, # histogram2d
],
)
:pgfplotsx => [ 6, # images
10, # histogram2d
22, # contourf
23, # pie
32, # spy
38, # histogram2d
] )
+14 -4
View File
@@ -3,7 +3,7 @@ using REPL
function _plots_defaults()
if isdefined(Main, :PLOTS_DEFAULTS)
copy(Dict{Symbol,Any}(Main.PLOTS_DEFAULTS))
Dict{Symbol,Any}(Main.PLOTS_DEFAULTS)
else
Dict{Symbol,Any}()
end
@@ -13,9 +13,11 @@ end
function __init__()
user_defaults = _plots_defaults()
if haskey(user_defaults, :theme)
theme(pop!(user_defaults, :theme))
theme(user_defaults[:theme])
end
for (k,v) in user_defaults
k == :theme || default(k, v)
end
default(; user_defaults...)
insert!(Base.Multimedia.displays, findlast(x -> x isa Base.TextDisplay || x isa REPL.REPLDisplay, Base.Multimedia.displays) + 1, PlotsDisplay())
@@ -29,41 +31,49 @@ function __init__()
@require HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" begin
fn = joinpath(@__DIR__, "backends", "hdf5.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d" begin
fn = joinpath(@__DIR__, "backends", "inspectdr.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PGFPlots = "3b7a836e-365b-5785-a47d-02c71176b4aa" begin
fn = joinpath(@__DIR__, "backends", "deprecated", "pgfplots.jl")
fn = joinpath(@__DIR__, "backends", "pgfplots.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require ORCA = "47be7bcc-f1a6-5447-8b36-7eeeff7534fd" begin
fn = joinpath(@__DIR__, "backends", "orca.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925" begin
fn = joinpath(@__DIR__, "backends", "pgfplotsx.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" begin
fn = joinpath(@__DIR__, "backends", "plotlyjs.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" begin
fn = joinpath(@__DIR__, "backends", "pyplot.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" begin
fn = joinpath(@__DIR__, "backends", "unicodeplots.jl")
include(fn)
@require Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" Revise.track(Plots, fn)
end
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
+90 -90
View File
@@ -1,51 +1,54 @@
defaultOutputFormat(plt::Plot) = "png"
function png(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "png")
io = open(fn, "w")
show(io, MIME("image/png"), plt)
close(io)
fn = addExtension(fn, "png")
io = open(fn, "w")
show(io, MIME("image/png"), plt)
close(io)
end
png(fn::AbstractString) = png(current(), fn)
function svg(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "svg")
io = open(fn, "w")
show(io, MIME("image/svg+xml"), plt)
close(io)
fn = addExtension(fn, "svg")
io = open(fn, "w")
show(io, MIME("image/svg+xml"), plt)
close(io)
end
svg(fn::AbstractString) = svg(current(), fn)
function pdf(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "pdf")
io = open(fn, "w")
show(io, MIME("application/pdf"), plt)
close(io)
fn = addExtension(fn, "pdf")
io = open(fn, "w")
show(io, MIME("application/pdf"), plt)
close(io)
end
pdf(fn::AbstractString) = pdf(current(), fn)
function ps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "ps")
io = open(fn, "w")
show(io, MIME("application/postscript"), plt)
close(io)
fn = addExtension(fn, "ps")
io = open(fn, "w")
show(io, MIME("application/postscript"), plt)
close(io)
end
ps(fn::AbstractString) = ps(current(), fn)
function eps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "eps")
io = open(fn, "w")
show(io, MIME("image/eps"), plt)
close(io)
fn = addExtension(fn, "eps")
io = open(fn, "w")
show(io, MIME("image/eps"), plt)
close(io)
end
eps(fn::AbstractString) = eps(current(), fn)
function tex(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "tex")
io = open(fn, "w")
show(io, MIME("application/x-tex"), plt)
close(io)
fn = addExtension(fn, "tex")
io = open(fn, "w")
show(io, MIME("application/x-tex"), plt)
close(io)
end
tex(fn::AbstractString) = tex(current(), fn)
@@ -66,39 +69,48 @@ end
html(fn::AbstractString) = html(current(), fn)
function txt(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "txt")
io = open(fn, "w")
show(io, MIME("text/plain"), plt)
close(io)
fn = addExtension(fn, "txt")
io = open(fn, "w")
show(io, MIME("text/plain"), plt)
close(io)
end
txt(fn::AbstractString) = txt(current(), fn)
# ----------------------------------------------------------------
const _savemap = Dict(
"png" => png,
"svg" => svg,
"pdf" => pdf,
"ps" => ps,
"ps" => ps,
"eps" => eps,
"tex" => tex,
"json" => json,
"html" => html,
"tikz" => tex,
"txt" => txt,
)
)
const _extension_map = Dict("tikz" => "tex")
function getExtension(fn::AbstractString)
pieces = split(fn, ".")
length(pieces) > 1 || error("Can't extract file extension: ", fn)
ext = pieces[end]
haskey(_savemap, ext) || error("Invalid file extension: ", fn)
ext
end
function addExtension(fn::AbstractString, ext::AbstractString)
oldfn, oldext = splitext(fn)
oldext = chop(oldext, head = 1, tail = 0)
if get(_extension_map, oldext, oldext) == ext
return fn
try
oldext = getExtension(fn)
if oldext == ext
return fn
else
return string(fn, ".", ext)
return "$fn.$ext"
end
catch
return "$fn.$ext"
end
end
"""
@@ -109,28 +121,27 @@ type is inferred from the file extension. All backends support png and pdf
file types, some also support svg, ps, eps, html and tex.
"""
function savefig(plt::Plot, fn::AbstractString)
fn = abspath(expanduser(fn))
fn = abspath(expanduser(fn))
# get the extension
local ext
try
ext = getExtension(fn)
catch
# if we couldn't extract the extension, add the default
ext = defaultOutputFormat(plt)
fn = addExtension(fn, ext)
end
# get the extension
fn, ext = splitext(fn)
ext = chop(ext, head = 1, tail = 0)
if isempty(ext)
ext = defaultOutputFormat(plt)
end
# save it
if haskey(_savemap, ext)
func = _savemap[ext]
return func(plt, fn)
else
error("Invalid file extension: ", fn)
end
# save it
func = get(_savemap, ext) do
error("Unsupported extension $ext with filename ", fn)
end
func(plt, fn)
end
savefig(fn::AbstractString) = savefig(current(), fn)
# ---------------------------------------------------------
"""
gui([plot])
@@ -153,13 +164,17 @@ end
_do_plot_show(plt, showval::Bool) = showval && gui(plt)
function _do_plot_show(plt, showval::Symbol)
showval == :gui && gui(plt)
showval in (:inline, :ijulia) && inline(plt)
showval in (:inline,:ijulia) && inline(plt)
end
# ---------------------------------------------------------
const _best_html_output_type =
KW(:pyplot => :png, :unicodeplots => :txt, :plotlyjs => :html, :plotly => :html)
const _best_html_output_type = KW(
:pyplot => :png,
:unicodeplots => :txt,
:plotlyjs => :html,
:plotly => :html
)
# a backup for html... passes to svg or png depending on the html_output_format arg
function _show(io::IO, ::MIME"text/html", plt::Plot)
@@ -169,12 +184,7 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end
if output_type == :png
# @info("writing png to html output")
print(
io,
"<img src=\"data:image/png;base64,",
base64encode(show, MIME("image/png"), plt),
"\" />",
)
print(io, "<img src=\"data:image/png;base64,", base64encode(show, MIME("image/png"), plt), "\" />")
elseif output_type == :svg
# @info("writing svg to html output")
show(io, MIME("image/svg+xml"), plt)
@@ -186,7 +196,7 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end
# delegate showable to _show instead
function Base.showable(m::M, plt::P) where {M <: MIME, P <: Plot}
function Base.showable(m::M, plt::P) where {M<:MIME, P<:Plot}
return hasmethod(_show, Tuple{IO, M, P})
end
@@ -195,31 +205,21 @@ function _display(plt::Plot)
end
# for writing to io streams... first prepare, then callback
for mime in (
"text/plain",
"text/html",
"image/png",
"image/eps",
"image/svg+xml",
"application/eps",
"application/pdf",
"application/postscript",
"application/x-tex",
"application/vnd.plotly.v1+json",
)
for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml",
"application/eps", "application/pdf", "application/postscript",
"application/x-tex", "application/vnd.plotly.v1+json")
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
if haskey(io, :juno_plotsize)
showjuno(io, m, plt)
showjuno(io, m, plt)
else
prepare_output(plt)
_show(io, m, plt)
prepare_output(plt)
_show(io, m, plt)
end
return nothing
end
end
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) =
showjuno(io, MIME("text/html"), plt)
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) = showjuno(io, MIME("text/html"), plt)
# default text/plain for all backends
_show(io::IO, ::MIME{Symbol("text/plain")}, plt::Plot) = show(io, plt)
@@ -258,25 +258,25 @@ function showjuno(io::IO, m, plt)
scale = minimum(jsize[i] / sz[i] for i in 1:2)
plt[:size] = [s * scale for s in sz]
plt[:dpi] = jratio * Plots.DPI
plt[:dpi] = jratio*Plots.DPI
plt[:thickness_scaling] *= scale
prepare_output(plt)
try
_showjuno(io, m, plt)
_showjuno(io, m, plt)
finally
plt[:size] = sz
plt[:dpi] = dpi
plt[:thickness_scaling] = thickness_scaling
plt[:size] = sz
plt[:dpi] = dpi
plt[:thickness_scaling] = thickness_scaling
end
end
function _showjuno(io::IO, m::MIME"image/svg+xml", plt)
if Symbol(plt.attr[:html_output_format]) :svg
throw(MethodError(show, (typeof(m), typeof(plt))))
else
_show(io, m, plt)
end
if Symbol(plt.attr[:html_output_format]) :svg
throw(MethodError(show, (typeof(m), typeof(plt))))
else
_show(io, m, plt)
end
end
Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot) = false
+29 -58
View File
@@ -1,8 +1,8 @@
# RecipesPipeline API
# RecipePipeline API
## Warnings
function RecipesPipeline.warn_on_recipe_aliases!(
function RecipePipeline.warn_on_recipe_aliases!(
plt::Plot,
plotattributes,
recipe_type,
@@ -14,25 +14,25 @@ function RecipesPipeline.warn_on_recipe_aliases!(
if k !== dk
@warn "Attribute alias `$k` detected in the $recipe_type recipe defined for the signature $(_signature_string(Val{recipe_type}, args...)). To ensure expected behavior it is recommended to use the default attribute `$dk`."
end
plotattributes[dk] = RecipesPipeline.pop_kw!(plotattributes, k)
plotattributes[dk] = pop_kw!(plotattributes, k)
end
end
end
function RecipesPipeline.warn_on_recipe_aliases!(
function RecipePipeline.warn_on_recipe_aliases!(
plt::Plot,
v::AbstractVector,
recipe_type,
args...,
)
foreach(x -> RecipesPipeline.warn_on_recipe_aliases!(plt, x, recipe_type, args...), v)
foreach(x -> RecipePipeline.warn_on_recipe_aliases!(plt, x, recipe_type, args...), v)
end
function RecipesPipeline.warn_on_recipe_aliases!(
function RecipePipeline.warn_on_recipe_aliases!(
plt::Plot,
rd::RecipeData,
recipe_type,
args...,
)
RecipesPipeline.warn_on_recipe_aliases!(plt, rd.plotattributes, recipe_type, args...)
RecipePipeline.warn_on_recipe_aliases!(plt, rd.plotattributes, recipe_type, args...)
end
function _signature_string(::Type{Val{:user}}, args...)
@@ -45,28 +45,28 @@ _signature_string(::Type{Val{:series}}, st) = "(::Type{Val{:$st}}, x, y, z)"
## Grouping
RecipesPipeline.splittable_attribute(plt::Plot, key, val::SeriesAnnotations, len) =
RecipesPipeline.splittable_attribute(plt, key, val.strs, len)
RecipePipeline.splittable_attribute(plt::Plot, key, val::SeriesAnnotations, len) =
RecipePipeline.splittable_attribute(plt, key, val.strs, len)
function RecipesPipeline.split_attribute(plt::Plot, key, val::SeriesAnnotations, indices)
split_strs = _RecipesPipeline.split_attribute(key, val.strs, indices)
function RecipePipeline.split_attribute(plt::Plot, key, val::SeriesAnnotations, indices)
split_strs = _RecipePipeline.split_attribute(key, val.strs, indices)
return SeriesAnnotations(split_strs, val.font, val.baseshape, val.scalefactor)
end
## Preprocessing attributes
RecipesPipeline.preprocess_attributes!(plt::Plot, plotattributes) =
RecipesPipeline.preprocess_attributes!(plotattributes) # in src/args.jl
RecipePipeline.preprocess_attributes!(plt::Plot, plotattributes) =
preprocess_attributes!(plotattributes) # in src/args.jl
RecipesPipeline.is_axis_attribute(plt::Plot, attr) = is_axis_attr_noletter(attr) # in src/args.jl
RecipePipeline.is_axis_attribute(plt::Plot, attr) = is_axis_attr_noletter(attr) # in src/args.jl
RecipesPipeline.is_subplot_attribute(plt::Plot, attr) = is_subplot_attr(attr) # in src/args.jl
RecipePipeline.is_subplot_attribute(plt::Plot, attr) = is_subplot_attr(attr) # in src/args.jl
## User recipes
function RecipesPipeline.process_userrecipe!(plt::Plot, kw_list, kw)
function RecipePipeline.process_userrecipe!(plt::Plot, kw_list, kw)
_preprocess_userrecipe(kw)
warn_on_unsupported_scales(plt.backend, kw)
# add the plot index
@@ -105,7 +105,7 @@ end
function _add_errorbar_kw(kw_list::Vector{KW}, kw::AKW)
# handle error bars by creating new recipedata data... these will have
# the same recipedata index as the recipedata they are copied from
for esym in (:xerror, :yerror, :zerror)
for esym in (:xerror, :yerror)
if get(kw, esym, nothing) !== nothing
# we make a copy of the KW and apply an errorbar recipe
errkw = copy(kw)
@@ -142,37 +142,22 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::AKW)
end
RecipesPipeline.get_axis_limits(plt::Plot, f, letter) = axis_limits(plt[1], letter)
RecipePipeline.get_axis_limits(plt::Plot, f, letter) = axis_limits(plt[1], :x)
## Plot recipes
RecipesPipeline.type_alias(plt::Plot) = get(_typeAliases, st, st)
RecipePipeline.type_alias(plt::Plot) = get(_typeAliases, st, st)
## Plot setup
function RecipesPipeline.plot_setup!(plt::Plot, plotattributes, kw_list)
function RecipePipeline.plot_setup!(plt::Plot, plotattributes, kw_list)
_plot_setup(plt, plotattributes, kw_list)
_subplot_setup(plt, plotattributes, kw_list)
return nothing
end
function RecipesPipeline.process_sliced_series_attributes!(plt::Plots.Plot, kw_list)
# swap errors
err_inds = findall(kw -> get(kw, :seriestype, :path) in (:xerror, :yerror, :zerror), kw_list)
for ind in err_inds
if get(kw_list[ind-1],:seriestype,:path) == :scatter
tmp = copy(kw_list[ind])
kw_list[ind] = copy(kw_list[ind-1])
kw_list[ind-1] = tmp
end
end
return nothing
end
# TODO: Should some of this logic be moved to RecipesPipeline?
# TODO: Should some of this logic be moved to RecipePipeline?
function _plot_setup(plt::Plot, plotattributes::AKW, kw_list::Vector{KW})
# merge in anything meant for the Plot
for kw in kw_list, (k, v) in kw
@@ -284,19 +269,18 @@ end
## Series recipes
function RecipesPipeline.slice_series_attributes!(plt::Plot, kw_list, kw)
function RecipePipeline.slice_series_attributes!(plt::Plot, kw_list, kw)
sp::Subplot = kw[:subplot]
# in series attributes given as vector with one element per series,
# select the value for current series
_slice_series_args!(kw, plt, sp, series_idx(kw_list, kw))
return nothing
end
RecipesPipeline.series_defaults(plt::Plot) = _series_defaults # in args.jl
RecipePipeline.series_defaults(plt::Plot) = _series_defaults # in args.jl
RecipesPipeline.is_seriestype_supported(plt::Plot, st) = is_seriestype_supported(st)
RecipePipeline.is_seriestype_supported(plt::Plot, st) = is_seriestype_supported(st)
function RecipesPipeline.add_series!(plt::Plot, plotattributes)
function RecipePipeline.add_series!(plt::Plot, plotattributes)
sp = _prepare_subplot(plt, plotattributes)
_expand_subplot_extrema(sp, plotattributes, plotattributes[:seriestype])
_update_series_attributes!(plotattributes, plt, sp)
@@ -314,7 +298,7 @@ function _prepare_subplot(plt::Plot{T}, plotattributes::AKW) where {T}
st = _override_seriestype_check(plotattributes, st)
# change to a 3d projection for this subplot?
if RecipesPipeline.needs_3d_axes(st)
if needs_3d_axes(st)
sp.attr[:projection] = "3d"
end
@@ -328,7 +312,7 @@ end
function _override_seriestype_check(plotattributes::AKW, st::Symbol)
# do we want to override the series type?
if !RecipesPipeline.is3d(st) && !(st in (:contour, :contour3d))
if !is3d(st) && !(st in (:contour, :contour3d))
z = plotattributes[:z]
if !isa(z, Nothing) &&
(size(plotattributes[:x]) == size(plotattributes[:y]) == size(z))
@@ -346,7 +330,7 @@ function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
ymin, ymax = ignorenan_extrema(plotattributes[:y])
expand_extrema!(sp[:xaxis], (xmin, xmax))
expand_extrema!(sp[:yaxis], (ymin, ymax))
elseif !(st in (:histogram, :bins2d, :histogram2d))
elseif !(st in (:pie, :histogram, :bins2d, :histogram2d))
expand_extrema!(sp, plotattributes)
end
# expand for zerolines (axes through origin)
@@ -357,20 +341,7 @@ function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
end
function _add_the_series(plt, sp, plotattributes)
extra_kwargs = warn_on_unsupported_args(plt.backend, plotattributes)
if (kw = plt[:extra_kwargs]) isa AbstractDict
plt[:extra_plot_kwargs] = get(kw,:plot,KW())
sp[:extra_kwargs] = get(kw,:subplot, KW())
plotattributes[:extra_kwargs] = get(kw,:series,KW())
elseif plt[:extra_kwargs] == :plot
plt[:extra_plot_kwargs] = extra_kwargs
elseif plt[:extra_kwargs] == :subplot
sp[:extra_kwargs] = extra_kwargs
elseif plt[:extra_kwargs] == :series
plotattributes[:extra_kwargs] = extra_kwargs
else
ArgumentError("Unsupported type for extra keyword arguments")
end
warn_on_unsupported_args(plt.backend, plotattributes)
warn_on_unsupported(plt.backend, plotattributes)
series = Series(plotattributes)
push!(plt.series_list, series)
+6 -4
View File
@@ -49,7 +49,7 @@ as a String to look up its docstring; e.g. `plotattr("seriestype")`.
function plot(args...; kw...)
# this creates a new plot with args/kw and sets it to be the current plot
plotattributes = KW(kw)
RecipesPipeline.preprocess_attributes!(plotattributes)
preprocess_attributes!(plotattributes)
# create an empty Plot then process
plt = Plot()
@@ -61,7 +61,7 @@ end
# note: we split into plt1 and plts_tail so we can dispatch correctly
function plot(plt1::Plot, plts_tail::Plot...; kw...)
plotattributes = KW(kw)
RecipesPipeline.preprocess_attributes!(plotattributes)
preprocess_attributes!(plotattributes)
# build our plot vector from the args
n = length(plts_tail) + 1
@@ -153,7 +153,7 @@ end
# this adds to a specific plot... most plot commands will flow through here
function plot!(plt::Plot, args...; kw...)
plotattributes = KW(kw)
RecipesPipeline.preprocess_attributes!(plotattributes)
preprocess_attributes!(plotattributes)
# merge!(plt.user_attr, plotattributes)
_plot!(plt, plotattributes, args)
end
@@ -164,7 +164,7 @@ end
# a list of series KW dicts.
# note: at entry, we only have those preprocessed args which were passed in... no default values yet
function _plot!(plt::Plot, plotattributes, args)
RecipesPipeline.recipe_pipeline!(plt, plotattributes, args)
RecipePipeline.recipe_pipeline!(plt, plotattributes, args)
current(plt)
_do_plot_show(plt, plt[:show])
return plt
@@ -212,3 +212,5 @@ function plot!(sp::Subplot, args...; kw...)
plt = sp.plt
plot!(plt, args...; kw..., subplot = findfirst(isequal(sp), plt.subplots))
end
# --------------------------------------------------------------------
+572 -98
View File
@@ -6,9 +6,10 @@ function _precompile_()
isdefined(Plots, Symbol("#_make_hist##kw")) && precompile(Tuple{getfield(Plots, Symbol("#_make_hist##kw")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Tuple{Int64, Int64}})
isdefined(Plots, Symbol("#_make_hist##kw")) && precompile(Tuple{getfield(Plots, Symbol("#_make_hist##kw")), NamedTuple{(:normed, :weights), Tuple{Bool, Nothing}}, typeof(Plots._make_hist), Tuple{Array{Float64, 1}}, Symbol})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:formatter,), Tuple{Symbol}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:formatter,), Tuple{typeof(RecipesPipeline.datetimeformatter)}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:formatter,), Tuple{typeof(Plots.datetimeformatter)}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Int64, Int64}, Bool}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :ticks), Tuple{Bool, Nothing}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:gridlinewidth, :grid, :gridalpha, :gridstyle, :foreground_color_grid), Tuple{Int64, Bool, Float64, Symbol, ColorTypes.RGBA{Float64}}}, typeof(Plots.attr!), Plots.Axis})
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:guide,), Tuple{String}}, typeof(Plots.attr!), Plots.Axis})
@@ -29,7 +30,6 @@ function _precompile_()
isdefined(Plots, Symbol("#gr_polyline##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_polyline##kw")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Base.UnitRange{Int64}, Array{Float64, 1}})
isdefined(Plots, Symbol("#gr_polyline##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_polyline##kw")), NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}}, typeof(Plots.gr_polyline), Base.UnitRange{Int64}, Base.UnitRange{Int64}})
isdefined(Plots, Symbol("#gr_set_font##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_set_font##kw")), NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}}, typeof(Plots.gr_set_font), Plots.Font})
isdefined(Plots, Symbol("#gr_set_font##kw")) && precompile(Tuple{getfield(Plots, Symbol("#gr_set_font##kw")), NamedTuple{(:halign, :valign, :rotation, :color), Tuple{Symbol, Symbol, Int64, ColorTypes.RGBA{Float64}}}, typeof(Plots.gr_set_font), Plots.Font})
isdefined(Plots, Symbol("#heatmap##kw")) && precompile(Tuple{getfield(Plots, Symbol("#heatmap##kw")), NamedTuple{(:aspect_ratio,), Tuple{Int64}}, typeof(Plots.heatmap), Array{String, 1}, Int})
isdefined(Plots, Symbol("#histogram##kw")) && precompile(Tuple{getfield(Plots, Symbol("#histogram##kw")), NamedTuple{(:bins, :weights), Tuple{Symbol, Array{Int64, 1}}}, typeof(Plots.histogram), Array{Float64, 1}})
isdefined(Plots, Symbol("#histogram2d##kw")) && precompile(Tuple{getfield(Plots, Symbol("#histogram2d##kw")), NamedTuple{(:nbins, :show_empty_bins, :normed, :aspect_ratio), Tuple{Tuple{Int64, Int64}, Bool, Bool, Int64}}, typeof(Plots.histogram2d), Array{Base.Complex{Float64}, 1}})
@@ -37,10 +37,7 @@ function _precompile_()
isdefined(Plots, Symbol("#hline!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#hline!##kw")), NamedTuple{(:line,), Tuple{Tuple{Int64, Symbol, Float64, Array{Symbol, 2}}}}, typeof(Plots.hline!), Array{Float64, 2}})
isdefined(Plots, Symbol("#lens!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#lens!##kw")), NamedTuple{(:inset,), Tuple{Tuple{Int64, Measures.BoundingBox{Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}, Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}}}}}, typeof(Plots.lens!), Array{Int64, 1}, Int})
isdefined(Plots, Symbol("#pie##kw")) && precompile(Tuple{getfield(Plots, Symbol("#pie##kw")), NamedTuple{(:title, :l), Tuple{String, Float64}}, typeof(Plots.pie), Array{String, 1}, Int})
isdefined(Plots, Symbol("#plotly_annotation_dict##kw")) && precompile(Tuple{getfield(Plots, Symbol("#plotly_annotation_dict##kw")), NamedTuple{(:xref, :yref), Tuple{String, String}}, typeof(Plots.plotly_annotation_dict), Float64, Float64, Plots.PlotText})
isdefined(Plots, Symbol("#plotly_annotation_dict##kw")) && precompile(Tuple{getfield(Plots, Symbol("#plotly_annotation_dict##kw")), NamedTuple{(:xref, :yref), Tuple{String, String}}, typeof(Plots.plotly_annotation_dict), Float64, Float64, String})
isdefined(Plots, Symbol("#plotly_annotation_dict##kw")) && precompile(Tuple{getfield(Plots, Symbol("#plotly_annotation_dict##kw")), NamedTuple{(:xref, :yref), Tuple{String, String}}, typeof(Plots.plotly_annotation_dict), Int64, Float64, Plots.PlotText})
isdefined(Plots, Symbol("#plotly_annotation_dict##kw")) && precompile(Tuple{getfield(Plots, Symbol("#plotly_annotation_dict##kw")), NamedTuple{(:xref, :yref), Tuple{String, String}}, typeof(Plots.plotly_annotation_dict), Int64, Float64, String})
isdefined(Plots, Symbol("#portfoliocomposition##kw")) && precompile(Tuple{getfield(Plots, Symbol("#portfoliocomposition##kw")), NamedTuple{(:labels,), Tuple{Array{String, 2}}}, typeof(Plots.portfoliocomposition), Array{Float64, 2}, Int})
isdefined(Plots, Symbol("#scatter!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter!##kw")), NamedTuple{(:marker, :series_annotations), Tuple{Tuple{Int64, Float64, Symbol}, Array{Any, 1}}}, typeof(Plots.scatter!), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
isdefined(Plots, Symbol("#scatter!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter!##kw")), NamedTuple{(:markersize, :c), Tuple{Int64, Symbol}}, typeof(Plots.scatter!), Array{Float64, 1}})
@@ -50,20 +47,500 @@ function _precompile_()
isdefined(Plots, Symbol("#scatter##kw")) && precompile(Tuple{getfield(Plots, Symbol("#scatter##kw")), NamedTuple{(:marker_z, :color, :legend), Tuple{typeof(Base.:+), Symbol, Bool}}, typeof(Plots.scatter), Array{Float64, 1}, Array{Float64, 1}})
isdefined(Plots, Symbol("#standalone_html##kw")) && precompile(Tuple{getfield(Plots, Symbol("#standalone_html##kw")), NamedTuple{(:title,), Tuple{String}}, typeof(Plots.standalone_html), Plots.Plot{Plots.PlotlyBackend}})
isdefined(Plots, Symbol("#test_examples##kw")) && precompile(Tuple{getfield(Plots, Symbol("#test_examples##kw")), NamedTuple{(:skip,), Tuple{Array{Int64, 1}}}, typeof(Plots.test_examples), Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Array{Float64, 1}, 1}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Array{T, 1} where T, 1}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Dates.DateTime, 1}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._apply_type_recipe), Base.Dict{Symbol, Any}, Array{Function, 1}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._apply_type_recipe), Base.Dict{Symbol, Any}, Int64, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._apply_type_recipe), Base.Dict{Symbol, Any}, Plots.RecipePipeline.Formatted{Array{Int64, 1}}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._apply_type_recipe), Base.Dict{Symbol, Any}, Plots.RecipePipeline.Surface{Array{Float64, 2}}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._apply_type_recipe), Base.Dict{Symbol, Any}, typeof(identity), Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Array{Float64, 1}, Array{Float64, 1}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Array{Float64, 1}, Base.UnitRange{Int64}, Plots.RecipePipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Array{Float64, 1}, typeof(identity), Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Array{String, 1}, Array{Float64, 1}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Array{String, 1}, Array{String, 1}, Plots.RecipePipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Plots.RecipePipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Plots.RecipePipeline.Surface{Array{Float64, 2}}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Base.StepRange{Int64, Int64}, Array{Float64, 1}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Base.StepRange{Int64, Int64}, Plots.RecipePipeline.Surface{Array{Float64, 2}}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Nothing, Array{Float64, 1}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Nothing, Array{Union{Base.Missing, Float64}, 1}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Nothing, Base.UnitRange{Int64}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Nothing, Nothing, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._compute_xyz), Nothing, Plots.RecipePipeline.Surface{Array{Float64, 2}}, Nothing})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, Plots.Spy}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy, typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.RecipePipeline.GroupBy}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._expand_seriestype_array), Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.RecipePipeline._extract_group_attributes), Array{String, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._filter_input_data!), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._finish_userrecipe!), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}, RecipesBase.RecipeData})
precompile(Tuple{typeof(Plots.RecipePipeline._finish_userrecipe!), Plots.Plot{Plots.PlotlyBackend}, Array{Base.Dict{Symbol, Any}, 1}, RecipesBase.RecipeData})
precompile(Tuple{typeof(Plots.RecipePipeline._nobigs), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._postprocess_axis_args!), Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline._prepare_series_data), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._prepare_series_data), Array{Float64, 2}})
precompile(Tuple{typeof(Plots.RecipePipeline._prepare_series_data), Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._prepare_series_data), Array{Real, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._prepare_series_data), Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._prepare_series_data), Array{Union{Base.Missing, Number}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._preprocess_axis_args!), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_fillrange), Int64, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_fillrange), Nothing, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_plotrecipe), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_plotrecipe), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_plotrecipes!), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_plotrecipes!), Plots.Plot{Plots.PlotlyBackend}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_ribbon), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_ribbon), Int64, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_ribbon), Nothing, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_ribbon), Tuple{Base.LinRange{Float64}, Base.LinRange{Float64}}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_ribbon), typeof(identity), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_seriesrecipe), Plots.Plot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.RecipePipeline._process_seriesrecipe), Plots.Plot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.RecipePipeline._process_seriesrecipes!), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_seriesrecipes!), Plots.Plot{Plots.PlotlyBackend}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots.RecipePipeline._process_userrecipes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots.RecipePipeline._recipedata_vector), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.RecipePipeline._scaled_adapted_grid), typeof(identity), Symbol, Symbol, Float64, Float64})
precompile(Tuple{typeof(Plots.RecipePipeline._series_data_vector), Array{Array{Float64, 1}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._series_data_vector), Array{Array{T, 1} where T, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._series_data_vector), Array{Float64, 2}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._series_data_vector), Array{Function, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._series_data_vector), Array{Real, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._series_data_vector), Array{Union{Base.Missing, Int64}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._series_data_vector), Array{Union{Base.Missing, Number}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline._series_data_vector), typeof(identity), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.add_series!), Plots.Plot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.RecipePipeline.add_series!), Plots.Plot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.RecipePipeline.filter_data!), Base.Dict{Symbol, Any}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.filter_data), Array{Float64, 1}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.filter_data), Base.OneTo{Int64}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.filter_data), Nothing, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Array{Symbol, 2}})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Type{Base.Val{:contour}}})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Type{Base.Val{:heatmap}}})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Type{Base.Val{:path3d}}})
precompile(Tuple{typeof(Plots.RecipePipeline.is3d), Type{Int}})
precompile(Tuple{typeof(Plots.RecipePipeline.is_axis_attribute), Plots.Plot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.is_axis_attribute), Plots.Plot{Plots.PlotlyBackend}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.is_seriestype_supported), Plots.Plot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.is_seriestype_supported), Plots.Plot{Plots.PlotlyBackend}, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.is_surface), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.is_surface), Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.is_surface), Type{Base.Val{:contour}}})
precompile(Tuple{typeof(Plots.RecipePipeline.is_surface), Type{Base.Val{:heatmap}}})
precompile(Tuple{typeof(Plots.RecipePipeline.is_surface), Type{Int}})
precompile(Tuple{typeof(Plots.RecipePipeline.needs_3d_axes), Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.needs_3d_axes), Type{Base.Val{:path3d}}})
precompile(Tuple{typeof(Plots.RecipePipeline.needs_3d_axes), Type{Int}})
precompile(Tuple{typeof(Plots.RecipePipeline.preprocess_attributes!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.preprocess_attributes!), Plots.Plot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.RecipePipeline.preprocess_attributes!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.preprocess_attributes!), Plots.Plot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.RecipePipeline.process_userrecipe!), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.process_userrecipe!), Plots.Plot{Plots.PlotlyBackend}, Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}, Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{typeof(Base.log), Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Base.Complex{Float64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Dates.DateTime, 1}, Base.UnitRange{Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Function, 1}, Float64, Float64}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Int64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Plots.OHLC{T} where T<:Real, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{String, 1}, Array{String, 1}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Tuple{Int64, Real}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Union{Base.Missing, Int64}, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.StepRange{Int64, Int64}, Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Base.UnitRange{Int64}}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.PortfolioComposition}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{Plots.Spy}})
precompile(Tuple{typeof(Plots.RecipePipeline.recipe_pipeline!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Tuple{}})
precompile(Tuple{typeof(Plots.RecipePipeline.slice_series_attributes!), Plots.Plot{Plots.GRBackend}, Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.slice_series_attributes!), Plots.Plot{Plots.PlotlyBackend}, Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.GRBackend}, Symbol, Array{Int64, 1}, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.GRBackend}, Symbol, Array{String, 1}, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.GRBackend}, Symbol, Array{Symbol, 2}, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.GRBackend}, Symbol, Plots.GridLayout, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.GRBackend}, Symbol, Plots.Plot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.GRBackend}, Symbol, String, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.GRBackend}, Symbol, Symbol, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.PlotlyBackend}, Symbol, Array{Int64, 1}, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.PlotlyBackend}, Symbol, Array{String, 1}, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.PlotlyBackend}, Symbol, Array{Symbol, 2}, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.PlotlyBackend}, Symbol, Plots.GridLayout, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.PlotlyBackend}, Symbol, Plots.Plot{Plots.PlotlyBackend}, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.PlotlyBackend}, Symbol, String, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.splittable_attribute), Plots.Plot{Plots.PlotlyBackend}, Symbol, Symbol, Int64})
precompile(Tuple{typeof(Plots.RecipePipeline.unzip), Array{Tuple{Array{Float64, 1}, Array{Float64, 1}}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.unzip), Array{Tuple{Float64, Float64, Float64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Array{T, 1} where T, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Array{T, 1} where T, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Base.Complex{Float64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Dates.DateTime, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Float64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Float64, 2}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Function, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Int64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Plots.OHLC{T} where T<:Real, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{String, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Tuple{Int64, Real}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Base.StepRange{Int64, Int64}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Int64, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Nothing, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Plots.PortfolioComposition})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Plots.RecipePipeline.Formatted{Array{Int64, 1}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Plots.RecipePipeline.GroupBy, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Plots.Spy})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Type{Int}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, typeof(identity), Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Array{T, 1} where T, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Array{T, 1} where T, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Base.Complex{Float64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Dates.DateTime, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Float64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Float64, 2}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Function, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Int64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Plots.OHLC{T} where T<:Real, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{String, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Tuple{Int64, Real}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Base.StepRange{Int64, Int64}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Int64, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Nothing, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Plots.PortfolioComposition})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Plots.RecipePipeline.Formatted{Array{Int64, 1}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Plots.RecipePipeline.GroupBy, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Plots.Spy})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Type{Int}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, typeof(identity), Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict, Symbol, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Array{T, 1} where T, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Array{T, 1} where T, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Base.Complex{Float64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Dates.DateTime, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Float64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Float64, 2}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Function, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Int64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Plots.OHLC{T} where T<:Real, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{String, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Tuple{Int64, Real}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Base.StepRange{Int64, Int64}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Int64, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Nothing, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Plots.PortfolioComposition})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Plots.RecipePipeline.Formatted{Array{Int64, 1}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Plots.RecipePipeline.GroupBy, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Plots.Spy})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, Type{Int}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.GRBackend}, RecipesBase.RecipeData, Symbol, typeof(identity), Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Array{T, 1} where T, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Array{T, 1} where T, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Base.Complex{Float64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Dates.DateTime, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Float64, 2}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Function, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Int64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Plots.OHLC{T} where T<:Real, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{String, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Tuple{Int64, Real}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Base.StepRange{Int64, Int64}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Nothing, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Plots.PortfolioComposition})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Plots.RecipePipeline.Formatted{Array{Int64, 1}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Plots.RecipePipeline.GroupBy, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Plots.Spy})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, Type{Int}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Array{RecipesBase.RecipeData, 1}, Symbol, typeof(identity), Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Array{T, 1} where T, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Array{T, 1} where T, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Base.Complex{Float64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Dates.DateTime, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Float64, 2}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Function, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Int64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Plots.OHLC{T} where T<:Real, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{String, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Tuple{Int64, Real}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Base.StepRange{Int64, Int64}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Nothing, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Plots.PortfolioComposition})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Plots.RecipePipeline.Formatted{Array{Int64, 1}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Plots.RecipePipeline.GroupBy, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Plots.Spy})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Type{Int}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, typeof(identity), Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict, Symbol, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Array{T, 1} where T, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Array{T, 1} where T, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Base.Complex{Float64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Dates.DateTime, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Float64, 2}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Function, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Int64, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Plots.OHLC{T} where T<:Real, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{String, 1}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Tuple{Int64, Real}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Array{Union{Base.Missing, Int64}, 1}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Base.StepRange{Int64, Int64}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Nothing, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Plots.PortfolioComposition})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Plots.RecipePipeline.Formatted{Array{Int64, 1}}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Plots.RecipePipeline.GroupBy, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Plots.Spy})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Symbol})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, Type{Int}, Int})
precompile(Tuple{typeof(Plots.RecipePipeline.warn_on_recipe_aliases!), Plots.Plot{Plots.PlotlyBackend}, RecipesBase.RecipeData, Symbol, typeof(identity), Int})
precompile(Tuple{typeof(Plots.RecipePipeline.wrap_surfaces!), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.__init__)})
precompile(Tuple{typeof(Plots._add_errorbar_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._add_markershape), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._add_smooth_kw), Array{Base.Dict{Symbol, Any}, 1}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._as_gradient), PlotUtils.ContinuousColorGradient})
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._add_the_series), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._backend_instance), Symbol})
precompile(Tuple{typeof(Plots._bin_centers), Array{Float64, 1}})
precompile(Tuple{typeof(Plots._binbarlike_baseline), Float64, Symbol})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Int64, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Nothing, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{PlotUtils.ContinuousColorGradient, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{PlotUtils.ColorGradient, 1}, String})
precompile(Tuple{typeof(Plots._cbar_unique), Array{Symbol, 1}, String})
precompile(Tuple{typeof(Plots._create_backend_figure), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._create_backend_figure), Plots.Plot{Plots.PlotlyBackend}})
@@ -77,6 +554,7 @@ function _precompile_()
precompile(Tuple{typeof(Plots._cycle), Base.OneTo{Int64}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots._cycle), Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Int64})
precompile(Tuple{typeof(Plots._cycle), Base.StepRange{Int64, Int64}, Array{Int64, 1}})
precompile(Tuple{typeof(Plots._cycle), Base.StepRange{Int64, Int64}, Int64})
precompile(Tuple{typeof(Plots._cycle), ColorTypes.RGBA{Float64}, Int64})
precompile(Tuple{typeof(Plots._cycle), Float64, Int64})
precompile(Tuple{typeof(Plots._cycle), Int64, Base.StepRange{Int64, Int64}})
@@ -84,8 +562,6 @@ function _precompile_()
precompile(Tuple{typeof(Plots._cycle), Nothing, Array{Int64, 1}})
precompile(Tuple{typeof(Plots._cycle), Nothing, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots._cycle), Nothing, Int64})
precompile(Tuple{typeof(Plots._cycle), PlotUtils.ColorPalette, Int64})
precompile(Tuple{typeof(Plots._cycle), PlotUtils.ContinuousColorGradient, Int64})
precompile(Tuple{typeof(Plots._cycle), Plots.Shape, Int64})
precompile(Tuple{typeof(Plots._cycle), Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots._cycle), Plots.Subplot{Plots.PlotlyBackend}, Int64})
@@ -94,15 +570,15 @@ function _precompile_()
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Bool})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots._do_plot_show), Plots.Plot{Plots.PlotlyBackend}, Bool})
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._expand_subplot_extrema), Plots.Subplot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._heatmap_edges), Array{Float64, 1}, Bool})
precompile(Tuple{typeof(Plots._hist_edge), Tuple{Array{Float64, 1}}, Int64, Symbol})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Int64})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}, Array{Float64, 1}}, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots._hist_edges), Tuple{Array{Float64, 1}}, Symbol})
precompile(Tuple{typeof(Plots._initialize_backend), Plots.PlotlyBackend})
precompile(Tuple{typeof(Plots._override_seriestype_check), RecipesPipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._override_seriestype_check), Plots.RecipePipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots._pick_default_backend)})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{Float64, 1}, 1}, Array{Array{Float64, 1}, 1}}})
precompile(Tuple{typeof(Plots._plot!), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Tuple{Array{Array{T, 1} where T, 1}, Array{Float64, 2}}})
@@ -160,24 +636,24 @@ function _precompile_()
precompile(Tuple{typeof(Plots._plot_setup), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._plotly_framestyle), Symbol})
precompile(Tuple{typeof(Plots._plots_defaults)})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._preprocess_barlike), RecipesPipeline.DefaultsDict, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_barlike), RecipesPipeline.DefaultsDict, Array{Int64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_barlike), RecipesPipeline.DefaultsDict, Base.OneTo{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_binlike), RecipesPipeline.DefaultsDict, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._prepare_subplot), Plots.Plot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._preprocess_barlike), Plots.RecipePipeline.DefaultsDict, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_barlike), Plots.RecipePipeline.DefaultsDict, Array{Int64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_barlike), Plots.RecipePipeline.DefaultsDict, Base.OneTo{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_binlike), Plots.RecipePipeline.DefaultsDict, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots._preprocess_userrecipe), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._replace_linewidth), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._replace_linewidth), Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._replace_markershape), Array{Symbol, 2}})
precompile(Tuple{typeof(Plots._replace_markershape), Plots.Shape})
precompile(Tuple{typeof(Plots._scale_adjusted_values), Type{Float64}, Array{Float64, 1}, Symbol})
precompile(Tuple{typeof(Plots._series_index), RecipesPipeline.DefaultsDict, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._series_index), RecipesPipeline.DefaultsDict, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._series_index), Plots.RecipePipeline.DefaultsDict, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._series_index), Plots.RecipePipeline.DefaultsDict, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._show), Base.IOStream, Base.Multimedia.MIME{Symbol("image/png")}, Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._slice_series_args!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots._slice_series_args!), Base.Dict{Symbol, Any}, Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Int64})
precompile(Tuple{typeof(Plots._slice_series_args!), RecipesPipeline.DefaultsDict, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots._slice_series_args!), RecipesPipeline.DefaultsDict, Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Int64})
precompile(Tuple{typeof(Plots._slice_series_args!), Plots.RecipePipeline.DefaultsDict, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Int64})
precompile(Tuple{typeof(Plots._slice_series_args!), Plots.RecipePipeline.DefaultsDict, Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Int64})
precompile(Tuple{typeof(Plots._subplot_setup), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._subplot_setup), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Array{Base.Dict{Symbol, Any}, 1}})
precompile(Tuple{typeof(Plots._transform_ticks), Base.StepRange{Int64, Int64}})
@@ -185,11 +661,11 @@ function _precompile_()
precompile(Tuple{typeof(Plots._transform_ticks), Nothing})
precompile(Tuple{typeof(Plots._transform_ticks), Symbol})
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, RecipesPipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Axis, Plots.RecipePipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict, Symbol, Int64})
precompile(Tuple{typeof(Plots._update_axis_colors), Plots.Axis})
precompile(Tuple{typeof(Plots._update_axis_links), Plots.Plot{Plots.GRBackend}, Plots.Axis, Symbol})
precompile(Tuple{typeof(Plots._update_axis_links), Plots.Plot{Plots.PlotlyBackend}, Plots.Axis, Symbol})
@@ -199,22 +675,22 @@ function _precompile_()
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._update_min_padding!), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._update_series_attributes!), RecipesPipeline.DefaultsDict, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._update_series_attributes!), RecipesPipeline.DefaultsDict, Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._update_plot_args), Plots.Plot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots._update_series_attributes!), Plots.RecipePipeline.DefaultsDict, Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._update_series_attributes!), Plots.RecipePipeline.DefaultsDict, Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Base.Dict{Symbol, Any}, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_args), Plots.Plot{Plots.PlotlyBackend}, Plots.Subplot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict, Int64, Bool})
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots._update_subplot_colors), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots._update_subplot_periphery), Plots.Subplot{Plots.GRBackend}, Array{Any, 1}})
precompile(Tuple{typeof(Plots._update_subplot_periphery), Plots.Subplot{Plots.PlotlyBackend}, Array{Any, 1}})
precompile(Tuple{typeof(Plots.addExtension), String, String})
precompile(Tuple{typeof(Plots.add_layout_pct!), Base.Dict{Symbol, Any}, Expr, Int64, Int64})
precompile(Tuple{typeof(Plots.aliasesAndAutopick), RecipesPipeline.DefaultsDict, Symbol, Base.Dict{Symbol, Symbol}, Array{Symbol, 1}, Int64})
precompile(Tuple{typeof(Plots.aliasesAndAutopick), Plots.RecipePipeline.DefaultsDict, Symbol, Base.Dict{Symbol, Symbol}, Array{Symbol, 1}, Int64})
precompile(Tuple{typeof(Plots.allAlphas), Int64})
precompile(Tuple{typeof(Plots.allStyles), Int64})
precompile(Tuple{typeof(Plots.allStyles), Symbol})
@@ -222,6 +698,7 @@ function _precompile_()
precompile(Tuple{typeof(Plots.arrow), Int64})
precompile(Tuple{typeof(Plots.attr), Plots.EmptyLayout, Symbol, Symbol})
precompile(Tuple{typeof(Plots.attr), Plots.EmptyLayout, Symbol})
precompile(Tuple{typeof(Plots.autopick), Array{ColorTypes.RGBA{Float64}, 1}, Int64})
precompile(Tuple{typeof(Plots.autopick_ignore_none_auto), Array{Symbol, 1}, Int64})
precompile(Tuple{typeof(Plots.axis_drawing_info), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.axis_drawing_info_3d), Plots.Subplot{Plots.GRBackend}})
@@ -247,10 +724,10 @@ function _precompile_()
precompile(Tuple{typeof(Plots.bottompad), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64, Array{Plots.Plot{T} where T<:RecipesBase.AbstractBackend, 1}})
precompile(Tuple{typeof(Plots.build_layout), Plots.GridLayout, Int64})
precompile(Tuple{typeof(Plots.build_layout), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.build_layout), Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.calc_num_subplots), Plots.EmptyLayout})
precompile(Tuple{typeof(Plots.calc_num_subplots), Plots.GridLayout})
precompile(Tuple{typeof(Plots.color_or_nothing!), RecipesPipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots.color_or_nothing!), Plots.RecipePipeline.DefaultsDict, Symbol})
precompile(Tuple{typeof(Plots.colorbar_style), Plots.Series})
precompile(Tuple{typeof(Plots.compute_gridsize), Int64, Int64, Int64})
precompile(Tuple{typeof(Plots.concatenate_fillrange), Base.UnitRange{Int64}, Tuple{Array{Float64, 1}, Array{Float64, 1}}})
@@ -276,11 +753,7 @@ function _precompile_()
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Base.Missing})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, Char})
precompile(Tuple{typeof(Plots.discrete_value!), Plots.Axis, String})
precompile(Tuple{typeof(Plots.ensure_gradient!), RecipesPipeline.DefaultsDict, Symbol, Symbol})
precompile(Tuple{typeof(Plots.error_coords), Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.error_coords), Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.error_style!), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.error_zipit), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.ensure_gradient!), Plots.RecipePipeline.DefaultsDict, Symbol, Symbol})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.OneTo{Int64}})
@@ -289,14 +762,14 @@ function _precompile_()
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Float64})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Int64})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, RecipesPipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Plots.RecipePipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Axis, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.GRBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.PlotlyBackend}, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.GRBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.expand_extrema!), Plots.Subplot{Plots.PlotlyBackend}, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.extend_by_data!), Array{Float64, 1}, Float64})
precompile(Tuple{typeof(Plots.extend_series_data!), Plots.Series, Float64, Symbol})
precompile(Tuple{typeof(Plots.fakedata), Int64, Int64})
precompile(Tuple{typeof(Plots.fg_color), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.fg_color), Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.font), Int64, Int})
precompile(Tuple{typeof(Plots.font), String, Int})
precompile(Tuple{typeof(Plots.font), Symbol, Int})
@@ -311,13 +784,11 @@ function _precompile_()
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.PlotlyBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.get_clims), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.get_colorgradient), Plots.Series})
precompile(Tuple{typeof(Plots.get_fillalpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_fillalpha), Plots.Series})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.get_fillcolor), Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.get_gradient), PlotUtils.ContinuousColorGradient})
precompile(Tuple{typeof(Plots.get_linealpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_linealpha), Plots.Series})
precompile(Tuple{typeof(Plots.get_linecolor), Plots.Series, Float64, Float64, Int64})
@@ -331,16 +802,16 @@ function _precompile_()
precompile(Tuple{typeof(Plots.get_markercolor), Plots.Series, Float64, Float64, Int64})
precompile(Tuple{typeof(Plots.get_markerstrokealpha), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_markerstrokecolor), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_markerstrokewidth), Plots.Series, Int64})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{Any, 1}}})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Float64, 1}, Array{String, 1}}})
precompile(Tuple{typeof(Plots.get_minor_ticks), Plots.Subplot{Plots.GRBackend}, Plots.Axis, Tuple{Array{Int64, 1}, Array{String, 1}}})
precompile(Tuple{typeof(Plots.get_plotly_marker), Symbol, String})
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), ColorTypes.RGBA{Float64}, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), Int64, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), Int64, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ContinuousColorGradient, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ContinuousColorGradient, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ColorGradient, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), PlotUtils.ColorGradient, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.GRBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_series_color), Symbol, Plots.Subplot{Plots.PlotlyBackend}, Int64, Symbol})
precompile(Tuple{typeof(Plots.get_subplot), Plots.Plot{Plots.GRBackend}, Plots.Subplot{Plots.GRBackend}})
@@ -357,32 +828,33 @@ function _precompile_()
precompile(Tuple{typeof(Plots.gr_display), Plots.Plot{Plots.GRBackend}, String})
precompile(Tuple{typeof(Plots.gr_display), Plots.Subplot{Plots.GRBackend}, Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_draw_colorbar), Plots.GRColorbar, Plots.Subplot{Plots.GRBackend}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64, Float64, Float64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64, Float64, Float64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Float64, Float64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Float64, Float64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Int64, Tuple{Float64, Float64}, Int64, Float64, Float64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Int64, Tuple{Float64, Float64}, Int64, Float64, Float64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64, Int64})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64, Int64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Float64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Float64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Float64, Tuple{Float64, Float64}, Int64, Int64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Int64, Tuple{Float64, Float64}, Int64, Int64, Plots.Shape})
precompile(Tuple{typeof(Plots.gr_draw_marker), Plots.Series, Int64, Int64, Tuple{Float64, Float64}, Int64, Int64, Symbol})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}, Int64, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Array{Int64, 1}, Array{Int64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Array{Float64, 1}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.OneTo{Int64}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Float64, Float64})
precompile(Tuple{typeof(Plots.gr_draw_markers), Plots.Series, Float64, Float64, Tuple{Float64, Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_fill_viewport), Array{Float64, 1}, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_get_color), Plots.Series})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{Any, 1}}, Int64})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Float64, 1}, Array{String, 1}}, Int64})
precompile(Tuple{typeof(Plots.gr_get_ticks_size), Tuple{Array{Int64, 1}, Array{String, 1}}, Int64})
precompile(Tuple{typeof(Plots.gr_getcolorind), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_inqtext), Int64, Int64, String})
precompile(Tuple{typeof(Plots.gr_legend_pos), Plots.Subplot{Plots.GRBackend}, Float64, Float64})
precompile(Tuple{typeof(Plots.gr_linetype), Symbol})
precompile(Tuple{typeof(Plots.gr_polaraxes), Int64, Float64, Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}, typeof(identity)})
precompile(Tuple{typeof(Plots.gr_polyline), Array{Float64, 1}, Array{Float64, 1}})
@@ -390,18 +862,18 @@ function _precompile_()
precompile(Tuple{typeof(Plots.gr_set_fill), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_fillcolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_font), Plots.Font})
precompile(Tuple{typeof(Plots.gr_set_gradient), PlotUtils.ContinuousColorGradient})
precompile(Tuple{typeof(Plots.gr_set_gradient), PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots.gr_set_gradient), Plots.Series})
precompile(Tuple{typeof(Plots.gr_set_line), Float64, Symbol, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, PlotUtils.ContinuousColorGradient})
precompile(Tuple{typeof(Plots.gr_set_linecolor), PlotUtils.ContinuousColorGradient})
precompile(Tuple{typeof(Plots.gr_set_line), Int64, Symbol, PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots.gr_set_linecolor), PlotUtils.ColorGradient})
precompile(Tuple{typeof(Plots.gr_set_markercolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_textcolor), ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Float64})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Int64})
precompile(Tuple{typeof(Plots.gr_set_transparency), ColorTypes.RGBA{Float64}, Nothing})
precompile(Tuple{typeof(Plots.gr_set_transparency), Float64})
precompile(Tuple{typeof(Plots.gr_set_viewport_cmap), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_set_viewport_polar)})
precompile(Tuple{typeof(Plots.gr_set_xticks_font), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.gr_set_yticks_font), Plots.Subplot{Plots.GRBackend}})
@@ -421,7 +893,6 @@ function _precompile_()
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Plots.Shape, Symbol})
precompile(Tuple{typeof(Plots.handleColors!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.has_attribute_segments), Plots.Series})
precompile(Tuple{typeof(Plots.has_black_border_for_default), Symbol})
precompile(Tuple{typeof(Plots.hascolorbar), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.hascolorbar), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.hasgrid), Symbol, Symbol})
@@ -454,15 +925,22 @@ function _precompile_()
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.is_2tuple), Tuple{Int64, Measures.BoundingBox{Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}, Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}}}})
precompile(Tuple{typeof(Plots.is_axis_attr), Symbol})
precompile(Tuple{typeof(Plots.is_axis_attr_noletter), Symbol})
precompile(Tuple{typeof(Plots.is_default_attribute), Symbol})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.PlotlyBackend, Symbol})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.Shape})
precompile(Tuple{typeof(Plots.is_marker_supported), Plots.Stroke})
precompile(Tuple{typeof(Plots.is_marker_supported), Symbol})
precompile(Tuple{typeof(Plots.is_scale_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.is_scale_supported), Plots.PlotlyBackend, Symbol})
precompile(Tuple{typeof(Plots.is_series_attr), Symbol})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Plots.PlotlyBackend, Symbol})
precompile(Tuple{typeof(Plots.is_seriestype_supported), Symbol})
precompile(Tuple{typeof(Plots.is_style_supported), Plots.GRBackend, Symbol})
precompile(Tuple{typeof(Plots.is_style_supported), Plots.PlotlyBackend, Symbol})
precompile(Tuple{typeof(Plots.is_subplot_attr), Symbol})
precompile(Tuple{typeof(Plots.is_uniformly_spaced), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iscontour), Plots.Series})
precompile(Tuple{typeof(Plots.isijulia)})
@@ -470,7 +948,7 @@ function _precompile_()
precompile(Tuple{typeof(Plots.ispolar), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.ispolar), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.isvertical), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.isvertical), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.isvertical), Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.iter_segments), Array{Float64, 1}, Array{Float64, 1}, Int})
precompile(Tuple{typeof(Plots.iter_segments), Array{Float64, 1}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.iter_segments), Array{Int64, 1}, Array{Float64, 1}})
@@ -488,7 +966,7 @@ function _precompile_()
precompile(Tuple{typeof(Plots.layout_args), Int64, Tuple{Int64, Int64}})
precompile(Tuple{typeof(Plots.layout_args), Int64})
precompile(Tuple{typeof(Plots.layout_args), Plots.GridLayout})
precompile(Tuple{typeof(Plots.layout_args), RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.layout_args), Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.left), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.left), Measures.BoundingBox{Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}, Tuple{Measures.Length{:w, Float64}, Measures.Length{:h, Float64}}}})
precompile(Tuple{typeof(Plots.leftpad), Plots.Subplot{Plots.GRBackend}})
@@ -496,15 +974,14 @@ function _precompile_()
precompile(Tuple{typeof(Plots.legendfont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.legendfont), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.legendtitlefont), Plots.Subplot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.like_histogram), Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Array{RecipesBase.AbstractLayout, 1}, Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Axis, Plots.Axis})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Axis})
precompile(Tuple{typeof(Plots.link_axes!), Plots.GridLayout, Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Subplot{Plots.GRBackend}, Symbol})
precompile(Tuple{typeof(Plots.link_axes!), Plots.Subplot{Plots.PlotlyBackend}, Symbol})
precompile(Tuple{typeof(Plots.link_subplots), Array{RecipesBase.AbstractLayout, 1}, Symbol})
precompile(Tuple{typeof(Plots.locate_annotation), Plots.Subplot{Plots.GRBackend}, Int64, Float64, Plots.PlotText})
precompile(Tuple{typeof(Plots.locate_annotation), Plots.Subplot{Plots.PlotlyBackend}, Int64, Float64, Plots.PlotText})
precompile(Tuple{typeof(Plots.make_fillrange_from_ribbon), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.make_fillrange_side), Base.UnitRange{Int64}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.make_fillrange_side), Base.UnitRange{Int64}, Base.LinRange{Float64}})
@@ -522,8 +999,8 @@ function _precompile_()
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis, Nothing})
precompile(Tuple{typeof(Plots.parse_axis_kw), Symbol})
precompile(Tuple{typeof(Plots.partialcircle), Float64, Float64, Int64, Int64})
precompile(Tuple{typeof(Plots.partialcircle), Int64, Float64, Int64, Int64})
precompile(Tuple{typeof(Plots.pie_labels), Plots.Subplot{Plots.GRBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.pie_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.plotarea!), Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.plotarea!), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.plotarea!), Plots.Subplot{Plots.PlotlyBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
@@ -533,19 +1010,19 @@ function _precompile_()
precompile(Tuple{typeof(Plots.plotly_apply_aspect_ratio), Plots.Subplot{Plots.PlotlyBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotly_axis), Plots.Plot{Plots.PlotlyBackend}, Plots.Axis, Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.plotly_colorbar_hack), Plots.Series, Base.Dict{Symbol, Any}, Symbol})
precompile(Tuple{typeof(Plots.plotly_colorscale), PlotUtils.CategoricalColorGradient, Int64})
precompile(Tuple{typeof(Plots.plotly_colorscale), PlotUtils.ContinuousColorGradient, Int64})
precompile(Tuple{typeof(Plots.plotly_colorscale), PlotUtils.ContinuousColorGradient, Nothing})
precompile(Tuple{typeof(Plots.plotly_colorscale), PlotUtils.ColorGradient, Nothing})
precompile(Tuple{typeof(Plots.plotly_data), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Array{Int64, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Array{String, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{String, 1}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.OneTo{Int64}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Nothing})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, RecipesPipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Plots.RecipePipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.plotly_domain), Plots.Subplot{Plots.PlotlyBackend}, Symbol})
precompile(Tuple{typeof(Plots.plotly_font), Plots.Font, ColorTypes.RGBA{Float64}})
precompile(Tuple{typeof(Plots.plotly_font), Plots.Font})
@@ -559,16 +1036,16 @@ function _precompile_()
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Float64, 1}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Float64, 2}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Int64, 1}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{String, 1}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.OneTo{Int64}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.StepRange{Int64, Int64}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.UnitRange{Int64}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, RecipesPipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Plots.RecipePipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.plotly_polar!), Base.Dict{Symbol, Any}, Plots.Series})
precompile(Tuple{typeof(Plots.plotly_polaraxis), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.plotly_series), Plots.Plot{Plots.PlotlyBackend}, Plots.Series})
precompile(Tuple{typeof(Plots.plotly_series), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Array{Float64, 1}, Array{Float64, 1}, Array{Float64, 1}, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Array{Float64, 1}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Array{Int64, 1}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Array{Int64, 1}, Array{Int64, 1}, Nothing, Tuple{Float64, Float64}})
@@ -579,10 +1056,12 @@ function _precompile_()
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Base.UnitRange{Int64}, Array{Float64, 1}, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_segments), Plots.Series, Base.Dict{Symbol, Any}, Nothing, Nothing, Nothing, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_series_shapes), Plots.Plot{Plots.PlotlyBackend}, Plots.Series, Tuple{Float64, Float64}})
precompile(Tuple{typeof(Plots.plotly_surface_data), Plots.Series, RecipesPipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.plotly_surface_data), Plots.Series, Plots.RecipePipeline.Surface{Array{Float64, 2}}})
precompile(Tuple{typeof(Plots.png), Plots.Plot{Plots.GRBackend}, String})
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.GRBackend}})
precompile(Tuple{typeof(Plots.prepare_output), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.preprocess_attributes!), Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.preprocess_attributes!), Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Bool})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Int64})
precompile(Tuple{typeof(Plots.processFillArg), Base.Dict{Symbol, Any}, Symbol})
@@ -593,7 +1072,7 @@ function _precompile_()
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Float64, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Int64, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), Base.Dict{Symbol, Any}, Symbol, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), RecipesPipeline.DefaultsDict, Bool, Symbol})
precompile(Tuple{typeof(Plots.processGridArg!), Plots.RecipePipeline.DefaultsDict, Bool, Symbol})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Array{Symbol, 2}})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Float64})
precompile(Tuple{typeof(Plots.processLineArg), Base.Dict{Symbol, Any}, Int64})
@@ -617,9 +1096,9 @@ function _precompile_()
precompile(Tuple{typeof(Plots.process_axis_arg!), Base.Dict{Symbol, Any}, Tuple{Int64, Int64}, Symbol})
precompile(Tuple{typeof(Plots.recompute_lengths), Array{Measures.Measure, 1}})
precompile(Tuple{typeof(Plots.replaceAlias!), Base.Dict{Symbol, Any}, Symbol, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.replaceAlias!), RecipesPipeline.DefaultsDict, Symbol, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.replaceAlias!), Plots.RecipePipeline.DefaultsDict, Symbol, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.replaceAliases!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.replaceAliases!), RecipesPipeline.DefaultsDict, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.replaceAliases!), Plots.RecipePipeline.DefaultsDict, Base.Dict{Symbol, Symbol}})
precompile(Tuple{typeof(Plots.reset_axis_defaults_byletter!)})
precompile(Tuple{typeof(Plots.right), Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
precompile(Tuple{typeof(Plots.rightpad), Plots.Subplot{Plots.GRBackend}})
@@ -635,12 +1114,10 @@ function _precompile_()
precompile(Tuple{typeof(Plots.showaxis), Symbol, Symbol})
precompile(Tuple{typeof(Plots.shrink_by), Float64, Float64, Float64})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Base.Dict{Symbol, Any}, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, RecipesPipeline.DefaultsDict, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg!), RecipesPipeline.DefaultsDict, RecipesPipeline.DefaultsDict, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg!), Base.Dict{Symbol, Any}, Plots.RecipePipeline.DefaultsDict, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg!), Plots.RecipePipeline.DefaultsDict, Plots.RecipePipeline.DefaultsDict, Symbol, Int64, Bool})
precompile(Tuple{typeof(Plots.slice_arg), Array{ColorTypes.RGBA{Float64}, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{Float64, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{Measures.Length{:mm, Float64}, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{PlotUtils.ContinuousColorGradient, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{String, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Array{Symbol, 2}, Int64})
precompile(Tuple{typeof(Plots.slice_arg), Base.ReshapedArray{Int64, 2, Base.UnitRange{Int64}, Tuple{}}, Int64})
@@ -674,9 +1151,6 @@ function _precompile_()
precompile(Tuple{typeof(Plots.text_size), Int64, Int64, Int64})
precompile(Tuple{typeof(Plots.tick_padding), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis})
precompile(Tuple{typeof(Plots.tickfont), Plots.Axis})
precompile(Tuple{typeof(Plots.ticksType), Tuple{Array{Float64, 1}, Array{Any, 1}}})
precompile(Tuple{typeof(Plots.ticksType), Tuple{Array{Float64, 1}, Array{String, 1}}})
precompile(Tuple{typeof(Plots.ticksType), Tuple{Array{Int64, 1}, Array{String, 1}}})
precompile(Tuple{typeof(Plots.title!), String})
precompile(Tuple{typeof(Plots.title_padding), Plots.Subplot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.titlefont), Plots.Subplot{Plots.GRBackend}})
@@ -693,10 +1167,10 @@ function _precompile_()
precompile(Tuple{typeof(Plots.update_inset_bboxes!), Plots.Plot{Plots.PlotlyBackend}})
precompile(Tuple{typeof(Plots.vline!), Array{Int64, 1}})
precompile(Tuple{typeof(Plots.wand_edges), Array{Float64, 1}})
precompile(Tuple{typeof(Plots.warn_on_unsupported), Plots.GRBackend, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported), Plots.PlotlyBackend, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported_args), Plots.GRBackend, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported_args), Plots.PlotlyBackend, RecipesPipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported), Plots.GRBackend, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported), Plots.PlotlyBackend, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported_args), Plots.GRBackend, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported_args), Plots.PlotlyBackend, Plots.RecipePipeline.DefaultsDict})
precompile(Tuple{typeof(Plots.warn_on_unsupported_scales), Plots.GRBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.warn_on_unsupported_scales), Plots.PlotlyBackend, Base.Dict{Symbol, Any}})
precompile(Tuple{typeof(Plots.widen), Float64, Float64, Symbol})
+107 -96
View File
@@ -71,9 +71,8 @@ const POTENTIAL_VECTOR_ARGUMENTS = [
:marker_z,
:markerstrokecolor,
:markerstrokealpha,
:xerror,
:yerror,
:zerror,
:yerror,
:series_annotations,
:fillrange,
]
@@ -112,7 +111,7 @@ end
@recipe function f(::Type{Val{:hline}}, x, y, z)
n = length(y)
newx = repeat(Float64[1, 2, NaN], n)
newx = repeat(Float64[-1, 1, NaN], n)
newy = vec(Float64[yi for i = 1:3, yi in y])
x := newx
y := newy
@@ -124,7 +123,7 @@ end
@recipe function f(::Type{Val{:vline}}, x, y, z)
n = length(y)
newx = vec(Float64[yi for i = 1:3, yi in y])
newy = repeat(Float64[1, 2, NaN], n)
newy = repeat(Float64[-1, 1, NaN], n)
x := newx
y := newy
seriestype := :straightline
@@ -459,8 +458,8 @@ end
end
@deps plots_heatmap shape
is_3d(::Type{Val{:plots_heatmap}}) = true
RecipesPipeline.is_surface(::Type{Val{:plots_heatmap}}) = true
RecipesPipeline.is_surface(::Type{Val{:hexbin}}) = true
is_surface(::Type{Val{:plots_heatmap}}) = true
# ---------------------------------------------------------------------------
# Histograms
@@ -538,19 +537,14 @@ end
@recipe function f(::Type{Val{:scatterbins}}, x, y, z)
edge, weights, xscale, yscale, baseline =
_preprocess_binlike(plotattributes, x, y)
@series begin
x := _bin_centers(edge)
xerror := diff(edge) / 2
primary := false
seriestype := :xerror
()
end
xerror := diff(edge) / 2
x := _bin_centers(edge)
y := weights
seriestype := :scatter
()
end
@deps scatterbins xerror scatter
@deps scatterbins scatter
function _stepbins_path(
edge,
@@ -891,28 +885,6 @@ end
end
# ---------------------------------------------------------------------------
# pie
@recipe function f(::Type{Val{:pie}}, x, y, z)
framestyle --> :none
aspect_ratio --> true
s = sum(y)
θ = 0
for i in eachindex(y)
θ_new = θ + 2π * y[i] / s
coords = [(0.0, 0.0); partialcircle(θ, θ_new, 50)]
@series begin
seriestype := :shape
label --> string(x[i])
x := first.(coords)
y := last.(coords)
end
θ = θ_new
end
end
@deps pie shape
# ---------------------------------------------------------------------------
# scatter 3d
@@ -1028,7 +1000,7 @@ end
function error_style!(plotattributes::AKW)
plotattributes[:seriestype] = :path
plotattributes[:markercolor] = plotattributes[:markerstrokecolor]
plotattributes[:linecolor] = plotattributes[:markerstrokecolor]
plotattributes[:linewidth] = plotattributes[:markerstrokewidth]
plotattributes[:label] = ""
end
@@ -1042,65 +1014,52 @@ function error_zipit(ebar)
end
end
error_tuple(x) = x, x
error_tuple(x::Tuple) = x
function error_coords(errorbar, errordata, otherdata...)
ed = Vector{float_extended_type(errordata)}(undef, 0)
od = [Vector{float_extended_type(odi)}(undef, 0) for odi in otherdata]
for (i, edi) in enumerate(errordata)
for (j, odj) in enumerate(otherdata)
odi = _cycle(odj, i)
nanappend!(od[j], [odi, odi])
function error_coords(xorig, yorig, ebar)
# init empty x/y, and zip errors if passed Tuple{Vector,Vector}
x, y = Array{float_extended_type(xorig)}(undef, 0), Array{Float64}(undef, 0)
# for each point, create a line segment from the bottom to the top of the errorbar
for i = 1:max(length(xorig), length(yorig))
xi = _cycle(xorig, i)
yi = _cycle(yorig, i)
ebi = _cycle(ebar, i)
nanappend!(x, [xi, xi])
e1, e2 = if istuple(ebi)
first(ebi), last(ebi)
elseif isscalar(ebi)
ebi, ebi
else
error("unexpected ebi type $(typeof(ebi)) for errorbar: $ebi")
end
e1, e2 = error_tuple(_cycle(errorbar, i))
nanappend!(ed, [edi - e1, edi + e2])
nanappend!(y, [yi - e1, yi + e2])
end
return (ed, od...)
x, y
end
# we will create a series of path segments, where each point represents one
# side of an errorbar
@recipe function f(::Type{Val{:xerror}}, x, y, z)
error_style!(plotattributes)
markershape := :vline
xerr = error_zipit(plotattributes[:xerror])
if z === nothing
plotattributes[:x], plotattributes[:y] = error_coords(xerr, x, y)
else
plotattributes[:x], plotattributes[:y], plotattributes[:z] =
error_coords(xerr, x, y, z)
end
()
end
@deps xerror path
@recipe function f(::Type{Val{:yerror}}, x, y, z)
error_style!(plotattributes)
markershape := :hline
yerr = error_zipit(plotattributes[:yerror])
if z === nothing
plotattributes[:y], plotattributes[:x] = error_coords(yerr, y, x)
else
plotattributes[:y], plotattributes[:x], plotattributes[:z] =
error_coords(yerr, y, x, z)
end
plotattributes[:x], plotattributes[:y] = error_coords(
plotattributes[:x],
plotattributes[:y],
error_zipit(plotattributes[:yerror]),
)
()
end
@deps yerror path
@recipe function f(::Type{Val{:zerror}}, x, y, z)
@recipe function f(::Type{Val{:xerror}}, x, y, z)
error_style!(plotattributes)
markershape := :hline
if z !== nothing
zerr = error_zipit(plotattributes[:zerror])
plotattributes[:z], plotattributes[:x], plotattributes[:y] =
error_coords(zerr, z, x, y)
end
markershape := :vline
plotattributes[:y], plotattributes[:x] = error_coords(
plotattributes[:y],
plotattributes[:x],
error_zipit(plotattributes[:xerror]),
)
()
end
@deps zerror path
@deps xerror path
# TODO: move quiver to PlotRecipes
@@ -1192,7 +1151,7 @@ function quiver_using_hack(plotattributes::AKW)
)
end
plotattributes[:x], plotattributes[:y] = RecipesPipeline.unzip(pts[2:end])
plotattributes[:x], plotattributes[:y] = Plots.unzip(pts[2:end])
# KW[plotattributes]
end
@@ -1311,13 +1270,13 @@ end
# --------------------------------------------------------------------
# Lists of tuples and GeometryTypes.Points
# --------------------------------------------------------------------
@recipe f(v::AVec{<:GeometryTypes.Point}) = RecipesPipeline.unzip(v)
@recipe f(v::AVec{<:GeometryTypes.Point}) = unzip(v)
@recipe f(p::GeometryTypes.Point) = [p]
# Special case for 4-tuples in :ohlc series
@recipe f(xyuv::AVec{<:Tuple{R1, R2, R3, R4}}) where {R1, R2, R3, R4} =
get(plotattributes, :seriestype, :path) == :ohlc ? OHLC[OHLC(t...) for t in xyuv] :
RecipesPipeline.unzip(xyuv)
unzip(xyuv)
# -------------------------------------------------
@@ -1415,7 +1374,7 @@ end
@recipe function f(::Type{Val{:spy}}, x, y, z)
yflip := true
aspect_ratio := 1
rs, cs, zs = Plots.findnz(z.surf)
rs, cs, zs = findnz(z.surf)
xlims := ignorenan_extrema(cs)
ylims := ignorenan_extrema(rs)
if plotattributes[:markershape] == :none
@@ -1435,18 +1394,6 @@ end
()
end
Plots.findnz(A::AbstractSparseMatrix) = findnz(A)
# fallback function for finding non-zero elements of non-sparse matrices
function Plots.findnz(A::AbstractMatrix)
keysnz = findall(!iszero, A)
rs = [k[1] for k in keysnz]
cs = [k[2] for k in keysnz]
zs = A[keysnz]
rs, cs, zs
end
# -------------------------------------------------
"Adds ax+b... straight line over the current plot, without changing the axis limits"
@@ -1455,6 +1402,26 @@ abline!(plt::Plot, a, b; kw...) =
abline!(args...; kw...) = abline!(current(), args...; kw...)
# -------------------------------------------------
# Dates & Times
dateformatter(dt) = string(Date(Dates.UTD(dt)))
datetimeformatter(dt) = string(DateTime(Dates.UTM(dt)))
timeformatter(t) = string(Dates.Time(Dates.Nanosecond(t)))
@recipe f(::Type{Date}, dt::Date) = (dt -> Dates.value(dt), dateformatter)
@recipe f(::Type{DateTime}, dt::DateTime) =
(dt -> Dates.value(dt), datetimeformatter)
@recipe f(::Type{Dates.Time}, t::Dates.Time) = (t -> Dates.value(t), timeformatter)
@recipe f(::Type{P}, t::P) where {P<:Dates.Period} =
(t -> Dates.value(t), t -> string(P(t)))
# -------------------------------------------------
# Characters
@recipe f(::Type{<:AbstractChar}, ::AbstractChar) = (string, string)
# -------------------------------------------------
# Complex Numbers
@@ -1474,6 +1441,50 @@ end
end
# --------------------------------------------------
# Color Gradients
@userplot ShowLibrary
@recipe function f(cl::ShowLibrary)
if !(length(cl.args) == 1 && isa(cl.args[1], Symbol))
error("showlibrary takes the name of a color library as a Symbol")
end
library = PlotUtils.color_libraries[cl.args[1]]
z = sqrt.((1:15) * reshape(1:20, 1, :))
seriestype := :heatmap
ticks := nothing
legend := false
layout --> length(library.lib)
i = 0
for grad in sort(collect(keys(library.lib)))
@series begin
seriescolor := cgrad(grad, cl.args[1])
title := string(grad)
subplot := i += 1
z
end
end
end
@userplot ShowGradient
@recipe function f(grad::ShowGradient)
if !(length(grad.args) == 1 && isa(grad.args[1], Symbol))
error("showgradient takes the name of a color gradient as a Symbol")
end
z = sqrt.((1:15) * reshape(1:20, 1, :))
seriestype := :heatmap
ticks := nothing
legend := false
seriescolor := grad.args[1]
title := string(grad.args[1])
z
end
# Moved in from PlotRecipes - see: http://stackoverflow.com/a/37732384/5075246
@userplot PortfolioComposition
+6 -6
View File
@@ -251,7 +251,7 @@ Draw contour lines of the `Surface` z.
# Example
```julia-repl
julia> x = y = range(-20, stop = 20, length = 100)
julia> x = y = range(-20, 20, length = 100)
julia> contour(x, y, (x, y) -> x^2 + y^2)
```
"""
@@ -272,7 +272,7 @@ Draw a 3D surface plot.
# Example
```julia-repl
julia> using LinearAlgebra
julia> x = y = range(-3, stop = 3, length = 100)
julia> x = y = range(-3, 3, length = 100)
julia> surface(x, y, (x, y) -> sinc(norm([x, y])))
```
"""
@@ -381,7 +381,8 @@ julia> curves([1,2,3,4],[1,1,2,4])
@shorthands curves
"Plot a pie diagram"
@shorthands pie
pie(args...; kw...) = plot(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
pie!(args...; kw...) = plot!(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing)
"Plot with seriestype :path3d"
plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d)
@@ -437,9 +438,8 @@ julia> plot(1:10)
julia> annotate!([(7,3,"(7,3)"),(3,7,text("hey", 14, :left, :top, :green))])
```
"""
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
annotate!(anns::Tuple...; kw...) = plot!(; annotation = collect(anns), kw...)
annotate!(anns::AVec{<:Tuple}; kw...) = plot!(; annotation = anns, kw...)
annotate!(anns...; kw...) = plot!(; annotation = anns, kw...)
annotate!(anns::AVec{T}; kw...) where {T<:Tuple} = plot!(; annotation = anns, kw...)
"Flip the current plots' x axis"
xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...)
+6 -18
View File
@@ -42,24 +42,12 @@ get_subplot_index(plt::Plot, sp::Subplot) = findfirst(x -> x === sp, plt.subplot
series_list(sp::Subplot) = sp.series_list # filter(series -> series.plotattributes[:subplot] === sp, sp.plt.series_list)
function should_add_to_legend(series::Series)
series.plotattributes[:primary] &&
series.plotattributes[:label] != "" &&
!(
series.plotattributes[:seriestype] in (
:hexbin,
:bins2d,
:histogram2d,
:hline,
:vline,
:contour,
:contourf,
:contour3d,
:surface,
:wireframe,
:heatmap,
:image,
)
)
series.plotattributes[:primary] && series.plotattributes[:label] != "" &&
!(series.plotattributes[:seriestype] in (
:hexbin,:bins2d,:histogram2d,:hline,:vline,
:contour,:contourf,:contour3d,:surface,:wireframe,
:heatmap, :pie, :image
))
end
# ----------------------------------------------------------------------
+19 -9
View File
@@ -14,15 +14,25 @@ function _theme(s::Symbol, defaults::AKW; kw...)
# Set the theme's gradient as default
if haskey(defaults, :colorgradient)
PlotUtils.default_cgrad(pop!(defaults, :colorgradient))
PlotUtils.clibrary(:misc)
PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s))
pop!(defaults, :colorgradient)
else
PlotUtils.default_cgrad(:default)
PlotUtils.clibrary(:Plots)
PlotUtils.default_cgrad(default = :sequential, sequential = :inferno)
end
# maybe overwrite the theme's gradient
kw = KW(kw)
if haskey(kw, :colorgradient)
PlotUtils.default_cgrad(pop!(kw, :colorgradient))
kwgrad = pop!(kw, :colorgradient)
for clib in clibraries()
if kwgrad in cgradients(clib)
PlotUtils.clibrary(clib)
PlotUtils.default_cgrad(default = :sequential, sequential = kwgrad)
break
end
end
end
# Set the theme's defaults
@@ -47,12 +57,12 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
defaults = PlotThemes._themes[thm].defaults
# get the gradient
gradient_colors = color_list(cgrad(get(defaults, :colorgradient, :default)))
gradient_colors = get(defaults, :colorgradient, cgrad(:inferno).colors)
colorgradient = cgrad(cfunc.(RGB.(gradient_colors)))
# get the palette
cp = color_list(palette(get(defaults, :palette, :default)))
cp = cfunc.(RGB.(cp))
palette = get(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17))
palette = cfunc.(RGB.(palette))
# apply the theme
for k in keys(defaults)
@@ -79,7 +89,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
for j in 1:4
@series begin
subplot := 1
color_palette := cp
palette := palette
seriestype := :path
cumsum(randn(50))
end
@@ -87,7 +97,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
@series begin
subplot := 2
seriestype := :scatter
color_palette := cp
palette := palette
marker := (:circle, :diamond, :star5, :square)[j]
randn(10), randn(10)
end
@@ -96,7 +106,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func
@series begin
subplot := 3
seriestype := :histogram
color_palette := cp
palette := palette
randn(1000) .+ (0:2:4)'
end
+61 -138
View File
@@ -1,8 +1,8 @@
function replace_image_with_heatmap(z::Array{T}) where T<:Colorant
n, m = size(z)
colors = palette(vec(z))
newz = reshape(1:n*m, n, m)
colors = ColorGradient(vec(z))
newz = reshape(range(0, stop=1, length=n*m), n, m)
newz, colors
end
@@ -75,15 +75,11 @@ function iter_segments(series::Series)
if series[:seriestype] in (:scatter, :scatter3d)
return [[i] for i in eachindex(y)]
else
if any(isnan,y)
return [iter_segments(y)...]
else
return [i:(i + 1) for i in firstindex(y):lastindex(y)-1]
end
return [i:(i + 1) for i in firstindex(y):lastindex(y)-1]
end
else
segs = UnitRange{Int}[]
args = RecipesPipeline.is3d(series) ? (x, y, z) : (x, y)
args = is3d(series) ? (x, y, z) : (x, y)
for seg in iter_segments(args...)
push!(segs, seg)
end
@@ -134,13 +130,11 @@ _cycle(v::AVec, indices::AVec{Int}) = map(i -> _cycle(v,i), indices)
_cycle(v::AMat, indices::AVec{Int}) = map(i -> _cycle(v,i), indices)
_cycle(v, indices::AVec{Int}) = fill(v, length(indices))
_cycle(cl::PlotUtils.AbstractColorList, idx::Int) = cl[mod1(idx, end)]
_cycle(cl::PlotUtils.AbstractColorList, idx::AVec{Int}) = cl[mod1.(idx, end)]
_cycle(grad::ColorGradient, idx::Int) = _cycle(grad.colors, idx)
_cycle(grad::ColorGradient, indices::AVec{Int}) = _cycle(grad.colors, indices)
_as_gradient(grad) = grad
_as_gradient(v::AbstractVector{<:Colorant}) = cgrad(v)
_as_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
_as_gradient(c::Colorant) = cgrad([c, c])
_as_gradient(grad::ColorGradient) = grad
_as_gradient(c::Colorant) = ColorGradient([c,c])
makevec(v::AVec) = v
makevec(v::T) where {T} = T[v]
@@ -151,14 +145,14 @@ maketuple(x::Tuple{T,S}) where {T,S} = x
for i in 2:4
@eval begin
RecipesPipeline.unzip(v::Union{AVec{<:Tuple{Vararg{T,$i} where T}},
unzip(v::Union{AVec{<:Tuple{Vararg{T,$i} where T}},
AVec{<:GeometryTypes.Point{$i}}}) = $(Expr(:tuple, (:([t[$j] for t in v]) for j=1:i)...))
end
end
RecipesPipeline.unzip(v::Union{AVec{<:GeometryTypes.Point{N}},
unzip(v::Union{AVec{<:GeometryTypes.Point{N}},
AVec{<:Tuple{Vararg{T,N} where T}}}) where N = error("$N-dimensional unzip not implemented.")
RecipesPipeline.unzip(v::Union{AVec{<:GeometryTypes.Point},
unzip(v::Union{AVec{<:GeometryTypes.Point},
AVec{<:Tuple}}) = error("Can't unzip points of different dimensions.")
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
@@ -193,7 +187,7 @@ end
function replaceAlias!(plotattributes::AKW, k::Symbol, aliases::Dict{Symbol,Symbol})
if haskey(aliases, k)
plotattributes[aliases[k]] = RecipesPipeline.pop_kw!(plotattributes, k)
plotattributes[aliases[k]] = pop_kw!(plotattributes, k)
end
end
@@ -212,6 +206,13 @@ Base.first(x::Symbol) = x
sortedkeys(plotattributes::Dict) = sort(collect(keys(plotattributes)))
const _scale_base = Dict{Symbol, Real}(
:log10 => 10,
:log2 => 2,
:ln => ,
)
function _heatmap_edges(v::AVec, isedges::Bool = false)
length(v) == 1 && return v[1] .+ [-0.5, 0.5]
if isedges return v end
@@ -225,7 +226,7 @@ end
"create an (n+1) list of the outsides of heatmap rectangles"
function heatmap_edges(v::AVec, scale::Symbol = :identity, isedges::Bool = false)
f, invf = RecipesPipeline.scale_func(scale), RecipesPipeline.inverse_scale_func(scale)
f, invf = scale_func(scale), inverse_scale_func(scale)
map(invf, _heatmap_edges(map(f,v), isedges))
end
@@ -302,11 +303,6 @@ Base.convert(::Type{Vector{T}}, rng::AbstractRange{S}) where {T<:Real,S<:Real} =
Base.merge(a::AbstractVector, b::AbstractVector) = sort(unique(vcat(a,b)))
# recursively merge kw-dicts, e.g. for merging extra_kwargs / extra_plot_kwargs in plotly)
recursive_merge(x::AbstractDict...) = merge(recursive_merge, x...)
# if values are not AbstractDicts, take the last definition (as does merge)
recursive_merge(x...) = x[end]
nanpush!(a::AbstractVector, b) = (push!(a, NaN); push!(a, b))
nanappend!(a::AbstractVector, b) = (push!(a, NaN); append!(a, b))
@@ -419,46 +415,44 @@ xlims(sp_idx::Int = 1) = xlims(current(), sp_idx)
ylims(sp_idx::Int = 1) = ylims(current(), sp_idx)
zlims(sp_idx::Int = 1) = zlims(current(), sp_idx)
# These functions return an operator for use in `get_clims(::Seres, op)`
process_clims(lims::Tuple{<:Number,<:Number}) = (zlims -> ifelse.(isfinite.(lims), lims, zlims)) ignorenan_extrema
process_clims(s::Union{Symbol,Nothing,Missing}) = ignorenan_extrema
# don't specialize on ::Function otherwise python functions won't work
process_clims(f) = f
function get_clims(sp::Subplot, op=process_clims(sp[:clims]))
function get_clims(sp::Subplot)
zmin, zmax = Inf, -Inf
for series in series_list(sp)
if series[:colorbar_entry]
zmin, zmax = _update_clims(zmin, zmax, get_clims(series, op)...)
zmin, zmax = _update_clims(zmin, zmax, get_clims(series)...)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(sp::Subplot, series::Series, op=process_clims(sp[:clims]))
zmin, zmax = if series[:colorbar_entry]
get_clims(sp, op)
else
get_clims(series, op)
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
"""
get_clims(::Series, op=Plots.ignorenan_extrema)
function get_clims(sp::Subplot, series::Series)
zmin, zmax = if series[:colorbar_entry]
get_clims(sp)
else
get_clims(series)
end
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
Finds the limits for the colorbar by taking the "z-values" for the series and passing them into `op`,
which must return the tuple `(zmin, zmax)`. The default op is the extrema of the finite
values of the input.
"""
function get_clims(series::Series, op=ignorenan_extrema)
function get_clims(series::Series)
zmin, zmax = Inf, -Inf
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface, :hexbin)
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface)
for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z])
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, op(vals.surf)...)
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...)
elseif (vals !== nothing) && (eltype(vals) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, op(vals)...)
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals)...)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
@@ -492,7 +486,7 @@ end
hascolorbar(series::Series) = colorbar_style(series) !== nothing
hascolorbar(sp::Subplot) = sp[:colorbar] != :none && any(hascolorbar(s) for s in series_list(sp))
iscontour(series::Series) = series[:seriestype] in (:contour, :contour3d)
iscontour(series::Series) = series[:seriestype] == :contour
isfilledcontour(series::Series) = iscontour(series) && series[:fillrange] !== nothing
function contour_levels(series::Series, clims)
@@ -527,7 +521,8 @@ for comp in (:line, :fill, :marker)
if z === nothing
isa(c, ColorGradient) ? c : plot_color(_cycle(c, i))
else
get(get_gradient(c), z[i], (cmin, cmax))
grad = isa(c, ColorGradient) ? c : cgrad()
grad[clamp((_cycle(z, i) - cmin) / (cmax - cmin), 0, 1)]
end
end
@@ -545,28 +540,9 @@ for comp in (:line, :fill, :marker)
end
end
function get_colorgradient(series::Series)
st = series[:seriestype]
if st in (:surface, :heatmap) || isfilledcontour(series)
series[:fillcolor]
elseif st in (:contour, :wireframe)
series[:linecolor]
elseif series[:marker_z] !== nothing
series[:markercolor]
elseif series[:line_z] !== nothing
series[:linecolor]
elseif series[:fill_z] !== nothing
series[:fillcolor]
end
end
single_color(c, v = 0.5) = c
single_color(grad::ColorGradient, v = 0.5) = grad[v]
get_gradient(c) = cgrad()
get_gradient(cg::ColorGradient) = cg
get_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
function get_linewidth(series, i::Int = 1)
_cycle(series[:linewidth], i)
end
@@ -598,28 +574,7 @@ function has_attribute_segments(series::Series)
end
series[:seriestype] == :shape && return false
# ... else we check relevant attributes if they have multiple inputs
return any(
(typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1)
for
attr in [
:seriescolor,
:seriesalpha,
:linecolor,
:linealpha,
:linewidth,
:linestyle,
:fillcolor,
:fillalpha,
:markercolor,
:markeralpha,
:markersize,
:markerstrokecolor,
:markerstrokealpha,
:markerstrokewidth,
]
) || any(
typeof(series[attr]) <: AbstractArray for attr in (:line_z, :fill_z, :marker_z)
)
return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :linestyle, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray for attr in (:line_z, :fill_z, :marker_z))
end
function get_aspect_ratio(sp)
@@ -635,17 +590,6 @@ function get_aspect_ratio(sp)
return aspect_ratio
end
get_size(kw) = get(kw, :size, default(:size))
get_size(plt::Plot) = get_size(plt.attr)
get_size(sp::Subplot) = get_size(sp.plt)
get_size(series::Series) = get_size(series.plotattributes[:subplot])
get_thickness_scaling(kw) = get(kw, :thickness_scaling, default(:thickness_scaling))
get_thickness_scaling(plt::Plot) = get_thickness_scaling(plt.attr)
get_thickness_scaling(sp::Subplot) = get_thickness_scaling(sp.plt)
get_thickness_scaling(series::Series) =
get_thickness_scaling(series.plotattributes[:subplot])
# ---------------------------------------------------------------
makekw(; kw...) = KW(kw)
@@ -879,7 +823,7 @@ end
extend_to_length!(v::AbstractRange, n) = range(first(v), step = step(v), length = n)
function extend_to_length!(v::AbstractVector, n)
vmax = isempty(v) ? 0 : ignorenan_maximum(v)
vmax = isempy(v) ? 0 : ignorenan_maximum(v)
extend_by_data!(v, vmax .+ (1:(n - length(v))))
end
extend_by_data!(v::AbstractVector, x) = isimmutable(v) ? vcat(v, x) : push!(v, x)
@@ -891,7 +835,7 @@ end
function attr!(series::Series; kw...)
plotattributes = KW(kw)
RecipesPipeline.preprocess_attributes!(plotattributes)
preprocess_attributes!(plotattributes)
for (k,v) in plotattributes
if haskey(_series_defaults, k)
series[k] = v
@@ -905,7 +849,7 @@ end
function attr!(sp::Subplot; kw...)
plotattributes = KW(kw)
RecipesPipeline.preprocess_attributes!(plotattributes)
preprocess_attributes!(plotattributes)
for (k,v) in plotattributes
if haskey(_subplot_defaults, k)
sp[k] = v
@@ -988,7 +932,7 @@ px2inch(px::Real) = float(px / PX_PER_INCH)
inch2mm(inches::Real) = float(inches * MM_PER_INCH)
mm2inch(mm::Real) = float(mm / MM_PER_INCH)
px2mm(px::Real) = float(px * MM_PER_PX)
mm2px(mm::Real) = float(mm / MM_PER_PX)
mm2px(mm::Real) = float(px / MM_PER_PX)
"Smallest x in plot"
@@ -1079,21 +1023,10 @@ end
function straightline_data(series, expansion_factor = 1)
sp = series[:subplot]
xl, yl = isvertical(series) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp))
# handle axes scales
xscale = sp[:xaxis][:scale]
xf = RecipesPipeline.scale_func(xscale)
xinvf = RecipesPipeline.inverse_scale_func(xscale)
yscale = sp[:yaxis][:scale]
yf = RecipesPipeline.scale_func(yscale)
yinvf = RecipesPipeline.inverse_scale_func(yscale)
xl, yl = xf.(xl), yf.(yl)
x, y = xf.(series[:x]), yf.(series[:y])
x, y = series[:x], series[:y]
n = length(x)
xdata, ydata = if n == 2
straightline_data(xl, yl, x, y, expansion_factor)
if n == 2
return straightline_data(xl, yl, x, y, expansion_factor)
else
k, r = divrem(n, 3)
if r == 0
@@ -1102,13 +1035,11 @@ function straightline_data(series, expansion_factor = 1)
inds = (3 * i - 2):(3 * i - 1)
xdata[inds], ydata[inds] = straightline_data(xl, yl, x[inds], y[inds], expansion_factor)
end
xdata, ydata
return xdata, ydata
else
error("Misformed data. `straightline_data` either accepts vectors of length 2 or 3k. The provided series has length $n")
end
end
return xinvf.(xdata), yinvf.(ydata)
end
function straightline_data(xl, yl, x, y, expansion_factor = 1)
@@ -1140,28 +1071,20 @@ end
function shape_data(series, expansion_factor = 1)
sp = series[:subplot]
xl, yl = isvertical(series) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp))
# handle axes scales
xscale = sp[:xaxis][:scale]
xf = RecipesPipeline.scale_func(xscale)
xinvf = RecipesPipeline.inverse_scale_func(xscale)
yscale = sp[:yaxis][:scale]
yf = RecipesPipeline.scale_func(yscale)
yinvf = RecipesPipeline.inverse_scale_func(yscale)
x, y = copy(series[:x]), copy(series[:y])
x, y = series[:x], series[:y]
factor = 100
for i in eachindex(x)
if x[i] == -Inf
x[i] = xinvf(xf(xl[1]) - expansion_factor * (xf(xl[2]) - xf(xl[1])))
x[i] = xl[1] - expansion_factor * (xl[2] - xl[1])
elseif x[i] == Inf
x[i] = xinvf(xf(xl[2]) + expansion_factor * (xf(xl[2]) - xf(xl[1])))
x[i] = xl[2] + expansion_factor * (xl[2] - xl[1])
end
end
for i in eachindex(y)
if y[i] == -Inf
y[i] = yinvf(yf(yl[1]) - expansion_factor * (yf(yl[2]) - yf(yl[1])))
y[i] = yl[1] - expansion_factor * (yl[2] - yl[1])
elseif y[i] == Inf
y[i] = yinvf(yf(yl[2]) + expansion_factor * (yf(yl[2]) - yf(yl[1])))
y[i] = yl[2] + expansion_factor * (yl[2] - yl[1])
end
end
return x, y
+18 -25
View File
@@ -9,7 +9,6 @@ using LibGit2
using GeometryTypes
using Dates
include("test_axes.jl")
include("test_hdf5plots.jl")
include("test_pgfplotsx.jl")
@@ -48,27 +47,26 @@ img_tol = is_ci() ? 1e-2 : Sys.islinux() ? 1e-3 : 0.1
## Uncomment the following lines to update reference images for different backends
# @testset "GR" begin
# image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
# end
#
# plotly()
# @testset "Plotly" begin
# image_comparison_facts(:plotly, tol=img_tol, skip = Plots._backend_skips[:plotlyjs])
# end
#
# pyplot()
# @testset "PyPlot" begin
# image_comparison_facts(:pyplot, tol=img_tol, skip = Plots._backend_skips[:pyplot])
# end
#
# pgfplotsx()
# @testset "PGFPlotsX" begin
# image_comparison_facts(:pgfplotsx, tol=img_tol, skip = Plots._backend_skips[:pgfplotsx])
# end
#=
@testset "GR" begin
image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
end
# 10 Histogram2D
plotly()
@testset "Plotly" begin
image_comparison_facts(:plotly, tol=img_tol, skip = Plots._backend_skips[:plotlyjs])
end
pyplot()
@testset "PyPlot" begin
image_comparison_facts(:pyplot, tol=img_tol, skip = Plots._backend_skips[:pyplot])
end
pgfplots()
@testset "PGFPlots" begin
image_comparison_facts(:pgfplots, tol=img_tol, skip = Plots._backend_skips[:pgfplots])
end
=#
##
@testset "Backends" begin
@@ -179,9 +177,4 @@ end
@test isequal(collect(zip(Plots.unzip(z)...)), z)
@test isequal(collect(zip(Plots.unzip(GeometryTypes.Point.(z))...)), z)
end
op1 = Plots.process_clims((1.0, 2.0))
op2 = Plots.process_clims((1, 2.0))
data = randn(100, 100)
@test op1(data) == op2(data)
@test Plots.process_clims(nothing) == Plots.process_clims(missing) == Plots.process_clims(:auto)
end
-14
View File
@@ -1,14 +0,0 @@
using Plots, Test
@testset "Showaxis" begin
for value in Plots._allShowaxisArgs
@test plot(1:5, showaxis = value)[1][:yaxis][:showaxis] isa Bool
end
@test plot(1:5, showaxis = :y)[1][:yaxis][:showaxis] == true
@test plot(1:5, showaxis = :y)[1][:xaxis][:showaxis] == false
end
@testset "Magic axis" begin
@test plot(1, axis=nothing)[1][:xaxis][:ticks] == []
@test plot(1, axis=nothing)[1][:yaxis][:ticks] == []
end # testset
+8 -61
View File
@@ -71,7 +71,7 @@ end
pl = scatter!(
y,
zcolor = abs.(y .- 0.5),
m = (:hot, 0.8, Plots.stroke(1, :green)),
m = (:heat, 0.8, Plots.stroke(1, :green)),
ms = 10 * abs.(y .- 0.5) .+ 4,
lab = ["grad", "", "ient"],
)
@@ -84,7 +84,7 @@ end
@test marker.options["mark"] == "*"
@test marker.options["mark options"]["color"] ==
RGBA{Float64}(colorant"green", 0.8)
@test marker.options["mark options"]["line width"] == 0.75 # 1px is 0.75pt
@test marker.options["mark options"]["line width"] == 1
end # testset
@testset "Plot in pieces" begin
pic = plot(rand(100) / 3, reg = true, fill = (0, :green))
@@ -122,7 +122,7 @@ end
plot(
Plots.fakedata(100, 10),
layout = 4,
palette = [:grays :blues :hot :rainbow],
palette = [:grays :blues :heat :lightrainbow],
bg_inside = [:orange :pink :darkblue :black],
)
end # testset
@@ -211,7 +211,7 @@ end
marker_z = ((x, y) -> begin
x + y
end),
color = :bwr,
color = :bluesreds,
legend = false,
)
plot(p1, p2)
@@ -245,39 +245,15 @@ end
end # testset
@testset "Annotations" begin
y = rand(10)
pgfx_plot = plot(
plot(
y,
annotations = (3, y[3], Plots.text("this is \\#3", :left)),
leg = false,
)
Plots._update_plot_object(pgfx_plot)
axis_content = Plots.pgfx_axes(pgfx_plot.o)[1].contents
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 1
mktempdir() do path
file_path =joinpath(path,"annotations.tex")
@test_nowarn savefig(pgfx_plot, file_path)
open(file_path) do io
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 1
end
end
annotate!([
(5, y[5], Plots.text("this is \\#5", 16, :red, :center)),
(10, y[10], Plots.text("this is \\#10", :right, 20, "courier")),
])
Plots._update_plot_object(pgfx_plot)
axis_content = Plots.pgfx_axes(pgfx_plot.o)[1].contents
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 3
mktempdir() do path
file_path =joinpath(path,"annotations.tex")
@test_nowarn savefig(pgfx_plot, file_path)
open(file_path) do io
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 3
end
end
annotation_plot = scatter!(
range(2, stop = 8, length = 6),
rand(6),
@@ -291,18 +267,9 @@ end
Plots.text("data", :green),
],
)
Plots._update_plot_object(annotation_plot)
axis_content = Plots.pgfx_axes(annotation_plot.o)[1].contents
nodes = filter(x -> !isa(x, PGFPlotsX.Plot), axis_content)
@test length(nodes) == 9
mktempdir() do path
file_path =joinpath(path,"annotations.tex")
@test_nowarn savefig(annotation_plot, file_path)
open(file_path) do io
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 9
end
end
# mktempdir() do path
# @test_nowarn savefig(annotation_plot, path*"annotation.pdf")
# end
end # testset
@testset "Ribbon" begin
aa = rand(10)
@@ -326,23 +293,3 @@ end
# end
end # testset
end # testset
@testset "Extra kwargs" begin
pl = plot(1:5, test = "me")
@test pl[1][1].plotattributes[:extra_kwargs][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :subplot)
@test pl[1].attr[:extra_kwargs][:test] == "me"
pl = plot(1:5, test = "me", extra_kwargs = :plot)
@test pl.attr[:extra_plot_kwargs][:test] == "me"
pl = plot(1:5, extra_kwargs = Dict(:plot => Dict(:test => "me"), :series => Dict(:and => "me too")))
@test pl.attr[:extra_plot_kwargs][:test] == "me"
@test pl[1][1].plotattributes[:extra_kwargs][:and] == "me too"
pl = plot(
plot(1:5, title="Line"),
scatter(1:5, title="Scatter", extra_kwargs=Dict(:subplot=>Dict("axis line shift" => "10pt")))
)
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test !haskey(axes[1].options.dict, "axis line shift")
@test haskey(axes[2].options.dict, "axis line shift")
end # testset