fixes/improvements to annotations; added series_annotations keyword
This commit is contained in:
parent
333c2765fe
commit
862ac3af8a
@ -159,6 +159,7 @@ _series_defaults[:contours] = false # add contours to 3d surface an
|
|||||||
_series_defaults[:match_dimensions] = false # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196
|
_series_defaults[:match_dimensions] = false # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196
|
||||||
# this ONLY effects whether or not the z-matrix is transposed for a heatmap display!
|
# this ONLY effects whether or not the z-matrix is transposed for a heatmap display!
|
||||||
_series_defaults[:subplot] = :auto # which subplot(s) does this series belong to?
|
_series_defaults[:subplot] = :auto # which subplot(s) does this series belong to?
|
||||||
|
_series_defaults[:series_annotations] = [] # a list of annotations which apply to the coordinates of this series
|
||||||
|
|
||||||
|
|
||||||
const _plot_defaults = KW()
|
const _plot_defaults = KW()
|
||||||
@ -199,7 +200,7 @@ _subplot_defaults[:legend] = :best
|
|||||||
_subplot_defaults[:colorbar] = :legend
|
_subplot_defaults[:colorbar] = :legend
|
||||||
_subplot_defaults[:legendfont] = font(8)
|
_subplot_defaults[:legendfont] = font(8)
|
||||||
_subplot_defaults[:grid] = true
|
_subplot_defaults[:grid] = true
|
||||||
_subplot_defaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation)
|
_subplot_defaults[:annotations] = [] # annotation tuples... list of (x,y,annotation)
|
||||||
# _subplot_defaults[:polar] = false
|
# _subplot_defaults[:polar] = false
|
||||||
_subplot_defaults[:projection] = :none # can also be :polar or :3d
|
_subplot_defaults[:projection] = :none # can also be :polar or :3d
|
||||||
_subplot_defaults[:aspect_ratio] = :none # choose from :none or :equal
|
_subplot_defaults[:aspect_ratio] = :none # choose from :none or :equal
|
||||||
@ -346,7 +347,7 @@ add_aliases(:fillrange, :fillrng, :frange, :fillto, :fill_between)
|
|||||||
add_aliases(:group, :g, :grouping)
|
add_aliases(:group, :g, :grouping)
|
||||||
add_aliases(:bins, :bin, :nbin, :nbins, :nb)
|
add_aliases(:bins, :bin, :nbin, :nbins, :nb)
|
||||||
add_aliases(:ribbon, :rib)
|
add_aliases(:ribbon, :rib)
|
||||||
add_aliases(:annotation, :ann, :anns, :annotate, :annotations)
|
add_aliases(:annotations, :ann, :anns, :annotate, :annotation)
|
||||||
add_aliases(:xguide, :xlabel, :xlab, :xl)
|
add_aliases(:xguide, :xlabel, :xlab, :xl)
|
||||||
add_aliases(:xlims, :xlim, :xlimit, :xlimits)
|
add_aliases(:xlims, :xlim, :xlimit, :xlimits)
|
||||||
add_aliases(:xticks, :xtick)
|
add_aliases(:xticks, :xtick)
|
||||||
@ -385,6 +386,7 @@ add_aliases(:match_dimensions, :transpose, :transpose_z)
|
|||||||
add_aliases(:subplot, :sp, :subplt, :splt)
|
add_aliases(:subplot, :sp, :subplt, :splt)
|
||||||
add_aliases(:projection, :proj)
|
add_aliases(:projection, :proj)
|
||||||
add_aliases(:title_location, :title_loc, :titleloc)
|
add_aliases(:title_location, :title_loc, :titleloc)
|
||||||
|
add_aliases(:series_annotations, :series_ann, :seriesann, :series_anns, :seriesanns, :series_annotation)
|
||||||
|
|
||||||
|
|
||||||
# add all pluralized forms to the _keyAliases dict
|
# add all pluralized forms to the _keyAliases dict
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
supportedArgs(::BokehBackend) = [
|
supportedArgs(::BokehBackend) = [
|
||||||
# :annotation,
|
# :annotations,
|
||||||
# :axis,
|
# :axis,
|
||||||
# :background_color,
|
# :background_color,
|
||||||
:linecolor,
|
:linecolor,
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
supportedArgs(::GadflyBackend) = [
|
supportedArgs(::GadflyBackend) = [
|
||||||
:annotation,
|
:annotations,
|
||||||
:background_color, :foreground_color, :color_palette,
|
:background_color, :foreground_color, :color_palette,
|
||||||
:group, :label, :seriestype,
|
:group, :label, :seriestype,
|
||||||
:seriescolor, :seriesalpha,
|
:seriescolor, :seriesalpha,
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
# [WEBSITE]
|
# [WEBSITE]
|
||||||
|
|
||||||
supportedArgs(::GLVisualizeBackend) = [
|
supportedArgs(::GLVisualizeBackend) = [
|
||||||
# :annotation,
|
# :annotations,
|
||||||
# :axis,
|
# :axis,
|
||||||
# :background_color,
|
# :background_color,
|
||||||
# :color_palette,
|
# :color_palette,
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
supportedArgs(::GRBackend) = [
|
supportedArgs(::GRBackend) = [
|
||||||
:annotation,
|
:annotations,
|
||||||
:background_color, :foreground_color, :color_palette,
|
:background_color, :foreground_color, :color_palette,
|
||||||
:background_color_legend, :background_color_inside, :background_color_outside,
|
:background_color_legend, :background_color_inside, :background_color_outside,
|
||||||
:foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
|
:foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
# https://plot.ly/javascript/getting-started
|
# https://plot.ly/javascript/getting-started
|
||||||
|
|
||||||
supportedArgs(::PlotlyBackend) = [
|
supportedArgs(::PlotlyBackend) = [
|
||||||
:annotation,
|
:annotations,
|
||||||
:background_color, :foreground_color, :color_palette,
|
:background_color, :foreground_color, :color_palette,
|
||||||
# :background_color_legend, :background_color_inside, :background_color_outside,
|
# :background_color_legend, :background_color_inside, :background_color_outside,
|
||||||
# :foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
|
# :foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
supportedArgs(::PyPlotBackend) = [
|
supportedArgs(::PyPlotBackend) = [
|
||||||
:annotation,
|
:annotations,
|
||||||
:background_color, :foreground_color, :color_palette,
|
:background_color, :foreground_color, :color_palette,
|
||||||
:background_color_legend, :background_color_inside, :background_color_outside,
|
:background_color_legend, :background_color_inside, :background_color_outside,
|
||||||
:foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
|
:foreground_color_legend, :foreground_color_grid, :foreground_color_axis,
|
||||||
@ -1153,6 +1153,11 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW)
|
|||||||
# ticksz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize
|
# ticksz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize
|
||||||
# guidesz = get(d, :guidefont, attr[:guidefont]).pointsize
|
# guidesz = get(d, :guidefont, attr[:guidefont]).pointsize
|
||||||
|
|
||||||
|
# add the annotations
|
||||||
|
for ann in attr[:annotations]
|
||||||
|
createPyPlotAnnotationObject(sp, ann...)
|
||||||
|
end
|
||||||
|
|
||||||
# title
|
# title
|
||||||
if haskey(attr, :title)
|
if haskey(attr, :title)
|
||||||
loc = lowercase(string(attr[:title_location]))
|
loc = lowercase(string(attr[:title_location]))
|
||||||
@ -1252,28 +1257,28 @@ end
|
|||||||
|
|
||||||
# TODO: these should apply to a Subplot, NOT a Plot
|
# TODO: these should apply to a Subplot, NOT a Plot
|
||||||
|
|
||||||
# function createPyPlotAnnotationObject(plt::Plot{PyPlotBackend}, x, y, val::@compat(AbstractString))
|
function createPyPlotAnnotationObject(sp::Subplot{PyPlotBackend}, x, y, val::@compat(AbstractString))
|
||||||
# ax = getLeftAxis(plt)
|
ax = sp.o
|
||||||
# ax[:annotate](val, xy = (x,y))
|
ax[:annotate](val, xy = (x,y))
|
||||||
# end
|
end
|
||||||
#
|
|
||||||
#
|
|
||||||
# function createPyPlotAnnotationObject(plt::Plot{PyPlotBackend}, x, y, val::PlotText)
|
function createPyPlotAnnotationObject(sp::Subplot{PyPlotBackend}, x, y, val::PlotText)
|
||||||
# ax = getLeftAxis(plt)
|
ax = sp.o
|
||||||
# ax[:annotate](val.str,
|
ax[:annotate](val.str,
|
||||||
# xy = (x,y),
|
xy = (x,y),
|
||||||
# family = val.font.family,
|
family = val.font.family,
|
||||||
# color = getPyPlotColor(val.font.color),
|
color = getPyPlotColor(val.font.color),
|
||||||
# horizontalalignment = val.font.halign == :hcenter ? "center" : string(val.font.halign),
|
horizontalalignment = val.font.halign == :hcenter ? "center" : string(val.font.halign),
|
||||||
# verticalalignment = val.font.valign == :vcenter ? "center" : string(val.font.valign),
|
verticalalignment = val.font.valign == :vcenter ? "center" : string(val.font.valign),
|
||||||
# rotation = val.font.rotation * 180 / π,
|
rotation = val.font.rotation * 180 / π,
|
||||||
# size = val.font.pointsize
|
size = val.font.pointsize
|
||||||
# )
|
)
|
||||||
# end
|
end
|
||||||
#
|
|
||||||
# function _add_annotations{X,Y,V}(plt::Plot{PyPlotBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
# function _add_annotations(sp::Subplot{PyPlotBackend}, anns::AVec)
|
||||||
# for ann in anns
|
# for ann in anns
|
||||||
# createPyPlotAnnotationObject(plt, ann...)
|
# createPyPlotAnnotationObject(sp, ann...)
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
supportedArgs(::QwtBackend) = [
|
supportedArgs(::QwtBackend) = [
|
||||||
:annotation,
|
:annotations,
|
||||||
:axis,
|
:axis,
|
||||||
:background_color,
|
:background_color,
|
||||||
:linecolor,
|
:linecolor,
|
||||||
|
|||||||
@ -24,11 +24,11 @@ function _add_series(plt::Plot{[PkgName]Backend}, series::Series)
|
|||||||
# TODO: add one series to the underlying package
|
# TODO: add one series to the underlying package
|
||||||
end
|
end
|
||||||
|
|
||||||
function _add_annotations{X,Y,V}(plt::Plot{[PkgName]AbstractBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
# function _add_annotations{X,Y,V}(plt::Plot{[PkgName]AbstractBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||||
for ann in anns
|
# for ann in anns
|
||||||
# TODO: add the annotation to the plot
|
# # TODO: add the annotation to the plot
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
@ -61,13 +61,13 @@ end
|
|||||||
# # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
|
# # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
|
||||||
# end
|
# end
|
||||||
|
|
||||||
function _expand_limits(lims, plt::Plot{[PkgName]AbstractBackend}, isx::Bool)
|
# function _expand_limits(lims, plt::Plot{[PkgName]AbstractBackend}, isx::Bool)
|
||||||
# TODO: call expand limits for each plot data
|
# # TODO: call expand limits for each plot data
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
function _remove_axis(plt::Plot{[PkgName]AbstractBackend}, isx::Bool)
|
# function _remove_axis(plt::Plot{[PkgName]AbstractBackend}, isx::Bool)
|
||||||
# TODO: if plot is inner subplot, might need to remove ticks or axis labels
|
# # TODO: if plot is inner subplot, might need to remove ticks or axis labels
|
||||||
end
|
# end
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
# https://github.com/Evizero/UnicodePlots.jl
|
# https://github.com/Evizero/UnicodePlots.jl
|
||||||
|
|
||||||
supportedArgs(::UnicodePlotsBackend) = [
|
supportedArgs(::UnicodePlotsBackend) = [
|
||||||
# :annotation,
|
# :annotations,
|
||||||
# :args,
|
# :args,
|
||||||
# :axis,
|
# :axis,
|
||||||
# :background_color,
|
# :background_color,
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
# credit goes to https://github.com/jverzani for contributing to the first draft of this backend implementation
|
# credit goes to https://github.com/jverzani for contributing to the first draft of this backend implementation
|
||||||
|
|
||||||
supportedArgs(::WinstonBackend) = [
|
supportedArgs(::WinstonBackend) = [
|
||||||
:annotation,
|
:annotations,
|
||||||
# :args,
|
# :args,
|
||||||
# :axis,
|
# :axis,
|
||||||
# :background_color,
|
# :background_color,
|
||||||
|
|||||||
@ -252,6 +252,7 @@ immutable PlotText
|
|||||||
end
|
end
|
||||||
PlotText(str) = PlotText(string(str), font())
|
PlotText(str) = PlotText(string(str), font())
|
||||||
|
|
||||||
|
text(t::PlotText) = t
|
||||||
function text(str, args...)
|
function text(str, args...)
|
||||||
PlotText(string(str), font(args...))
|
PlotText(string(str), font(args...))
|
||||||
end
|
end
|
||||||
|
|||||||
104
src/plot.jl
104
src/plot.jl
@ -172,14 +172,14 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
args = tuple(extractGroupArgs(d[:group], args...), args...)
|
args = tuple(extractGroupArgs(d[:group], args...), args...)
|
||||||
end
|
end
|
||||||
|
|
||||||
# initialize the annotations list with what was passed in
|
# # initialize the annotations list with what was passed in
|
||||||
# TODO: there must be cleaner way to handle this!
|
# # TODO: there must be cleaner way to handle this!
|
||||||
anns = annotations(get(d, :annotation, NTuple{3}[]))
|
# anns = annotations(get(d, :annotation, NTuple{3}[]))
|
||||||
if typeof(anns) <: AVec{PlotText}
|
# if typeof(anns) <: AVec{PlotText}
|
||||||
anns = NTuple{3}[]
|
# anns = NTuple{3}[]
|
||||||
else
|
# else
|
||||||
delete!(d, :annotation)
|
# delete!(d, :annotation)
|
||||||
end
|
# end
|
||||||
|
|
||||||
|
|
||||||
# for plotting recipes, swap out the args and update the parameter dictionary
|
# for plotting recipes, swap out the args and update the parameter dictionary
|
||||||
@ -250,12 +250,12 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
|
|
||||||
# !!! note: at this point, kw_list is fully decomposed into individual series... one KW per series !!!
|
# !!! note: at this point, kw_list is fully decomposed into individual series... one KW per series !!!
|
||||||
|
|
||||||
# TODO: move annotations into subplot update
|
# # TODO: move annotations into subplot update
|
||||||
# now include any annotations which were added during recipes
|
# # now include any annotations which were added during recipes
|
||||||
for kw in kw_list
|
# for kw in kw_list
|
||||||
append!(anns, annotations(pop!(kw, :annotation, [])))
|
# append!(anns, annotations(pop!(kw, :annotation, [])))
|
||||||
end
|
# end
|
||||||
# @show anns
|
# # @show anns
|
||||||
|
|
||||||
|
|
||||||
# for kw in kw_list
|
# for kw in kw_list
|
||||||
@ -296,6 +296,18 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
sp = kw[:subplot] = get_subplot(plt, sp)
|
sp = kw[:subplot] = get_subplot(plt, sp)
|
||||||
idx = get_subplot_index(plt, sp)
|
idx = get_subplot_index(plt, sp)
|
||||||
|
|
||||||
|
# strip out series annotations (those which are based on series x/y coords)
|
||||||
|
# and add them to the subplot attr
|
||||||
|
sp_anns = annotations(sp.attr[:annotations])
|
||||||
|
anns = annotations(pop!(kw, :series_annotations, []))
|
||||||
|
if length(anns) > 0
|
||||||
|
x, y = kw[:x], kw[:y]
|
||||||
|
nx, ny, na = map(length, (x,y,anns))
|
||||||
|
n = max(nx, ny, na)
|
||||||
|
anns = [(x[mod1(i,nx)], y[mod1(i,ny)], text(anns[mod1(i,na)])) for i=1:n]
|
||||||
|
end
|
||||||
|
sp.attr[:annotations] = vcat(sp_anns, anns)
|
||||||
|
|
||||||
# we update subplot args in case something like the color palatte is part of the recipe
|
# we update subplot args in case something like the color palatte is part of the recipe
|
||||||
# DD(sp.attr[:xaxis].d, "before USA $i")
|
# DD(sp.attr[:xaxis].d, "before USA $i")
|
||||||
# DD(kw, "kw")
|
# DD(kw, "kw")
|
||||||
@ -319,8 +331,8 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
# DD(sp.attr[:xaxis].d, "after $i")
|
# DD(sp.attr[:xaxis].d, "after $i")
|
||||||
end
|
end
|
||||||
|
|
||||||
# now that we're done adding all the series, add the annotations
|
# # now that we're done adding all the series, add the annotations
|
||||||
_add_annotations(plt, anns)
|
# _add_annotations(plt, anns)
|
||||||
|
|
||||||
# TODO just need to pass plt... and we should do all non-series updates here
|
# TODO just need to pass plt... and we should do all non-series updates here
|
||||||
_update_plot(plt, plt.plotargs)
|
_update_plot(plt, plt.plotargs)
|
||||||
@ -484,38 +496,40 @@ end
|
|||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
annotations(::@compat(Void)) = []
|
annotations(::Void) = []
|
||||||
annotations{X,Y,V}(v::AVec{@compat(Tuple{X,Y,V})}) = v
|
annotations(anns::AVec) = anns
|
||||||
annotations{X,Y,V}(t::@compat(Tuple{X,Y,V})) = [t]
|
annotations(anns) = Any[anns]
|
||||||
annotations(v::AVec{PlotText}) = v
|
# annotations{X,Y,V}(v::AVec{@compat(Tuple{X,Y,V})}) = v
|
||||||
annotations(v::AVec) = map(PlotText, v)
|
# annotations{X,Y,V}(t::@compat(Tuple{X,Y,V})) = [t]
|
||||||
annotations(anns) = error("Expecting a tuple (or vector of tuples) for annotations: ",
|
# annotations(v::AVec{PlotText}) = v
|
||||||
"(x, y, annotation)\n got: $(typeof(anns))")
|
# annotations(v::AVec) = map(PlotText, v)
|
||||||
|
# annotations(anns) = error("Expecting a tuple (or vector of tuples) for annotations: ",
|
||||||
|
# "(x, y, annotation)\n got: $(typeof(anns))")
|
||||||
|
|
||||||
function annotations(plt::Plot, anns)
|
# function annotations(plt::Plot, anns)
|
||||||
anns = annotations(anns)
|
# anns = annotations(anns)
|
||||||
# if we just have a list of PlotText objects, then create (x,y,text) tuples
|
# # if we just have a list of PlotText objects, then create (x,y,text) tuples
|
||||||
if typeof(anns) <: AVec{PlotText}
|
# if typeof(anns) <: AVec{PlotText}
|
||||||
x, y = plt[plt.n]
|
# x, y = plt[plt.n]
|
||||||
anns = Tuple{Float64,Float64,PlotText}[(x[i], y[i], t) for (i,t) in enumerate(anns)]
|
# anns = Tuple{Float64,Float64,PlotText}[(x[i], y[i], t) for (i,t) in enumerate(anns)]
|
||||||
end
|
# end
|
||||||
anns
|
# anns
|
||||||
end
|
# end
|
||||||
|
|
||||||
|
|
||||||
function _add_annotations(plt::Plot, d::KW)
|
# function _add_annotations(plt::Plot, d::KW)
|
||||||
anns = annotations(get(d, :annotation, nothing))
|
# anns = annotations(get(d, :annotation, nothing))
|
||||||
if !isempty(anns)
|
# if !isempty(anns)
|
||||||
|
#
|
||||||
# if we just have a list of PlotText objects, then create (x,y,text) tuples
|
# # if we just have a list of PlotText objects, then create (x,y,text) tuples
|
||||||
if typeof(anns) <: AVec{PlotText}
|
# if typeof(anns) <: AVec{PlotText}
|
||||||
x, y = plt[plt.n]
|
# x, y = plt[plt.n]
|
||||||
anns = Tuple{Float64,Float64,PlotText}[(x[i], y[i], t) for (i,t) in enumerate(anns)]
|
# anns = Tuple{Float64,Float64,PlotText}[(x[i], y[i], t) for (i,t) in enumerate(anns)]
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
_add_annotations(plt, anns)
|
# _add_annotations(plt, anns)
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user