Improve support for Shapes, markers & colors.
Details: Control font & background color. Support arbitrary marker shapes. Support more pre-defined markers. Support Shapes in plots. Support ln-plots. Also: Fix ncolumns. Update supported section.
This commit is contained in:
parent
e381c13dc6
commit
c78444fc24
@ -2,16 +2,15 @@
|
|||||||
# https://github.com/ma-laforge/InspectDR.jl
|
# https://github.com/ma-laforge/InspectDR.jl
|
||||||
|
|
||||||
#=TODO:
|
#=TODO:
|
||||||
|
Tweak scale factor for width & other sizes
|
||||||
|
|
||||||
Not supported by InspectDR:
|
Not supported by InspectDR:
|
||||||
:foreground_color_title (font), title_location
|
:foreground_color_grid
|
||||||
:background_color_legend, :background_color_inside, :background_color_outside,
|
:foreground_color_border
|
||||||
:foreground_color_grid, :foreground_color_legend, :foreground_color_title,
|
|
||||||
:foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text,
|
|
||||||
:polar,
|
:polar,
|
||||||
|
|
||||||
|
|
||||||
Add in functionality to Plots.jl:
|
Add in functionality to Plots.jl:
|
||||||
:annotations, :aspect_ratio,
|
:aspect_ratio,
|
||||||
=#
|
=#
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@ -50,58 +49,34 @@ const _inspectdr_attr = merge_with_base_supported([
|
|||||||
])
|
])
|
||||||
const _inspectdr_style = [:auto, :solid, :dash, :dot, :dashdot]
|
const _inspectdr_style = [:auto, :solid, :dash, :dot, :dashdot]
|
||||||
const _inspectdr_seriestype = [
|
const _inspectdr_seriestype = [
|
||||||
:path, :scatter #, :steppre, :steppost, :shape,
|
:path, :scatter, :shape #, :steppre, :steppost
|
||||||
]
|
]
|
||||||
#see: _allMarkers, _shape_keys
|
#see: _allMarkers, _shape_keys
|
||||||
const _inspectdr_marker = Symbol[
|
const _inspectdr_marker = Symbol[
|
||||||
:none,
|
:none, :auto,
|
||||||
:auto,
|
:circle, :rect, :diamond,
|
||||||
:circle,
|
:cross, :xcross,
|
||||||
:rect,
|
:utriangle, :dtriangle, :rtriangle, :ltriangle,
|
||||||
:diamond,
|
:pentagon, :hexagon, :heptagon, :octagon,
|
||||||
# :hexagon,
|
:star4, :star5, :star6, :star7, :star8,
|
||||||
:cross,
|
:vline, :hline, :+, :x,
|
||||||
:xcross,
|
|
||||||
:utriangle,
|
|
||||||
:dtriangle,
|
|
||||||
:rtriangle,
|
|
||||||
:ltriangle,
|
|
||||||
# :pentagon,
|
|
||||||
# :heptagon,
|
|
||||||
# :octagon,
|
|
||||||
# :star4,
|
|
||||||
# :star5,
|
|
||||||
# :star6,
|
|
||||||
# :star7,
|
|
||||||
:star8,
|
|
||||||
# :vline,
|
|
||||||
# :hline,
|
|
||||||
:+,
|
|
||||||
:x,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const _inspectdr_scale = [:identity, :ln, :log2, :log10] #Does not really support ln, (plot using log10 instead).
|
const _inspectdr_scale = [:identity, :ln, :log2, :log10]
|
||||||
|
|
||||||
|
is_marker_supported(::InspectDRBackend, shape::Shape) = true
|
||||||
|
|
||||||
#Do we avoid Map to avoid possible pre-comile issues?
|
#Do we avoid Map to avoid possible pre-comile issues?
|
||||||
function _inspectdr_mapglyph(s::Symbol)
|
function _inspectdr_mapglyph(s::Symbol)
|
||||||
s == :rect && return :square
|
s == :rect && return :square
|
||||||
s == :utriangle && return :uarrow
|
|
||||||
s == :dtriangle && return :darrow
|
|
||||||
s == :ltriangle && return :larrow
|
|
||||||
s == :rtriangle && return :rarrow
|
|
||||||
s == :xcross && return :diagcross
|
|
||||||
s == :star8 && return :*
|
|
||||||
|
|
||||||
#= Actually supported:
|
|
||||||
:square, :diamond,
|
|
||||||
:uarrow, :darrow, :larrow, :rarrow, #usually triangles
|
|
||||||
:cross, :+, :diagcross, :x,
|
|
||||||
:circle, :o, :star, :*,
|
|
||||||
=#
|
|
||||||
|
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _inspectdr_mapglyph(s::Shape)
|
||||||
|
x, y = coords(s)
|
||||||
|
return InspectDR.GlyphPolyline(x, y)
|
||||||
|
end
|
||||||
|
|
||||||
# py_marker(markers::AVec) = map(py_marker, markers)
|
# py_marker(markers::AVec) = map(py_marker, markers)
|
||||||
function _inspectdr_mapglyph(markers::AVec)
|
function _inspectdr_mapglyph(markers::AVec)
|
||||||
warn("Vectors of markers are currently unsupported in InspectDR.")
|
warn("Vectors of markers are currently unsupported in InspectDR.")
|
||||||
@ -124,6 +99,25 @@ end
|
|||||||
#Hack: suggested point size does not seem adequate relative to plot size, for some reason.
|
#Hack: suggested point size does not seem adequate relative to plot size, for some reason.
|
||||||
_inspectdr_mapptsize(v) = 1.5*v
|
_inspectdr_mapptsize(v) = 1.5*v
|
||||||
|
|
||||||
|
function _inspectdr_add_annotations(plot, x, y, val)
|
||||||
|
#What kind of annotation is this?
|
||||||
|
end
|
||||||
|
|
||||||
|
#plot::InspectDR.Plot2D
|
||||||
|
function _inspectdr_add_annotations(plot, x, y, val::PlotText)
|
||||||
|
vmap = Dict{Symbol, Symbol}(:top=>:t, :bottom=>:b) #:vcenter
|
||||||
|
hmap = Dict{Symbol, Symbol}(:left=>:l, :right=>:r) #:hcenter
|
||||||
|
align = Symbol(get(vmap, val.font.valign, :c), get(hmap, val.font.halign, :c))
|
||||||
|
fnt = InspectDR.Font(val.font.family, val.font.pointsize,
|
||||||
|
color =_inspectdr_mapcolor(val.font.color)
|
||||||
|
)
|
||||||
|
ann = InspectDR.atext(val.str, x=x, y=y,
|
||||||
|
font=fnt, angle=val.font.rotation, align=align
|
||||||
|
)
|
||||||
|
InspectDR.add(plot, ann)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
#InspectDR-dependent structures and method signatures.
|
#InspectDR-dependent structures and method signatures.
|
||||||
#(To be evalutated only once ready to load module)
|
#(To be evalutated only once ready to load module)
|
||||||
@ -132,6 +126,11 @@ const _inspectdr_depcode = quote
|
|||||||
import InspectDR
|
import InspectDR
|
||||||
export InspectDR
|
export InspectDR
|
||||||
|
|
||||||
|
#Glyph used when plotting "Shape"s:
|
||||||
|
const INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline(
|
||||||
|
2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y
|
||||||
|
)
|
||||||
|
|
||||||
type InspectDRPlotEnv
|
type InspectDRPlotEnv
|
||||||
#Stores reference to active plot GUI:
|
#Stores reference to active plot GUI:
|
||||||
cur_gui::Nullable{InspectDR.GtkPlot}
|
cur_gui::Nullable{InspectDR.GtkPlot}
|
||||||
@ -142,13 +141,13 @@ end #_inspectdr_depcode
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function _inspectdr_getscale(s::Symbol)
|
function _inspectdr_getscale(s::Symbol)
|
||||||
#TODO: Support :ln, :asinh, :sqrt
|
#TODO: Support :asinh, :sqrt
|
||||||
if :log2 == s
|
if :log2 == s
|
||||||
return InspectDR.AxisScale(:log2)
|
return InspectDR.AxisScale(:log2)
|
||||||
elseif :log10 == s
|
elseif :log10 == s
|
||||||
return InspectDR.AxisScale(:log10)
|
return InspectDR.AxisScale(:log10)
|
||||||
elseif :ln == s
|
elseif :ln == s
|
||||||
return InspectDR.AxisScale(:log10) #At least it will be a log-plot
|
return InspectDR.AxisScale(:ln)
|
||||||
else #identity
|
else #identity
|
||||||
return InspectDR.AxisScale(:lin)
|
return InspectDR.AxisScale(:lin)
|
||||||
end
|
end
|
||||||
@ -203,7 +202,10 @@ function _initialize_subplot(plt::Plot{InspectDRBackend}, sp::Subplot{InspectDRB
|
|||||||
#Don't do anything without a "subplot" object: Will process later.
|
#Don't do anything without a "subplot" object: Will process later.
|
||||||
if nothing == plot; return; end
|
if nothing == plot; return; end
|
||||||
plot.data = []
|
plot.data = []
|
||||||
|
plot.markers = [] #Clear old markers
|
||||||
|
plot.atext = [] #Clear old annotation
|
||||||
|
plot.apline = [] #Clear old poly lines
|
||||||
|
|
||||||
return plot
|
return plot
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -235,10 +237,44 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
|
|||||||
#= TODO: Eventually support
|
#= TODO: Eventually support
|
||||||
series[:fillcolor] #I think this is fill under line
|
series[:fillcolor] #I think this is fill under line
|
||||||
zorder = series[:series_plotindex]
|
zorder = series[:series_plotindex]
|
||||||
|
|
||||||
|
For st in :shape:
|
||||||
|
zorder = series[:series_plotindex],
|
||||||
=#
|
=#
|
||||||
|
|
||||||
#TODO: scale width & sizes
|
if st in (:shape,)
|
||||||
if st in (:path, :scatter) #, :steppre, :steppost)
|
nmax = 0
|
||||||
|
for (i,rng) in enumerate(iter_segments(x, y))
|
||||||
|
nmax = i
|
||||||
|
if length(rng) > 1
|
||||||
|
linewidth = series[:linewidth]
|
||||||
|
linecolor = _inspectdr_mapcolor(cycle(series[:linecolor], i))
|
||||||
|
fillcolor = _inspectdr_mapcolor(cycle(series[:fillcolor], i))
|
||||||
|
line = InspectDR.line(
|
||||||
|
style=:solid, width=linewidth, color=linecolor
|
||||||
|
)
|
||||||
|
apline = InspectDR.PolylineAnnotation(
|
||||||
|
x[rng], y[rng], line=line, fillcolor=fillcolor
|
||||||
|
)
|
||||||
|
push!(plot.apline, apline)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
i = (nmax >= 2? div(nmax, 2): nmax) #Must pick one set of colors for legend
|
||||||
|
if i > 1 #Add dummy waveform for legend entry:
|
||||||
|
linewidth = series[:linewidth]
|
||||||
|
linecolor = _inspectdr_mapcolor(cycle(series[:linecolor], i))
|
||||||
|
fillcolor = _inspectdr_mapcolor(cycle(series[:fillcolor], i))
|
||||||
|
wfrm = InspectDR.add(plot, Float64[], Float64[], id=series[:label])
|
||||||
|
wfrm.line = InspectDR.line(
|
||||||
|
style=:none, width=linewidth, #linewidth affects glyph
|
||||||
|
)
|
||||||
|
wfrm.glyph = InspectDR.glyph(
|
||||||
|
shape = INSPECTDR_GLYPH_SHAPE, size = 8,
|
||||||
|
color = linecolor, fillcolor = fillcolor
|
||||||
|
)
|
||||||
|
end
|
||||||
|
elseif st in (:path, :scatter) #, :steppre, :steppost)
|
||||||
#NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think).
|
#NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think).
|
||||||
linewidth = series[:linewidth]
|
linewidth = series[:linewidth]
|
||||||
#More efficient & allows some support for markerstrokewidth:
|
#More efficient & allows some support for markerstrokewidth:
|
||||||
@ -261,6 +297,12 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series)
|
|||||||
fillcolor = _inspectdr_mapcolor(series[:markercolor]),
|
fillcolor = _inspectdr_mapcolor(series[:markercolor]),
|
||||||
)
|
)
|
||||||
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)
|
||||||
|
_inspectdr_add_annotations(plot, xi, yi, PlotText(str, fnt))
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -285,7 +327,6 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
|||||||
plot.axes = InspectDR.AxesRect(xscale, yscale)
|
plot.axes = InspectDR.AxesRect(xscale, yscale)
|
||||||
xmin, xmax = axis_limits(xaxis)
|
xmin, xmax = axis_limits(xaxis)
|
||||||
ymin, ymax = axis_limits(yaxis)
|
ymin, ymax = axis_limits(yaxis)
|
||||||
#TODO: not sure which extents we should be modifying.
|
|
||||||
plot.ext = InspectDR.PExtents2D() #reset
|
plot.ext = InspectDR.PExtents2D() #reset
|
||||||
plot.ext_full = InspectDR.PExtents2D(xmin, xmax, ymin, ymax)
|
plot.ext_full = InspectDR.PExtents2D(xmin, xmax, ymin, ymax)
|
||||||
a = plot.annotation
|
a = plot.annotation
|
||||||
@ -293,20 +334,31 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
|||||||
a.xlabel = xaxis[:guide]; a.ylabel = yaxis[:guide]
|
a.xlabel = xaxis[:guide]; a.ylabel = yaxis[:guide]
|
||||||
|
|
||||||
l = plot.layout
|
l = plot.layout
|
||||||
l.fnttitle.name = sp[:titlefont].family
|
l.framedata.fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
|
||||||
l.fnttitle._size = _inspectdr_mapptsize(sp[:titlefont].pointsize)
|
l.framedata.line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
|
||||||
|
l.fnttitle = InspectDR.Font(sp[:titlefont].family,
|
||||||
|
_inspectdr_mapptsize(sp[:titlefont].pointsize),
|
||||||
|
color = _inspectdr_mapcolor(sp[:foreground_color_title])
|
||||||
|
)
|
||||||
#Cannot independently control fonts of axes with InspectDR:
|
#Cannot independently control fonts of axes with InspectDR:
|
||||||
l.fntaxlabel.name = xaxis[:guidefont].family
|
l.fntaxlabel = InspectDR.Font(xaxis[:guidefont].family,
|
||||||
l.fntaxlabel._size = _inspectdr_mapptsize(xaxis[:guidefont].pointsize)
|
_inspectdr_mapptsize(xaxis[:guidefont].pointsize),
|
||||||
l.fntticklabel.name = xaxis[:tickfont].family
|
color = _inspectdr_mapcolor(xaxis[:foreground_color_guide])
|
||||||
l.fntticklabel._size = _inspectdr_mapptsize(xaxis[:tickfont].pointsize)
|
)
|
||||||
|
l.fntticklabel = InspectDR.Font(xaxis[:tickfont].family,
|
||||||
|
_inspectdr_mapptsize(xaxis[:tickfont].pointsize),
|
||||||
|
color = _inspectdr_mapcolor(xaxis[:foreground_color_text])
|
||||||
|
)
|
||||||
#No independent control of grid???
|
#No independent control of grid???
|
||||||
l.grid = sp[:grid]? gridon: gridoff
|
l.grid = sp[:grid]? gridon: gridoff
|
||||||
leg = l.legend
|
leg = l.legend
|
||||||
leg.enabled = (sp[:legend] != :none)
|
leg.enabled = (sp[:legend] != :none)
|
||||||
#leg.width = 150 #TODO: compute???
|
#leg.width = 150 #TODO: compute???
|
||||||
leg.font.name = sp[:legendfont].family
|
leg.font = InspectDR.Font(sp[:legendfont].family,
|
||||||
leg.font._size = _inspectdr_mapptsize(sp[:legendfont].pointsize)
|
_inspectdr_mapptsize(sp[:legendfont].pointsize),
|
||||||
|
color = _inspectdr_mapcolor(sp[:foreground_color_legend])
|
||||||
|
)
|
||||||
|
leg.frame.fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
|
||||||
end
|
end
|
||||||
|
|
||||||
# called just before updating layout bounding boxes... in case you need to prep
|
# called just before updating layout bounding boxes... in case you need to prep
|
||||||
@ -322,11 +374,21 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend})
|
|||||||
sp.o = mplot.subplots[i]
|
sp.o = mplot.subplots[i]
|
||||||
_initialize_subplot(plt, sp)
|
_initialize_subplot(plt, sp)
|
||||||
_inspectdr_setupsubplot(sp)
|
_inspectdr_setupsubplot(sp)
|
||||||
|
|
||||||
|
sp.o.layout.frame.fillcolor =
|
||||||
|
_inspectdr_mapcolor(plt[:background_color_outside])
|
||||||
|
|
||||||
|
# add the annotations
|
||||||
|
for ann in sp[:annotations]
|
||||||
|
_inspectdr_add_annotations(mplot.subplots[i], ann...)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#Do not yet support absolute plot positionning.
|
#Do not yet support absolute plot positionning.
|
||||||
#Just try to make things look more-or less ok:
|
#Just try to make things look more-or less ok:
|
||||||
if nsubplots <= 4
|
if nsubplots <= 1
|
||||||
|
mplot.ncolumns = 1
|
||||||
|
elseif nsubplots <= 4
|
||||||
mplot.ncolumns = 2
|
mplot.ncolumns = 2
|
||||||
elseif nsubplots <= 6
|
elseif nsubplots <= 6
|
||||||
mplot.ncolumns = 3
|
mplot.ncolumns = 3
|
||||||
@ -377,7 +439,7 @@ const _inspectdr_mimeformats_nodpi = Dict(
|
|||||||
"image/svg+xml" => "svg",
|
"image/svg+xml" => "svg",
|
||||||
"application/eps" => "eps",
|
"application/eps" => "eps",
|
||||||
"image/eps" => "eps",
|
"image/eps" => "eps",
|
||||||
# "application/postscript" => "ps", #TODO: support
|
# "application/postscript" => "ps", #TODO: support once Cairo supports PSSurface
|
||||||
"application/pdf" => "pdf"
|
"application/pdf" => "pdf"
|
||||||
)
|
)
|
||||||
_inspectdr_show(io::IO, mime::MIME, ::Void) =
|
_inspectdr_show(io::IO, mime::MIME, ::Void) =
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user