add_arrows function; plotly cleanup and arrows attempt

This commit is contained in:
Thomas Breloff 2016-05-10 17:22:47 -04:00
parent baf410c712
commit a0ca9d675f
4 changed files with 104 additions and 75 deletions

View File

@ -150,17 +150,6 @@ end
# ----------------------------------------------------------------
# TODO:
# _plotDefaults[:yrightlabel] = ""
# _plotDefaults[:xlims] = :auto
# _plotDefaults[:ylims] = :auto
# _plotDefaults[:xticks] = :auto
# _plotDefaults[:yticks] = :auto
# _plotDefaults[:xscale] = :identity
# _plotDefaults[:yscale] = :identity
# _plotDefaults[:xflip] = false
# _plotDefaults[:yflip] = false
function plotlyfont(font::Font, color = font.color)
KW(
:family => font.family,
@ -189,6 +178,29 @@ function get_annotation_dict(x, y, ptxt::PlotText)
))
end
# function get_annotation_dict_for_arrow(d::KW, xyprev::Tuple, xy::Tuple, a::Arrow)
# xdiff = xyprev[1] - xy[1]
# ydiff = xyprev[2] - xy[2]
# dist = sqrt(xdiff^2 + ydiff^2)
# KW(
# :showarrow => true,
# :x => xy[1],
# :y => xy[2],
# # :ax => xyprev[1] - xy[1],
# # :ay => xy[2] - xyprev[2],
# # :ax => 0,
# # :ay => -40,
# :ax => 10xdiff / dist,
# :ay => -10ydiff / dist,
# :arrowcolor => webcolor(d[:linecolor], d[:linealpha]),
# :xref => "x",
# :yref => "y",
# :arrowsize => 10a.headwidth,
# # :arrowwidth => a.headlength,
# :arrowwidth => 0.1,
# )
# end
function plotlyscale(scale::Symbol)
if scale == :log10
"log"
@ -263,58 +275,72 @@ end
# function get_plot_json(plt::Plot{PlotlyBackend})
# d = plt.plotargs
function plotly_layout(d::KW)
d_out = KW()
function plotly_layout(d::KW, seriesargs::AVec{KW})
d_out = KW()
d_out[:width], d_out[:height] = d[:size]
d_out[:width], d_out[:height] = d[:size]
bgcolor = webcolor(d[:background_color])
fgcolor = webcolor(d[:foreground_color])
bgcolor = webcolor(d[:background_color])
fgcolor = webcolor(d[:foreground_color])
# set the fields for the plot
d_out[:title] = d[:title]
d_out[:titlefont] = plotlyfont(d[:guidefont], fgcolor)
d_out[:margin] = KW(:l=>35, :b=>30, :r=>8, :t=>20)
d_out[:plot_bgcolor] = bgcolor
d_out[:paper_bgcolor] = bgcolor
# set the fields for the plot
d_out[:title] = d[:title]
d_out[:titlefont] = plotlyfont(d[:guidefont], fgcolor)
d_out[:margin] = KW(:l=>35, :b=>30, :r=>8, :t=>20)
d_out[:plot_bgcolor] = bgcolor
d_out[:paper_bgcolor] = bgcolor
# TODO: x/y axis tick values/labels
if is3d(d)
d_out[:scene] = KW(
:xaxis => plotlyaxis(d, "x"),
:yaxis => plotlyaxis(d, "y"),
:xzxis => plotlyaxis(d, "z"),
)
else
d_out[:xaxis] = plotlyaxis(d, "x")
d_out[:yaxis] = plotlyaxis(d, "y")
end
# TODO: x/y axis tick values/labels
if any(is3d, seriesargs)
d_out[:scene] = KW(
:xaxis => plotlyaxis(d, "x"),
:yaxis => plotlyaxis(d, "y"),
:xzxis => plotlyaxis(d, "z"),
)
else
d_out[:xaxis] = plotlyaxis(d, "x")
d_out[:yaxis] = plotlyaxis(d, "y")
end
# legend
d_out[:showlegend] = d[:legend] != :none
if d[:legend] != :none
d_out[:legend] = KW(
:bgcolor => bgcolor,
:bordercolor => fgcolor,
:font => plotlyfont(d[:legendfont]),
)
end
# legend
d_out[:showlegend] = d[:legend] != :none
if d[:legend] != :none
d_out[:legend] = KW(
:bgcolor => bgcolor,
:bordercolor => fgcolor,
:font => plotlyfont(d[:legendfont]),
)
end
# annotations
anns = get(d, :annotation_list, [])
if !isempty(anns)
d_out[:annotations] = [get_annotation_dict(ann...) for ann in anns]
end
# annotations
anns = get(d, :annotation_list, [])
d_out[:annotations] = if isempty(anns)
KW[]
else
KW[get_annotation_dict(ann...) for ann in anns]
end
if get(d, :polar, false)
d_out[:direction] = "counterclockwise"
end
# # arrows
# for sargs in seriesargs
# a = sargs[:arrow]
# if sargs[:linetype] in (:path, :line) && typeof(a) <: Arrow
# add_arrows(sargs[:x], sargs[:y]) do xyprev, xy
# push!(d_out[:annotations], get_annotation_dict_for_arrow(sargs, xyprev, xy, a))
# end
# end
# end
# dumpdict(d_out,"",true)
# @show d_out[:annotations]
d_out
if get(d, :polar, false)
d_out[:direction] = "counterclockwise"
end
d_out
end
function get_plot_json(plt::Plot{PlotlyBackend})
JSON.json(plotly_layout(plt.plotargs))
JSON.json(plotly_layout(plt.plotargs, plt.seriesargs))
end

