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) function plotlyfont(font::Font, color = font.color)
KW( KW(
:family => font.family, :family => font.family,
@ -189,6 +178,29 @@ function get_annotation_dict(x, y, ptxt::PlotText)
)) ))
end 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) function plotlyscale(scale::Symbol)
if scale == :log10 if scale == :log10
"log" "log"
@ -263,58 +275,72 @@ end
# function get_plot_json(plt::Plot{PlotlyBackend}) # function get_plot_json(plt::Plot{PlotlyBackend})
# d = plt.plotargs # d = plt.plotargs
function plotly_layout(d::KW) function plotly_layout(d::KW, seriesargs::AVec{KW})
d_out = 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]) bgcolor = webcolor(d[:background_color])
fgcolor = webcolor(d[:foreground_color]) fgcolor = webcolor(d[:foreground_color])
# set the fields for the plot # set the fields for the plot
d_out[:title] = d[:title] d_out[:title] = d[:title]
d_out[:titlefont] = plotlyfont(d[:guidefont], fgcolor) d_out[:titlefont] = plotlyfont(d[:guidefont], fgcolor)
d_out[:margin] = KW(:l=>35, :b=>30, :r=>8, :t=>20) d_out[:margin] = KW(:l=>35, :b=>30, :r=>8, :t=>20)
d_out[:plot_bgcolor] = bgcolor d_out[:plot_bgcolor] = bgcolor
d_out[:paper_bgcolor] = bgcolor d_out[:paper_bgcolor] = bgcolor
# TODO: x/y axis tick values/labels # TODO: x/y axis tick values/labels
if is3d(d) if any(is3d, seriesargs)
d_out[:scene] = KW( d_out[:scene] = KW(
:xaxis => plotlyaxis(d, "x"), :xaxis => plotlyaxis(d, "x"),
:yaxis => plotlyaxis(d, "y"), :yaxis => plotlyaxis(d, "y"),
:xzxis => plotlyaxis(d, "z"), :xzxis => plotlyaxis(d, "z"),
) )
else else
d_out[:xaxis] = plotlyaxis(d, "x") d_out[:xaxis] = plotlyaxis(d, "x")
d_out[:yaxis] = plotlyaxis(d, "y") d_out[:yaxis] = plotlyaxis(d, "y")
end end
# legend # legend
d_out[:showlegend] = d[:legend] != :none d_out[:showlegend] = d[:legend] != :none
if d[:legend] != :none if d[:legend] != :none
d_out[:legend] = KW( d_out[:legend] = KW(
:bgcolor => bgcolor, :bgcolor => bgcolor,
:bordercolor => fgcolor, :bordercolor => fgcolor,
:font => plotlyfont(d[:legendfont]), :font => plotlyfont(d[:legendfont]),
) )
end end
# annotations # annotations
anns = get(d, :annotation_list, []) anns = get(d, :annotation_list, [])
if !isempty(anns) d_out[:annotations] = if isempty(anns)
d_out[:annotations] = [get_annotation_dict(ann...) for ann in anns] KW[]
end else
KW[get_annotation_dict(ann...) for ann in anns]
end
if get(d, :polar, false) # # arrows
d_out[:direction] = "counterclockwise" # for sargs in seriesargs
end # 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 end
function get_plot_json(plt::Plot{PlotlyBackend}) function get_plot_json(plt::Plot{PlotlyBackend})
JSON.json(plotly_layout(plt.plotargs)) JSON.json(plotly_layout(plt.plotargs, plt.seriesargs))
end end

View File

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

View File

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

View File

@ -433,6 +433,20 @@ function arrow(args...)
end 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
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------