extract gr_draw_<seriestype> functions
This commit is contained in:
parent
44bd1812e0
commit
51527705de
@ -333,35 +333,6 @@ function gr_draw_marker(series, xi, yi, clims, i, msize, strokewidth, shape::Sym
|
||||
end
|
||||
|
||||
|
||||
# draw the markers, one at a time
|
||||
function gr_draw_markers(
|
||||
series::Series,
|
||||
x,
|
||||
y,
|
||||
clims,
|
||||
msize = series[:markersize],
|
||||
strokewidth = series[:markerstrokewidth],
|
||||
)
|
||||
|
||||
isempty(x) && return
|
||||
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
||||
|
||||
shapes = series[:markershape]
|
||||
if shapes != :none
|
||||
for (i, rng) in enumerate(iter_segments(series, :scatter))
|
||||
rng = intersect(eachindex(x), rng)
|
||||
if !isempty(rng)
|
||||
ms = get_thickness_scaling(series) * _cycle(msize, i)
|
||||
msw = get_thickness_scaling(series) * _cycle(strokewidth, i)
|
||||
shape = _cycle(shapes, i)
|
||||
for j in rng
|
||||
gr_draw_marker(series, _cycle(x, j), _cycle(y, j), clims, i, ms, msw, shape)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
function gr_set_line(lw, style, c, s) # s can be Subplot or Series
|
||||
@ -900,305 +871,25 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
# fill in the plot area background
|
||||
gr_fill_plotarea(sp, viewport_plotarea)
|
||||
|
||||
cbar = GRColorbar()
|
||||
|
||||
draw_axes = sp[:framestyle] != :none
|
||||
# axes_2d = true
|
||||
for series in series_list(sp)
|
||||
# st = series[:seriestype]
|
||||
# if st in (:heatmap, :image)
|
||||
# x, y = heatmap_edges(series[:x], sp[:xaxis][:scale], series[:y], sp[:yaxis][:scale], size(series[:z]))
|
||||
# xy_lims = x[1], x[end], y[1], y[end]
|
||||
# expand_extrema!(sp[:xaxis], x)
|
||||
# expand_extrema!(sp[:yaxis], y)
|
||||
# end
|
||||
|
||||
gr_update_colorbar!(cbar,series)
|
||||
end
|
||||
|
||||
# set our plot area view
|
||||
GR.setviewport(viewport_plotarea...)
|
||||
|
||||
# these are the Axis objects, which hold scale, lims, etc
|
||||
xaxis = sp[:xaxis]
|
||||
yaxis = sp[:yaxis]
|
||||
zaxis = sp[:zaxis]
|
||||
|
||||
# set the scale flags and window
|
||||
gr_set_window(sp)
|
||||
gr_set_window(sp, viewport_plotarea)
|
||||
|
||||
# draw the axes
|
||||
gr_draw_axes(sp, viewport_plotarea)
|
||||
|
||||
# add the guides
|
||||
GR.savestate()
|
||||
if sp[:title] != ""
|
||||
gr_set_font(titlefont(sp), sp)
|
||||
loc = sp[:titlelocation]
|
||||
if loc == :left
|
||||
xpos = viewport_plotarea[1]
|
||||
halign = GR.TEXT_HALIGN_LEFT
|
||||
elseif loc == :right
|
||||
xpos = viewport_plotarea[2]
|
||||
halign = GR.TEXT_HALIGN_RIGHT
|
||||
else
|
||||
xpos = gr_view_xcenter(viewport_plotarea)
|
||||
halign = GR.TEXT_HALIGN_CENTER
|
||||
end
|
||||
GR.settextalign(halign, GR.TEXT_VALIGN_TOP)
|
||||
gr_text(xpos, viewport_subplot[4], sp[:title])
|
||||
end
|
||||
|
||||
GR.restorestate()
|
||||
gr_add_title(sp, viewport_plotarea, viewport_subplot)
|
||||
|
||||
# this needs to be here to point the colormap to the right indices
|
||||
GR.setcolormap(1000 + GR.COLORMAP_COOLWARM)
|
||||
|
||||
for (idx, series) in enumerate(series_list(sp))
|
||||
st = series[:seriestype]
|
||||
# init the colorbar
|
||||
cbar = GRColorbar()
|
||||
|
||||
# update the current stored gradient
|
||||
gr_set_gradient(series)
|
||||
|
||||
GR.savestate()
|
||||
|
||||
# update the bounding window
|
||||
if ispolar(sp)
|
||||
gr_set_viewport_polar(viewport_plotarea)
|
||||
else
|
||||
xmin, xmax, ymin, ymax = gr_xy_axislims(sp)
|
||||
if xmax > xmin && ymax > ymin
|
||||
GR.setwindow(xmin, xmax, ymin, ymax)
|
||||
end
|
||||
end
|
||||
|
||||
x, y, z = series[:x], series[:y], series[:z]
|
||||
frng = series[:fillrange]
|
||||
|
||||
clims = get_clims(sp, series)
|
||||
|
||||
# add custom frame shapes to markershape?
|
||||
series_annotations_shapes!(series)
|
||||
# -------------------------------------------------------
|
||||
|
||||
# recompute data
|
||||
if typeof(z) <: Surface
|
||||
z = vec(transpose_z(series, z.surf, false))
|
||||
elseif ispolar(sp)
|
||||
rmin, rmax = axis_limits(sp, :y)
|
||||
if frng !== nothing
|
||||
_, frng = convert_to_polar(x, frng, (rmin, rmax))
|
||||
end
|
||||
x, y = convert_to_polar(x, y, (rmin, rmax))
|
||||
end
|
||||
|
||||
if st == :straightline
|
||||
x, y = straightline_data(series)
|
||||
end
|
||||
|
||||
if st in (:path, :scatter, :straightline)
|
||||
if x !== nothing && length(x) > 1
|
||||
lz = series[:line_z]
|
||||
segments = iter_segments(series, st)
|
||||
# do area fill
|
||||
if frng !== nothing
|
||||
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
||||
fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng))
|
||||
for (i, rng) in enumerate(segments)
|
||||
fc = get_fillcolor(series, clims, i)
|
||||
gr_set_fillcolor(fc)
|
||||
fx = _cycle(x, vcat(rng, reverse(rng)))
|
||||
fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng)))
|
||||
gr_set_transparency(fc, get_fillalpha(series, i))
|
||||
GR.fillarea(fx, fy)
|
||||
end
|
||||
end
|
||||
|
||||
# draw the line(s)
|
||||
if st in (:path, :straightline)
|
||||
for (i, rng) in enumerate(segments)
|
||||
lc = get_linecolor(series, clims, i)
|
||||
gr_set_line(
|
||||
get_linewidth(series, i), get_linestyle(series, i), lc, sp
|
||||
)
|
||||
arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none
|
||||
arrowstyle = isa(series[:arrow], Arrow) ? series[:arrow].style : :simple
|
||||
gr_set_fillcolor(lc)
|
||||
gr_set_transparency(lc, get_linealpha(series, i))
|
||||
gr_polyline(x[rng], y[rng]; arrowside = arrowside, arrowstyle = arrowstyle)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if series[:markershape] != :none
|
||||
gr_draw_markers(series, x, y, clims)
|
||||
end
|
||||
|
||||
elseif st == :contour
|
||||
GR.setspace(clims[1], clims[2], 0, 90)
|
||||
GR.setlinetype(gr_linetype(get_linestyle(series)))
|
||||
GR.setlinewidth(max(0, get_linewidth(series)) / gr_nominal_size(sp))
|
||||
is_lc_black = let black=plot_color(:black)
|
||||
plot_color(series[:linecolor]) in (black,[black])
|
||||
end
|
||||
h = gr_contour_levels(series, clims)
|
||||
if series[:fillrange] !== nothing
|
||||
if series[:fillcolor] != series[:linecolor] && !is_lc_black
|
||||
@warn("GR: filled contour only supported with black contour lines")
|
||||
end
|
||||
GR.contourf(x, y, h, z, series[:contour_labels] == true ? 1 : 0)
|
||||
else
|
||||
coff = is_lc_black ? 0 : 1000
|
||||
GR.contour(x, y, h, z, coff + (series[:contour_labels] == true ? 1 : 0))
|
||||
end
|
||||
|
||||
elseif st in [:surface, :wireframe]
|
||||
if st == :surface
|
||||
if length(x) == length(y) == length(z)
|
||||
GR.trisurface(x, y, z)
|
||||
else
|
||||
try
|
||||
GR.gr3.surface(x, y, z, GR.OPTION_COLORED_MESH)
|
||||
catch
|
||||
GR.surface(x, y, z, GR.OPTION_COLORED_MESH)
|
||||
end
|
||||
end
|
||||
else
|
||||
GR.setfillcolorind(0)
|
||||
GR.surface(x, y, z, GR.OPTION_FILLED_MESH)
|
||||
end
|
||||
|
||||
elseif st == :volume
|
||||
sp[:legend] = :none
|
||||
GR.gr3.clear()
|
||||
dmin, dmax = GR.gr3.volume(y.v, 0)
|
||||
|
||||
elseif st == :heatmap
|
||||
zmin, zmax = clims
|
||||
fillgrad = _as_gradient(series[:fillcolor])
|
||||
if !ispolar(sp)
|
||||
GR.setspace(clims..., 0, 90)
|
||||
x, y = heatmap_edges(series[:x], sp[:xaxis][:scale], series[:y], sp[:yaxis][:scale], size(series[:z]))
|
||||
w, h = length(x) - 1, length(y) - 1
|
||||
if is_uniformly_spaced(x) && is_uniformly_spaced(y)
|
||||
# For uniformly spaced data use GR.drawimage, which can be
|
||||
# much faster than GR.nonuniformcellarray, especially for
|
||||
# pdf output, and also supports alpha values.
|
||||
# Note that drawimage draws uniformly spaced data correctly
|
||||
# even on log scales, where it is visually non-uniform.
|
||||
colors = plot_color.(get(fillgrad, z, clims), series[:fillalpha])
|
||||
rgba = gr_color.(colors)
|
||||
GR.drawimage(first(x), last(x), last(y), first(y), w, h, rgba)
|
||||
else
|
||||
if something(series[:fillalpha],1) < 1
|
||||
@warn "GR: transparency not supported in non-uniform heatmaps. Alpha values ignored."
|
||||
end
|
||||
z_normalized = get_z_normalized.(z, zmin, zmax)
|
||||
rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized]
|
||||
GR.nonuniformcellarray(x, y, w, h, rgba)
|
||||
end
|
||||
else
|
||||
phimin, phimax = 0.0, 360.0 # nonuniform polar array is not yet supported in GR.jl
|
||||
nx, ny = length(series[:x]), length(series[:y])
|
||||
xmin, xmax, ymin, ymax = gr_xy_axislims(sp)
|
||||
GR.setwindow(-ymax, ymax, -ymax, ymax)
|
||||
if ymin > 0
|
||||
@warn "'ymin[1] > 0' (rmin) is not yet supported."
|
||||
end
|
||||
if series[:y][end] != ny
|
||||
@warn "Right now only the maximum value of y (r) is taken into account."
|
||||
end
|
||||
# colors = get(fillgrad, z, clims)
|
||||
# GR.polarcellarray(0, 0, phimin, phimax, ymin, ymax, nx, ny, colors)
|
||||
z_normalized = get_z_normalized.(z, zmin, zmax)
|
||||
# z_normalized = map(c -> c == invisible() ? 256/255 : PlotUtils.getinverse(fillgrad.colors, c), colors)
|
||||
rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized]
|
||||
GR.polarcellarray(0, 0, phimin, phimax, 0, ymax, nx, ny, rgba)
|
||||
# Right now only the maximum value of y (r) is taken into account.
|
||||
# This is certainly not perfect but nonuniform polar array is not yet supported in GR.jl
|
||||
end
|
||||
|
||||
elseif st in (:path3d, :scatter3d)
|
||||
# draw path
|
||||
if st == :path3d
|
||||
if length(x) > 1
|
||||
lz = series[:line_z]
|
||||
segments = iter_segments(series, st)
|
||||
for (i, rng) in enumerate(segments)
|
||||
lc = get_linecolor(series, clims, i)
|
||||
gr_set_line(
|
||||
get_linewidth(series, i), get_linestyle(series, i), lc, sp
|
||||
)
|
||||
gr_set_transparency(lc, get_linealpha(series, i))
|
||||
GR.polyline3d(x[rng], y[rng], z[rng])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# draw markers
|
||||
if st == :scatter3d || series[:markershape] != :none
|
||||
x2, y2 = RecipesPipeline.unzip(map(GR.wc3towc, x, y, z))
|
||||
gr_draw_markers(series, x2, y2, clims)
|
||||
end
|
||||
|
||||
elseif st == :shape
|
||||
x, y = shape_data(series)
|
||||
for (i,rng) in enumerate(iter_segments(x, y))
|
||||
if length(rng) > 1
|
||||
# connect to the beginning
|
||||
rng = vcat(rng, rng[1])
|
||||
|
||||
# get the segments
|
||||
xseg, yseg = x[rng], y[rng]
|
||||
|
||||
# draw the interior
|
||||
fc = get_fillcolor(series, clims, i)
|
||||
gr_set_fill(fc)
|
||||
gr_set_transparency(fc, get_fillalpha(series, i))
|
||||
GR.fillarea(xseg, yseg)
|
||||
|
||||
# draw the shapes
|
||||
lc = get_linecolor(series, clims, i)
|
||||
gr_set_line(get_linewidth(series, i), get_linestyle(series, i), lc, sp)
|
||||
gr_set_transparency(lc, get_linealpha(series, i))
|
||||
GR.polyline(xseg, yseg)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
elseif st == :image
|
||||
z = transpose_z(series, series[:z].surf, true)'
|
||||
x, y = heatmap_edges(series[:x], sp[:xaxis][:scale], series[:y], sp[:yaxis][:scale], size(z))
|
||||
w, h = size(z)
|
||||
xmin, xmax = ignorenan_extrema(x)
|
||||
ymin, ymax = ignorenan_extrema(y)
|
||||
rgba = gr_color.(z)
|
||||
GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba)
|
||||
end
|
||||
|
||||
# this is all we need to add the series_annotations text
|
||||
anns = series[:series_annotations]
|
||||
for (xi,yi,str,fnt) in EachAnn(anns, x, y)
|
||||
gr_set_font(fnt, sp)
|
||||
gr_text(GR.wctondc(xi, yi)..., str)
|
||||
end
|
||||
|
||||
if sp[:legend] == :inline && should_add_to_legend(series)
|
||||
gr_set_font(legendfont(sp), sp)
|
||||
gr_set_textcolor(plot_color(sp[:legendfontcolor]))
|
||||
if sp[:yaxis][:mirror]
|
||||
(_,i) = sp[:xaxis][:flip] ? findmax(x) : findmin(x)
|
||||
GR.settextalign(GR.TEXT_HALIGN_RIGHT, GR.TEXT_VALIGN_HALF)
|
||||
offset = -0.01
|
||||
else
|
||||
(_,i) = sp[:xaxis][:flip] ? findmin(x) : findmax(x)
|
||||
GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF)
|
||||
offset = 0.01
|
||||
end
|
||||
(x_l,y_l) = GR.wctondc(x[i],y[i])
|
||||
gr_text(x_l+offset,y_l,series[:label])
|
||||
end
|
||||
GR.restorestate()
|
||||
for series in series_list(sp)
|
||||
gr_add_series(sp, series)
|
||||
gr_update_colorbar!(cbar, series)
|
||||
end
|
||||
|
||||
# draw the colorbar
|
||||
@ -1208,16 +899,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
gr_add_legend(sp, leg, viewport_plotarea)
|
||||
|
||||
# add annotations
|
||||
GR.savestate()
|
||||
# update the bounding window
|
||||
if ispolar(sp)
|
||||
gr_set_viewport_polar(viewport_plotarea)
|
||||
else
|
||||
xmin, xmax, ymin, ymax = gr_xy_axislims(sp)
|
||||
if xmax > xmin && ymax > ymin
|
||||
GR.setwindow(xmin, xmax, ymin, ymax)
|
||||
end
|
||||
end
|
||||
for ann in sp[:annotations]
|
||||
x, y, val = locate_annotation(sp, ann...)
|
||||
x, y = if RecipesPipeline.is3d(sp)
|
||||
@ -1228,7 +909,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
gr_set_font(val.font, sp)
|
||||
gr_text(x, y, val.str)
|
||||
end
|
||||
GR.restorestate()
|
||||
end
|
||||
|
||||
|
||||
@ -1479,7 +1159,10 @@ function gr_update_viewport_ratio!(viewport_plotarea, sp)
|
||||
end
|
||||
end
|
||||
|
||||
function gr_set_window(sp)
|
||||
function gr_set_window(sp, viewport_plotarea)
|
||||
if ispolar(sp)
|
||||
gr_set_viewport_polar(viewport_plotarea)
|
||||
else
|
||||
xmin, xmax, ymin, ymax = gr_xy_axislims(sp)
|
||||
scaleop = 0
|
||||
if xmax > xmin && ymax > ymin
|
||||
@ -1492,6 +1175,7 @@ function gr_set_window(sp)
|
||||
GR.setscale(scaleop)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function gr_fill_plotarea(sp, viewport_plotarea)
|
||||
if !RecipesPipeline.is3d(sp)
|
||||
@ -1499,6 +1183,7 @@ function gr_fill_plotarea(sp, viewport_plotarea)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
## Axes
|
||||
|
||||
function gr_draw_axes(sp, viewport_plotarea)
|
||||
@ -1769,6 +1454,310 @@ function gr_label_axis_3d(sp, letter)
|
||||
end
|
||||
end
|
||||
|
||||
function gr_add_title(sp, viewport_plotarea, viewport_subplot)
|
||||
if sp[:title] != ""
|
||||
GR.savestate()
|
||||
gr_set_font(titlefont(sp), sp)
|
||||
loc = sp[:titlelocation]
|
||||
if loc == :left
|
||||
xpos = viewport_plotarea[1]
|
||||
halign = GR.TEXT_HALIGN_LEFT
|
||||
elseif loc == :right
|
||||
xpos = viewport_plotarea[2]
|
||||
halign = GR.TEXT_HALIGN_RIGHT
|
||||
else
|
||||
xpos = gr_view_xcenter(viewport_plotarea)
|
||||
halign = GR.TEXT_HALIGN_CENTER
|
||||
end
|
||||
GR.settextalign(halign, GR.TEXT_VALIGN_TOP)
|
||||
gr_text(xpos, viewport_subplot[4], sp[:title])
|
||||
GR.restorestate()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
## Series
|
||||
|
||||
function gr_add_series(sp, series)
|
||||
st = series[:seriestype]
|
||||
|
||||
# update the current stored gradient
|
||||
gr_set_gradient(series)
|
||||
|
||||
GR.savestate()
|
||||
|
||||
x, y, z = series[:x], series[:y], series[:z]
|
||||
xscale, yscale = sp[:xaxis][:scale], sp[:yaxis][:scale]
|
||||
frng = series[:fillrange]
|
||||
|
||||
# recompute data
|
||||
if typeof(z) <: Surface
|
||||
z = transpose_z(series, z.surf, false)
|
||||
elseif ispolar(sp)
|
||||
rmin, rmax = axis_limits(sp, :y)
|
||||
if frng !== nothing
|
||||
_, frng = convert_to_polar(x, frng, (rmin, rmax))
|
||||
end
|
||||
x, y = convert_to_polar(x, y, (rmin, rmax))
|
||||
end
|
||||
|
||||
clims = get_clims(sp, series)
|
||||
|
||||
# add custom frame shapes to markershape?
|
||||
series_annotations_shapes!(series)
|
||||
# -------------------------------------------------------
|
||||
|
||||
# draw the series
|
||||
if st in (:path, :scatter, :straightline)
|
||||
if st === :straightline
|
||||
x, y = straightline_data(series)
|
||||
end
|
||||
gr_draw_segments(series, x, y, frng, clims)
|
||||
if series[:markershape] !== :none
|
||||
gr_draw_markers(series, x, y, clims)
|
||||
end
|
||||
elseif st === :shape
|
||||
gr_draw_shapes(series, x, y, clims)
|
||||
elseif st in (:path3d, :scatter3d)
|
||||
gr_draw_segments_3d(series, x, y, z, clims)
|
||||
if st === :scatter3d || series[:markershape] !== :none
|
||||
# TODO: Do we need to transform to 2d coordinates here?
|
||||
x2, y2 = RecipesPipeline.unzip(map(GR.wc3towc, x, y, z))
|
||||
gr_draw_markers(series, x2, y2, clims)
|
||||
end
|
||||
elseif st === :contour
|
||||
gr_draw_contour(series, x, y, z, clims)
|
||||
elseif st in (:surface, :wireframe)
|
||||
gr_draw_surface(series, x, y, z, clims)
|
||||
elseif st === :volume
|
||||
sp[:legend] = :none
|
||||
GR.gr3.clear()
|
||||
dmin, dmax = GR.gr3.volume(y.v, 0)
|
||||
elseif st in (:heatmap, :image)
|
||||
if !ispolar(series)
|
||||
x, y = heatmap_edges(x, xscale, y, yscale, size(z))
|
||||
end
|
||||
if st === :heatmap
|
||||
gr_draw_heatmap(series, x, y, z, clims)
|
||||
else
|
||||
gr_draw_image(series, x, y, z, clims)
|
||||
end
|
||||
end
|
||||
|
||||
# this is all we need to add the series_annotations text
|
||||
anns = series[:series_annotations]
|
||||
for (xi,yi,str,fnt) in EachAnn(anns, x, y)
|
||||
gr_set_font(fnt, sp)
|
||||
gr_text(GR.wctondc(xi, yi)..., str)
|
||||
end
|
||||
|
||||
if sp[:legend] == :inline && should_add_to_legend(series)
|
||||
gr_set_font(legendfont(sp), sp)
|
||||
gr_set_textcolor(plot_color(sp[:legendfontcolor]))
|
||||
if sp[:yaxis][:mirror]
|
||||
(_,i) = sp[:xaxis][:flip] ? findmax(x) : findmin(x)
|
||||
GR.settextalign(GR.TEXT_HALIGN_RIGHT, GR.TEXT_VALIGN_HALF)
|
||||
offset = -0.01
|
||||
else
|
||||
(_,i) = sp[:xaxis][:flip] ? findmin(x) : findmax(x)
|
||||
GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF)
|
||||
offset = 0.01
|
||||
end
|
||||
(x_l,y_l) = GR.wctondc(x[i],y[i])
|
||||
gr_text(x_l+offset,y_l,series[:label])
|
||||
end
|
||||
GR.restorestate()
|
||||
end
|
||||
|
||||
function gr_draw_segments(series, x, y, fillrange, clims)
|
||||
st = series[:seriestype]
|
||||
if x !== nothing && length(x) > 1
|
||||
segments = iter_segments(series, st)
|
||||
# do area fill
|
||||
if fillrange !== nothing
|
||||
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
||||
fr_from, fr_to = (is_2tuple(fillrange) ? fillrange : (y, fillrange))
|
||||
for (i, rng) in enumerate(segments)
|
||||
fc = get_fillcolor(series, clims, i)
|
||||
gr_set_fillcolor(fc)
|
||||
fx = _cycle(x, vcat(rng, reverse(rng)))
|
||||
fy = vcat(_cycle(fr_from, rng), _cycle(fr_to, reverse(rng)))
|
||||
gr_set_transparency(fc, get_fillalpha(series, i))
|
||||
GR.fillarea(fx, fy)
|
||||
end
|
||||
end
|
||||
|
||||
# draw the line(s)
|
||||
if st in (:path, :straightline)
|
||||
for (i, rng) in enumerate(segments)
|
||||
lc = get_linecolor(series, clims, i)
|
||||
gr_set_line(
|
||||
get_linewidth(series, i), get_linestyle(series, i), lc, series
|
||||
)
|
||||
arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none
|
||||
arrowstyle = isa(series[:arrow], Arrow) ? series[:arrow].style : :simple
|
||||
gr_set_fillcolor(lc)
|
||||
gr_set_transparency(lc, get_linealpha(series, i))
|
||||
gr_polyline(x[rng], y[rng]; arrowside = arrowside, arrowstyle = arrowstyle)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function gr_draw_segments_3d(series, x, y, z, clims)
|
||||
if series[:seriestype] === :path3d && length(x) > 1
|
||||
lz = series[:line_z]
|
||||
segments = iter_segments(series, :path3d)
|
||||
for (i, rng) in enumerate(segments)
|
||||
lc = get_linecolor(series, clims, i)
|
||||
gr_set_line(
|
||||
get_linewidth(series, i), get_linestyle(series, i), lc, series
|
||||
)
|
||||
gr_set_transparency(lc, get_linealpha(series, i))
|
||||
GR.polyline3d(x[rng], y[rng], z[rng])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function gr_draw_markers(
|
||||
series::Series,
|
||||
x,
|
||||
y,
|
||||
clims,
|
||||
msize = series[:markersize],
|
||||
strokewidth = series[:markerstrokewidth],
|
||||
)
|
||||
|
||||
isempty(x) && return
|
||||
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
||||
|
||||
shapes = series[:markershape]
|
||||
if shapes != :none
|
||||
for (i, rng) in enumerate(iter_segments(series, :scatter))
|
||||
rng = intersect(eachindex(x), rng)
|
||||
if !isempty(rng)
|
||||
ms = get_thickness_scaling(series) * _cycle(msize, i)
|
||||
msw = get_thickness_scaling(series) * _cycle(strokewidth, i)
|
||||
shape = _cycle(shapes, i)
|
||||
for j in rng
|
||||
gr_draw_marker(series, _cycle(x, j), _cycle(y, j), clims, i, ms, msw, shape)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function gr_draw_shapes(series, x, y, clims)
|
||||
x, y = shape_data(series)
|
||||
for (i,rng) in enumerate(iter_segments(x, y))
|
||||
if length(rng) > 1
|
||||
# connect to the beginning
|
||||
rng = vcat(rng, rng[1])
|
||||
|
||||
# get the segments
|
||||
xseg, yseg = x[rng], y[rng]
|
||||
|
||||
# draw the interior
|
||||
fc = get_fillcolor(series, clims, i)
|
||||
gr_set_fill(fc)
|
||||
gr_set_transparency(fc, get_fillalpha(series, i))
|
||||
GR.fillarea(xseg, yseg)
|
||||
|
||||
# draw the shapes
|
||||
lc = get_linecolor(series, clims, i)
|
||||
gr_set_line(get_linewidth(series, i), get_linestyle(series, i), lc, series)
|
||||
gr_set_transparency(lc, get_linealpha(series, i))
|
||||
GR.polyline(xseg, yseg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function gr_draw_contour(series, x, y, z, clims)
|
||||
GR.setspace(clims[1], clims[2], 0, 90)
|
||||
gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series), series)
|
||||
is_lc_black = let black=plot_color(:black)
|
||||
plot_color(series[:linecolor]) in (black,[black])
|
||||
end
|
||||
h = gr_contour_levels(series, clims)
|
||||
if series[:fillrange] !== nothing
|
||||
if series[:fillcolor] != series[:linecolor] && !is_lc_black
|
||||
@warn("GR: filled contour only supported with black contour lines")
|
||||
end
|
||||
GR.contourf(x, y, h, z, series[:contour_labels] == true ? 1 : 0)
|
||||
else
|
||||
coff = is_lc_black ? 0 : 1000
|
||||
GR.contour(x, y, h, z, coff + (series[:contour_labels] == true ? 1 : 0))
|
||||
end
|
||||
end
|
||||
|
||||
function gr_draw_surface(series, x, y, z, clims)
|
||||
if series[:seriestype] === :surface
|
||||
if length(x) == length(y) == length(z)
|
||||
GR.trisurface(x, y, z)
|
||||
else
|
||||
try
|
||||
GR.gr3.surface(x, y, z, GR.OPTION_COLORED_MESH)
|
||||
catch
|
||||
GR.surface(x, y, z, GR.OPTION_COLORED_MESH)
|
||||
end
|
||||
end
|
||||
else # wireframe
|
||||
GR.setfillcolorind(0)
|
||||
GR.surface(x, y, z, GR.OPTION_FILLED_MESH)
|
||||
end
|
||||
end
|
||||
|
||||
function gr_draw_heatmap(series, x, y, z, clims)
|
||||
fillgrad = _as_gradient(series[:fillcolor])
|
||||
if !ispolar(series)
|
||||
GR.setspace(clims..., 0, 90)
|
||||
w, h = length(x) - 1, length(y) - 1
|
||||
if is_uniformly_spaced(x) && is_uniformly_spaced(y)
|
||||
# For uniformly spaced data use GR.drawimage, which can be
|
||||
# much faster than GR.nonuniformcellarray, especially for
|
||||
# pdf output, and also supports alpha values.
|
||||
# Note that drawimage draws uniformly spaced data correctly
|
||||
# even on log scales, where it is visually non-uniform.
|
||||
colors = plot_color.(get(fillgrad, z, clims), series[:fillalpha])
|
||||
rgba = gr_color.(colors)
|
||||
GR.drawimage(first(x), last(x), last(y), first(y), w, h, rgba)
|
||||
else
|
||||
if something(series[:fillalpha], 1) < 1
|
||||
@warn "GR: transparency not supported in non-uniform heatmaps. Alpha values ignored."
|
||||
end
|
||||
z_normalized = get_z_normalized.(z, clims...)
|
||||
rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized]
|
||||
GR.nonuniformcellarray(x, y, w, h, rgba)
|
||||
end
|
||||
else
|
||||
phimin, phimax = 0.0, 360.0 # nonuniform polar array is not yet supported in GR.jl
|
||||
nx, ny = length(series[:x]), length(series[:y])
|
||||
xmin, xmax, ymin, ymax = gr_xy_axislims(sp)
|
||||
GR.setwindow(-ymax, ymax, -ymax, ymax)
|
||||
if ymin > 0
|
||||
@warn "'ymin[1] > 0' (rmin) is not yet supported."
|
||||
end
|
||||
if series[:y][end] != ny
|
||||
@warn "Right now only the maximum value of y (r) is taken into account."
|
||||
end
|
||||
z_normalized = get_z_normalized.(z, clims...)
|
||||
rgba = Int32[round(Int32, 1000 + _i * 255) for _i in z_normalized]
|
||||
GR.polarcellarray(0, 0, phimin, phimax, 0, ymax, nx, ny, rgba)
|
||||
# Right now only the maximum value of y (r) is taken into account.
|
||||
# This is certainly not perfect but nonuniform polar array is not yet supported in GR.jl
|
||||
end
|
||||
end
|
||||
|
||||
function gr_draw_image(series, x, y, z, clims)
|
||||
z = transpose_z(series, series[:z].surf, true)'
|
||||
w, h = size(z)
|
||||
xmin, xmax = ignorenan_extrema(x)
|
||||
ymin, ymax = ignorenan_extrema(y)
|
||||
rgba = gr_color.(z)
|
||||
GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba)
|
||||
end
|
||||
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
for (mime, fmt) in (
|
||||
|
||||
@ -659,6 +659,7 @@ function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText)
|
||||
(x, y, lab)
|
||||
end
|
||||
locate_annotation(sp::Subplot, x, y, label::PlotText) = (x, y, label)
|
||||
locate_annotation(sp::Subplot, x, y, z, label::PlotText) = (x, y, z, label)
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
"type which represents z-values for colors and sizes (and anything else that might come up)"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user