View File

@ -141,7 +141,7 @@ end
# TODO: override this to update plot items (title, xlabel, etc) after creation
function _update_plot(plt::Plot{PlotlyJSBackend}, d::KW)
pdict = plotly_layout(d)
pdict = plotly_layout(plt.plotargs, plt.seriesargs)
syncplot = plt.o
w,h = d[:size]
PlotlyJS.relayout!(syncplot, pdict, width = w, height = h)

View File

@ -421,37 +421,26 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW)
)[1]
push!(handles, handle)
if d[:arrow] != nothing
if !is3d(d) # TODO: handle 3d later
n = length(x)
a = d[:arrow]
@assert typeof(a) == Arrow
a = d[:arrow]
if a != nothing && !is3d(d) # TODO: handle 3d later
if typeof(a) != Arrow
warn("Unexpected type for arrow: $(typeof(a))")
else
arrowprops = KW(
# :arrowstyle => (a.style == :open ? "->" : (a.style == :closed ? "-|>" : string(a.style))),
:arrowstyle => "simple,head_length=$(a.headlength),head_width=$(a.headwidth)",
# :arrowstyle => "simple",
:shrinkA => 0,
:shrinkB => 0,
:edgecolor => pylinecolor(d),
:facecolor => pylinecolor(d),
:linewidth => d[:linewidth],
:linestyle => getPyPlotLineStyle(lt, d[:linestyle]),
# :head_length => a.headlength,
# :head_width => a.headwidth,
)
for i=2:n
xystart = (x[i-1], y[i-1])
xyend = (x[i], y[i])
if ok(xystart) && ok(xyend)
if i==n || !ok(x[i+1], y[i+1])
# add the arrow from xystart to xyend
ax[:annotate]("",
xytext = (0.001xystart[1] + 0.999xyend[1], 0.001xystart[2] + 0.999xyend[2]),
xy = xyend,
arrowprops = arrowprops
)
end
end
add_arrows(x, y) do xyprev, xy
ax[:annotate]("",
xytext = (0.001xyprev[1] + 0.999xy[1], 0.001xyprev[2] + 0.999xy[2]),
xy = xy,
arrowprops = arrowprops
)
end
end
end

View File

@ -433,6 +433,20 @@ function arrow(args...)
end
# allow for do-block notation which gets called on every valid start/end pair which
# we need to draw an arrow
function add_arrows(func::Function, x::AVec, y::AVec)
for i=2:length(x)
xyprev = (x[i-1], y[i-1])
xy = (x[i], y[i])
if ok(xyprev) && ok(xy)
if i==length(x) || !ok(x[i+1], y[i+1])
# add the arrow from xyprev to xy
func(xyprev, xy)
end
end
end
end
# -----------------------------------------------------------------------