Start fillstyle for GR and PyPlot

This commit is contained in:
Pearl Li 2020-10-27 22:38:16 -07:00
parent 8ce603d3eb
commit eb0e6c7ed1
5 changed files with 67 additions and 10 deletions

View File

@ -13,6 +13,7 @@ const _arg_desc = KW(
:fillrange => "Number or AbstractVector. Fills area between fillrange and y for line-types, sets the base for bar/stick types, and similar for other types.", :fillrange => "Number or AbstractVector. Fills area between fillrange and y for line-types, sets the base for bar/stick types, and similar for other types.",
:fillcolor => "Color Type. Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`.", :fillcolor => "Color Type. Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`.",
:fillalpha => "Number in [0,1]. The alpha/opacity override for the fill area. `nothing` (the default) means it will take the alpha value of fillcolor.", :fillalpha => "Number in [0,1]. The alpha/opacity override for the fill area. `nothing` (the default) means it will take the alpha value of fillcolor.",
:fillstyle => "Symbol. Style of the fill area. `nothing` (the default) means solid fill. Choose from :/, :\\, :|, :-, :+, :x",
:markershape => "Symbol, Shape, or AbstractVector. Choose from $(_allMarkers).", :markershape => "Symbol, Shape, or AbstractVector. Choose from $(_allMarkers).",
:markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.", :markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.",
:markeralpha => "Number in [0,1]. The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor.", :markeralpha => "Number in [0,1]. The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor.",

View File

@ -285,6 +285,7 @@ const _series_defaults = KW(
:fillrange => nothing, # ribbons, areas, etc :fillrange => nothing, # ribbons, areas, etc
:fillcolor => :match, :fillcolor => :match,
:fillalpha => nothing, :fillalpha => nothing,
:fillstyle => nothing,
:markershape => :none, :markershape => :none,
:markercolor => :match, :markercolor => :match,
:markeralpha => nothing, :markeralpha => nothing,
@ -805,6 +806,7 @@ function processLineArg(plotattributes::AKW, arg)
arg.size === nothing || (plotattributes[:fillrange] = arg.size) arg.size === nothing || (plotattributes[:fillrange] = arg.size)
arg.color === nothing || (plotattributes[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color)) arg.color === nothing || (plotattributes[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color))
arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha) arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha)
arg.style === nothing || (plotattributes[:fillstyle] = arg.style)
elseif typeof(arg) <: Arrow || arg in (:arrow, :arrows) elseif typeof(arg) <: Arrow || arg in (:arrow, :arrows)
plotattributes[:arrow] = arg plotattributes[:arrow] = arg
@ -871,6 +873,7 @@ function processFillArg(plotattributes::AKW, arg)
arg.size === nothing || (plotattributes[:fillrange] = arg.size) arg.size === nothing || (plotattributes[:fillrange] = arg.size)
arg.color === nothing || (plotattributes[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color)) arg.color === nothing || (plotattributes[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color))
arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha) arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha)
arg.style === nothing || (plotattributes[:fillstyle] = arg.style)
elseif typeof(arg) <: Bool elseif typeof(arg) <: Bool
plotattributes[:fillrange] = arg ? 0 : nothing plotattributes[:fillrange] = arg ? 0 : nothing

View File

