Merge branch 'julia0.7' into julia0.7
This commit is contained in:
commit
8d50828998
31
NEWS.md
31
NEWS.md
@ -3,13 +3,42 @@
|
|||||||
|
|
||||||
#### notes on release changes, ongoing development, and future planned work
|
#### notes on release changes, ongoing development, and future planned work
|
||||||
|
|
||||||
- All new development should target 0.15!
|
- Minor version 0.17 is the last one to support Julia 0.6!!
|
||||||
- Minor version 0.11 is the last one to support Julia 0.5!!
|
- Minor version 0.11 is the last one to support Julia 0.5!!
|
||||||
- Critical bugfixes only
|
- Critical bugfixes only
|
||||||
- `backports` branch is for Julia 0.5
|
- `backports` branch is for Julia 0.5
|
||||||
|
|
||||||
---
|
---
|
||||||
## (current master)
|
## (current master)
|
||||||
|
- All new development should target Julia 0.7!
|
||||||
|
|
||||||
|
## 0.17.3
|
||||||
|
- Log-scale heatmap edge computation
|
||||||
|
- Fix size and dpi for GR and PyPlot
|
||||||
|
- Fix fillrange with line segments on PyPlot and Plotly
|
||||||
|
- fix flip for heatmap and image on GR
|
||||||
|
- New attributes for PGFPlots
|
||||||
|
- Widen axes for most series types and log scales
|
||||||
|
- Plotly: fix log scale with no ticks
|
||||||
|
- Fix axis flip on Plotly
|
||||||
|
- Fix hover and zcolor interaction in Plotly
|
||||||
|
- WebIO integration for PlotlyJS backend
|
||||||
|
|
||||||
|
## 0.17.2
|
||||||
|
- fix single subplot in plotly
|
||||||
|
- implement `(xyz)lims = :round`
|
||||||
|
- PyPlot: fix bg_legend = invisible()
|
||||||
|
- set fallback tick specification for axes with discrete values
|
||||||
|
- restructure of show methods
|
||||||
|
|
||||||
|
## 0.17.1
|
||||||
|
- Fix contour for PGFPlots
|
||||||
|
- 32Bit fix: Int64 -> Int
|
||||||
|
- Make series of shapes and segments toggle together in Plotly(JS)
|
||||||
|
- Fix marker arguments
|
||||||
|
- Fix processing order of series recipes
|
||||||
|
- Fix Plotly(JS) ribbon
|
||||||
|
- Contour plots with x,y in grid form on PyPlot
|
||||||
|
|
||||||
## 0.17.0
|
## 0.17.0
|
||||||
- Add GR dependency to make it the default backend
|
- Add GR dependency to make it the default backend
|
||||||
|
|||||||
@ -65,6 +65,7 @@ const _arg_desc = KW(
|
|||||||
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
|
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
|
||||||
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
|
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
|
||||||
:dpi => "Number. Dots Per Inch of output figures",
|
: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.",
|
:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.",
|
||||||
:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.",
|
: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",
|
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",
|
||||||
@ -110,7 +111,7 @@ const _arg_desc = KW(
|
|||||||
|
|
||||||
# axis args
|
# axis args
|
||||||
:guide => "String. Axis guide (label).",
|
:guide => "String. Axis guide (label).",
|
||||||
:lims => "NTuple{2,Number}. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example).",
|
:lims => "NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example). `:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]",
|
||||||
:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
|
:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`",
|
||||||
:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`",
|
:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`",
|
||||||
:rotation => "Number. Degrees rotation of tick labels.",
|
:rotation => "Number. Degrees rotation of tick labels.",
|
||||||
@ -139,5 +140,6 @@ const _arg_desc = KW(
|
|||||||
:gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)",
|
:gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)",
|
||||||
:gridlinewidth => "Number. Width of the grid lines (in pixels)",
|
:gridlinewidth => "Number. Width of the grid lines (in pixels)",
|
||||||
:tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`",
|
:tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`",
|
||||||
:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`"
|
:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`",
|
||||||
|
:widen => "Bool. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders. Defaults to `true`.",
|
||||||
)
|
)
|
||||||
|
|||||||
47
src/args.jl
47
src/args.jl
@ -301,6 +301,7 @@ const _plot_defaults = KW(
|
|||||||
:inset_subplots => nothing, # optionally pass a vector of (parent,bbox) tuples which are
|
:inset_subplots => nothing, # optionally pass a vector of (parent,bbox) tuples which are
|
||||||
# the parent layout and the relative bounding box of inset subplots
|
# the parent layout and the relative bounding box of inset subplots
|
||||||
:dpi => DPI, # dots per inch for images, etc
|
:dpi => DPI, # dots per inch for images, etc
|
||||||
|
:thickness_scaling => 1,
|
||||||
:display_type => :auto,
|
:display_type => :auto,
|
||||||
:extra_kwargs => KW(),
|
:extra_kwargs => KW(),
|
||||||
)
|
)
|
||||||
@ -381,6 +382,7 @@ const _axis_defaults = KW(
|
|||||||
:gridlinewidth => 0.5,
|
:gridlinewidth => 0.5,
|
||||||
:tick_direction => :in,
|
:tick_direction => :in,
|
||||||
:showaxis => true,
|
:showaxis => true,
|
||||||
|
:widen => true,
|
||||||
)
|
)
|
||||||
|
|
||||||
const _suppress_warnings = Set{Symbol}([
|
const _suppress_warnings = Set{Symbol}([
|
||||||
@ -1473,26 +1475,19 @@ function _replace_linewidth(d::KW)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
||||||
pkg = plt.backend
|
|
||||||
globalIndex = d[:series_plotindex]
|
|
||||||
|
|
||||||
# add default values to our dictionary, being careful not to delete what we just added!
|
# add default values to our dictionary, being careful not to delete what we just added!
|
||||||
for (k,v) in _series_defaults
|
for (k,v) in _series_defaults
|
||||||
slice_arg!(d, d, k, v, commandIndex, false)
|
slice_arg!(d, d, k, v, commandIndex, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
# this is how many series belong to this subplot
|
return d
|
||||||
# plotIndex = count(series -> series.d[:subplot] === sp && series.d[:primary], plt.series_list)
|
end
|
||||||
plotIndex = 0
|
|
||||||
for series in sp.series_list
|
|
||||||
if series[:primary]
|
function _update_series_attributes!(d::KW, plt::Plot, sp::Subplot)
|
||||||
plotIndex += 1
|
pkg = plt.backend
|
||||||
end
|
globalIndex = d[:series_plotindex]
|
||||||
end
|
plotIndex = _series_index(d, sp)
|
||||||
# plotIndex = count(series -> series[:primary], sp.series_list)
|
|
||||||
if get(d, :primary, true)
|
|
||||||
plotIndex += 1
|
|
||||||
end
|
|
||||||
|
|
||||||
aliasesAndAutopick(d, :linestyle, _styleAliases, supported_styles(pkg), plotIndex)
|
aliasesAndAutopick(d, :linestyle, _styleAliases, supported_styles(pkg), plotIndex)
|
||||||
aliasesAndAutopick(d, :markershape, _markerAliases, supported_markers(pkg), plotIndex)
|
aliasesAndAutopick(d, :markershape, _markerAliases, supported_markers(pkg), plotIndex)
|
||||||
@ -1528,11 +1523,11 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
|||||||
|
|
||||||
# update markerstrokecolor
|
# update markerstrokecolor
|
||||||
d[:markerstrokecolor] = if d[:markerstrokecolor] == :match
|
d[:markerstrokecolor] = if d[:markerstrokecolor] == :match
|
||||||
plot_color(sp[:foreground_color_subplot], d[:markerstrokealpha])
|
plot_color(sp[:foreground_color_subplot])
|
||||||
elseif d[:markerstrokecolor] == :auto
|
elseif d[:markerstrokecolor] == :auto
|
||||||
getSeriesRGBColor(plot_color(d[:markercolor], d[:markeralpha]), sp, plotIndex)
|
getSeriesRGBColor.(d[:markercolor], sp, plotIndex)
|
||||||
else
|
else
|
||||||
getSeriesRGBColor(plot_color(d[:markerstrokecolor], d[:markerstrokealpha]), sp, plotIndex)
|
getSeriesRGBColor.(d[:markerstrokecolor], sp, plotIndex)
|
||||||
end
|
end
|
||||||
|
|
||||||
# if marker_z, fill_z or line_z are set, ensure we have a gradient
|
# if marker_z, fill_z or line_z are set, ensure we have a gradient
|
||||||
@ -1562,3 +1557,19 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
|||||||
_replace_linewidth(d)
|
_replace_linewidth(d)
|
||||||
d
|
d
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _series_index(d, sp)
|
||||||
|
idx = 0
|
||||||
|
for series in series_list(sp)
|
||||||
|
if series[:primary]
|
||||||
|
idx += 1
|
||||||
|
end
|
||||||
|
if series == d
|
||||||
|
return idx
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if get(d, :primary, true)
|
||||||
|
idx += 1
|
||||||
|
end
|
||||||
|
return idx
|
||||||
|
end
|
||||||
|
|||||||
44
src/axes.jl
44
src/axes.jl
@ -246,19 +246,17 @@ function get_ticks(axis::Axis)
|
|||||||
ticks = ticks == :native ? :auto : ticks
|
ticks = ticks == :native ? :auto : ticks
|
||||||
|
|
||||||
dvals = axis[:discrete_values]
|
dvals = axis[:discrete_values]
|
||||||
cv, dv = if !isempty(dvals)
|
cv, dv = if typeof(ticks) <: Symbol
|
||||||
|
if !isempty(dvals)
|
||||||
# discrete ticks...
|
# discrete ticks...
|
||||||
n = length(dvals)
|
n = length(dvals)
|
||||||
rng = if ticks == :auto
|
rng = if ticks == :auto
|
||||||
Int[round(Int,i) for i in linspace(1, n, 15)]
|
Int[round(Int,i) for i in linspace(1, n, 15)]
|
||||||
elseif ticks == :all
|
else # if ticks == :all
|
||||||
1:n
|
1:n
|
||||||
elseif typeof(ticks) <: Int
|
|
||||||
Int[round(Int,i) for i in linspace(1, n, ticks)]
|
|
||||||
end
|
end
|
||||||
axis[:continuous_values][rng], dvals[rng]
|
axis[:continuous_values][rng], dvals[rng]
|
||||||
elseif typeof(ticks) <: Symbol
|
elseif ispolar(axis.sps[1]) && axis[:letter] == :x
|
||||||
if ispolar(axis.sps[1]) && axis[:letter] == :x
|
|
||||||
#force theta axis to be full circle
|
#force theta axis to be full circle
|
||||||
(collect(0:pi/4:7pi/4), string.(0:45:315))
|
(collect(0:pi/4:7pi/4), string.(0:45:315))
|
||||||
else
|
else
|
||||||
@ -266,8 +264,13 @@ function get_ticks(axis::Axis)
|
|||||||
optimal_ticks_and_labels(axis)
|
optimal_ticks_and_labels(axis)
|
||||||
end
|
end
|
||||||
elseif typeof(ticks) <: Union{AVec, Int}
|
elseif typeof(ticks) <: Union{AVec, Int}
|
||||||
|
if !isempty(dvals) && typeof(ticks) <: Int
|
||||||
|
rng = Int[round(Int,i) for i in linspace(1, length(dvals), ticks)]
|
||||||
|
axis[:continuous_values][rng], dvals[rng]
|
||||||
|
else
|
||||||
# override ticks, but get the labels
|
# override ticks, but get the labels
|
||||||
optimal_ticks_and_labels(axis, ticks)
|
optimal_ticks_and_labels(axis, ticks)
|
||||||
|
end
|
||||||
elseif typeof(ticks) <: NTuple{2, Any}
|
elseif typeof(ticks) <: NTuple{2, Any}
|
||||||
# assuming we're passed (ticks, labels)
|
# assuming we're passed (ticks, labels)
|
||||||
ticks
|
ticks
|
||||||
@ -415,21 +418,23 @@ end
|
|||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
# push the limits out slightly
|
# push the limits out slightly
|
||||||
function widen(lmin, lmax)
|
function widen(lmin, lmax, scale = :identity)
|
||||||
span = lmax - lmin
|
f, invf = scalefunc(scale), invscalefunc(scale)
|
||||||
|
span = f(lmax) - f(lmin)
|
||||||
# eps = NaNMath.max(1e-16, min(1e-2span, 1e-10))
|
# eps = NaNMath.max(1e-16, min(1e-2span, 1e-10))
|
||||||
eps = NaNMath.max(1e-16, 0.03span)
|
eps = NaNMath.max(1e-16, 0.03span)
|
||||||
lmin-eps, lmax+eps
|
invf(f(lmin)-eps), invf(f(lmax)+eps)
|
||||||
end
|
end
|
||||||
|
|
||||||
# figure out if widening is a good idea. if there's a scale set it's too tricky,
|
# figure out if widening is a good idea.
|
||||||
# so lazy out and don't widen
|
const _widen_seriestypes = (:line, :path, :steppre, :steppost, :sticks, :scatter, :barbins, :barhist, :histogram, :scatterbins, :scatterhist, :stepbins, :stephist, :bins2d, :histogram2d, :bar, :shape, :path3d, :scatter3d)
|
||||||
|
|
||||||
function default_should_widen(axis::Axis)
|
function default_should_widen(axis::Axis)
|
||||||
should_widen = false
|
should_widen = false
|
||||||
if axis[:scale] == :identity && !is_2tuple(axis[:lims])
|
if !is_2tuple(axis[:lims])
|
||||||
for sp in axis.sps
|
for sp in axis.sps
|
||||||
for series in series_list(sp)
|
for series in series_list(sp)
|
||||||
if series.d[:seriestype] in (:scatter,) || series.d[:markershape] != :none
|
if series.d[:seriestype] in _widen_seriestypes
|
||||||
should_widen = true
|
should_widen = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -438,6 +443,13 @@ function default_should_widen(axis::Axis)
|
|||||||
should_widen
|
should_widen
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function round_limits(amin,amax)
|
||||||
|
scale = 10^(1-round(log10(amax - amin)))
|
||||||
|
amin = floor(amin*scale)/scale
|
||||||
|
amax = ceil(amax*scale)/scale
|
||||||
|
amin, amax
|
||||||
|
end
|
||||||
|
|
||||||
# using the axis extrema and limit overrides, return the min/max value for this axis
|
# using the axis extrema and limit overrides, return the min/max value for this axis
|
||||||
function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis))
|
function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis))
|
||||||
ex = axis[:extrema]
|
ex = axis[:extrema]
|
||||||
@ -466,8 +478,10 @@ function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis)
|
|||||||
else
|
else
|
||||||
amin, amax
|
amin, amax
|
||||||
end
|
end
|
||||||
elseif should_widen
|
elseif should_widen && axis[:widen]
|
||||||
widen(amin, amax)
|
widen(amin, amax, axis[:scale])
|
||||||
|
elseif lims == :round
|
||||||
|
round_limits(amin,amax)
|
||||||
else
|
else
|
||||||
amin, amax
|
amin, amax
|
||||||
end
|
end
|
||||||
|
|||||||
@ -353,25 +353,18 @@ function gr_draw_markers(series::Series, x, y, msize, mz)
|
|||||||
msi = _cycle(msize, i)
|
msi = _cycle(msize, i)
|
||||||
shape = _cycle(shapes, i)
|
shape = _cycle(shapes, i)
|
||||||
cfunc = isa(shape, Shape) ? gr_set_fillcolor : gr_set_markercolor
|
cfunc = isa(shape, Shape) ? gr_set_fillcolor : gr_set_markercolor
|
||||||
cfuncind = isa(shape, Shape) ? GR.setfillcolorind : GR.setmarkercolorind
|
|
||||||
|
|
||||||
# draw a filled in shape, slightly bigger, to estimate a stroke
|
# draw a filled in shape, slightly bigger, to estimate a stroke
|
||||||
if series[:markerstrokewidth] > 0
|
if series[:markerstrokewidth] > 0
|
||||||
cfunc(_cycle(series[:markerstrokecolor], i)) #, series[:markerstrokealpha])
|
cfunc(get_markerstrokecolor(series, i))
|
||||||
|
gr_set_transparency(get_markerstrokealpha(series, i))
|
||||||
gr_draw_marker(x[i], y[i], msi + series[:markerstrokewidth], shape)
|
gr_draw_marker(x[i], y[i], msi + series[:markerstrokewidth], shape)
|
||||||
end
|
end
|
||||||
|
|
||||||
# draw the shape
|
# draw the shape - don't draw filled area if marker shape is 1D
|
||||||
if mz == nothing
|
|
||||||
cfunc(_cycle(series[:markercolor], i)) #, series[:markeralpha])
|
|
||||||
else
|
|
||||||
# pick a color from the pre-loaded gradient
|
|
||||||
ci = round(Int, 1000 + _cycle(mz, i) * 255)
|
|
||||||
cfuncind(ci)
|
|
||||||
gr_set_transparency(_gr_gradient_alpha[ci-999])
|
|
||||||
end
|
|
||||||
# don't draw filled area if marker shape is 1D
|
|
||||||
if !(shape in (:hline, :vline, :+, :x))
|
if !(shape in (:hline, :vline, :+, :x))
|
||||||
|
cfunc(get_markercolor(series, i))
|
||||||
|
gr_set_transparency(get_markeralpha(series, i))
|
||||||
gr_draw_marker(x[i], y[i], msi, shape)
|
gr_draw_marker(x[i], y[i], msi, shape)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -390,7 +383,7 @@ end
|
|||||||
function gr_set_line(lw, style, c) #, a)
|
function gr_set_line(lw, style, c) #, a)
|
||||||
GR.setlinetype(gr_linetype[style])
|
GR.setlinetype(gr_linetype[style])
|
||||||
w, h = gr_plot_size
|
w, h = gr_plot_size
|
||||||
GR.setlinewidth(max(0, lw / ((w + h) * 0.001)))
|
GR.setlinewidth(_gr_thickness_scaling[1] * max(0, lw / ((w + h) * 0.001)))
|
||||||
gr_set_linecolor(c) #, a)
|
gr_set_linecolor(c) #, a)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -403,6 +396,7 @@ end
|
|||||||
|
|
||||||
# this stores the conversion from a font pointsize to "percentage of window height" (which is what GR uses)
|
# this stores the conversion from a font pointsize to "percentage of window height" (which is what GR uses)
|
||||||
const _gr_point_mult = 0.0018 * ones(1)
|
const _gr_point_mult = 0.0018 * ones(1)
|
||||||
|
const _gr_thickness_scaling = ones(1)
|
||||||
|
|
||||||
# set the font attributes... assumes _gr_point_mult has been populated already
|
# set the font attributes... assumes _gr_point_mult has been populated already
|
||||||
function gr_set_font(f::Font; halign = f.halign, valign = f.valign,
|
function gr_set_font(f::Font; halign = f.halign, valign = f.valign,
|
||||||
@ -549,6 +543,9 @@ end
|
|||||||
function gr_display(plt::Plot, fmt="")
|
function gr_display(plt::Plot, fmt="")
|
||||||
GR.clearws()
|
GR.clearws()
|
||||||
|
|
||||||
|
_gr_thickness_scaling[1] = plt[:thickness_scaling]
|
||||||
|
dpi_factor = plt[:dpi] / Plots.DPI
|
||||||
|
|
||||||
# collect some monitor/display sizes in meters and pixels
|
# collect some monitor/display sizes in meters and pixels
|
||||||
display_width_meters, display_height_meters, display_width_px, display_height_px = GR.inqdspsize()
|
display_width_meters, display_height_meters, display_width_px, display_height_px = GR.inqdspsize()
|
||||||
display_width_ratio = display_width_meters / display_width_px
|
display_width_ratio = display_width_meters / display_width_px
|
||||||
@ -557,14 +554,6 @@ function gr_display(plt::Plot, fmt="")
|
|||||||
# compute the viewport_canvas, normalized to the larger dimension
|
# compute the viewport_canvas, normalized to the larger dimension
|
||||||
viewport_canvas = Float64[0,1,0,1]
|
viewport_canvas = Float64[0,1,0,1]
|
||||||
w, h = plt[:size]
|
w, h = plt[:size]
|
||||||
if !haskey(ENV, "PLOTS_TEST")
|
|
||||||
dpi_factor = plt[:dpi] / DPI
|
|
||||||
if fmt == "png"
|
|
||||||
dpi_factor *= 6
|
|
||||||
end
|
|
||||||
else
|
|
||||||
dpi_factor = 1
|
|
||||||
end
|
|
||||||
gr_plot_size[:] = [w, h]
|
gr_plot_size[:] = [w, h]
|
||||||
if w > h
|
if w > h
|
||||||
ratio = float(h) / w
|
ratio = float(h) / w
|
||||||
@ -587,7 +576,7 @@ function gr_display(plt::Plot, fmt="")
|
|||||||
|
|
||||||
# update point mult
|
# update point mult
|
||||||
px_per_pt = px / pt
|
px_per_pt = px / pt
|
||||||
_gr_point_mult[1] = 1.5 * px_per_pt / max(h,w)
|
_gr_point_mult[1] = 1.5 * _gr_thickness_scaling[1] * px_per_pt / max(h,w)
|
||||||
|
|
||||||
# subplots:
|
# subplots:
|
||||||
for sp in plt.subplots
|
for sp in plt.subplots
|
||||||
@ -633,13 +622,14 @@ function gr_get_ticks_size(ticks, i)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function _update_min_padding!(sp::Subplot{GRBackend})
|
function _update_min_padding!(sp::Subplot{GRBackend})
|
||||||
|
dpi = sp.plt[:thickness_scaling]
|
||||||
if !haskey(ENV, "GKSwstype")
|
if !haskey(ENV, "GKSwstype")
|
||||||
if isijulia() || (isdefined(Main, :Juno) && Juno.isactive())
|
if isijulia() || (isdefined(Main, :Juno) && Juno.isactive())
|
||||||
ENV["GKSwstype"] = "svg"
|
ENV["GKSwstype"] = "svg"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Add margin given by the user
|
# Add margin given by the user
|
||||||
leftpad = 2mm + sp[:left_margin]
|
leftpad = 4mm + sp[:left_margin]
|
||||||
toppad = 2mm + sp[:top_margin]
|
toppad = 2mm + sp[:top_margin]
|
||||||
rightpad = 4mm + sp[:right_margin]
|
rightpad = 4mm + sp[:right_margin]
|
||||||
bottompad = 2mm + sp[:bottom_margin]
|
bottompad = 2mm + sp[:bottom_margin]
|
||||||
@ -675,7 +665,7 @@ function _update_min_padding!(sp::Subplot{GRBackend})
|
|||||||
if sp[:yaxis][:guide] != ""
|
if sp[:yaxis][:guide] != ""
|
||||||
leftpad += 4mm
|
leftpad += 4mm
|
||||||
end
|
end
|
||||||
sp.minpad = (leftpad, toppad, rightpad, bottompad)
|
sp.minpad = Tuple(dpi * [leftpad, toppad, rightpad, bottompad])
|
||||||
end
|
end
|
||||||
|
|
||||||
function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||||
@ -725,6 +715,12 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
end
|
end
|
||||||
if st == :heatmap
|
if st == :heatmap
|
||||||
outside_ticks = true
|
outside_ticks = true
|
||||||
|
for ax in (sp[:xaxis], sp[:yaxis])
|
||||||
|
v = series[ax[:letter]]
|
||||||
|
if diff(collect(extrema(diff(v))))[1] > 1e-6*std(v)
|
||||||
|
warn("GR: heatmap only supported with equally spaced data.")
|
||||||
|
end
|
||||||
|
end
|
||||||
x, y = heatmap_edges(series[:x], sp[:xaxis][:scale]), heatmap_edges(series[:y], sp[:yaxis][:scale])
|
x, y = heatmap_edges(series[:x], sp[:xaxis][:scale]), heatmap_edges(series[:y], sp[:yaxis][:scale])
|
||||||
xy_lims = x[1], x[end], y[1], y[end]
|
xy_lims = x[1], x[end], y[1], y[end]
|
||||||
expand_extrema!(sp[:xaxis], x)
|
expand_extrema!(sp[:xaxis], x)
|
||||||
@ -776,7 +772,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
|
|
||||||
# draw the axes
|
# draw the axes
|
||||||
gr_set_font(tickfont(xaxis))
|
gr_set_font(tickfont(xaxis))
|
||||||
GR.setlinewidth(1)
|
GR.setlinewidth(sp.plt[:thickness_scaling])
|
||||||
|
|
||||||
if is3d(sp)
|
if is3d(sp)
|
||||||
zmin, zmax = gr_lims(zaxis, true)
|
zmin, zmax = gr_lims(zaxis, true)
|
||||||
@ -1046,10 +1042,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if series[:markershape] != :none
|
if series[:markershape] != :none
|
||||||
if series[:marker_z] != nothing
|
|
||||||
zmin, zmax = extrema(series[:marker_z])
|
|
||||||
GR.setspace(zmin, zmax, 0, 90)
|
|
||||||
end
|
|
||||||
gr_draw_markers(series, x, y, clims)
|
gr_draw_markers(series, x, y, clims)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1100,6 +1092,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
elseif st == :heatmap
|
elseif st == :heatmap
|
||||||
xmin, xmax, ymin, ymax = xy_lims
|
xmin, xmax, ymin, ymax = xy_lims
|
||||||
zmin, zmax = clims
|
zmin, zmax = clims
|
||||||
|
m, n = length(x), length(y)
|
||||||
|
xinds = sort(1:m, rev = xaxis[:flip])
|
||||||
|
yinds = sort(1:n, rev = yaxis[:flip])
|
||||||
|
z = reshape(reshape(z, m, n)[xinds, yinds], m*n)
|
||||||
GR.setspace(zmin, zmax, 0, 90)
|
GR.setspace(zmin, zmax, 0, 90)
|
||||||
grad = isa(series[:fillcolor], ColorGradient) ? series[:fillcolor] : cgrad()
|
grad = isa(series[:fillcolor], ColorGradient) ? series[:fillcolor] : cgrad()
|
||||||
colors = [plot_color(grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)], series[:fillalpha]) for zi=z]
|
colors = [plot_color(grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)], series[:fillalpha]) for zi=z]
|
||||||
@ -1203,7 +1199,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
|
|
||||||
elseif st == :image
|
elseif st == :image
|
||||||
z = transpose_z(series, series[:z].surf, true)'
|
z = transpose_z(series, series[:z].surf, true)'
|
||||||
w, h = size(z)
|
w, h = length(x), length(y)
|
||||||
|
xinds = sort(1:w, rev = xaxis[:flip])
|
||||||
|
yinds = sort(1:h, rev = yaxis[:flip])
|
||||||
|
z = z[xinds, yinds]
|
||||||
xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y])
|
xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y])
|
||||||
if eltype(z) <: Colors.AbstractGray
|
if eltype(z) <: Colors.AbstractGray
|
||||||
grey = round.(UInt8, float(z) * 255)
|
grey = round.(UInt8, float(z) * 255)
|
||||||
|
|||||||
@ -240,10 +240,6 @@ end
|
|||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
_show(io::IO, mime::MIME"text/plain", plt::Plot{HDF5Backend}) = nothing #Don't show
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
|
||||||
|
|
||||||
# Display/show the plot (open a GUI window, or browser page, for example).
|
# Display/show the plot (open a GUI window, or browser page, for example).
|
||||||
function _display(plt::Plot{HDF5Backend})
|
function _display(plt::Plot{HDF5Backend})
|
||||||
msg = "HDF5 interface does not support `display()` function."
|
msg = "HDF5 interface does not support `display()` function."
|
||||||
|
|||||||
@ -523,7 +523,6 @@ for (mime, fmt) in _inspectdr_mimeformats_nodpi
|
|||||||
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
|
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
_show(io::IO, mime::MIME"text/plain", plt::Plot{InspectDRBackend}) = nothing #Don't show
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -8,11 +8,12 @@ end
|
|||||||
|
|
||||||
const _pgfplots_attr = merge_with_base_supported([
|
const _pgfplots_attr = merge_with_base_supported([
|
||||||
:annotations,
|
:annotations,
|
||||||
# :background_color_legend,
|
:background_color_legend,
|
||||||
:background_color_inside,
|
:background_color_inside,
|
||||||
# :background_color_outside,
|
# :background_color_outside,
|
||||||
# :foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
|
# :foreground_color_legend,
|
||||||
# :foreground_color_text, :foreground_color_border,
|
:foreground_color_grid, :foreground_color_axis,
|
||||||
|
:foreground_color_text, :foreground_color_border,
|
||||||
:label,
|
:label,
|
||||||
:seriescolor, :seriesalpha,
|
:seriescolor, :seriesalpha,
|
||||||
:linecolor, :linestyle, :linewidth, :linealpha,
|
:linecolor, :linestyle, :linewidth, :linealpha,
|
||||||
@ -149,6 +150,10 @@ function pgf_colormap(grad::ColorGradient)
|
|||||||
end,", ")
|
end,", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
pgf_thickness_scaling(plt::Plot) = plt[:thickness_scaling]
|
||||||
|
pgf_thickness_scaling(sp::Subplot) = pgf_thickness_scaling(sp.plt)
|
||||||
|
pgf_thickness_scaling(series) = pgf_thickness_scaling(series[:subplot])
|
||||||
|
|
||||||
function pgf_fillstyle(d, i = 1)
|
function pgf_fillstyle(d, i = 1)
|
||||||
cstr,a = pgf_color(get_fillcolor(d, i))
|
cstr,a = pgf_color(get_fillcolor(d, i))
|
||||||
fa = get_fillalpha(d, i)
|
fa = get_fillalpha(d, i)
|
||||||
@ -158,42 +163,45 @@ function pgf_fillstyle(d, i = 1)
|
|||||||
"fill = $cstr, fill opacity=$a"
|
"fill = $cstr, fill opacity=$a"
|
||||||
end
|
end
|
||||||
|
|
||||||
function pgf_linestyle(d, i = 1)
|
function pgf_linestyle(linewidth::Real, color, α = 1, linestyle = "solid")
|
||||||
cstr,a = pgf_color(get_linecolor(d, i))
|
cstr, a = pgf_color(plot_color(color, α))
|
||||||
la = get_linealpha(d, i)
|
|
||||||
if la != nothing
|
|
||||||
a = la
|
|
||||||
end
|
|
||||||
"""
|
"""
|
||||||
color = $cstr,
|
color = $cstr,
|
||||||
draw opacity=$a,
|
draw opacity = $a,
|
||||||
line width=$(get_linewidth(d, i)),
|
line width = $linewidth,
|
||||||
$(get(_pgfplots_linestyles, get_linestyle(d, i), "solid"))"""
|
$(get(_pgfplots_linestyles, linestyle, "solid"))"""
|
||||||
|
end
|
||||||
|
|
||||||
|
function pgf_linestyle(d, i = 1)
|
||||||
|
lw = pgf_thickness_scaling(d) * get_linewidth(d, i)
|
||||||
|
lc = get_linecolor(d, i)
|
||||||
|
la = get_linealpha(d, i)
|
||||||
|
ls = get_linestyle(d, i)
|
||||||
|
return pgf_linestyle(lw, lc, la, ls)
|
||||||
|
end
|
||||||
|
|
||||||
|
function pgf_font(fontsize, thickness_scaling = 1, font = "\\selectfont")
|
||||||
|
fs = fontsize * thickness_scaling
|
||||||
|
return string("{\\fontsize{", fs, " pt}{", 1.3fs, " pt}", font, "}")
|
||||||
end
|
end
|
||||||
|
|
||||||
function pgf_marker(d, i = 1)
|
function pgf_marker(d, i = 1)
|
||||||
shape = _cycle(d[:markershape], i)
|
shape = _cycle(d[:markershape], i)
|
||||||
cstr, a = pgf_color(_cycle(d[:markercolor], i))
|
cstr, a = pgf_color(plot_color(get_markercolor(d, i), get_markeralpha(d, i)))
|
||||||
if d[:markeralpha] != nothing
|
cstr_stroke, a_stroke = pgf_color(plot_color(get_markerstrokecolor(d, i), get_markerstrokealpha(d, i)))
|
||||||
a = _cycle(d[:markeralpha], i)
|
|
||||||
end
|
|
||||||
cstr_stroke, a_stroke = pgf_color(_cycle(d[:markerstrokecolor], i))
|
|
||||||
if d[:markerstrokealpha] != nothing
|
|
||||||
a_stroke = _cycle(d[:markerstrokealpha], i)
|
|
||||||
end
|
|
||||||
"""
|
"""
|
||||||
mark = $(get(_pgfplots_markers, shape, "*")),
|
mark = $(get(_pgfplots_markers, shape, "*")),
|
||||||
mark size = $(0.5 * _cycle(d[:markersize], i)),
|
mark size = $(pgf_thickness_scaling(d) * 0.5 * _cycle(d[:markersize], i)),
|
||||||
mark options = {
|
mark options = {
|
||||||
color = $cstr_stroke, draw opacity = $a_stroke,
|
color = $cstr_stroke, draw opacity = $a_stroke,
|
||||||
fill = $cstr, fill opacity = $a,
|
fill = $cstr, fill opacity = $a,
|
||||||
line width = $(_cycle(d[:markerstrokewidth], i)),
|
line width = $(pgf_thickness_scaling(d) * _cycle(d[:markerstrokewidth], i)),
|
||||||
rotate = $(shape == :dtriangle ? 180 : 0),
|
rotate = $(shape == :dtriangle ? 180 : 0),
|
||||||
$(get(_pgfplots_linestyles, _cycle(d[:markerstrokestyle], i), "solid"))
|
$(get(_pgfplots_linestyles, _cycle(d[:markerstrokestyle], i), "solid"))
|
||||||
}"""
|
}"""
|
||||||
end
|
end
|
||||||
|
|
||||||
function pgf_add_annotation!(o,x,y,val)
|
function pgf_add_annotation!(o, x, y, val, thickness_scaling = 1)
|
||||||
# Construct the style string.
|
# Construct the style string.
|
||||||
# Currently supports color and orientation
|
# Currently supports color and orientation
|
||||||
cstr,a = pgf_color(val.font.color)
|
cstr,a = pgf_color(val.font.color)
|
||||||
@ -202,7 +210,8 @@ function pgf_add_annotation!(o,x,y,val)
|
|||||||
style="""
|
style="""
|
||||||
$(get(_pgf_annotation_halign,val.font.halign,"")),
|
$(get(_pgf_annotation_halign,val.font.halign,"")),
|
||||||
color=$cstr, draw opacity=$(convert(Float16,a)),
|
color=$cstr, draw opacity=$(convert(Float16,a)),
|
||||||
rotate=$(val.font.rotation)
|
rotate=$(val.font.rotation),
|
||||||
|
font=$(pgf_font(val.font.pointsize, thickness_scaling))
|
||||||
"""))
|
"""))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -222,10 +231,6 @@ function pgf_series(sp::Subplot, series::Series)
|
|||||||
straightline_data(series)
|
straightline_data(series)
|
||||||
elseif st == :shape
|
elseif st == :shape
|
||||||
shape_data(series)
|
shape_data(series)
|
||||||
elseif d[:marker_z] != nothing
|
|
||||||
# If a marker_z is used pass it as third coordinate to a 2D plot.
|
|
||||||
# See "Scatter Plots" in PGFPlots documentation
|
|
||||||
d[:x], d[:y], d[:marker_z]
|
|
||||||
elseif ispolar(sp)
|
elseif ispolar(sp)
|
||||||
theta, r = filter_radial_data(d[:x], d[:y], axis_limits(sp[:yaxis]))
|
theta, r = filter_radial_data(d[:x], d[:y], axis_limits(sp[:yaxis]))
|
||||||
rad2deg.(theta), r
|
rad2deg.(theta), r
|
||||||
@ -380,8 +385,9 @@ function pgf_axis(sp::Subplot, letter)
|
|||||||
# axis guide
|
# axis guide
|
||||||
kw[Symbol(letter,:label)] = axis[:guide]
|
kw[Symbol(letter,:label)] = axis[:guide]
|
||||||
|
|
||||||
# Add ticklabel rotations
|
# Add label font
|
||||||
push!(style, "$(letter)ticklabel style={rotate = $(axis[:rotation])}")
|
cstr, α = pgf_color(plot_color(axis[:guidefontcolor]))
|
||||||
|
push!(style, string(letter, "label style = {font = ", pgf_font(axis[:guidefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", axis[:guidefontrotation], "}"))
|
||||||
|
|
||||||
# flip/reverse?
|
# flip/reverse?
|
||||||
axis[:flip] && push!(style, "$letter dir=reverse")
|
axis[:flip] && push!(style, "$letter dir=reverse")
|
||||||
@ -437,6 +443,9 @@ function pgf_axis(sp::Subplot, letter)
|
|||||||
push!(style, string(letter, "ticklabels = {}"))
|
push!(style, string(letter, "ticklabels = {}"))
|
||||||
end
|
end
|
||||||
push!(style, string(letter, "tick align = ", (axis[:tick_direction] == :out ? "outside" : "inside")))
|
push!(style, string(letter, "tick align = ", (axis[:tick_direction] == :out ? "outside" : "inside")))
|
||||||
|
cstr, α = pgf_color(plot_color(axis[:tickfontcolor]))
|
||||||
|
push!(style, string(letter, "ticklabel style = {font = ", pgf_font(axis[:tickfontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", axis[:tickfontrotation], "}"))
|
||||||
|
push!(style, string(letter, " grid style = {", pgf_linestyle(pgf_thickness_scaling(sp) * axis[:gridlinewidth], axis[:foreground_color_grid], axis[:gridalpha], axis[:gridstyle]), "}"))
|
||||||
end
|
end
|
||||||
|
|
||||||
# framestyle
|
# framestyle
|
||||||
@ -449,7 +458,7 @@ function pgf_axis(sp::Subplot, letter)
|
|||||||
if framestyle == :zerolines
|
if framestyle == :zerolines
|
||||||
push!(style, string("extra ", letter, " ticks = 0"))
|
push!(style, string("extra ", letter, " ticks = 0"))
|
||||||
push!(style, string("extra ", letter, " tick labels = "))
|
push!(style, string("extra ", letter, " tick labels = "))
|
||||||
push!(style, string("extra ", letter, " tick style = {grid = major, major grid style = {color = black, draw opacity=1.0, line width=0.5), solid}}"))
|
push!(style, string("extra ", letter, " tick style = {grid = major, major grid style = {", pgf_linestyle(pgf_thickness_scaling(sp), axis[:foreground_color_axis], 1.0), "}}"))
|
||||||
end
|
end
|
||||||
|
|
||||||
if !axis[:showaxis]
|
if !axis[:showaxis]
|
||||||
@ -457,6 +466,8 @@ function pgf_axis(sp::Subplot, letter)
|
|||||||
end
|
end
|
||||||
if !axis[:showaxis] || framestyle in (:zerolines, :grid, :none)
|
if !axis[:showaxis] || framestyle in (:zerolines, :grid, :none)
|
||||||
push!(style, string(letter, " axis line style = {draw opacity = 0}"))
|
push!(style, string(letter, " axis line style = {draw opacity = 0}"))
|
||||||
|
else
|
||||||
|
push!(style, string(letter, " axis line style = {", pgf_linestyle(pgf_thickness_scaling(sp), axis[:foreground_color_axis], 1.0), "}"))
|
||||||
end
|
end
|
||||||
|
|
||||||
# return the style list and KW args
|
# return the style list and KW args
|
||||||
@ -501,6 +512,8 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
|
|
||||||
if sp[:title] != ""
|
if sp[:title] != ""
|
||||||
kw[:title] = "$(sp[:title])"
|
kw[:title] = "$(sp[:title])"
|
||||||
|
cstr, α = pgf_color(plot_color(sp[:titlefontcolor]))
|
||||||
|
push!(style, string("title style = {font = ", pgf_font(sp[:titlefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", sp[:titlefontrotation], "}"))
|
||||||
end
|
end
|
||||||
|
|
||||||
if sp[:aspect_ratio] in (1, :equal)
|
if sp[:aspect_ratio] in (1, :equal)
|
||||||
@ -511,6 +524,8 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
if haskey(_pgfplots_legend_pos, legpos)
|
if haskey(_pgfplots_legend_pos, legpos)
|
||||||
kw[:legendPos] = _pgfplots_legend_pos[legpos]
|
kw[:legendPos] = _pgfplots_legend_pos[legpos]
|
||||||
end
|
end
|
||||||
|
cstr, a = pgf_color(plot_color(sp[:background_color_legend]))
|
||||||
|
push!(style, string("legend style = {", pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], 1.0, "solid"), ",", "fill = $cstr,", "font = ", pgf_font(sp[:legendfontsize], pgf_thickness_scaling(sp)), "}"))
|
||||||
|
|
||||||
if any(s[:seriestype] == :contour for s in series_list(sp))
|
if any(s[:seriestype] == :contour for s in series_list(sp))
|
||||||
kw[:view] = "{0}{90}"
|
kw[:view] = "{0}{90}"
|
||||||
@ -564,13 +579,13 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
# add series annotations
|
# add series annotations
|
||||||
anns = series[:series_annotations]
|
anns = series[:series_annotations]
|
||||||
for (xi,yi,str,fnt) in EachAnn(anns, series[:x], series[:y])
|
for (xi,yi,str,fnt) in EachAnn(anns, series[:x], series[:y])
|
||||||
pgf_add_annotation!(o, xi, yi, PlotText(str, fnt))
|
pgf_add_annotation!(o, xi, yi, PlotText(str, fnt), pgf_thickness_scaling(series))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# add the annotations
|
# add the annotations
|
||||||
for ann in sp[:annotations]
|
for ann in sp[:annotations]
|
||||||
pgf_add_annotation!(o, locate_annotation(sp, ann...)...)
|
pgf_add_annotation!(o, locate_annotation(sp, ann...)..., pgf_thickness_scaling(sp))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -263,6 +263,7 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
|
|||||||
end
|
end
|
||||||
|
|
||||||
ax[:tickangle] = -axis[:rotation]
|
ax[:tickangle] = -axis[:rotation]
|
||||||
|
ax[:type] = plotly_scale(axis[:scale])
|
||||||
lims = axis_limits(axis)
|
lims = axis_limits(axis)
|
||||||
|
|
||||||
if axis[:ticks] != :native || axis[:lims] != :auto
|
if axis[:ticks] != :native || axis[:lims] != :auto
|
||||||
@ -271,14 +272,13 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
|
|||||||
|
|
||||||
if !(axis[:ticks] in (nothing, :none, false))
|
if !(axis[:ticks] in (nothing, :none, false))
|
||||||
ax[:titlefont] = plotly_font(guidefont(axis))
|
ax[:titlefont] = plotly_font(guidefont(axis))
|
||||||
ax[:type] = plotly_scale(axis[:scale])
|
|
||||||
ax[:tickfont] = plotly_font(tickfont(axis))
|
ax[:tickfont] = plotly_font(tickfont(axis))
|
||||||
ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis])
|
ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis])
|
||||||
ax[:linecolor] = rgba_string(axis[:foreground_color_axis])
|
ax[:linecolor] = rgba_string(axis[:foreground_color_axis])
|
||||||
|
|
||||||
# flip
|
# flip
|
||||||
if axis[:flip]
|
if axis[:flip]
|
||||||
ax[:autorange] = "reversed"
|
ax[:range] = reverse(ax[:range])
|
||||||
end
|
end
|
||||||
|
|
||||||
# ticks
|
# ticks
|
||||||
@ -328,9 +328,11 @@ function plotly_layout(plt::Plot)
|
|||||||
|
|
||||||
d_out[:annotations] = KW[]
|
d_out[:annotations] = KW[]
|
||||||
|
|
||||||
|
multiple_subplots = length(plt.subplots) > 1
|
||||||
|
|
||||||
for sp in plt.subplots
|
for sp in plt.subplots
|
||||||
spidx = sp[:subplot_index]
|
spidx = multiple_subplots ? sp[:subplot_index] : ""
|
||||||
x_idx, y_idx = plotly_link_indicies(plt, sp)
|
x_idx, y_idx = multiple_subplots ? plotly_link_indicies(plt, sp) : ("", "")
|
||||||
# add an annotation for the title... positioned horizontally relative to plotarea,
|
# add an annotation for the title... positioned horizontally relative to plotarea,
|
||||||
# but vertically just below the top of the subplot bounding box
|
# but vertically just below the top of the subplot bounding box
|
||||||
if sp[:title] != ""
|
if sp[:title] != ""
|
||||||
@ -388,6 +390,7 @@ function plotly_layout(plt::Plot)
|
|||||||
:bgcolor => rgba_string(sp[:background_color_legend]),
|
:bgcolor => rgba_string(sp[:background_color_legend]),
|
||||||
:bordercolor => rgba_string(sp[:foreground_color_legend]),
|
:bordercolor => rgba_string(sp[:foreground_color_legend]),
|
||||||
:font => plotly_font(legendfont(sp)),
|
:font => plotly_font(legendfont(sp)),
|
||||||
|
:tracegroupgap => 0,
|
||||||
:x => xpos,
|
:x => xpos,
|
||||||
:y => ypos
|
:y => ypos
|
||||||
)
|
)
|
||||||
@ -584,6 +587,8 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
return plotly_series_segments(series, d_out, x, y, z)
|
return plotly_series_segments(series, d_out, x, y, z)
|
||||||
|
|
||||||
elseif st == :heatmap
|
elseif st == :heatmap
|
||||||
|
x = heatmap_edges(x, sp[:xaxis][:scale])
|
||||||
|
y = heatmap_edges(y, sp[:yaxis][:scale])
|
||||||
d_out[:type] = "heatmap"
|
d_out[:type] = "heatmap"
|
||||||
d_out[:x], d_out[:y], d_out[:z] = x, y, z
|
d_out[:x], d_out[:y], d_out[:z] = x, y, z
|
||||||
d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
||||||
@ -632,31 +637,17 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
|
|
||||||
# add "marker"
|
# add "marker"
|
||||||
if hasmarker
|
if hasmarker
|
||||||
|
inds = eachindex(x)
|
||||||
d_out[:marker] = KW(
|
d_out[:marker] = KW(
|
||||||
:symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])),
|
:symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])),
|
||||||
# :opacity => series[:markeralpha],
|
# :opacity => series[:markeralpha],
|
||||||
:size => 2 * series[:markersize],
|
:size => 2 * _cycle(series[:markersize], inds),
|
||||||
# :color => rgba_string(series[:markercolor]),
|
:color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))),
|
||||||
:line => KW(
|
:line => KW(
|
||||||
:color => _cycle(rgba_string.(series[:markerstrokecolor]),eachindex(series[:x])),
|
:color => rgba_string.(plot_color.(get_markerstrokecolor.(series, inds), get_markerstrokealpha.(series, inds))),
|
||||||
:width => series[:markerstrokewidth],
|
:width => _cycle(series[:markerstrokewidth], inds),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# gotta hack this (for now?) since plotly can't handle rgba values inside the gradient
|
|
||||||
if series[:marker_z] == nothing
|
|
||||||
d_out[:marker][:color] = _cycle(rgba_string.(series[:markercolor]),eachindex(series[:x]))
|
|
||||||
else
|
|
||||||
# grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha])
|
|
||||||
# grad = as_gradient(series[:markercolor], series[:markeralpha])
|
|
||||||
cmin, cmax = get_clims(sp)
|
|
||||||
# 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)
|
|
||||||
d_out[:marker][:color] = [clamp(zi, cmin, cmax) for zi in series[:marker_z]]
|
|
||||||
d_out[:marker][:cmin] = cmin
|
|
||||||
d_out[:marker][:cmax] = cmax
|
|
||||||
d_out[:marker][:colorscale] = plotly_colorscale(series[:markercolor], series[:markeralpha])
|
|
||||||
d_out[:marker][:showscale] = hascolorbar(sp)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
plotly_polar!(d_out, series)
|
plotly_polar!(d_out, series)
|
||||||
@ -674,11 +665,12 @@ function plotly_series_shapes(plt::Plot, series::Series)
|
|||||||
|
|
||||||
# these are the axes that the series should be mapped to
|
# these are the axes that the series should be mapped to
|
||||||
x_idx, y_idx = plotly_link_indicies(plt, series[:subplot])
|
x_idx, y_idx = plotly_link_indicies(plt, series[:subplot])
|
||||||
base_d = KW()
|
d_base = KW(
|
||||||
base_d[:xaxis] = "x$(x_idx)"
|
:xaxis => "x$(x_idx)",
|
||||||
base_d[:yaxis] = "y$(y_idx)"
|
:yaxis => "y$(y_idx)",
|
||||||
base_d[:name] = series[:label]
|
:name => series[:label],
|
||||||
# base_d[:legendgroup] = series[:label]
|
:legendgroup => series[:label],
|
||||||
|
)
|
||||||
|
|
||||||
x, y = (plotly_data(series, letter, data)
|
x, y = (plotly_data(series, letter, data)
|
||||||
for (letter, data) in zip((:x, :y), shape_data(series))
|
for (letter, data) in zip((:x, :y), shape_data(series))
|
||||||
@ -688,7 +680,7 @@ function plotly_series_shapes(plt::Plot, series::Series)
|
|||||||
length(rng) < 2 && continue
|
length(rng) < 2 && continue
|
||||||
|
|
||||||
# to draw polygons, we actually draw lines with fill
|
# to draw polygons, we actually draw lines with fill
|
||||||
d_out = merge(base_d, KW(
|
d_out = merge(d_base, KW(
|
||||||
:type => "scatter",
|
:type => "scatter",
|
||||||
:mode => "lines",
|
:mode => "lines",
|
||||||
:x => vcat(x[rng], x[rng[1]]),
|
:x => vcat(x[rng], x[rng[1]]),
|
||||||
@ -709,9 +701,11 @@ function plotly_series_shapes(plt::Plot, series::Series)
|
|||||||
d_outs[i] = d_out
|
d_outs[i] = d_out
|
||||||
end
|
end
|
||||||
if series[:fill_z] != nothing
|
if series[:fill_z] != nothing
|
||||||
push!(d_outs, plotly_colorbar_hack(series, base_d, :fill))
|
push!(d_outs, plotly_colorbar_hack(series, d_base, :fill))
|
||||||
elseif series[:line_z] != nothing
|
elseif series[:line_z] != nothing
|
||||||
push!(d_outs, plotly_colorbar_hack(series, base_d, :line))
|
push!(d_outs, plotly_colorbar_hack(series, d_base, :line))
|
||||||
|
elseif series[:marker_z] != nothing
|
||||||
|
push!(d_outs, plotly_colorbar_hack(series, d_base, :marker))
|
||||||
end
|
end
|
||||||
d_outs
|
d_outs
|
||||||
end
|
end
|
||||||
@ -729,10 +723,11 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z)
|
|||||||
d_outs = Vector{KW}((hasfillrange ? 2 : 1 ) * length(segments))
|
d_outs = Vector{KW}((hasfillrange ? 2 : 1 ) * length(segments))
|
||||||
|
|
||||||
for (i,rng) in enumerate(segments)
|
for (i,rng) in enumerate(segments)
|
||||||
length(rng) < 2 && continue
|
!isscatter && length(rng) < 2 && continue
|
||||||
|
|
||||||
d_out = deepcopy(d_base)
|
d_out = deepcopy(d_base)
|
||||||
d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
|
d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
|
||||||
|
d_out[:legendgroup] = series[:label]
|
||||||
|
|
||||||
# set the type
|
# set the type
|
||||||
if st in (:path, :scatter, :scattergl, :straightline)
|
if st in (:path, :scatter, :scattergl, :straightline)
|
||||||
@ -766,30 +761,15 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z)
|
|||||||
# add "marker"
|
# add "marker"
|
||||||
if hasmarker
|
if hasmarker
|
||||||
d_out[:marker] = KW(
|
d_out[:marker] = KW(
|
||||||
:symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])),
|
:symbol => get(_plotly_markers, _cycle(series[:markershape], i), string(_cycle(series[:markershape], i))),
|
||||||
# :opacity => series[:markeralpha],
|
# :opacity => series[:markeralpha],
|
||||||
:size => 2 * series[:markersize],
|
:size => 2 * _cycle(series[:markersize], i),
|
||||||
# :color => rgba_string(series[:markercolor]),
|
:color => rgba_string(plot_color(get_markercolor(series, i), get_markeralpha(series, i))),
|
||||||
:line => KW(
|
:line => KW(
|
||||||
:color => _cycle(rgba_string.(series[:markerstrokecolor]), eachindex(rng)),
|
:color => rgba_string(plot_color(get_markerstrokecolor(series, i), get_markerstrokealpha(series, i))),
|
||||||
:width => series[:markerstrokewidth],
|
:width => _cycle(series[:markerstrokewidth], i),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# gotta hack this (for now?) since plotly can't handle rgba values inside the gradient
|
|
||||||
if series[:marker_z] == nothing
|
|
||||||
d_out[:marker][:color] = _cycle(rgba_string.(series[:markercolor]), eachindex(rng))
|
|
||||||
else
|
|
||||||
# grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha])
|
|
||||||
# grad = as_gradient(series[:markercolor], series[:markeralpha])
|
|
||||||
cmin, cmax = get_clims(sp)
|
|
||||||
# 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)
|
|
||||||
d_out[:marker][:color] = [clamp(zi, cmin, cmax) for zi in _cycle(series[:marker_z], rng)]
|
|
||||||
d_out[:marker][:cmin] = cmin
|
|
||||||
d_out[:marker][:cmax] = cmax
|
|
||||||
d_out[:marker][:colorscale] = plotly_colorscale(series[:markercolor], series[:markeralpha])
|
|
||||||
d_out[:marker][:showscale] = hascolorbar(sp)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# add "line"
|
# add "line"
|
||||||
@ -809,7 +789,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z)
|
|||||||
end
|
end
|
||||||
|
|
||||||
plotly_polar!(d_out, series)
|
plotly_polar!(d_out, series)
|
||||||
plotly_hover!(d_out, series[:hover])
|
plotly_hover!(d_out, _cycle(series[:hover], rng))
|
||||||
|
|
||||||
if hasfillrange
|
if hasfillrange
|
||||||
# if hasfillrange is true, return two dictionaries (one for original
|
# if hasfillrange is true, return two dictionaries (one for original
|
||||||
@ -825,14 +805,14 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z)
|
|||||||
series[:fillrange] = (f1, f2)
|
series[:fillrange] = (f1, f2)
|
||||||
end
|
end
|
||||||
if isa(series[:fillrange], AbstractVector)
|
if isa(series[:fillrange], AbstractVector)
|
||||||
d_out_fillrange[:y] = series[:fillrange]
|
d_out_fillrange[:y] = series[:fillrange][rng]
|
||||||
delete!(d_out_fillrange, :fill)
|
delete!(d_out_fillrange, :fill)
|
||||||
delete!(d_out_fillrange, :fillcolor)
|
delete!(d_out_fillrange, :fillcolor)
|
||||||
else
|
else
|
||||||
# if fillrange is a tuple with upper and lower limit, d_out_fillrange
|
# if fillrange is a tuple with upper and lower limit, d_out_fillrange
|
||||||
# is the series that will do the filling
|
# is the series that will do the filling
|
||||||
d_out_fillrange[:x], d_out_fillrange[:y] =
|
fillrng = Tuple(series[:fillrange][i][rng] for i in 1:2)
|
||||||
concatenate_fillrange(x[rng], series[:fillrange][rng])
|
d_out_fillrange[:x], d_out_fillrange[:y] = concatenate_fillrange(x[rng], fillrng)
|
||||||
d_out_fillrange[:line][:width] = 0
|
d_out_fillrange[:line][:width] = 0
|
||||||
delete!(d_out, :fill)
|
delete!(d_out, :fill)
|
||||||
delete!(d_out, :fillcolor)
|
delete!(d_out, :fillcolor)
|
||||||
@ -848,6 +828,8 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z)
|
|||||||
push!(d_outs, plotly_colorbar_hack(series, d_base, :line))
|
push!(d_outs, plotly_colorbar_hack(series, d_base, :line))
|
||||||
elseif series[:fill_z] != nothing
|
elseif series[:fill_z] != nothing
|
||||||
push!(d_outs, plotly_colorbar_hack(series, d_base, :fill))
|
push!(d_outs, plotly_colorbar_hack(series, d_base, :fill))
|
||||||
|
elseif series[:marker_z] != nothing
|
||||||
|
push!(d_outs, plotly_colorbar_hack(series, d_base, :marker))
|
||||||
end
|
end
|
||||||
|
|
||||||
d_outs
|
d_outs
|
||||||
@ -858,6 +840,7 @@ function plotly_colorbar_hack(series::Series, d_base::KW, sym::Symbol)
|
|||||||
cmin, cmax = get_clims(series[:subplot])
|
cmin, cmax = get_clims(series[:subplot])
|
||||||
d_out[:showlegend] = false
|
d_out[:showlegend] = false
|
||||||
d_out[:type] = is3d(series) ? :scatter3d : :scatter
|
d_out[:type] = is3d(series) ? :scatter3d : :scatter
|
||||||
|
d_out[:hoverinfo] = :none
|
||||||
d_out[:mode] = :markers
|
d_out[:mode] = :markers
|
||||||
d_out[:x], d_out[:y] = [series[:x][1]], [series[:y][1]]
|
d_out[:x], d_out[:y] = [series[:x][1]], [series[:y][1]]
|
||||||
if is3d(series)
|
if is3d(series)
|
||||||
@ -866,6 +849,7 @@ function plotly_colorbar_hack(series::Series, d_base::KW, sym::Symbol)
|
|||||||
# 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)
|
# 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)
|
||||||
d_out[:marker] = KW(
|
d_out[:marker] = KW(
|
||||||
:size => 0,
|
:size => 0,
|
||||||
|
:opacity => 0,
|
||||||
:color => [0.5],
|
:color => [0.5],
|
||||||
:cmin => cmin,
|
:cmin => cmin,
|
||||||
:cmax => cmax,
|
:cmax => cmax,
|
||||||
@ -944,17 +928,7 @@ end
|
|||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
function _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyBackend})
|
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
|
||||||
# show_png_from_html(io, plt)
|
|
||||||
error("png output from the plotly backend is not supported. Please use plotlyjs instead.")
|
|
||||||
end
|
|
||||||
|
|
||||||
function _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyBackend})
|
|
||||||
error("svg output from the plotly backend is not supported. Please use plotlyjs instead.")
|
|
||||||
end
|
|
||||||
|
|
||||||
function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
|
|
||||||
prepare_output(plt)
|
|
||||||
write(io, html_head(plt) * html_body(plt))
|
write(io, html_head(plt) * html_body(plt))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -88,8 +88,7 @@ end
|
|||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend})
|
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend})
|
||||||
prepare_output(plt)
|
|
||||||
if isijulia() && !_use_remote[]
|
if isijulia() && !_use_remote[]
|
||||||
write(io, PlotlyJS.html_body(PlotlyJS.JupyterPlot(plt.o)))
|
write(io, PlotlyJS.html_body(PlotlyJS.JupyterPlot(plt.o)))
|
||||||
else
|
else
|
||||||
@ -121,6 +120,12 @@ function _display(plt::Plot{PlotlyJSBackend})
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@require WebIO begin
|
||||||
|
function WebIO.render(plt::Plot{PlotlyJSBackend})
|
||||||
|
prepare_output(plt)
|
||||||
|
WebIO.render(plt.o)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function closeall(::PlotlyJSBackend)
|
function closeall(::PlotlyJSBackend)
|
||||||
if !isplotnull() && isa(current().o, PlotlyJS.SyncPlot)
|
if !isplotnull() && isa(current().o, PlotlyJS.SyncPlot)
|
||||||
|
|||||||
@ -395,14 +395,14 @@ function py_bbox_title(ax)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz)
|
function py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz)
|
||||||
ptsz * plt[:dpi] / DPI
|
ptsz
|
||||||
end
|
end
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
# Create the window/figure for this backend.
|
# Create the window/figure for this backend.
|
||||||
function _create_backend_figure(plt::Plot{PyPlotBackend})
|
function _create_backend_figure(plt::Plot{PyPlotBackend})
|
||||||
w,h = map(px2inch, plt[:size])
|
w,h = map(px2inch, Tuple(s * plt[:dpi] / Plots.DPI for s in plt[:size]))
|
||||||
|
|
||||||
# # reuse the current figure?
|
# # reuse the current figure?
|
||||||
fig = if plt[:overwrite_figure]
|
fig = if plt[:overwrite_figure]
|
||||||
@ -570,12 +570,12 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
if series[:markershape] != :none && st in (:path, :scatter, :path3d,
|
if series[:markershape] != :none && st in (:path, :scatter, :path3d,
|
||||||
:scatter3d, :steppre, :steppost,
|
:scatter3d, :steppre, :steppost,
|
||||||
:bar)
|
:bar)
|
||||||
if series[:marker_z] == nothing
|
markercolor = if any(typeof(series[arg]) <: AVec for arg in (:markercolor, :markeralpha)) || series[:marker_z] != nothing
|
||||||
extrakw[:c] = series[:markershape] in (:+, :x, :hline, :vline) ? py_markerstrokecolor(series) : py_color_fix(py_markercolor(series), x)
|
py_color(plot_color.(get_markercolor.(series, eachindex(x)), get_markeralpha.(series, eachindex(x))))
|
||||||
else
|
else
|
||||||
extrakw[:c] = convert(Vector{Float64}, series[:marker_z])
|
py_color(plot_color(series[:markercolor], series[:markeralpha]))
|
||||||
extrakw[:cmap] = py_markercolormap(series)
|
|
||||||
end
|
end
|
||||||
|
extrakw[:c] = py_color_fix(markercolor, x)
|
||||||
xyargs = if st == :bar && !isvertical(series)
|
xyargs = if st == :bar && !isvertical(series)
|
||||||
(y, x)
|
(y, x)
|
||||||
else
|
else
|
||||||
@ -591,11 +591,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
msc = py_markerstrokecolor(series)
|
msc = py_markerstrokecolor(series)
|
||||||
lw = py_dpi_scale(plt, series[:markerstrokewidth])
|
lw = py_dpi_scale(plt, series[:markerstrokewidth])
|
||||||
for i=1:length(y)
|
for i=1:length(y)
|
||||||
extrakw[:c] = if series[:marker_z] == nothing
|
extrakw[:c] = _cycle(markercolor, i)
|
||||||
py_color_fix(py_color(_cycle(series[:markercolor],i)), x)
|
|
||||||
else
|
|
||||||
extrakw[:c]
|
|
||||||
end
|
|
||||||
|
|
||||||
push!(handle, ax[:scatter](_cycle(x,i), _cycle(y,i);
|
push!(handle, ax[:scatter](_cycle(x,i), _cycle(y,i);
|
||||||
label = series[:label],
|
label = series[:label],
|
||||||
@ -638,6 +634,12 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
|
|
||||||
if st in (:contour, :contour3d)
|
if st in (:contour, :contour3d)
|
||||||
z = transpose_z(series, z.surf)
|
z = transpose_z(series, z.surf)
|
||||||
|
if typeof(x)<:Plots.Surface
|
||||||
|
x = Plots.transpose_z(series, x.surf)
|
||||||
|
end
|
||||||
|
if typeof(y)<:Plots.Surface
|
||||||
|
y = Plots.transpose_z(series, y.surf)
|
||||||
|
end
|
||||||
|
|
||||||
if st == :contour3d
|
if st == :contour3d
|
||||||
extrakw[:extend3d] = true
|
extrakw[:extend3d] = true
|
||||||
@ -835,9 +837,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
end
|
end
|
||||||
n = length(dim1)
|
n = length(dim1)
|
||||||
args = if typeof(fillrange) <: Union{Real, AVec}
|
args = if typeof(fillrange) <: Union{Real, AVec}
|
||||||
dim1, expand_data(fillrange, n), dim2
|
dim1, _cycle(fillrange, rng), dim2
|
||||||
elseif is_2tuple(fillrange)
|
elseif is_2tuple(fillrange)
|
||||||
dim1, expand_data(fillrange[1], n), expand_data(fillrange[2], n)
|
dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng)
|
||||||
end
|
end
|
||||||
|
|
||||||
handle = ax[f](args..., trues(n), false, py_fillstepstyle(st);
|
handle = ax[f](args..., trues(n), false, py_fillstepstyle(st);
|
||||||
@ -953,10 +955,10 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
w, h = plt[:size]
|
w, h = plt[:size]
|
||||||
fig = plt.o
|
fig = plt.o
|
||||||
fig[:clear]()
|
fig[:clear]()
|
||||||
dpi = plt[:dpi]
|
dpi = plt[:thickness_scaling] * plt[:dpi]
|
||||||
fig[:set_size_inches](w/dpi, h/dpi, forward = true)
|
fig[:set_size_inches](w/DPI/plt[:thickness_scaling], h/DPI/plt[:thickness_scaling], forward = true)
|
||||||
fig[set_facecolor_sym](py_color(plt[:background_color_outside]))
|
fig[set_facecolor_sym](py_color(plt[:background_color_outside]))
|
||||||
fig[:set_dpi](dpi)
|
fig[:set_dpi](plt[:dpi])
|
||||||
|
|
||||||
# resize the window
|
# resize the window
|
||||||
PyPlot.plt[:get_current_fig_manager]()[:resize](w, h)
|
PyPlot.plt[:get_current_fig_manager]()[:resize](w, h)
|
||||||
@ -1014,10 +1016,16 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
kw[:ticks] = locator
|
kw[:ticks] = locator
|
||||||
kw[:format] = formatter
|
kw[:format] = formatter
|
||||||
kw[:boundaries] = vcat(0, kw[:values] + 0.5)
|
kw[:boundaries] = vcat(0, kw[:values] + 0.5)
|
||||||
elseif any(colorbar_series[attr] != nothing for attr in (:line_z, :fill_z))
|
elseif any(colorbar_series[attr] != nothing for attr in (:line_z, :fill_z, :marker_z))
|
||||||
cmin, cmax = get_clims(sp)
|
cmin, cmax = get_clims(sp)
|
||||||
norm = pycolors[:Normalize](vmin = cmin, vmax = cmax)
|
norm = pycolors[:Normalize](vmin = cmin, vmax = cmax)
|
||||||
f = colorbar_series[:line_z] != nothing ? py_linecolormap : py_fillcolormap
|
f = if colorbar_series[:line_z] != nothing
|
||||||
|
py_linecolormap
|
||||||
|
elseif colorbar_series[:fill_z] != nothing
|
||||||
|
py_fillcolormap
|
||||||
|
else
|
||||||
|
py_markercolormap
|
||||||
|
end
|
||||||
cmap = pycmap[:ScalarMappable](norm = norm, cmap = f(colorbar_series))
|
cmap = pycmap[:ScalarMappable](norm = norm, cmap = f(colorbar_series))
|
||||||
cmap[:set_array]([])
|
cmap[:set_array]([])
|
||||||
handle = cmap
|
handle = cmap
|
||||||
@ -1077,7 +1085,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
pyaxis[Symbol(:tick_, pos)]() # the tick labels
|
pyaxis[Symbol(:tick_, pos)]() # the tick labels
|
||||||
end
|
end
|
||||||
py_set_scale(ax, axis)
|
py_set_scale(ax, axis)
|
||||||
axis[:ticks] != :native || axis[:lims] != :auto ? py_set_lims(ax, axis) : nothing
|
axis[:ticks] != :native ? py_set_lims(ax, axis) : nothing
|
||||||
if ispolar(sp) && letter == :y
|
if ispolar(sp) && letter == :y
|
||||||
ax[:set_rlabel_position](90)
|
ax[:set_rlabel_position](90)
|
||||||
end
|
end
|
||||||
@ -1201,7 +1209,9 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend})
|
|||||||
rightpad += sp[:right_margin]
|
rightpad += sp[:right_margin]
|
||||||
bottompad += sp[:bottom_margin]
|
bottompad += sp[:bottom_margin]
|
||||||
|
|
||||||
sp.minpad = (leftpad, toppad, rightpad, bottompad)
|
dpi_factor = sp.plt[:thickness_scaling] * Plots.DPI / sp.plt[:dpi]
|
||||||
|
|
||||||
|
sp.minpad = Tuple(dpi_factor .* [leftpad, toppad, rightpad, bottompad])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -1262,8 +1272,8 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
|
|||||||
linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)),
|
linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)),
|
||||||
linestyle = py_linestyle(:path, get_linestyle(series)),
|
linestyle = py_linestyle(:path, get_linestyle(series)),
|
||||||
marker = py_marker(series[:markershape]),
|
marker = py_marker(series[:markershape]),
|
||||||
markeredgecolor = py_markerstrokecolor(series),
|
markeredgecolor = py_color(get_markerstrokecolor(series), get_markerstrokealpha(series)),
|
||||||
markerfacecolor = series[:marker_z] == nothing ? py_markercolor(series) : py_color(series[:markercolor][0.5])
|
markerfacecolor = series[:marker_z] == nothing ? py_color(get_markercolor(series), get_markeralpha(series)) : py_color(series[:markercolor][0.5])
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
series[:serieshandle][1]
|
series[:serieshandle][1]
|
||||||
@ -1278,23 +1288,17 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
|
|||||||
labels,
|
labels,
|
||||||
loc = get(_pyplot_legend_pos, leg, "best"),
|
loc = get(_pyplot_legend_pos, leg, "best"),
|
||||||
scatterpoints = 1,
|
scatterpoints = 1,
|
||||||
fontsize = py_dpi_scale(plt, sp[:legendfontsize])
|
fontsize = py_dpi_scale(plt, sp[:legendfontsize]),
|
||||||
# family = sp[:legendfont].family
|
facecolor = py_color(sp[:background_color_legend]),
|
||||||
# framealpha = 0.6
|
edgecolor = py_color(sp[:foreground_color_legend]),
|
||||||
|
framealpha = alpha(plot_color(sp[:background_color_legend])),
|
||||||
)
|
)
|
||||||
leg[:set_zorder](1000)
|
leg[:set_zorder](1000)
|
||||||
sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle])
|
sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle])
|
||||||
|
|
||||||
fgcolor = py_color(sp[:foreground_color_legend])
|
|
||||||
lfcolor = py_color(sp[:legendfontcolor])
|
|
||||||
for txt in leg[:get_texts]()
|
for txt in leg[:get_texts]()
|
||||||
PyPlot.plt[:setp](txt, color = lfcolor, family = sp[:legendfontfamily])
|
PyPlot.plt[:setp](txt, color = py_color(sp[:legendfontcolor]), family = sp[:legendfontfamily])
|
||||||
end
|
end
|
||||||
|
|
||||||
# set some legend properties
|
|
||||||
frame = leg[:get_frame]()
|
|
||||||
frame[set_facecolor_sym](py_color(sp[:background_color_legend]))
|
|
||||||
frame[:set_edgecolor](fgcolor)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1356,7 +1360,7 @@ for (mime, fmt) in _pyplot_mimeformats
|
|||||||
# figsize = map(px2inch, plt[:size]),
|
# figsize = map(px2inch, plt[:size]),
|
||||||
facecolor = fig[:get_facecolor](),
|
facecolor = fig[:get_facecolor](),
|
||||||
edgecolor = "none",
|
edgecolor = "none",
|
||||||
dpi = plt[:dpi]
|
dpi = plt[:dpi] * plt[:thickness_scaling]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -212,7 +212,7 @@ end
|
|||||||
|
|
||||||
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
|
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
|
||||||
unicodeplots_rebuild(plt)
|
unicodeplots_rebuild(plt)
|
||||||
map(show, plt.o)
|
foreach(x -> show(io, x), plt.o)
|
||||||
nothing
|
nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -157,17 +157,6 @@ end
|
|||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
const _mimeformats = Dict(
|
|
||||||
"application/eps" => "eps",
|
|
||||||
"image/eps" => "eps",
|
|
||||||
"application/pdf" => "pdf",
|
|
||||||
"image/png" => "png",
|
|
||||||
"application/postscript" => "ps",
|
|
||||||
"image/svg+xml" => "svg",
|
|
||||||
"text/plain" => "txt",
|
|
||||||
"application/x-tex" => "tex",
|
|
||||||
)
|
|
||||||
|
|
||||||
const _best_html_output_type = KW(
|
const _best_html_output_type = KW(
|
||||||
:pyplot => :png,
|
:pyplot => :png,
|
||||||
:unicodeplots => :txt,
|
:unicodeplots => :txt,
|
||||||
@ -177,7 +166,7 @@ const _best_html_output_type = KW(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# a backup for html... passes to svg or png depending on the html_output_format arg
|
# a backup for html... passes to svg or png depending on the html_output_format arg
|
||||||
function Base.show(io::IO, ::MIME"text/html", plt::Plot)
|
function _show(io::IO, ::MIME"text/html", plt::Plot)
|
||||||
output_type = Symbol(plt.attr[:html_output_format])
|
output_type = Symbol(plt.attr[:html_output_format])
|
||||||
if output_type == :auto
|
if output_type == :auto
|
||||||
output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
|
output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
|
||||||
@ -191,26 +180,32 @@ function Base.show(io::IO, ::MIME"text/html", plt::Plot)
|
|||||||
elseif output_type == :txt
|
elseif output_type == :txt
|
||||||
show(io, MIME("text/plain"), plt)
|
show(io, MIME("text/plain"), plt)
|
||||||
else
|
else
|
||||||
error("only png or svg allowed. got: $output_type")
|
error("only png or svg allowed. got: $(repr(output_type))")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function _show(io::IO, m, plt::Plot{B}) where B
|
# delegate mimewritable (showable on julia 0.7) to _show instead
|
||||||
# Base.show_backtrace(STDOUT, backtrace())
|
function Base.mimewritable(m::M, plt::P) where {M<:MIME, P<:Plot}
|
||||||
warn("_show is not defined for this backend. m=", string(m))
|
return method_exists(_show, Tuple{IO, M, P})
|
||||||
end
|
end
|
||||||
|
|
||||||
function _display(plt::Plot)
|
function _display(plt::Plot)
|
||||||
warn("_display is not defined for this backend.")
|
warn("_display is not defined for this backend.")
|
||||||
end
|
end
|
||||||
|
|
||||||
# for writing to io streams... first prepare, then callback
|
# for writing to io streams... first prepare, then callback
|
||||||
for mime in keys(_mimeformats)
|
for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml",
|
||||||
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot{B}) where B
|
"application/eps", "application/pdf", "application/postscript",
|
||||||
|
"application/x-tex")
|
||||||
|
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
|
||||||
prepare_output(plt)
|
prepare_output(plt)
|
||||||
_show(io, m, plt)
|
_show(io, m, plt)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# default text/plain for all backends
|
||||||
|
_show(io::IO, ::MIME{Symbol("text/plain")}, plt::Plot) = show(io, plt)
|
||||||
|
|
||||||
"Close all open gui windows of the current backend"
|
"Close all open gui windows of the current backend"
|
||||||
closeall() = closeall(backend())
|
closeall() = closeall(backend())
|
||||||
|
|
||||||
@ -218,9 +213,10 @@ closeall() = closeall(backend())
|
|||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
# A backup, if no PNG generation is defined, is to try to make a PDF and use FileIO to convert
|
# A backup, if no PNG generation is defined, is to try to make a PDF and use FileIO to convert
|
||||||
|
|
||||||
|
const PDFBackends = Union{PGFPlotsBackend,PlotlyJSBackend,PyPlotBackend,InspectDRBackend,GRBackend}
|
||||||
if is_installed("FileIO")
|
if is_installed("FileIO")
|
||||||
@eval import FileIO
|
@eval import FileIO
|
||||||
function _show(io::IO, ::MIME"image/png", plt::Plot)
|
function _show(io::IO, ::MIME"image/png", plt::Plot{<:PDFBackends})
|
||||||
fn = tempname()
|
fn = tempname()
|
||||||
|
|
||||||
# first save a pdf file
|
# first save a pdf file
|
||||||
@ -288,7 +284,10 @@ end
|
|||||||
output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
|
output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
|
||||||
end
|
end
|
||||||
out = Dict()
|
out = Dict()
|
||||||
if output_type == :png
|
if output_type == :txt
|
||||||
|
mime = "text/plain"
|
||||||
|
out[mime] = sprint(show, MIME(mime), plt)
|
||||||
|
elseif output_type == :png
|
||||||
mime = "image/png"
|
mime = "image/png"
|
||||||
out[mime] = base64encode(show, MIME(mime), plt)
|
out[mime] = base64encode(show, MIME(mime), plt)
|
||||||
elseif output_type == :svg
|
elseif output_type == :svg
|
||||||
@ -304,11 +303,6 @@ end
|
|||||||
out
|
out
|
||||||
end
|
end
|
||||||
|
|
||||||
# default text/plain passes to html... handles Interact issues
|
|
||||||
function Base.show(io::IO, m::MIME"text/plain", plt::Plot)
|
|
||||||
show(io, MIME("text/html"), plt)
|
|
||||||
end
|
|
||||||
|
|
||||||
ENV["MPLBACKEND"] = "Agg"
|
ENV["MPLBACKEND"] = "Agg"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -322,9 +316,6 @@ end
|
|||||||
if Juno.isactive()
|
if Juno.isactive()
|
||||||
Media.media(Plot, Media.Plot)
|
Media.media(Plot, Media.Plot)
|
||||||
|
|
||||||
|
|
||||||
_show(io::IO, m::MIME"text/plain", plt::Plot{B}) where {B} = print(io, "Plot{$B}()")
|
|
||||||
|
|
||||||
function Juno.render(e::Juno.Editor, plt::Plot)
|
function Juno.render(e::Juno.Editor, plt::Plot)
|
||||||
Juno.render(e, nothing)
|
Juno.render(e, nothing)
|
||||||
end
|
end
|
||||||
@ -333,13 +324,20 @@ end
|
|||||||
function Juno.render(pane::Juno.PlotPane, plt::Plot)
|
function Juno.render(pane::Juno.PlotPane, plt::Plot)
|
||||||
# temporarily overwrite size to be Atom.plotsize
|
# temporarily overwrite size to be Atom.plotsize
|
||||||
sz = plt[:size]
|
sz = plt[:size]
|
||||||
|
dpi = plt[:dpi]
|
||||||
|
thickness_scaling = plt[:thickness_scaling]
|
||||||
jsize = Juno.plotsize()
|
jsize = Juno.plotsize()
|
||||||
jsize[1] == 0 && (jsize[1] = 400)
|
jsize[1] == 0 && (jsize[1] = 400)
|
||||||
jsize[2] == 0 && (jsize[2] = 500)
|
jsize[2] == 0 && (jsize[2] = 500)
|
||||||
|
|
||||||
plt[:size] = jsize
|
scale = minimum(jsize[i] / sz[i] for i in 1:2)
|
||||||
|
plt[:size] = (s * scale for s in sz)
|
||||||
|
plt[:dpi] = Plots.DPI
|
||||||
|
plt[:thickness_scaling] *= scale
|
||||||
Juno.render(pane, HTML(stringmime(MIME("text/html"), plt)))
|
Juno.render(pane, HTML(stringmime(MIME("text/html"), plt)))
|
||||||
plt[:size] = sz
|
plt[:size] = sz
|
||||||
|
plt[:dpi] = dpi
|
||||||
|
plt[:thickness_scaling] = thickness_scaling
|
||||||
end
|
end
|
||||||
# special handling for PlotlyJS
|
# special handling for PlotlyJS
|
||||||
function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend})
|
function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend})
|
||||||
|
|||||||
@ -327,7 +327,7 @@ end
|
|||||||
|
|
||||||
function _override_seriestype_check(d::KW, st::Symbol)
|
function _override_seriestype_check(d::KW, st::Symbol)
|
||||||
# do we want to override the series type?
|
# do we want to override the series type?
|
||||||
if !is3d(st)
|
if !is3d(st) && !(st in (:contour,:contour3d))
|
||||||
z = d[:z]
|
z = d[:z]
|
||||||
if !isa(z, Void) && (size(d[:x]) == size(d[:y]) == size(z))
|
if !isa(z, Void) && (size(d[:x]) == size(d[:y]) == size(z))
|
||||||
st = (st == :scatter ? :scatter3d : :path3d)
|
st = (st == :scatter ? :scatter3d : :path3d)
|
||||||
@ -398,6 +398,7 @@ function _process_seriesrecipe(plt::Plot, d::KW)
|
|||||||
sp = _prepare_subplot(plt, d)
|
sp = _prepare_subplot(plt, d)
|
||||||
_prepare_annotations(sp, d)
|
_prepare_annotations(sp, d)
|
||||||
_expand_subplot_extrema(sp, d, st)
|
_expand_subplot_extrema(sp, d, st)
|
||||||
|
_update_series_attributes!(d, plt, sp)
|
||||||
_add_the_series(plt, sp, d)
|
_add_the_series(plt, sp, d)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|||||||
@ -413,6 +413,7 @@ end
|
|||||||
z := nothing
|
z := nothing
|
||||||
seriestype := :shape
|
seriestype := :shape
|
||||||
label := ""
|
label := ""
|
||||||
|
widen --> false
|
||||||
()
|
()
|
||||||
end
|
end
|
||||||
@deps plots_heatmap shape
|
@deps plots_heatmap shape
|
||||||
|
|||||||
@ -627,7 +627,7 @@ group_as_matrix(t) = false
|
|||||||
else
|
else
|
||||||
g = args[1]
|
g = args[1]
|
||||||
if length(g.args) == 1
|
if length(g.args) == 1
|
||||||
x = zeros(Int64, lengthGroup)
|
x = zeros(Int, lengthGroup)
|
||||||
for indexes in groupby.groupIds
|
for indexes in groupby.groupIds
|
||||||
x[indexes] = 1:length(indexes)
|
x[indexes] = 1:length(indexes)
|
||||||
end
|
end
|
||||||
|
|||||||
56
src/utils.jl
56
src/utils.jl
@ -195,9 +195,13 @@ end
|
|||||||
function iter_segments(series::Series)
|
function iter_segments(series::Series)
|
||||||
x, y, z = series[:x], series[:y], series[:z]
|
x, y, z = series[:x], series[:y], series[:z]
|
||||||
if has_attribute_segments(series)
|
if has_attribute_segments(series)
|
||||||
return [i:(i + 1) for i in 1:(length(y) - 1)]
|
if series[:seriestype] in (:scatter, :scatter3d)
|
||||||
|
return [[i] for i in 1:length(y)]
|
||||||
else
|
else
|
||||||
segs = UnitRange{Int64}[]
|
return [i:(i + 1) for i in 1:(length(y) - 1)]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
segs = UnitRange{Int}[]
|
||||||
args = is3d(series) ? (x, y, z) : (x, y)
|
args = is3d(series) ? (x, y, z) : (x, y)
|
||||||
for seg in iter_segments(args...)
|
for seg in iter_segments(args...)
|
||||||
push!(segs, seg)
|
push!(segs, seg)
|
||||||
@ -354,19 +358,18 @@ const _scale_base = Dict{Symbol, Real}(
|
|||||||
:ln => e,
|
:ln => e,
|
||||||
)
|
)
|
||||||
|
|
||||||
"create an (n+1) list of the outsides of heatmap rectangles"
|
function _heatmap_edges(v::AVec)
|
||||||
function heatmap_edges(v::AVec, scale::Symbol = :identity)
|
|
||||||
vmin, vmax = ignorenan_extrema(v)
|
vmin, vmax = ignorenan_extrema(v)
|
||||||
extra_min = extra_max = 0.5 * (vmax-vmin) / (length(v)-1)
|
extra_min = (v[2] - v[1]) / 2
|
||||||
if scale in _logScales
|
extra_max = (v[end] - v[end - 1]) / 2
|
||||||
vmin > 0 || error("The axis values must be positive for a $scale scale")
|
|
||||||
while vmin - extra_min <= 0
|
|
||||||
extra_min /= _scale_base[scale]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
vcat(vmin-extra_min, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra_max)
|
vcat(vmin-extra_min, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra_max)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"create an (n+1) list of the outsides of heatmap rectangles"
|
||||||
|
function heatmap_edges(v::AVec, scale::Symbol = :identity)
|
||||||
|
f, invf = scalefunc(scale), invscalefunc(scale)
|
||||||
|
map(invf, _heatmap_edges(map(f,v)))
|
||||||
|
end
|
||||||
|
|
||||||
function calc_r_extrema(x, y)
|
function calc_r_extrema(x, y)
|
||||||
xmin, xmax = ignorenan_extrema(x)
|
xmin, xmax = ignorenan_extrema(x)
|
||||||
@ -620,7 +623,7 @@ function get_linecolor(series, i::Int = 1)
|
|||||||
lc = series[:linecolor]
|
lc = series[:linecolor]
|
||||||
lz = series[:line_z]
|
lz = series[:line_z]
|
||||||
if lz == nothing
|
if lz == nothing
|
||||||
isa(lc, ColorGradient) ? lc : _cycle(lc, i)
|
isa(lc, ColorGradient) ? lc : plot_color(_cycle(lc, i))
|
||||||
else
|
else
|
||||||
cmin, cmax = get_clims(series[:subplot])
|
cmin, cmax = get_clims(series[:subplot])
|
||||||
grad = isa(lc, ColorGradient) ? lc : cgrad()
|
grad = isa(lc, ColorGradient) ? lc : cgrad()
|
||||||
@ -644,7 +647,7 @@ function get_fillcolor(series, i::Int = 1)
|
|||||||
fc = series[:fillcolor]
|
fc = series[:fillcolor]
|
||||||
fz = series[:fill_z]
|
fz = series[:fill_z]
|
||||||
if fz == nothing
|
if fz == nothing
|
||||||
isa(fc, ColorGradient) ? fc : _cycle(fc, i)
|
isa(fc, ColorGradient) ? fc : plot_color(_cycle(fc, i))
|
||||||
else
|
else
|
||||||
cmin, cmax = get_clims(series[:subplot])
|
cmin, cmax = get_clims(series[:subplot])
|
||||||
grad = isa(fc, ColorGradient) ? fc : cgrad()
|
grad = isa(fc, ColorGradient) ? fc : cgrad()
|
||||||
@ -656,6 +659,31 @@ function get_fillalpha(series, i::Int = 1)
|
|||||||
_cycle(series[:fillalpha], i)
|
_cycle(series[:fillalpha], i)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function get_markercolor(series, i::Int = 1)
|
||||||
|
mc = series[:markercolor]
|
||||||
|
mz = series[:marker_z]
|
||||||
|
if mz == nothing
|
||||||
|
isa(mc, ColorGradient) ? mc : plot_color(_cycle(mc, i))
|
||||||
|
else
|
||||||
|
cmin, cmax = get_clims(series[:subplot])
|
||||||
|
grad = isa(mc, ColorGradient) ? mc : cgrad()
|
||||||
|
grad[clamp((_cycle(mz, i) - cmin) / (cmax - cmin), 0, 1)]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_markeralpha(series, i::Int = 1)
|
||||||
|
_cycle(series[:markeralpha], i)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_markerstrokecolor(series, i::Int = 1)
|
||||||
|
msc = series[:markerstrokecolor]
|
||||||
|
isa(msc, ColorGradient) ? msc : _cycle(msc, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_markerstrokealpha(series, i::Int = 1)
|
||||||
|
_cycle(series[:markerstrokealpha], i)
|
||||||
|
end
|
||||||
|
|
||||||
function has_attribute_segments(series::Series)
|
function has_attribute_segments(series::Series)
|
||||||
# we want to check if a series needs to be split into segments just because
|
# we want to check if a series needs to be split into segments just because
|
||||||
# of its attributes
|
# of its attributes
|
||||||
@ -666,7 +694,7 @@ function has_attribute_segments(series::Series)
|
|||||||
end
|
end
|
||||||
series[:seriestype] == :shape && return false
|
series[:seriestype] == :shape && return false
|
||||||
# ... else we check relevant attributes if they have multiple inputs
|
# ... 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, :fillcolor, :fillalpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z))
|
return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z, :marker_z))
|
||||||
end
|
end
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
|
|||||||
@ -23,7 +23,7 @@ default(size=(500,300))
|
|||||||
# TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that
|
# TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that
|
||||||
# is referenced in a button press callback (the button clicked callback will call notify() on that condition)
|
# is referenced in a button press callback (the button clicked callback will call notify() on that condition)
|
||||||
|
|
||||||
const _current_plots_version = v"0.17.0"
|
const _current_plots_version = v"0.17.3"
|
||||||
|
|
||||||
|
|
||||||
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2)
|
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user