Compare commits
20 Commits
v1.3.7
..
bbs/compat
| Author | SHA1 | Date | |
|---|---|---|---|
| 0762a29de3 | |||
| d6af1da35a | |||
| bbbee44c66 | |||
| 9499cef25d | |||
| 7c8952fadf | |||
| 8b2d3e926a | |||
| fb40ed1f59 | |||
| e88654cca5 | |||
| a9b9b3c357 | |||
| 99c8bfe12d | |||
| 3eb2b783dc | |||
| a20b275eaf | |||
| c29694ae70 | |||
| ebc93b6935 | |||
| 7dcbe911b1 | |||
| c2df99cc66 | |||
| a992effa5e | |||
| e49eb9bc83 | |||
| f2d7d394bb | |||
| 87d40cd34d |
+1
-1
@@ -4,7 +4,7 @@
|
||||
.DS_Store
|
||||
examples/.ipynb_checkpoints/*
|
||||
examples/meetup/.ipynb_checkpoints/*
|
||||
deps/plotly-latest.min.js
|
||||
deps/plotly-*
|
||||
deps/build.log
|
||||
deps/deps.jl
|
||||
Manifest.toml
|
||||
|
||||
+3
-4
@@ -1,7 +1,7 @@
|
||||
name = "Plots"
|
||||
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
author = ["Tom Breloff (@tbreloff)"]
|
||||
version = "1.3.7"
|
||||
version = "1.4.2"
|
||||
|
||||
[deps]
|
||||
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||
@@ -15,7 +15,6 @@ 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"
|
||||
@@ -40,7 +39,7 @@ GeometryTypes = "0.7, 0.8"
|
||||
JSON = "0.21"
|
||||
Measures = "0.3"
|
||||
NaNMath = "0.3"
|
||||
PGFPlotsX = "1.2.0"
|
||||
PGFPlotsX = "1.2.0 - 1.2.6"
|
||||
PlotThemes = "2"
|
||||
PlotUtils = "1"
|
||||
RecipesBase = "1"
|
||||
@@ -49,7 +48,7 @@ Reexport = "0.2"
|
||||
Requires = "1"
|
||||
Showoff = "0.3.1"
|
||||
StatsBase = "0.32, 0.33"
|
||||
julia = "1"
|
||||
julia = "1.4"
|
||||
|
||||
[extras]
|
||||
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
# Plots
|
||||
|
||||

|
||||
|
||||
[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
|
||||
[gh-ci-img]: https://github.com/JuliaPlots/Plots.jl/workflows/ci/badge.svg?branch=master
|
||||
[gh-ci-url]: https://github.com/JuliaPlots/Plots.jl/actions?query=workflow%3Aci
|
||||
|
||||
[pkgeval-img]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/P/Plots.svg
|
||||
[pkgeval-url]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/report.html
|
||||
@@ -17,8 +12,7 @@
|
||||
[docs-img]: https://img.shields.io/badge/docs-stable-blue.svg
|
||||
[docs-url]: http://docs.juliaplots.org/latest/
|
||||
|
||||
[![][travis-img]][travis-url]
|
||||
[![][appveyor-img]][appveyor-url]
|
||||
[![][gh-ci-img]][gh-ci-url]
|
||||
[![][pkgeval-img]][pkgeval-url]
|
||||
[](https://julialang.zulipchat.com/#narrow/stream/236493-plots)
|
||||
[![][docs-img]][docs-url]
|
||||
|
||||
Vendored
+4
-4
@@ -1,12 +1,12 @@
|
||||
|
||||
#TODO: download https://cdn.plot.ly/plotly-latest.min.js to deps/ if it doesn't exist
|
||||
#TODO: download https://cdn.plot.ly/plotly-1.54.2.min.js to deps/ if it doesn't exist
|
||||
file_path = ""
|
||||
if get(ENV, "PLOTS_HOST_DEPENDENCY_LOCAL", "false") == "true"
|
||||
global file_path
|
||||
local_fn = joinpath(dirname(@__FILE__), "plotly-latest.min.js")
|
||||
local_fn = joinpath(dirname(@__FILE__), "plotly-1.54.2.min.js")
|
||||
if !isfile(local_fn)
|
||||
@info("Cannot find deps/plotly-latest.min.js... downloading latest version.")
|
||||
download("https://cdn.plot.ly/plotly-latest.min.js", local_fn)
|
||||
@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)
|
||||
isfile(local_fn) && (file_path = local_fn)
|
||||
else
|
||||
file_path = local_fn
|
||||
|
||||
+5
-1
@@ -124,7 +124,11 @@ export
|
||||
center,
|
||||
BezierCurve,
|
||||
|
||||
plotattr
|
||||
plotattr,
|
||||
scalefontsize,
|
||||
scalefontsizes,
|
||||
resetfontsizes
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ 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`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` , `:inline` (note: only some may be supported in each backend)",
|
||||
: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)",
|
||||
: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",
|
||||
|
||||
+16
-2
@@ -20,7 +20,14 @@ 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]
|
||||
@@ -502,6 +509,13 @@ 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)
|
||||
@@ -623,7 +637,7 @@ for arg in keys(_series_defaults)
|
||||
_keyAliases[makeplural(arg)] = arg
|
||||
end
|
||||
|
||||
|
||||
add_non_underscore_aliases!(_keyAliases)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
+4
-10
@@ -181,16 +181,10 @@ function optimal_ticks_and_labels(sp::Subplot, axis::Axis, ticks = nothing)
|
||||
|
||||
labels = if any(isfinite, unscaled_ticks)
|
||||
formatter = axis[:formatter]
|
||||
if formatter == :auto
|
||||
# the default behavior is to make strings of the scaled values and then apply the labelfunc
|
||||
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :auto))
|
||||
elseif formatter == :plain
|
||||
# Leave the numbers in plain format
|
||||
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :plain))
|
||||
elseif formatter == :scientific
|
||||
Showoff.showoff(unscaled_ticks, :scientific)
|
||||
elseif formatter == :latex
|
||||
map(x -> string("\$", replace(convert_sci_unicode(x), '×' => "\\times"), "\$"), Showoff.showoff(unscaled_ticks, :auto))
|
||||
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))
|
||||
else
|
||||
# there was an override for the formatter... use that on the unscaled ticks
|
||||
map(formatter, unscaled_ticks)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using Pkg
|
||||
|
||||
struct NoBackend <: AbstractBackend end
|
||||
|
||||
const _backendType = Dict{Symbol, DataType}(:none => NoBackend)
|
||||
|
||||
+15
-8
@@ -590,7 +590,7 @@ function gr_legend_pos(sp::Subplot, w, h, viewport_plotarea)
|
||||
xpos = viewport_plotarea[1] + 0.11
|
||||
end
|
||||
else
|
||||
xpos = (viewport_plotarea[2]-viewport_plotarea[1])/2 - w/2 +.04
|
||||
xpos = (viewport_plotarea[2]-viewport_plotarea[1])/2 - w/2 +.04 + viewport_plotarea[1]
|
||||
end
|
||||
if occursin("top", str)
|
||||
if s == :outertop
|
||||
@@ -605,7 +605,8 @@ function gr_legend_pos(sp::Subplot, w, h, viewport_plotarea)
|
||||
ypos = viewport_plotarea[3] + h + 0.06
|
||||
end
|
||||
else
|
||||
ypos = (viewport_plotarea[4]-viewport_plotarea[3])/2 + h/2
|
||||
# Adding min y to shift legend pos to correct graph (#2377)
|
||||
ypos = (viewport_plotarea[4]-viewport_plotarea[3])/2 + h/2 + viewport_plotarea[3]
|
||||
end
|
||||
(xpos,ypos)
|
||||
end
|
||||
@@ -943,6 +944,12 @@ function is_equally_spaced(v)
|
||||
all(d .≈ d[1])
|
||||
end
|
||||
|
||||
remap(x, lo, hi) = (x - lo) / (hi - lo)
|
||||
function get_z_normalized(z, clims...)
|
||||
isnan(z) && return 256 / 255
|
||||
return remap(clamp(z, clims...), clims...)
|
||||
end
|
||||
|
||||
function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
_update_min_padding!(sp)
|
||||
|
||||
@@ -1712,8 +1719,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
if something(series[:fillalpha],1) < 1
|
||||
@warn "GR: transparency not supported in non-uniform heatmaps. Alpha values ignored."
|
||||
end
|
||||
colors = get(fillgrad, z, clims)
|
||||
z_normalized = map(c -> c == invisible() ? 256/255 : PlotUtils.getinverse(fillgrad, c), colors)
|
||||
z_normalized = get_z_normalized.(z, zmin, zmax)
|
||||
rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized]
|
||||
GR.nonuniformcellarray(x, y, w, h, rgba)
|
||||
end
|
||||
@@ -1729,10 +1735,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
if series[:y][end] != ny
|
||||
@warn "Right now only the maximum value of y (r) is taken into account."
|
||||
end
|
||||
colors = get(fillgrad, z, clims)
|
||||
z_normalized = map(c -> c == invisible() ? 256/255 : PlotUtils.getinverse(fillgrad.colors, c), colors)
|
||||
rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized]
|
||||
# colors = get(fillgrad, z, clims)
|
||||
# GR.polarcellarray(0, 0, phimin, phimax, ymin, ymax, nx, ny, colors)
|
||||
z_normalized = get_z_normalized.(z, zmin, zmax)
|
||||
# z_normalized = map(c -> c == invisible() ? 256/255 : PlotUtils.getinverse(fillgrad.colors, c), colors)
|
||||
rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized]
|
||||
GR.polarcellarray(0, 0, phimin, phimax, 0, ymax, nx, ny, rgba)
|
||||
# Right now only the maximum value of y (r) is taken into account.
|
||||
# This is certainly not perfect but nonuniform polar array is not yet supported in GR.jl
|
||||
@@ -1871,7 +1878,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
st == :shape && gr_polyline(x, y)
|
||||
end
|
||||
|
||||
if st in (:path, :straightline)
|
||||
if st in (:path, :straightline, :path3d)
|
||||
gr_set_transparency(lc, get_linealpha(series))
|
||||
if series[:fillrange] === nothing || series[:ribbon] !== nothing
|
||||
GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos])
|
||||
|
||||
@@ -988,6 +988,7 @@ end
|
||||
function pgfx_sanitize_string(s::LaTeXString)
|
||||
s = replace(s, r"\\?\#" => "\\#")
|
||||
s = replace(s, r"\\?\%" => "\\%")
|
||||
return LaTeXString(s)
|
||||
end
|
||||
end
|
||||
function pgfx_sanitize_plot!(plt)
|
||||
|
||||
@@ -828,7 +828,7 @@ 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-latest.min.js"
|
||||
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"
|
||||
|
||||
+29
-3
@@ -182,7 +182,7 @@ function labelfunc(scale::Symbol, backend::PyPlotBackend)
|
||||
elseif scale == :ln
|
||||
x -> PyPlot.LaTeXStrings.latexstring("e^{$x}")
|
||||
else
|
||||
string
|
||||
x -> PyPlot.LaTeXStrings.latexstring(convert_sci_unicode(x))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1016,8 +1016,34 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
||||
# 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
|
||||
cbax = divider.append_axes("right", size="5%", pad="2.5%") # Reasonable value works most of the usecases
|
||||
cb = fig."colorbar"(handle; cax=cbax, kw...)
|
||||
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
|
||||
|
||||
cb."set_label"(sp[:colorbar_title],size=py_thickness_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor]))
|
||||
|
||||
+26
-8
@@ -358,9 +358,15 @@ 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, :guidefontsize, :tickfontsize, :legendfontsize)
|
||||
for k in (:titlefontsize, :legendfontsize, :legendtitlefontsize)
|
||||
scalefontsize(k, factor)
|
||||
end
|
||||
|
||||
for letter in (:x,:y,:z)
|
||||
for k in (:guidefontsize, :tickfontsize)
|
||||
scalefontsize(Symbol(letter, k), factor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -369,15 +375,27 @@ end
|
||||
Resets font sizes to initial default values.
|
||||
"""
|
||||
function scalefontsizes()
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
resetfontsizes() = scalefontsizes()
|
||||
|
||||
"Wrap a string with font info"
|
||||
struct PlotText
|
||||
str::AbstractString
|
||||
|
||||
@@ -1474,50 +1474,6 @@ 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user