@ -110,6 +110,7 @@ end
gr_set_linecolor(c) = GR.setlinecolorind(gr_getcolorind(_cycle(c,1))) 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_bordercolor(c) = GR.setbordercolorind(gr_getcolorind(_cycle(c,1))) gr_set_bordercolor(c) = GR.setbordercolorind(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)))
@ -133,6 +134,24 @@ gr_set_arrowstyle(s::Symbol) = GR.setarrowstyle(get(
1, 1,
)) ))
gr_set_fillstyle(::Nothing) = GR.setfillintstyle(GR.INTSTYLE_SOLID)
function gr_set_fillstyle(s::Symbol)
GR.setfillintstyle(GR.INTSTYLE_HATCH)
GR.setfillstyle(get(
(
/ = 9,
\ = 10,
| = 7,
- = 8,
+ = 11,
x = 6,
),
s,
9),
)
end
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
@ -914,7 +933,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
gr_update_viewport_ratio!(viewport_plotarea, sp) gr_update_viewport_ratio!(viewport_plotarea, sp)
leg = gr_get_legend_geometry(viewport_plotarea, sp) leg = gr_get_legend_geometry(viewport_plotarea, sp)
gr_update_viewport_legend!(viewport_plotarea, sp, leg) gr_update_viewport_legend!(viewport_plotarea, sp, leg)
# fill in the plot area background # fill in the plot area background
gr_fill_plotarea(sp, viewport_plotarea) gr_fill_plotarea(sp, viewport_plotarea)
@ -998,6 +1017,8 @@ function gr_add_legend(sp, leg, viewport_plotarea)
if (st == :shape || series[:fillrange] !== nothing) && series[:ribbon] === nothing if (st == :shape || series[:fillrange] !== nothing) && series[:ribbon] === nothing
fc = get_fillcolor(series, clims) fc = get_fillcolor(series, clims)
gr_set_fill(fc) #, series[:fillalpha]) gr_set_fill(fc) #, series[:fillalpha])
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
l, r = xpos - leg.width_factor * 3.5, xpos - leg.width_factor / 2 l, r = xpos - leg.width_factor * 3.5, xpos - leg.width_factor / 2
b, t = ypos - 0.4 * leg.dy, ypos + 0.4 * leg.dy b, t = ypos - 0.4 * leg.dy, ypos + 0.4 * leg.dy
x = [l, r, r, l, l] x = [l, r, r, l, l]
@ -1468,10 +1489,10 @@ function gr_label_axis_3d(sp, letter)
if ax[:guide] != "" if ax[:guide] != ""
near_letter = letter in (:x, :z) ? :y : :x near_letter = letter in (:x, :z) ? :y : :x
far_letter = letter in (:x, :y) ? :z : :x far_letter = letter in (:x, :y) ? :z : :x
nax = sp[Symbol(near_letter, :axis)] nax = sp[Symbol(near_letter, :axis)]
fax = sp[Symbol(far_letter, :axis)] fax = sp[Symbol(far_letter, :axis)]
amin, amax = axis_limits(sp, letter) amin, amax = axis_limits(sp, letter)
namin, namax = axis_limits(sp, near_letter) namin, namax = axis_limits(sp, near_letter)
famin, famax = axis_limits(sp, far_letter) famin, famax = axis_limits(sp, far_letter)
@ -1629,6 +1650,8 @@ function gr_draw_segments(series, x, y, fillrange, clims)
for (i, rng) in enumerate(segments) for (i, rng) in enumerate(segments)
fc = get_fillcolor(series, clims, i) fc = get_fillcolor(series, clims, i)
gr_set_fillcolor(fc) gr_set_fillcolor(fc)
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
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)))
gr_set_transparency(fc, get_fillalpha(series, i)) gr_set_transparency(fc, get_fillalpha(series, i))
@ -1709,6 +1732,8 @@ function gr_draw_shapes(series, x, y, clims)
# draw the interior # draw the interior
fc = get_fillcolor(series, clims, i) fc = get_fillcolor(series, clims, i)
gr_set_fill(fc) gr_set_fill(fc)
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
gr_set_transparency(fc, get_fillalpha(series, i)) gr_set_transparency(fc, get_fillalpha(series, i))
GR.fillarea(xseg, yseg) GR.fillarea(xseg, yseg)

View File

