Merge pull request #1467 from daschw/segments
Segments: vector arguments, line_z and fill_z for GR, PyPlot, Plotly(JS) and PGFPlots
This commit is contained in:
commit
9acb89ba8a
18
src/args.jl
18
src/args.jl
@ -1450,18 +1450,18 @@ end
|
|||||||
|
|
||||||
|
|
||||||
# converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically
|
# converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically
|
||||||
function getSeriesRGBColor(c, α, sp::Subplot, n::Int)
|
function getSeriesRGBColor(c, sp::Subplot, n::Int)
|
||||||
if c == :auto
|
if c == :auto
|
||||||
c = autopick(sp[:color_palette], n)
|
c = autopick(sp[:color_palette], n)
|
||||||
elseif isa(c, Int)
|
elseif isa(c, Int)
|
||||||
c = autopick(sp[:color_palette], c)
|
c = autopick(sp[:color_palette], c)
|
||||||
end
|
end
|
||||||
plot_color(c, α)
|
plot_color(c)
|
||||||
end
|
end
|
||||||
|
|
||||||
function ensure_gradient!(d::KW, csym::Symbol, asym::Symbol)
|
function ensure_gradient!(d::KW, csym::Symbol, asym::Symbol)
|
||||||
if !isa(d[csym], ColorGradient)
|
if !isa(d[csym], ColorGradient)
|
||||||
d[csym] = cgrad(alpha = d[asym])
|
d[csym] = typeof(d[asym]) <: AbstractVector ? cgrad() : cgrad(alpha = d[asym])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1508,21 +1508,21 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# update series color
|
# update series color
|
||||||
d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], d[:seriesalpha], sp, plotIndex)
|
d[:seriescolor] = getSeriesRGBColor.(d[:seriescolor], sp, plotIndex)
|
||||||
|
|
||||||
# update other colors
|
# update other colors
|
||||||
for s in (:line, :marker, :fill)
|
for s in (:line, :marker, :fill)
|
||||||
csym, asym = Symbol(s,:color), Symbol(s,:alpha)
|
csym, asym = Symbol(s,:color), Symbol(s,:alpha)
|
||||||
d[csym] = if d[csym] == :auto
|
d[csym] = if d[csym] == :auto
|
||||||
plot_color(if has_black_border_for_default(d[:seriestype]) && s == :line
|
plot_color.(if has_black_border_for_default(d[:seriestype]) && s == :line
|
||||||
sp[:foreground_color_subplot]
|
sp[:foreground_color_subplot]
|
||||||
else
|
else
|
||||||
d[:seriescolor]
|
d[:seriescolor]
|
||||||
end, d[asym])
|
end)
|
||||||
elseif d[csym] == :match
|
elseif d[csym] == :match
|
||||||
plot_color(d[:seriescolor], d[asym])
|
plot_color.(d[:seriescolor])
|
||||||
else
|
else
|
||||||
getSeriesRGBColor(d[csym], d[asym], sp, plotIndex)
|
getSeriesRGBColor.(d[csym], sp, plotIndex)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1530,7 +1530,7 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
|||||||
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], d[:markerstrokealpha])
|
||||||
else
|
else
|
||||||
getSeriesRGBColor(d[:markerstrokecolor], d[:markerstrokealpha], sp, plotIndex)
|
getSeriesRGBColor(plot_color(d[:markerstrokecolor], d[:markerstrokealpha]), 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
|
||||||
|
|||||||
@ -135,7 +135,7 @@ const gr_font_family = Dict(
|
|||||||
# --------------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function gr_getcolorind(c)
|
function gr_getcolorind(c)
|
||||||
GR.settransparency(float(alpha(c)))
|
gr_set_transparency(float(alpha(c)))
|
||||||
convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c)))
|
convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c)))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -143,6 +143,8 @@ gr_set_linecolor(c) = GR.setlinecolorind(gr_getcolorind(_cycle(c,1)))
|
|||||||
gr_set_fillcolor(c) = GR.setfillcolorind(gr_getcolorind(_cycle(c,1)))
|
gr_set_fillcolor(c) = GR.setfillcolorind(gr_getcolorind(_cycle(c,1)))
|
||||||
gr_set_markercolor(c) = GR.setmarkercolorind(gr_getcolorind(_cycle(c,1)))
|
gr_set_markercolor(c) = GR.setmarkercolorind(gr_getcolorind(_cycle(c,1)))
|
||||||
gr_set_textcolor(c) = GR.settextcolorind(gr_getcolorind(_cycle(c,1)))
|
gr_set_textcolor(c) = GR.settextcolorind(gr_getcolorind(_cycle(c,1)))
|
||||||
|
gr_set_transparency(α::Real) = GR.settransparency(clamp(α, 0, 1))
|
||||||
|
function gr_set_transparency(::Void) end
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -230,7 +232,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot)
|
|||||||
#draw angular grid
|
#draw angular grid
|
||||||
if xaxis[:grid]
|
if xaxis[:grid]
|
||||||
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
|
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
|
||||||
GR.settransparency(xaxis[:gridalpha])
|
gr_set_transparency(xaxis[:gridalpha])
|
||||||
for i in 1:length(α)
|
for i in 1:length(α)
|
||||||
GR.polyline([sinf[i], 0], [cosf[i], 0])
|
GR.polyline([sinf[i], 0], [cosf[i], 0])
|
||||||
end
|
end
|
||||||
@ -239,7 +241,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot)
|
|||||||
#draw radial grid
|
#draw radial grid
|
||||||
if yaxis[:grid]
|
if yaxis[:grid]
|
||||||
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
|
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
|
||||||
GR.settransparency(yaxis[:gridalpha])
|
gr_set_transparency(yaxis[:gridalpha])
|
||||||
for i in 1:length(rtick_values)
|
for i in 1:length(rtick_values)
|
||||||
r = (rtick_values[i] - rmin) / (rmax - rmin)
|
r = (rtick_values[i] - rmin) / (rmax - rmin)
|
||||||
if r <= 1.0 && r >= 0.0
|
if r <= 1.0 && r >= 0.0
|
||||||
@ -250,7 +252,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot)
|
|||||||
end
|
end
|
||||||
|
|
||||||
#prepare to draw ticks
|
#prepare to draw ticks
|
||||||
GR.settransparency(1)
|
gr_set_transparency(1)
|
||||||
GR.setlinecolorind(90)
|
GR.setlinecolorind(90)
|
||||||
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF)
|
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF)
|
||||||
|
|
||||||
@ -319,9 +321,6 @@ function normalize_zvals(zv::AVec, clims::NTuple{2, <:Real})
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
gr_alpha(α::Void) = 1
|
|
||||||
gr_alpha(α::Real) = α
|
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
# draw ONE Shape
|
# draw ONE Shape
|
||||||
@ -369,7 +368,7 @@ function gr_draw_markers(series::Series, x, y, msize, mz)
|
|||||||
# pick a color from the pre-loaded gradient
|
# pick a color from the pre-loaded gradient
|
||||||
ci = round(Int, 1000 + _cycle(mz, i) * 255)
|
ci = round(Int, 1000 + _cycle(mz, i) * 255)
|
||||||
cfuncind(ci)
|
cfuncind(ci)
|
||||||
GR.settransparency(_gr_gradient_alpha[ci-999])
|
gr_set_transparency(_gr_gradient_alpha[ci-999])
|
||||||
end
|
end
|
||||||
# don't draw filled area if marker shape is 1D
|
# don't draw filled area if marker shape is 1D
|
||||||
if !(shape in (:hline, :vline, :+, :x))
|
if !(shape in (:hline, :vline, :+, :x))
|
||||||
@ -794,21 +793,21 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
|
|
||||||
if xaxis[:grid]
|
if xaxis[:grid]
|
||||||
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
|
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
|
||||||
GR.settransparency(xaxis[:gridalpha])
|
gr_set_transparency(xaxis[:gridalpha])
|
||||||
GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0)
|
GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0)
|
||||||
end
|
end
|
||||||
if yaxis[:grid]
|
if yaxis[:grid]
|
||||||
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
|
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
|
||||||
GR.settransparency(yaxis[:gridalpha])
|
gr_set_transparency(yaxis[:gridalpha])
|
||||||
GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0)
|
GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0)
|
||||||
end
|
end
|
||||||
if zaxis[:grid]
|
if zaxis[:grid]
|
||||||
gr_set_line(zaxis[:gridlinewidth], zaxis[:gridstyle], zaxis[:foreground_color_grid])
|
gr_set_line(zaxis[:gridlinewidth], zaxis[:gridstyle], zaxis[:foreground_color_grid])
|
||||||
GR.settransparency(zaxis[:gridalpha])
|
gr_set_transparency(zaxis[:gridalpha])
|
||||||
GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2)
|
GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2)
|
||||||
end
|
end
|
||||||
gr_set_line(1, :solid, xaxis[:foreground_color_axis])
|
gr_set_line(1, :solid, xaxis[:foreground_color_axis])
|
||||||
GR.settransparency(1)
|
gr_set_transparency(1)
|
||||||
GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize)
|
GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize)
|
||||||
GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize)
|
GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize)
|
||||||
|
|
||||||
@ -831,15 +830,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
# gr_set_linecolor(sp[:foreground_color_grid])
|
# gr_set_linecolor(sp[:foreground_color_grid])
|
||||||
# GR.grid(xtick, ytick, 0, 0, majorx, majory)
|
# GR.grid(xtick, ytick, 0, 0, majorx, majory)
|
||||||
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
|
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
|
||||||
GR.settransparency(xaxis[:gridalpha])
|
gr_set_transparency(xaxis[:gridalpha])
|
||||||
gr_polyline(coords(xgrid_segs)...)
|
gr_polyline(coords(xgrid_segs)...)
|
||||||
end
|
end
|
||||||
if yaxis[:grid]
|
if yaxis[:grid]
|
||||||
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
|
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
|
||||||
GR.settransparency(yaxis[:gridalpha])
|
gr_set_transparency(yaxis[:gridalpha])
|
||||||
gr_polyline(coords(ygrid_segs)...)
|
gr_polyline(coords(ygrid_segs)...)
|
||||||
end
|
end
|
||||||
GR.settransparency(1.0)
|
gr_set_transparency(1.0)
|
||||||
|
|
||||||
# axis lines
|
# axis lines
|
||||||
if xaxis[:showaxis]
|
if xaxis[:showaxis]
|
||||||
@ -858,7 +857,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
if xaxis[:showaxis]
|
if xaxis[:showaxis]
|
||||||
if sp[:framestyle] in (:zerolines, :grid)
|
if sp[:framestyle] in (:zerolines, :grid)
|
||||||
gr_set_line(1, :solid, xaxis[:foreground_color_grid])
|
gr_set_line(1, :solid, xaxis[:foreground_color_grid])
|
||||||
GR.settransparency(xaxis[:gridalpha])
|
gr_set_transparency(xaxis[:gridalpha])
|
||||||
else
|
else
|
||||||
gr_set_line(1, :solid, xaxis[:foreground_color_axis])
|
gr_set_line(1, :solid, xaxis[:foreground_color_axis])
|
||||||
end
|
end
|
||||||
@ -868,7 +867,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
if yaxis[:showaxis]
|
if yaxis[:showaxis]
|
||||||
if sp[:framestyle] in (:zerolines, :grid)
|
if sp[:framestyle] in (:zerolines, :grid)
|
||||||
gr_set_line(1, :solid, yaxis[:foreground_color_grid])
|
gr_set_line(1, :solid, yaxis[:foreground_color_grid])
|
||||||
GR.settransparency(yaxis[:gridalpha])
|
gr_set_transparency(yaxis[:gridalpha])
|
||||||
else
|
else
|
||||||
gr_set_line(1, :solid, yaxis[:foreground_color_axis])
|
gr_set_line(1, :solid, yaxis[:foreground_color_axis])
|
||||||
end
|
end
|
||||||
@ -920,10 +919,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
intensity = sp[:framestyle] == :semi ? 0.5 : 1.0
|
intensity = sp[:framestyle] == :semi ? 0.5 : 1.0
|
||||||
if sp[:framestyle] in (:box, :semi)
|
if sp[:framestyle] in (:box, :semi)
|
||||||
gr_set_line(intensity, :solid, xaxis[:foreground_color_border])
|
gr_set_line(intensity, :solid, xaxis[:foreground_color_border])
|
||||||
GR.settransparency(intensity)
|
gr_set_transparency(intensity)
|
||||||
gr_polyline(coords(xborder_segs)...)
|
gr_polyline(coords(xborder_segs)...)
|
||||||
gr_set_line(intensity, :solid, yaxis[:foreground_color_border])
|
gr_set_line(intensity, :solid, yaxis[:foreground_color_border])
|
||||||
GR.settransparency(intensity)
|
gr_set_transparency(intensity)
|
||||||
gr_polyline(coords(yborder_segs)...)
|
gr_polyline(coords(yborder_segs)...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1021,28 +1020,25 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
if st in (:path, :scatter, :straightline)
|
if st in (:path, :scatter, :straightline)
|
||||||
if length(x) > 1
|
if length(x) > 1
|
||||||
lz = series[:line_z]
|
lz = series[:line_z]
|
||||||
segments_iterator = if lz != nothing && length(lz) > 1
|
segments = iter_segments(series)
|
||||||
[i:(i + 1) for i in 1:(length(x) - 1)]
|
|
||||||
else
|
|
||||||
iter_segments(x, y)
|
|
||||||
end
|
|
||||||
# do area fill
|
# do area fill
|
||||||
if frng != nothing
|
if frng != nothing
|
||||||
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
||||||
fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng))
|
fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng))
|
||||||
for (i, rng) in enumerate(segments_iterator)
|
for (i, rng) in enumerate(segments)
|
||||||
gr_set_fillcolor(get_fillcolor(sp, series, i))
|
gr_set_fillcolor(get_fillcolor(series, i))
|
||||||
fx = _cycle(x, vcat(rng, reverse(rng)))
|
fx = _cycle(x, vcat(rng, reverse(rng)))
|
||||||
fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng)))
|
fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng)))
|
||||||
series[:fillalpha] != nothing && GR.settransparency(series[:fillalpha])
|
gr_set_transparency(get_fillalpha(series, i))
|
||||||
GR.fillarea(fx, fy)
|
GR.fillarea(fx, fy)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# draw the line(s)
|
# draw the line(s)
|
||||||
if st in (:path, :straightline)
|
if st in (:path, :straightline)
|
||||||
for (i, rng) in enumerate(segments_iterator)
|
for (i, rng) in enumerate(segments)
|
||||||
gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha])
|
gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i)) #, series[:linealpha])
|
||||||
|
gr_set_transparency(get_linealpha(series, i))
|
||||||
arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none
|
arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none
|
||||||
gr_polyline(x[rng], y[rng]; arrowside = arrowside)
|
gr_polyline(x[rng], y[rng]; arrowside = arrowside)
|
||||||
end
|
end
|
||||||
@ -1068,8 +1064,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
if series[:fillrange] != nothing
|
if series[:fillrange] != nothing
|
||||||
GR.surface(x, y, z, GR.OPTION_CELL_ARRAY)
|
GR.surface(x, y, z, GR.OPTION_CELL_ARRAY)
|
||||||
else
|
else
|
||||||
GR.setlinetype(gr_linetype[series[:linestyle]])
|
GR.setlinetype(gr_linetype[get_linestyle(series)])
|
||||||
GR.setlinewidth(max(0, series[:linewidth] / (sum(gr_plot_size) * 0.001)))
|
GR.setlinewidth(max(0, get_linewidth(series) / (sum(gr_plot_size) * 0.001)))
|
||||||
if plot_color(series[:linecolor]) == [plot_color(:black)]
|
if plot_color(series[:linecolor]) == [plot_color(:black)]
|
||||||
GR.contour(x, y, h, z, 0 + (series[:contour_labels] == true ? 1 : 0))
|
GR.contour(x, y, h, z, 0 + (series[:contour_labels] == true ? 1 : 0))
|
||||||
else
|
else
|
||||||
@ -1119,13 +1115,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
if st == :path3d
|
if st == :path3d
|
||||||
if length(x) > 1
|
if length(x) > 1
|
||||||
lz = series[:line_z]
|
lz = series[:line_z]
|
||||||
segments_iterator = if lz != nothing && length(lz) > 1
|
segments = iter_segments(series)
|
||||||
[i:(i + 1) for i in 1:(length(x) - 1)]
|
for (i, rng) in enumerate(segments)
|
||||||
else
|
gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i)) #, series[:linealpha])
|
||||||
iter_segments(x, y, z)
|
gr_set_transparency(get_linealpha(series, i))
|
||||||
end
|
|
||||||
for (i, rng) in enumerate(segments_iterator)
|
|
||||||
gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha])
|
|
||||||
GR.polyline3d(x[rng], y[rng], z[rng])
|
GR.polyline3d(x[rng], y[rng], z[rng])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1196,11 +1189,13 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
xseg, yseg = x[rng], y[rng]
|
xseg, yseg = x[rng], y[rng]
|
||||||
|
|
||||||
# draw the interior
|
# draw the interior
|
||||||
gr_set_fill(get_fillcolor(sp, series, i))
|
gr_set_fill(get_fillcolor(series, i))
|
||||||
|
gr_set_transparency(get_fillalpha(series, i))
|
||||||
GR.fillarea(xseg, yseg)
|
GR.fillarea(xseg, yseg)
|
||||||
|
|
||||||
# draw the shapes
|
# draw the shapes
|
||||||
gr_set_line(series[:linewidth], :solid, get_linecolor(sp, series, i))
|
gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i))
|
||||||
|
gr_set_transparency(get_linealpha(series, i))
|
||||||
GR.polyline(xseg, yseg)
|
GR.polyline(xseg, yseg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1232,7 +1227,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
# draw the colorbar
|
# draw the colorbar
|
||||||
if cmap && st != :contour # special colorbar with steps is drawn for contours
|
if cmap && st != :contour # special colorbar with steps is drawn for contours
|
||||||
gr_set_line(1, :solid, yaxis[:foreground_color_axis])
|
gr_set_line(1, :solid, yaxis[:foreground_color_axis])
|
||||||
GR.settransparency(1)
|
gr_set_transparency(1)
|
||||||
gr_colorbar(sp, clims)
|
gr_colorbar(sp, clims)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1279,29 +1274,30 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
|||||||
if sp[:legendtitle] != nothing
|
if sp[:legendtitle] != nothing
|
||||||
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF)
|
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF)
|
||||||
gr_set_textcolor(sp[:legendfontcolor])
|
gr_set_textcolor(sp[:legendfontcolor])
|
||||||
GR.settransparency(1)
|
gr_set_transparency(1)
|
||||||
gr_text(xpos - 0.03 + 0.5*w, ypos, string(sp[:legendtitle]))
|
gr_text(xpos - 0.03 + 0.5*w, ypos, string(sp[:legendtitle]))
|
||||||
ypos -= dy
|
ypos -= dy
|
||||||
end
|
end
|
||||||
for series in series_list(sp)
|
for series in series_list(sp)
|
||||||
should_add_to_legend(series) || continue
|
should_add_to_legend(series) || continue
|
||||||
st = series[:seriestype]
|
st = series[:seriestype]
|
||||||
gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series)) #, series[:linealpha])
|
gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series)) #, series[:linealpha])
|
||||||
|
|
||||||
if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing
|
if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing
|
||||||
gr_set_fill(get_fillcolor(sp, series)) #, series[:fillalpha])
|
gr_set_fill(get_fillcolor(series)) #, series[:fillalpha])
|
||||||
l, r = xpos-0.07, xpos-0.01
|
l, r = xpos-0.07, xpos-0.01
|
||||||
b, t = ypos-0.4dy, ypos+0.4dy
|
b, t = ypos-0.4dy, ypos+0.4dy
|
||||||
x = [l, r, r, l, l]
|
x = [l, r, r, l, l]
|
||||||
y = [b, b, t, t, b]
|
y = [b, b, t, t, b]
|
||||||
GR.settransparency(gr_alpha(series[:fillalpha]))
|
gr_set_transparency(get_fillalpha(series))
|
||||||
gr_polyline(x, y, GR.fillarea)
|
gr_polyline(x, y, GR.fillarea)
|
||||||
GR.settransparency(gr_alpha(series[:linealpha]))
|
gr_set_transparency(get_linealpha(series))
|
||||||
|
gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series))
|
||||||
st == :shape && gr_polyline(x, y)
|
st == :shape && gr_polyline(x, y)
|
||||||
end
|
end
|
||||||
|
|
||||||
if st in (:path, :straightline)
|
if st in (:path, :straightline)
|
||||||
GR.settransparency(gr_alpha(series[:linealpha]))
|
gr_set_transparency(get_linealpha(series))
|
||||||
if series[:fillrange] == nothing || series[:ribbon] != nothing
|
if series[:fillrange] == nothing || series[:ribbon] != nothing
|
||||||
GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos])
|
GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos])
|
||||||
else
|
else
|
||||||
|
|||||||
@ -27,7 +27,7 @@ const _pgfplots_attr = merge_with_base_supported([
|
|||||||
:tickfont, :guidefont, :legendfont,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:grid, :legend,
|
:grid, :legend,
|
||||||
:colorbar,
|
:colorbar,
|
||||||
:marker_z, #:levels,
|
:fill_z, :line_z, :marker_z, #:levels,
|
||||||
# :ribbon, :quiver, :arrow,
|
# :ribbon, :quiver, :arrow,
|
||||||
# :orientation,
|
# :orientation,
|
||||||
# :overwrite_figure,
|
# :overwrite_figure,
|
||||||
@ -148,33 +148,47 @@ function pgf_colormap(grad::ColorGradient)
|
|||||||
end,", ")
|
end,", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
function pgf_fillstyle(d::KW)
|
function pgf_fillstyle(d, i = 1)
|
||||||
cstr,a = pgf_color(d[:fillcolor])
|
cstr,a = pgf_color(get_fillcolor(d, i))
|
||||||
|
fa = get_fillalpha(d, i)
|
||||||
|
if fa != nothing
|
||||||
|
a = fa
|
||||||
|
end
|
||||||
"fill = $cstr, fill opacity=$a"
|
"fill = $cstr, fill opacity=$a"
|
||||||
end
|
end
|
||||||
|
|
||||||
function pgf_linestyle(d::KW)
|
function pgf_linestyle(d, i = 1)
|
||||||
cstr,a = pgf_color(d[:linecolor])
|
cstr,a = pgf_color(get_linecolor(d, i))
|
||||||
|
la = get_linealpha(d, i)
|
||||||
|
if la != nothing
|
||||||
|
a = la
|
||||||
|
end
|
||||||
"""
|
"""
|
||||||
color = $cstr,
|
color = $cstr,
|
||||||
draw opacity=$a,
|
draw opacity=$a,
|
||||||
line width=$(d[:linewidth]),
|
line width=$(get_linewidth(d, i)),
|
||||||
$(get(_pgfplots_linestyles, d[:linestyle], "solid"))"""
|
$(get(_pgfplots_linestyles, get_linestyle(d, i), "solid"))"""
|
||||||
end
|
end
|
||||||
|
|
||||||
function pgf_marker(d::KW)
|
function pgf_marker(d, i = 1)
|
||||||
shape = d[:markershape]
|
shape = _cycle(d[:markershape], i)
|
||||||
cstr, a = pgf_color(d[:markercolor])
|
cstr, a = pgf_color(_cycle(d[:markercolor], i))
|
||||||
cstr_stroke, a_stroke = pgf_color(d[:markerstrokecolor])
|
if d[:markeralpha] != nothing
|
||||||
|
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 * d[:markersize]),
|
mark size = $(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 = $(d[:markerstrokewidth]),
|
line width = $(_cycle(d[:markerstrokewidth], i)),
|
||||||
rotate = $(shape == :dtriangle ? 180 : 0),
|
rotate = $(shape == :dtriangle ? 180 : 0),
|
||||||
$(get(_pgfplots_linestyles, d[:markerstrokestyle], "solid"))
|
$(get(_pgfplots_linestyles, _cycle(d[:markerstrokestyle], i), "solid"))
|
||||||
}"""
|
}"""
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -196,24 +210,7 @@ end
|
|||||||
function pgf_series(sp::Subplot, series::Series)
|
function pgf_series(sp::Subplot, series::Series)
|
||||||
d = series.d
|
d = series.d
|
||||||
st = d[:seriestype]
|
st = d[:seriestype]
|
||||||
style = []
|
series_collection = PGFPlots.Plot[]
|
||||||
kw = KW()
|
|
||||||
push!(style, pgf_linestyle(d))
|
|
||||||
push!(style, pgf_marker(d))
|
|
||||||
|
|
||||||
if d[:fillrange] != nothing || st in (:shape,)
|
|
||||||
push!(style, pgf_fillstyle(d))
|
|
||||||
end
|
|
||||||
|
|
||||||
# add to legend?
|
|
||||||
if sp[:legend] != :none && should_add_to_legend(series)
|
|
||||||
kw[:legendentry] = d[:label]
|
|
||||||
if st == :shape || d[:fillrange] != nothing
|
|
||||||
push!(style, "area legend")
|
|
||||||
end
|
|
||||||
else
|
|
||||||
push!(style, "forget plot")
|
|
||||||
end
|
|
||||||
|
|
||||||
# function args
|
# function args
|
||||||
args = if st == :contour
|
args = if st == :contour
|
||||||
@ -241,11 +238,46 @@ function pgf_series(sp::Subplot, series::Series)
|
|||||||
else
|
else
|
||||||
a
|
a
|
||||||
end, args)
|
end, args)
|
||||||
# for (i,a) in enumerate(args)
|
|
||||||
# if typeof(a) <: AbstractVector && typeof(a) != Vector
|
if st in (:contour, :histogram2d)
|
||||||
# args[i] = collect(a)
|
style = []
|
||||||
# end
|
kw = KW()
|
||||||
# end
|
push!(style, pgf_linestyle(d))
|
||||||
|
push!(style, pgf_marker(d))
|
||||||
|
push!(style, "forget plot")
|
||||||
|
|
||||||
|
kw[:style] = join(style, ',')
|
||||||
|
func = if st == :histogram2d
|
||||||
|
PGFPlots.Histogram2
|
||||||
|
else
|
||||||
|
PGFPlots.Contour
|
||||||
|
end
|
||||||
|
push!(series_collection, func(args...; kw...))
|
||||||
|
|
||||||
|
else
|
||||||
|
# series segments
|
||||||
|
segments = iter_segments(series)
|
||||||
|
for (i, rng) in enumerate(segments)
|
||||||
|
style = []
|
||||||
|
kw = KW()
|
||||||
|
push!(style, pgf_linestyle(d, i))
|
||||||
|
push!(style, pgf_marker(d, i))
|
||||||
|
|
||||||
|
if st == :shape
|
||||||
|
push!(style, pgf_fillstyle(d, i))
|
||||||
|
end
|
||||||
|
|
||||||
|
# add to legend?
|
||||||
|
if i == 1 && sp[:legend] != :none && should_add_to_legend(series)
|
||||||
|
kw[:legendentry] = d[:label]
|
||||||
|
if st == :shape # || d[:fillrange] != nothing
|
||||||
|
push!(style, "area legend")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
push!(style, "forget plot")
|
||||||
|
end
|
||||||
|
|
||||||
|
seg_args = (arg[rng] for arg in args)
|
||||||
|
|
||||||
# include additional style, then add to the kw
|
# include additional style, then add to the kw
|
||||||
if haskey(_pgf_series_extrastyle, st)
|
if haskey(_pgf_series_extrastyle, st)
|
||||||
@ -253,19 +285,55 @@ function pgf_series(sp::Subplot, series::Series)
|
|||||||
end
|
end
|
||||||
kw[:style] = join(style, ',')
|
kw[:style] = join(style, ',')
|
||||||
|
|
||||||
|
# add fillrange
|
||||||
|
if series[:fillrange] != nothing && st != :shape
|
||||||
|
push!(series_collection, pgf_fillrange_series(series, i, _cycle(series[:fillrange], rng), seg_args...))
|
||||||
|
end
|
||||||
|
|
||||||
# build/return the series object
|
# build/return the series object
|
||||||
func = if st == :path3d
|
func = if st == :path3d
|
||||||
PGFPlots.Linear3
|
PGFPlots.Linear3
|
||||||
elseif st == :scatter
|
elseif st == :scatter
|
||||||
PGFPlots.Scatter
|
PGFPlots.Scatter
|
||||||
elseif st == :histogram2d
|
|
||||||
PGFPlots.Histogram2
|
|
||||||
elseif st == :contour
|
|
||||||
PGFPlots.Contour
|
|
||||||
else
|
else
|
||||||
PGFPlots.Linear
|
PGFPlots.Linear
|
||||||
end
|
end
|
||||||
func(args...; kw...)
|
push!(series_collection, func(seg_args...; kw...))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
series_collection
|
||||||
|
end
|
||||||
|
|
||||||
|
function pgf_fillrange_series(series, i, fillrange, args...)
|
||||||
|
st = series[:seriestype]
|
||||||
|
style = []
|
||||||
|
kw = KW()
|
||||||
|
push!(style, "line width = 0")
|
||||||
|
push!(style, "draw opacity = 0")
|
||||||
|
push!(style, pgf_fillstyle(series, i))
|
||||||
|
push!(style, pgf_marker(series, i))
|
||||||
|
push!(style, "forget plot")
|
||||||
|
if haskey(_pgf_series_extrastyle, st)
|
||||||
|
push!(style, _pgf_series_extrastyle[st])
|
||||||
|
end
|
||||||
|
kw[:style] = join(style, ',')
|
||||||
|
func = is3d(series) ? PGFPlots.Linear3 : PGFPlots.Linear
|
||||||
|
return func(pgf_fillrange_args(fillrange, args...)...; kw...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function pgf_fillrange_args(fillrange, x, y)
|
||||||
|
n = length(x)
|
||||||
|
x_fill = [x; x[n:-1:1]; x[1]]
|
||||||
|
y_fill = [y; _cycle(fillrange, n:-1:1); y[1]]
|
||||||
|
return x_fill, y_fill
|
||||||
|
end
|
||||||
|
|
||||||
|
function pgf_fillrange_args(fillrange, x, y, z)
|
||||||
|
n = length(x)
|
||||||
|
x_fill = [x; x[n:-1:1]; x[1]]
|
||||||
|
y_fill = [y; y[n:-1:1]; x[1]]
|
||||||
|
z_fill = [z; _cycle(fillrange, n:-1:1); z[1]]
|
||||||
|
return x_fill, y_fill, z_fill
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -438,7 +506,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
# As it is likely that all series within the same axis use the same
|
# As it is likely that all series within the same axis use the same
|
||||||
# colormap this should not cause any problem.
|
# colormap this should not cause any problem.
|
||||||
for series in series_list(sp)
|
for series in series_list(sp)
|
||||||
for col in (:markercolor, :fillcolor)
|
for col in (:markercolor, :fillcolor, :linecolor)
|
||||||
if typeof(series.d[col]) == ColorGradient
|
if typeof(series.d[col]) == ColorGradient
|
||||||
push!(style,"colormap={plots}{$(pgf_colormap(series.d[col]))}")
|
push!(style,"colormap={plots}{$(pgf_colormap(series.d[col]))}")
|
||||||
|
|
||||||
@ -458,7 +526,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
|
|
||||||
# add the series object to the PGFPlots.Axis
|
# add the series object to the PGFPlots.Axis
|
||||||
for series in series_list(sp)
|
for series in series_list(sp)
|
||||||
push!(o, pgf_series(sp, series))
|
push!.(o, pgf_series(sp, series))
|
||||||
|
|
||||||
# add series annotations
|
# add series annotations
|
||||||
anns = series[:series_annotations]
|
anns = series[:series_annotations]
|
||||||
|
|||||||
@ -30,7 +30,7 @@ const _plotly_attr = merge_with_base_supported([
|
|||||||
:tickfont, :guidefont, :legendfont,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:grid, :gridalpha, :gridlinewidth,
|
:grid, :gridalpha, :gridlinewidth,
|
||||||
:legend, :colorbar, :colorbar_title,
|
:legend, :colorbar, :colorbar_title,
|
||||||
:marker_z, :fill_z, :levels,
|
:marker_z, :fill_z, :line_z, :levels,
|
||||||
:ribbon, :quiver,
|
:ribbon, :quiver,
|
||||||
:orientation,
|
:orientation,
|
||||||
# :overwrite_figure,
|
# :overwrite_figure,
|
||||||
@ -543,23 +543,8 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# set the "type"
|
# set the "type"
|
||||||
if st in (:path, :scatter, :scattergl, :straightline)
|
if st in (:path, :scatter, :scattergl, :straightline, :path3d, :scatter3d)
|
||||||
d_out[:type] = st==:scattergl ? "scattergl" : "scatter"
|
return plotly_series_segments(series, d_out, x, y, z)
|
||||||
d_out[:mode] = if hasmarker
|
|
||||||
hasline ? "lines+markers" : "markers"
|
|
||||||
else
|
|
||||||
hasline ? "lines" : "none"
|
|
||||||
end
|
|
||||||
if series[:fillrange] == true || series[:fillrange] == 0 || isa(series[:fillrange], Tuple)
|
|
||||||
d_out[:fill] = "tozeroy"
|
|
||||||
d_out[:fillcolor] = rgba_string(series[:fillcolor])
|
|
||||||
elseif typeof(series[:fillrange]) <: Union{AbstractVector{<:Real}, Real}
|
|
||||||
d_out[:fill] = "tonexty"
|
|
||||||
d_out[:fillcolor] = rgba_string(series[:fillcolor])
|
|
||||||
elseif !(series[:fillrange] in (false, nothing))
|
|
||||||
warn("fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])")
|
|
||||||
end
|
|
||||||
d_out[:x], d_out[:y] = x, y
|
|
||||||
|
|
||||||
elseif st == :heatmap
|
elseif st == :heatmap
|
||||||
d_out[:type] = "heatmap"
|
d_out[:type] = "heatmap"
|
||||||
@ -583,7 +568,7 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
d_out[:hidesurface] = true
|
d_out[:hidesurface] = true
|
||||||
wirelines = KW(
|
wirelines = KW(
|
||||||
:show => true,
|
:show => true,
|
||||||
:color => rgba_string(series[:linecolor]),
|
:color => rgba_string(plot_color(series[:linecolor], series[:linealpha])),
|
||||||
:highlightwidth => series[:linewidth],
|
:highlightwidth => series[:linewidth],
|
||||||
)
|
)
|
||||||
d_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines)
|
d_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines)
|
||||||
@ -603,15 +588,6 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
d_out[:values] = y
|
d_out[:values] = y
|
||||||
d_out[:hoverinfo] = "label+percent+name"
|
d_out[:hoverinfo] = "label+percent+name"
|
||||||
|
|
||||||
elseif st in (:path3d, :scatter3d)
|
|
||||||
d_out[:type] = "scatter3d"
|
|
||||||
d_out[:mode] = if hasmarker
|
|
||||||
hasline ? "lines+markers" : "markers"
|
|
||||||
else
|
|
||||||
hasline ? "lines" : "none"
|
|
||||||
end
|
|
||||||
d_out[:x], d_out[:y], d_out[:z] = x, y, z
|
|
||||||
|
|
||||||
else
|
else
|
||||||
warn("Plotly: seriestype $st isn't supported.")
|
warn("Plotly: seriestype $st isn't supported.")
|
||||||
return KW()
|
return KW()
|
||||||
@ -646,61 +622,15 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# add "line"
|
|
||||||
if hasline
|
|
||||||
d_out[:line] = KW(
|
|
||||||
:color => rgba_string(series[:linecolor]),
|
|
||||||
:width => series[:linewidth],
|
|
||||||
:shape => if st == :steppre
|
|
||||||
"vh"
|
|
||||||
elseif st == :steppost
|
|
||||||
"hv"
|
|
||||||
else
|
|
||||||
"linear"
|
|
||||||
end,
|
|
||||||
:dash => string(series[:linestyle]),
|
|
||||||
# :dash => "solid",
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
plotly_polar!(d_out, series)
|
plotly_polar!(d_out, series)
|
||||||
plotly_hover!(d_out, series[:hover])
|
plotly_hover!(d_out, series[:hover])
|
||||||
|
|
||||||
if hasfillrange
|
|
||||||
# if hasfillrange is true, return two dictionaries (one for original
|
|
||||||
# series, one for series being filled to) instead of one
|
|
||||||
d_out_fillrange = deepcopy(d_out)
|
|
||||||
d_out_fillrange[:showlegend] = false
|
|
||||||
# if fillrange is provided as real or tuple of real, expand to array
|
|
||||||
if typeof(series[:fillrange]) <: Real
|
|
||||||
series[:fillrange] = fill(series[:fillrange], length(series[:x]))
|
|
||||||
elseif typeof(series[:fillrange]) <: Tuple
|
|
||||||
f1 = typeof(series[:fillrange][1]) <: Real ? fill(series[:fillrange][1], length(series[:x])) : series[:fillrange][1]
|
|
||||||
f2 = typeof(series[:fillrange][2]) <: Real ? fill(series[:fillrange][2], length(series[:x])) : series[:fillrange][2]
|
|
||||||
series[:fillrange] = (f1, f2)
|
|
||||||
end
|
|
||||||
if isa(series[:fillrange], AbstractVector)
|
|
||||||
d_out_fillrange[:y] = series[:fillrange]
|
|
||||||
delete!(d_out_fillrange, :fill)
|
|
||||||
delete!(d_out_fillrange, :fillcolor)
|
|
||||||
else
|
|
||||||
# if fillrange is a tuple with upper and lower limit, d_out_fillrange
|
|
||||||
# is the series that will do the filling
|
|
||||||
d_out_fillrange[:x], d_out_fillrange[:y] =
|
|
||||||
concatenate_fillrange(series[:x], series[:fillrange])
|
|
||||||
d_out_fillrange[:line][:width] = 0
|
|
||||||
delete!(d_out, :fill)
|
|
||||||
delete!(d_out, :fillcolor)
|
|
||||||
end
|
|
||||||
|
|
||||||
return [d_out_fillrange, d_out]
|
|
||||||
else
|
|
||||||
return [d_out]
|
return [d_out]
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function plotly_series_shapes(plt::Plot, series::Series)
|
function plotly_series_shapes(plt::Plot, series::Series)
|
||||||
d_outs = []
|
segments = iter_segments(series)
|
||||||
|
d_outs = Vector{KW}(length(segments))
|
||||||
|
|
||||||
# TODO: create a d_out for each polygon
|
# TODO: create a d_out for each polygon
|
||||||
# x, y = series[:x], series[:y]
|
# x, y = series[:x], series[:y]
|
||||||
@ -714,7 +644,7 @@ function plotly_series_shapes(plt::Plot, series::Series)
|
|||||||
# base_d[:legendgroup] = series[:label]
|
# base_d[:legendgroup] = series[:label]
|
||||||
|
|
||||||
x, y = shape_data(series)
|
x, y = shape_data(series)
|
||||||
for (i,rng) in enumerate(iter_segments(x,y))
|
for (i,rng) in enumerate(segments)
|
||||||
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
|
||||||
@ -724,23 +654,186 @@ function plotly_series_shapes(plt::Plot, series::Series)
|
|||||||
:x => vcat(x[rng], x[rng[1]]),
|
:x => vcat(x[rng], x[rng[1]]),
|
||||||
:y => vcat(y[rng], y[rng[1]]),
|
:y => vcat(y[rng], y[rng[1]]),
|
||||||
:fill => "tozeroy",
|
:fill => "tozeroy",
|
||||||
:fillcolor => rgba_string(_cycle(series[:fillcolor], i)),
|
:fillcolor => rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i))),
|
||||||
))
|
))
|
||||||
if series[:markerstrokewidth] > 0
|
if series[:markerstrokewidth] > 0
|
||||||
d_out[:line] = KW(
|
d_out[:line] = KW(
|
||||||
:color => rgba_string(_cycle(series[:linecolor], i)),
|
:color => rgba_string(plot_color(get_linecolor(series, i), get_linealpha(series, i))),
|
||||||
:width => series[:linewidth],
|
:width => get_linewidth(series, i),
|
||||||
:dash => string(series[:linestyle]),
|
:dash => string(get_linestyle(series, i)),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
|
d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
|
||||||
plotly_polar!(d_out, series)
|
plotly_polar!(d_out, series)
|
||||||
plotly_hover!(d_out, _cycle(series[:hover], i))
|
plotly_hover!(d_out, _cycle(series[:hover], i))
|
||||||
push!(d_outs, d_out)
|
d_outs[i] = d_out
|
||||||
|
end
|
||||||
|
if series[:fill_z] != nothing
|
||||||
|
push!(d_outs, plotly_colorbar_hack(series, base_d, :line))
|
||||||
end
|
end
|
||||||
d_outs
|
d_outs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function plotly_series_segments(series::Series, d_base::KW, x, y, z)
|
||||||
|
st = series[:seriestype]
|
||||||
|
sp = series[:subplot]
|
||||||
|
isscatter = st in (:scatter, :scatter3d, :scattergl)
|
||||||
|
hasmarker = isscatter || series[:markershape] != :none
|
||||||
|
hasline = st in (:path, :path3d, :straightline)
|
||||||
|
hasfillrange = st in (:path, :scatter, :scattergl, :straightline) &&
|
||||||
|
(isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple))
|
||||||
|
|
||||||
|
segments = iter_segments(series)
|
||||||
|
d_outs = Vector{KW}((hasfillrange ? 2 : 1 ) * length(segments))
|
||||||
|
|
||||||
|
for (i,rng) in enumerate(segments)
|
||||||
|
length(rng) < 2 && continue
|
||||||
|
|
||||||
|
d_out = deepcopy(d_base)
|
||||||
|
d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false
|
||||||
|
|
||||||
|
# set the type
|
||||||
|
if st in (:path, :scatter, :scattergl, :straightline)
|
||||||
|
d_out[:type] = st==:scattergl ? "scattergl" : "scatter"
|
||||||
|
d_out[:mode] = if hasmarker
|
||||||
|
hasline ? "lines+markers" : "markers"
|
||||||
|
else
|
||||||
|
hasline ? "lines" : "none"
|
||||||
|
end
|
||||||
|
if series[:fillrange] == true || series[:fillrange] == 0 || isa(series[:fillrange], Tuple)
|
||||||
|
d_out[:fill] = "tozeroy"
|
||||||
|
d_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i)))
|
||||||
|
elseif typeof(series[:fillrange]) <: Union{AbstractVector{<:Real}, Real}
|
||||||
|
d_out[:fill] = "tonexty"
|
||||||
|
d_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i)))
|
||||||
|
elseif !(series[:fillrange] in (false, nothing))
|
||||||
|
warn("fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])")
|
||||||
|
end
|
||||||
|
d_out[:x], d_out[:y] = x[rng], y[rng]
|
||||||
|
|
||||||
|
elseif st in (:path3d, :scatter3d)
|
||||||
|
d_out[:type] = "scatter3d"
|
||||||
|
d_out[:mode] = if hasmarker
|
||||||
|
hasline ? "lines+markers" : "markers"
|
||||||
|
else
|
||||||
|
hasline ? "lines" : "none"
|
||||||
|
end
|
||||||
|
d_out[:x], d_out[:y], d_out[:z] = x[rng], y[rng], z[rng]
|
||||||
|
end
|
||||||
|
|
||||||
|
# add "marker"
|
||||||
|
if hasmarker
|
||||||
|
d_out[:marker] = KW(
|
||||||
|
:symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])),
|
||||||
|
# :opacity => series[:markeralpha],
|
||||||
|
:size => 2 * series[:markersize],
|
||||||
|
# :color => rgba_string(series[:markercolor]),
|
||||||
|
:line => KW(
|
||||||
|
:color => _cycle(rgba_string.(series[:markerstrokecolor]), eachindex(rng)),
|
||||||
|
:width => series[:markerstrokewidth],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# add "line"
|
||||||
|
if hasline
|
||||||
|
d_out[:line] = KW(
|
||||||
|
:color => rgba_string(plot_color(get_linecolor(series, i), get_linealpha(series, i))),
|
||||||
|
:width => get_linewidth(series, i),
|
||||||
|
:shape => if st == :steppre
|
||||||
|
"vh"
|
||||||
|
elseif st == :steppost
|
||||||
|
"hv"
|
||||||
|
else
|
||||||
|
"linear"
|
||||||
|
end,
|
||||||
|
:dash => string(get_linestyle(series, i)),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
plotly_polar!(d_out, series)
|
||||||
|
plotly_hover!(d_out, series[:hover])
|
||||||
|
|
||||||
|
if hasfillrange
|
||||||
|
# if hasfillrange is true, return two dictionaries (one for original
|
||||||
|
# series, one for series being filled to) instead of one
|
||||||
|
d_out_fillrange = deepcopy(d_out)
|
||||||
|
d_out_fillrange[:showlegend] = false
|
||||||
|
# if fillrange is provided as real or tuple of real, expand to array
|
||||||
|
if typeof(series[:fillrange]) <: Real
|
||||||
|
series[:fillrange] = fill(series[:fillrange], length(rng))
|
||||||
|
elseif typeof(series[:fillrange]) <: Tuple
|
||||||
|
f1 = typeof(series[:fillrange][1]) <: Real ? fill(series[:fillrange][1], length(rng)) : series[:fillrange][1][rng]
|
||||||
|
f2 = typeof(series[:fillrange][2]) <: Real ? fill(series[:fillrange][2], length(rng)) : series[:fillrange][2][rng]
|
||||||
|
series[:fillrange] = (f1, f2)
|
||||||
|
end
|
||||||
|
if isa(series[:fillrange], AbstractVector)
|
||||||
|
d_out_fillrange[:y] = series[:fillrange]
|
||||||
|
delete!(d_out_fillrange, :fill)
|
||||||
|
delete!(d_out_fillrange, :fillcolor)
|
||||||
|
else
|
||||||
|
# if fillrange is a tuple with upper and lower limit, d_out_fillrange
|
||||||
|
# is the series that will do the filling
|
||||||
|
d_out_fillrange[:x], d_out_fillrange[:y] =
|
||||||
|
concatenate_fillrange(x[rng], series[:fillrange][rng])
|
||||||
|
d_out_fillrange[:line][:width] = 0
|
||||||
|
delete!(d_out, :fill)
|
||||||
|
delete!(d_out, :fillcolor)
|
||||||
|
end
|
||||||
|
|
||||||
|
d_outs[(2 * i - 1):(2 * i)] = [d_out_fillrange, d_out]
|
||||||
|
else
|
||||||
|
d_outs[i] = d_out
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if series[:line_z] != nothing
|
||||||
|
push!(d_outs, plotly_colorbar_hack(series, d_base, :line))
|
||||||
|
elseif series[:fill_z] != nothing
|
||||||
|
push!(d_outs, plotly_colorbar_hack(series, d_base, :fill))
|
||||||
|
end
|
||||||
|
|
||||||
|
d_outs
|
||||||
|
end
|
||||||
|
|
||||||
|
function plotly_colorbar_hack(series::Series, d_base::KW, sym::Symbol)
|
||||||
|
d_out = deepcopy(d_base)
|
||||||
|
cmin, cmax = get_clims(series[:subplot])
|
||||||
|
d_out[:showlegend] = false
|
||||||
|
d_out[:type] = is3d(series) ? :scatter3d : :scatter
|
||||||
|
d_out[:mode] = :markers
|
||||||
|
d_out[:x], d_out[:y] = [series[:x][1]], [series[:y][1]]
|
||||||
|
if is3d(series)
|
||||||
|
d_out[:z] = [series[:z][1]]
|
||||||
|
end
|
||||||
|
# zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line)
|
||||||
|
d_out[:marker] = KW(
|
||||||
|
:size => 0,
|
||||||
|
:color => [0.5],
|
||||||
|
:cmin => cmin,
|
||||||
|
:cmax => cmax,
|
||||||
|
:colorscale => plotly_colorscale(series[Symbol("$(sym)color")], 1),
|
||||||
|
:showscale => hascolorbar(series[:subplot]),
|
||||||
|
)
|
||||||
|
return d_out
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function plotly_polar!(d_out::KW, series::Series)
|
function plotly_polar!(d_out::KW, series::Series)
|
||||||
# convert polar plots x/y to theta/radius
|
# convert polar plots x/y to theta/radius
|
||||||
if ispolar(series[:subplot])
|
if ispolar(series[:subplot])
|
||||||
|
|||||||
@ -136,6 +136,7 @@ py_color(s) = py_color(parse(Colorant, string(s)))
|
|||||||
py_color(c::Colorant) = (red(c), green(c), blue(c), alpha(c))
|
py_color(c::Colorant) = (red(c), green(c), blue(c), alpha(c))
|
||||||
py_color(cs::AVec) = map(py_color, cs)
|
py_color(cs::AVec) = map(py_color, cs)
|
||||||
py_color(grad::ColorGradient) = py_color(grad.colors)
|
py_color(grad::ColorGradient) = py_color(grad.colors)
|
||||||
|
py_color(c::Colorant, α) = py_color(plot_color(c, α))
|
||||||
|
|
||||||
function py_colormap(grad::ColorGradient)
|
function py_colormap(grad::ColorGradient)
|
||||||
pyvals = [(z, py_color(grad[z])) for z in grad.values]
|
pyvals = [(z, py_color(grad[z])) for z in grad.values]
|
||||||
@ -492,61 +493,51 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
|
|
||||||
# line plot
|
# line plot
|
||||||
if st in (:path, :path3d, :steppre, :steppost, :straightline)
|
if st in (:path, :path3d, :steppre, :steppost, :straightline)
|
||||||
if series[:linewidth] > 0
|
if maximum(series[:linewidth]) > 0
|
||||||
if series[:line_z] == nothing
|
segments = iter_segments(series)
|
||||||
handle = ax[:plot](xyargs...;
|
# TODO: check LineCollection alternative for speed
|
||||||
label = series[:label],
|
# if length(segments) > 1 && (any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) && !(typeof(series[:linestyle]) <: AbstractVector)
|
||||||
|
# # multicolored line segments
|
||||||
|
# n = length(segments)
|
||||||
|
# # segments = Array(Any,n)
|
||||||
|
# segments = []
|
||||||
|
# kw = KW(
|
||||||
|
# :label => series[:label],
|
||||||
|
# :zorder => plt.n,
|
||||||
|
# :cmap => py_linecolormap(series),
|
||||||
|
# :linewidths => py_dpi_scale(plt, get_linewidth.(series, 1:n)),
|
||||||
|
# :linestyle => py_linestyle(st, get_linestyle.(series)),
|
||||||
|
# :norm => pycolors["Normalize"](; extrakw...)
|
||||||
|
# )
|
||||||
|
# lz = _cycle(series[:line_z], 1:n)
|
||||||
|
# handle = if is3d(st)
|
||||||
|
# line_segments = [[(x[j], y[j], z[j]) for j in rng] for rng in segments]
|
||||||
|
# lc = pyart3d["Line3DCollection"](line_segments; kw...)
|
||||||
|
# lc[:set_array](lz)
|
||||||
|
# ax[:add_collection3d](lc, zs=z) #, zdir='y')
|
||||||
|
# lc
|
||||||
|
# else
|
||||||
|
# line_segments = [[(x[j], y[j]) for j in rng] for rng in segments]
|
||||||
|
# lc = pycollections["LineCollection"](line_segments; kw...)
|
||||||
|
# lc[:set_array](lz)
|
||||||
|
# ax[:add_collection](lc)
|
||||||
|
# lc
|
||||||
|
# end
|
||||||
|
# push!(handles, handle)
|
||||||
|
# else
|
||||||
|
for (i, rng) in enumerate(iter_segments(series))
|
||||||
|
handle = ax[:plot]((arg[rng] for arg in xyargs)...;
|
||||||
|
label = i == 1 ? series[:label] : "",
|
||||||
zorder = series[:series_plotindex],
|
zorder = series[:series_plotindex],
|
||||||
color = py_linecolor(series),
|
color = py_color(get_linecolor(series, i), get_linealpha(series, i)),
|
||||||
linewidth = py_dpi_scale(plt, series[:linewidth]),
|
linewidth = py_dpi_scale(plt, get_linewidth(series, i)),
|
||||||
linestyle = py_linestyle(st, series[:linestyle]),
|
linestyle = py_linestyle(st, get_linestyle(series, i)),
|
||||||
solid_capstyle = "round",
|
solid_capstyle = "round",
|
||||||
drawstyle = py_stepstyle(st)
|
drawstyle = py_stepstyle(st)
|
||||||
)[1]
|
)[1]
|
||||||
push!(handles, handle)
|
push!(handles, handle)
|
||||||
|
|
||||||
else
|
|
||||||
# multicolored line segments
|
|
||||||
n = length(x) - 1
|
|
||||||
# segments = Array(Any,n)
|
|
||||||
segments = []
|
|
||||||
kw = KW(
|
|
||||||
:label => series[:label],
|
|
||||||
:zorder => plt.n,
|
|
||||||
:cmap => py_linecolormap(series),
|
|
||||||
:linewidth => py_dpi_scale(plt, series[:linewidth]),
|
|
||||||
:linestyle => py_linestyle(st, series[:linestyle]),
|
|
||||||
:norm => pycolors["Normalize"](; extrakw...)
|
|
||||||
)
|
|
||||||
lz = _cycle(series[:line_z], 1:n)
|
|
||||||
handle = if is3d(st)
|
|
||||||
for rng in iter_segments(x, y, z)
|
|
||||||
length(rng) < 2 && continue
|
|
||||||
for i in rng[1:end-1]
|
|
||||||
push!(segments, [(_cycle(x,i),_cycle(y,i),_cycle(z,i)),
|
|
||||||
(_cycle(x,i+1),_cycle(y,i+1),_cycle(z,i+1))])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
lc = pyart3d["Line3DCollection"](segments; kw...)
|
|
||||||
lc[:set_array](lz)
|
|
||||||
ax[:add_collection3d](lc, zs=z) #, zdir='y')
|
|
||||||
lc
|
|
||||||
else
|
|
||||||
for rng in iter_segments(x, y)
|
|
||||||
length(rng) < 2 && continue
|
|
||||||
for i in rng[1:end-1]
|
|
||||||
push!(segments, [(_cycle(x,i),_cycle(y,i)), (_cycle(x,i+1),_cycle(y,i+1))])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
lc = pycollections["LineCollection"](segments; kw...)
|
|
||||||
lc[:set_array](lz)
|
|
||||||
ax[:add_collection](lc)
|
|
||||||
lc
|
|
||||||
end
|
|
||||||
push!(handles, handle)
|
|
||||||
end
|
end
|
||||||
|
# end
|
||||||
|
|
||||||
a = series[:arrow]
|
a = series[:arrow]
|
||||||
if a != nothing && !is3d(st) # TODO: handle 3d later
|
if a != nothing && !is3d(st) # TODO: handle 3d later
|
||||||
@ -559,8 +550,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
:shrinkB => 0,
|
:shrinkB => 0,
|
||||||
:edgecolor => py_linecolor(series),
|
:edgecolor => py_linecolor(series),
|
||||||
:facecolor => py_linecolor(series),
|
:facecolor => py_linecolor(series),
|
||||||
:linewidth => py_dpi_scale(plt, series[:linewidth]),
|
:linewidth => py_dpi_scale(plt, get_linewidth(series)),
|
||||||
:linestyle => py_linestyle(st, series[:linestyle]),
|
:linestyle => py_linestyle(st, get_linestyle(series)),
|
||||||
)
|
)
|
||||||
add_arrows(x, y) do xyprev, xy
|
add_arrows(x, y) do xyprev, xy
|
||||||
ax[:annotate]("",
|
ax[:annotate]("",
|
||||||
@ -794,16 +785,17 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
|
|
||||||
if st == :shape
|
if st == :shape
|
||||||
handle = []
|
handle = []
|
||||||
for (i,rng) in enumerate(iter_segments(x, y))
|
for (i, rng) in enumerate(iter_segments(series))
|
||||||
if length(rng) > 1
|
if length(rng) > 1
|
||||||
path = pypath["Path"](hcat(x[rng], y[rng]))
|
path = pypath["Path"](hcat(x[rng], y[rng]))
|
||||||
patches = pypatches["PathPatch"](
|
patches = pypatches["PathPatch"](
|
||||||
path;
|
path;
|
||||||
label = series[:label],
|
label = series[:label],
|
||||||
zorder = series[:series_plotindex],
|
zorder = series[:series_plotindex],
|
||||||
edgecolor = py_color(_cycle(series[:linecolor], i)),
|
edgecolor = py_color(get_linecolor(series, i), get_linealpha(series, i)),
|
||||||
facecolor = py_color(_cycle(series[:fillcolor], i)),
|
facecolor = py_color(get_fillcolor(series, i), get_fillalpha(series, i)),
|
||||||
linewidth = py_dpi_scale(plt, series[:linewidth]),
|
linewidth = py_dpi_scale(plt, get_linewidth(series, i)),
|
||||||
|
linestyle = py_linestyle(st, get_linestyle(series, i)),
|
||||||
fill = true
|
fill = true
|
||||||
)
|
)
|
||||||
push!(handle, ax[:add_patch](patches))
|
push!(handle, ax[:add_patch](patches))
|
||||||
@ -835,10 +827,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
# handle area filling
|
# handle area filling
|
||||||
fillrange = series[:fillrange]
|
fillrange = series[:fillrange]
|
||||||
if fillrange != nothing && st != :contour
|
if fillrange != nothing && st != :contour
|
||||||
|
for (i, rng) in enumerate(iter_segments(series))
|
||||||
f, dim1, dim2 = if isvertical(series)
|
f, dim1, dim2 = if isvertical(series)
|
||||||
:fill_between, x, y
|
:fill_between, x[rng], y[rng]
|
||||||
else
|
else
|
||||||
:fill_betweenx, y, x
|
:fill_betweenx, y[rng], x[rng]
|
||||||
end
|
end
|
||||||
n = length(dim1)
|
n = length(dim1)
|
||||||
args = if typeof(fillrange) <: Union{Real, AVec}
|
args = if typeof(fillrange) <: Union{Real, AVec}
|
||||||
@ -849,11 +842,12 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
|
|
||||||
handle = ax[f](args..., trues(n), false, py_fillstepstyle(st);
|
handle = ax[f](args..., trues(n), false, py_fillstepstyle(st);
|
||||||
zorder = series[:series_plotindex],
|
zorder = series[:series_plotindex],
|
||||||
facecolor = py_fillcolor(series),
|
facecolor = py_color(get_fillcolor(series, i), get_fillalpha(series, i)),
|
||||||
linewidths = 0
|
linewidths = 0
|
||||||
)
|
)
|
||||||
push!(handles, handle)
|
push!(handles, handle)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# this is all we need to add the series_annotations text
|
# this is all we need to add the series_annotations text
|
||||||
anns = series[:series_annotations]
|
anns = series[:series_annotations]
|
||||||
@ -1020,6 +1014,13 @@ 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))
|
||||||
|
cmin, cmax = get_clims(sp)
|
||||||
|
norm = pycolors[:Normalize](vmin = cmin, vmax = cmax)
|
||||||
|
f = colorbar_series[:line_z] != nothing ? py_linecolormap : py_fillcolormap
|
||||||
|
cmap = pycmap[:ScalarMappable](norm = norm, cmap = f(colorbar_series))
|
||||||
|
cmap[:set_array]([])
|
||||||
|
handle = cmap
|
||||||
end
|
end
|
||||||
|
|
||||||
# create and store the colorbar object (handle) and the axis that it is drawn on.
|
# create and store the colorbar object (handle) and the axis that it is drawn on.
|
||||||
@ -1250,15 +1251,16 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
|
|||||||
# add a line/marker and a label
|
# add a line/marker and a label
|
||||||
push!(handles, if series[:seriestype] == :shape || series[:fillrange] != nothing
|
push!(handles, if series[:seriestype] == :shape || series[:fillrange] != nothing
|
||||||
pypatches[:Patch](
|
pypatches[:Patch](
|
||||||
edgecolor = py_color(_cycle(series[:linecolor],1)),
|
edgecolor = py_color(get_linecolor(series), get_linealpha(series)),
|
||||||
facecolor = py_color(_cycle(series[:fillcolor],1)),
|
facecolor = py_color(get_fillcolor(series), get_fillalpha(series)),
|
||||||
linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)),
|
linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)),
|
||||||
|
linestyle = py_linestyle(series[:seriestype], get_linestyle(series))
|
||||||
)
|
)
|
||||||
elseif series[:seriestype] in (:path, :straightline)
|
elseif series[:seriestype] in (:path, :straightline)
|
||||||
PyPlot.plt[:Line2D]((0,1),(0,0),
|
PyPlot.plt[:Line2D]((0,1),(0,0),
|
||||||
color = py_color(_cycle(series[:linecolor],1)),
|
color = py_color(get_linecolor(series), get_linealpha(series)),
|
||||||
linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)),
|
linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)),
|
||||||
linestyle = py_linestyle(:path,series[:linestyle]),
|
linestyle = py_linestyle(:path, get_linestyle(series)),
|
||||||
marker = py_marker(series[:markershape]),
|
marker = py_marker(series[:markershape]),
|
||||||
markeredgecolor = py_markerstrokecolor(series),
|
markeredgecolor = py_markerstrokecolor(series),
|
||||||
markerfacecolor = series[:marker_z] == nothing ? py_markercolor(series) : py_color(series[:markercolor][0.5])
|
markerfacecolor = series[:marker_z] == nothing ? py_markercolor(series) : py_color(series[:markercolor][0.5])
|
||||||
|
|||||||
51
src/utils.jl
51
src/utils.jl
@ -192,6 +192,20 @@ function iter_segments(args...)
|
|||||||
SegmentsIterator(tup, n)
|
SegmentsIterator(tup, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function iter_segments(series::Series)
|
||||||
|
x, y, z = series[:x], series[:y], series[:z]
|
||||||
|
if has_attribute_segments(series)
|
||||||
|
return [i:(i + 1) for i in 1:(length(y) - 1)]
|
||||||
|
else
|
||||||
|
segs = UnitRange{Int64}[]
|
||||||
|
args = is3d(series) ? (x, y, z) : (x, y)
|
||||||
|
for seg in iter_segments(args...)
|
||||||
|
push!(segs, seg)
|
||||||
|
end
|
||||||
|
return segs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# helpers to figure out if there are NaN values in a list of array types
|
# helpers to figure out if there are NaN values in a list of array types
|
||||||
anynan(i::Int, args::Tuple) = any(a -> !isfinite(_cycle(a,i)), args)
|
anynan(i::Int, args::Tuple) = any(a -> !isfinite(_cycle(a,i)), args)
|
||||||
anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend)
|
anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend)
|
||||||
@ -602,26 +616,38 @@ function hascolorbar(sp::Subplot)
|
|||||||
hascbar
|
hascbar
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_linecolor(sp::Subplot, series::Series, i::Int = 1)
|
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 : _cycle(lc, i)
|
||||||
else
|
else
|
||||||
cmin, cmax = get_clims(sp)
|
cmin, cmax = get_clims(series[:subplot])
|
||||||
grad = isa(lc, ColorGradient) ? lc : cgrad()
|
grad = isa(lc, ColorGradient) ? lc : cgrad()
|
||||||
grad[clamp((_cycle(lz, i) - cmin) / (cmax - cmin), 0, 1)]
|
grad[clamp((_cycle(lz, i) - cmin) / (cmax - cmin), 0, 1)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_fillcolor(sp::Subplot, series::Series, i::Int = 1)
|
function get_linealpha(series, i::Int = 1)
|
||||||
|
_cycle(series[:linealpha], i)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_linewidth(series, i::Int = 1)
|
||||||
|
_cycle(series[:linewidth], i)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_linestyle(series, i::Int = 1)
|
||||||
|
_cycle(series[:linestyle], i)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_fillcolor(series, i::Int = 1)
|
||||||
fc = series[:fillcolor]
|
fc = series[:fillcolor]
|
||||||
fz = series[:fill_z]
|
fz = series[:fill_z]
|
||||||
lz = series[:line_z]
|
lz = series[:line_z]
|
||||||
if fz == nothing && lz == nothing
|
if fz == nothing && lz == nothing
|
||||||
isa(fc, ColorGradient) ? fc : _cycle(fc, i)
|
isa(fc, ColorGradient) ? fc : _cycle(fc, i)
|
||||||
else
|
else
|
||||||
cmin, cmax = get_clims(sp)
|
cmin, cmax = get_clims(series[:subplot])
|
||||||
grad = isa(fc, ColorGradient) ? fc : cgrad()
|
grad = isa(fc, ColorGradient) ? fc : cgrad()
|
||||||
if fz != nothing
|
if fz != nothing
|
||||||
grad[clamp((_cycle(fz, i) - cmin) / (cmax - cmin), 0, 1)]
|
grad[clamp((_cycle(fz, i) - cmin) / (cmax - cmin), 0, 1)]
|
||||||
@ -631,6 +657,23 @@ function get_fillcolor(sp::Subplot, series::Series, i::Int = 1)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function get_fillalpha(series, i::Int = 1)
|
||||||
|
_cycle(series[:fillalpha], i)
|
||||||
|
end
|
||||||
|
|
||||||
|
function has_attribute_segments(series::Series)
|
||||||
|
# we want to check if a series needs to be split into segments just because
|
||||||
|
# of its attributes
|
||||||
|
for letter in (:x, :y, :z)
|
||||||
|
# If we have NaNs in the data they define the segments and
|
||||||
|
# SegmentsIterator is used
|
||||||
|
series[letter] != nothing && NaN in collect(series[letter]) && return false
|
||||||
|
end
|
||||||
|
series[:seriestype] == :shape && return false
|
||||||
|
# ... else we check relevant attributes if they have multiple inputs
|
||||||
|
return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z))
|
||||||
|
end
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
|
|
||||||
makekw(; kw...) = KW(kw)
|
makekw(; kw...) = KW(kw)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user