@ -162,6 +162,9 @@ function py_fillstepstyle(seriestype::Symbol)
return nothing return nothing
end end
py_fillstyle(::Nothing) = nothing
py_fillstyle(fillstyle::Symbol) = string(fillstyle)
# # untested... return a FontProperties object from a Plots.Font # # untested... return a FontProperties object from a Plots.Font
# function py_font(font::Font) # function py_font(font::Font)
# pyfont["FontProperties"]( # pyfont["FontProperties"](
@ -484,11 +487,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
y[rng], x[rng], z[rng] y[rng], x[rng], z[rng]
else else
y[rng], x[rng] y[rng], x[rng]
end end
else else
if RecipesPipeline.is3d(sp) if RecipesPipeline.is3d(sp)
x[rng], y[rng], z[rng] x[rng], y[rng], z[rng]
else else
x[rng], y[rng] x[rng], y[rng]
end end
end end
@ -672,13 +675,19 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
handle = [] handle = []
for (i, rng) in enumerate(iter_segments(series)) for (i, rng) in enumerate(iter_segments(series))
if length(rng) > 1 if length(rng) > 1
fillstyle = get_fillstyle(series, i)
has_fillstyle = !isnothing(fillstyle)
linecolor = get_linecolor(series, clims, i)
fillcolor = get_fillcolor(series, clims, i)
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(get_linecolor(series, clims, i), get_linealpha(series, i)), edgecolor = py_color(has_fillstyle ? fillcolor : linecolor, get_linealpha(series, i)),
facecolor = py_color(get_fillcolor(series, clims, i), get_fillalpha(series, i)), facecolor = py_color(fillcolor, has_fillstyle ? 0 : get_fillalpha(series, i)),
hatch = py_fillstyle(fillstyle),
linewidth = py_thickness_scale(plt, get_linewidth(series, i)), linewidth = py_thickness_scale(plt, get_linewidth(series, i)),
linestyle = py_linestyle(st, get_linestyle(series, i)), linestyle = py_linestyle(st, get_linestyle(series, i)),
fill = true fill = true
@ -710,9 +719,16 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng) dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng)
end end
fillstyle = get_fillstyle(series, i)
has_fillstyle = !isnothing(fillstyle)
linecolor = get_linecolor(series, clims, i)
fillcolor = get_fillcolor(series, clims, i)
handle = getproperty(ax, f)(args..., trues(n), false, py_fillstepstyle(st); handle = getproperty(ax, f)(args..., trues(n), false, py_fillstepstyle(st);
zorder = series[:series_plotindex], zorder = series[:series_plotindex],
facecolor = py_color(get_fillcolor(series, clims, i), get_fillalpha(series, i)), edgecolor = py_color(fillcolor, get_linealpha(series, i)),
facecolor = py_color(fillcolor, has_fillstyle ? 0 : get_fillalpha(series, i)),
hatch = py_fillstyle(fillstyle),
linewidths = 0 linewidths = 0
) )
push!(handles, handle) push!(handles, handle)
@ -1295,9 +1311,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, push!(handles,
if series[:seriestype] == :shape || series[:fillrange] !== nothing if series[:seriestype] == :shape || series[:fillrange] !== nothing
fillstyle = get_fillstyle(series)
has_fillstyle = !isnothing(fillstyle)
linecolor = get_linecolor(series, clims)
fillcolor = get_fillcolor(series, clims)
pypatches."Patch"( pypatches."Patch"(
edgecolor = py_color(single_color(get_linecolor(series, clims)), get_linealpha(series)), edgecolor = py_color(single_color(has_fillstyle ? fillcolor : linecolor), get_linealpha(series)),
facecolor = py_color(single_color(get_fillcolor(series, clims)), get_fillalpha(series)), facecolor = py_color(single_color(fillcolor), has_fillstyle ? 0 : get_fillalpha(series)),
hatch = py_fillstyle(fillstyle),
linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)), linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)),
linestyle = py_linestyle(series[:seriestype], get_linestyle(series)), linestyle = py_linestyle(series[:seriestype], get_linestyle(series)),
capstyle = "butt" capstyle = "butt"

View File

@ -557,6 +557,10 @@ function get_linestyle(series, i::Int = 1)
_cycle(series[:linestyle], i) _cycle(series[:linestyle], i)
end end
function get_fillstyle(series, i::Int = 1)
_cycle(series[:fillstyle], i)
end
function get_markerstrokecolor(series, i::Int = 1) function get_markerstrokecolor(series, i::Int = 1)
msc = series[:markerstrokecolor] msc = series[:markerstrokecolor]
isa(msc, ColorGradient) ? msc : _cycle(msc, i) isa(msc, ColorGradient) ? msc : _cycle(msc, i)
@ -592,6 +596,7 @@ function has_attribute_segments(series::Series)
:linestyle, :linestyle,
:fillcolor, :fillcolor,
:fillalpha, :fillalpha,
:fillstyle,
:markercolor, :markercolor,
:markeralpha, :markeralpha,
:markersize, :markersize,