From cf635cbdd98a0eaec4279c966e83237ca0718485 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Tue, 24 May 2016 12:20:03 -0400 Subject: [PATCH] renamed plotargs to attr; working on plotly backend --- src/args.jl | 30 +- src/backends.jl | 11 +- src/backends/bokeh.jl | 12 +- src/backends/gadfly.jl | 24 +- src/backends/glvisualize.jl | 2 +- src/backends/gr.jl | 12 +- src/backends/immerse.jl | 10 +- src/backends/pgfplots.jl | 14 +- src/backends/plotly.jl | 603 +++++++++++++++++------------------ src/backends/plotlyjs.jl | 14 +- src/backends/pyplot.jl | 16 +- src/backends/qwt.jl | 10 +- src/backends/unicodeplots.jl | 12 +- src/backends/web.jl | 6 +- src/backends/winston.jl | 14 +- src/colors.jl | 8 +- src/plot.jl | 19 +- src/recipes.jl | 2 +- src/series_args.jl | 4 +- src/series_new.jl | 4 +- src/types.jl | 6 +- 21 files changed, 405 insertions(+), 428 deletions(-) diff --git a/src/args.jl b/src/args.jl index d146d966..ad4cae15 100644 --- a/src/args.jl +++ b/src/args.jl @@ -57,6 +57,9 @@ is3d(seriestype::Symbol) = seriestype in _3dTypes is3d(series::Series) = is3d(series.d) is3d(d::KW) = trueOrAllTrue(is3d, d[:seriestype]) +is3d(sp::Subplot) = string(sp.attr[:projection]) == "3d" +ispolar(sp::Subplot) = string(sp.attr[:projection]) == "polar" + const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] @compat const _styleAliases = KW( :a => :auto, @@ -171,7 +174,7 @@ const _plot_defaults = KW( :foreground_color => :auto, # default for all foregrounds, and title color, :size => (600,400), :pos => (0,0), - :windowtitle => "Plots.jl", + :window_title => "Plots.jl", :show => false, :layout => 1, # :num_subplots => -1, @@ -231,6 +234,7 @@ const _suppress_warnings = KW( :x_discrete_indices => nothing, :y_discrete_indices => nothing, :z_discrete_indices => nothing, + :subplot => nothing, ) # add defaults for the letter versions @@ -381,7 +385,7 @@ add_aliases(:colorbar, :cb, :cbar, :colorkey) add_aliases(:smooth, :regression, :reg) add_aliases(:levels, :nlevels, :nlev, :levs) add_aliases(:size, :windowsize, :wsize) -add_aliases(:windowtitle, :wtitle) +add_aliases(:window_title, :windowtitle, :wtitle) add_aliases(:show, :gui, :display) add_aliases(:color_palette, :palette) add_aliases(:linkx, :xlink) @@ -627,7 +631,7 @@ function preprocessArgs!(d::KW) end # delete!(d, asym) - # # NOTE: this logic was moved to _add_plotargs... + # # NOTE: this logic was moved to _add_attr... # # turn :labels into :ticks_and_labels # tsym = symbol(letter * "ticks") # if haskey(d, tsym) && ticksType(d[tsym]) == :labels @@ -913,9 +917,9 @@ function color_or_match!(d::KW, k::Symbol, match_color) end -# update plotargs from an input dictionary +# update attr from an input dictionary function _update_plot_args(plt::Plot, d_in::KW) - pargs = plt.plotargs + pargs = plt.attr for (k,v) in _plot_defaults slice_arg!(d_in, pargs, k, v) end @@ -934,7 +938,7 @@ end # update a subplots args and axes function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::Integer) - pargs = plt.plotargs + pargs = plt.attr spargs = sp.attr # @show subplot_index, sp for (k,v) in _subplot_defaults @@ -1040,7 +1044,7 @@ function has_black_border_for_default(st::Symbol) end # # # build the argument dictionary for a series -# function getSeriesArgs(pkg::AbstractBackend, plotargs::KW, kw, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in plotargs, not plt +# function getSeriesArgs(pkg::AbstractBackend, attr::KW, kw, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in attr, not plt # kwdict = KW(kw) # d = KW() # @@ -1065,21 +1069,21 @@ end # aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex) # # # update color -# d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], plotargs, plotIndex) +# d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], attr, plotIndex) # # # # update linecolor # # c = d[:linecolor] -# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) +# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, attr, plotIndex)) # # d[:linecolor] = c # # # # update markercolor # # c = d[:markercolor] -# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) +# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, attr, plotIndex)) # # d[:markercolor] = c # # # # update fillcolor # # c = d[:fillcolor] -# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) +# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, attr, plotIndex)) # # d[:fillcolor] = c # # # update colors @@ -1091,13 +1095,13 @@ end # d[:seriescolor] # end # else -# getSeriesRGBColor(d[csym], plotargs, plotIndex) +# getSeriesRGBColor(d[csym], attr, plotIndex) # end # end # # # update markerstrokecolor # c = d[:markerstrokecolor] -# c = (c == :match ? plotargs[:foreground_color] : getSeriesRGBColor(c, plotargs, plotIndex)) +# c = (c == :match ? attr[:foreground_color] : getSeriesRGBColor(c, attr, plotIndex)) # d[:markerstrokecolor] = c # # # update alphas diff --git a/src/backends.jl b/src/backends.jl index e8ceec80..5b78aab6 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -48,15 +48,16 @@ include("backends/web.jl") plot(pkg::AbstractBackend; kw...) = error("plot($pkg; kw...) is not implemented") plot!(pkg::AbstractBackend, plt::Plot; kw...) = error("plot!($pkg, plt; kw...) is not implemented") _update_plot(pkg::AbstractBackend, plt::Plot, d::KW) = error("_update_plot($pkg, plt, d) is not implemented") -# subplot(pkg::AbstractBackend; kw...) = error("subplot($pkg; kw...) is not implemented") -# subplot!(pkg::AbstractBackend, subplt::Subplot; kw...) = error("subplot!($pkg, subplt; kw...) is not implemented") # don't do anything as a default _create_backend_figure(plt::Plot) = nothing +_initialize_subplot(plt::Plot, sp::Subplot) = nothing +_update_min_padding!(sp::Subplot) = nothing +_update_position!(sp::Subplot) = nothing _before_update(plt::Plot) = nothing -_series_added(plt::Plot) = nothing -# _add_annotations{X,Y,V}(plt::Plot, anns::AVec{Tuple{X,Y,V}}) = nothing -# _update_plot_pos_size(plt::AbstractPlot, d::KW) = nothing +_series_added(plt::Plot, series::Series) = nothing +_update_plot(plt::Plot, d::KW) = nothing +_series_updated(plt::Plot, series::Series) = nothing # --------------------------------------------------------- diff --git a/src/backends/bokeh.jl b/src/backends/bokeh.jl index 9ff99ad6..5d3c46db 100644 --- a/src/backends/bokeh.jl +++ b/src/backends/bokeh.jl @@ -37,7 +37,7 @@ supportedArgs(::BokehBackend) = [ # :show, :size, :title, - # :windowtitle, + # :window_title, :x, # :xguide, # :xlims, @@ -134,11 +134,11 @@ function _create_backend_figure(plt::Plot{BokehBackend}) datacolumns = Bokeh.BokehDataSet[] tools = Bokeh.tools() filename = tempname() * ".html" - title = plt.plotargs[:title] - w, h = plt.plotargs[:size] - xaxis_type = plt.plotargs[:xscale] == :log10 ? :log : :auto - yaxis_type = plt.plotargs[:yscale] == :log10 ? :log : :auto - # legend = plt.plotargs[:legend] ? xxxx : nothing + title = plt.attr[:title] + w, h = plt.attr[:size] + xaxis_type = plt.attr[:xscale] == :log10 ? :log : :auto + yaxis_type = plt.attr[:yscale] == :log10 ? :log : :auto + # legend = plt.attr[:legend] ? xxxx : nothing legend = nothing extra_args = KW() # TODO: we'll put extra settings (xlim, etc) here Bokeh.Plot(datacolumns, tools, filename, title, w, h, xaxis_type, yaxis_type, legend) #, extra_args) diff --git a/src/backends/gadfly.jl b/src/backends/gadfly.jl index 4c1790ed..359a724c 100644 --- a/src/backends/gadfly.jl +++ b/src/backends/gadfly.jl @@ -12,7 +12,7 @@ supportedArgs(::GadflyBackend) = [ :markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :fillrange, :fillcolor, :fillalpha, :bins, :n, :nc, :nr, :layout, :smooth, - :title, :windowtitle, :show, :size, + :title, :window_title, :show, :size, :x, :xguide, :xlims, :xticks, :xscale, :xflip, :y, :yguide, :ylims, :yticks, :yscale, :yflip, # :z, :zguide, :zlims, :zticks, :zscale, :zflip, @@ -190,7 +190,7 @@ function getMarkerGeom(d::KW) end end -function getGadflyMarkerTheme(d::KW, plotargs::KW) +function getGadflyMarkerTheme(d::KW, attr::KW) c = getColor(d[:markercolor]) α = d[:markeralpha] if α != nothing @@ -216,15 +216,15 @@ function getGadflyMarkerTheme(d::KW, plotargs::KW) end function addGadflyContColorScale(plt::Plot{GadflyBackend}, c) - plt.plotargs[:colorbar] == :none && return + plt.attr[:colorbar] == :none && return if !isa(c, ColorGradient) c = default_gradient() end push!(getGadflyContext(plt).scales, Gadfly.Scale.ContinuousColorScale(p -> RGB(getColorZ(c, p)))) end -function addGadflyMarker!(plt::Plot, numlayers::Int, d::KW, plotargs::KW, geoms...) - gfargs = vcat(geoms..., getGadflyMarkerTheme(d, plotargs), getMarkerGeom(d)) +function addGadflyMarker!(plt::Plot, numlayers::Int, d::KW, attr::KW, geoms...) + gfargs = vcat(geoms..., getGadflyMarkerTheme(d, attr), getMarkerGeom(d)) kwargs = KW() # handle continuous color scales for the markers @@ -241,7 +241,7 @@ end # --------------------------------------------------------------------------- function addToGadflyLegend(plt::Plot, d::KW) - if plt.plotargs[:legend] != :none && d[:label] != "" + if plt.attr[:legend] != :none && d[:label] != "" gplt = getGadflyContext(plt) # add the legend if needed @@ -308,7 +308,7 @@ function addGadflySeries!(plt::Plot, d::KW) # markers if d[:markershape] != :none || st == :shape - prepend!(layers, addGadflyMarker!(plt, length(gplt.layers), d, plt.plotargs, smooth...)) + prepend!(layers, addGadflyMarker!(plt, length(gplt.layers), d, plt.attr, smooth...)) end st in (:hist2d, :hexbin, :contour) || addToGadflyLegend(plt, d) @@ -575,7 +575,7 @@ end # Plot(gplt, pkg, 0, d, KW[]) # end function _create_backend_figure(plt::Plot{GadflyBackend}) - createGadflyPlotObject(plt.plotargs) + createGadflyPlotObject(plt.attr) end @@ -674,8 +674,8 @@ getGadflyContext(plt::Plot{GadflyBackend}) = plt.o # end setGadflyDisplaySize(w,h) = Compose.set_default_graphic_size(w * Compose.px, h * Compose.px) -setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.plotargs[:size]...) -# setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getplotargs(subplt, 1)[:size]...) +setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.attr[:size]...) +# setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getattr(subplt, 1)[:size]...) # ------------------------------------------------------------------------- @@ -703,13 +703,13 @@ end function Base.display(::PlotsDisplay, plt::Plot{GadflyBackend}) - setGadflyDisplaySize(plt.plotargs[:size]...) + setGadflyDisplaySize(plt.attr[:size]...) display(plt.o) end # function Base.display(::PlotsDisplay, subplt::Subplot{GadflyBackend}) -# setGadflyDisplaySize(getplotargs(subplt,1)[:size]...) +# setGadflyDisplaySize(getattr(subplt,1)[:size]...) # ctx = buildGadflySubplotContext(subplt) # # # taken from Gadfly since I couldn't figure out how to do it directly diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index e654e373..965201d0 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -37,7 +37,7 @@ supportedArgs(::GLVisualizeBackend) = [ # :show, # :size, # :title, - # :windowtitle, + # :window_title, # :x, # :xguide, # :xlims, diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 263cd76e..f42e4634 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -19,7 +19,7 @@ supportedArgs(::GRBackend) = [ :bins, :n, :nc, :nr, :layout, :smooth, - :title, :windowtitle, :show, :size, + :title, :window_title, :show, :size, :x, :xguide, :xlims, :xticks, :xscale, :xflip, :y, :yguide, :ylims, :yticks, :yscale, :yflip, # :axis, :yrightlabel, @@ -194,7 +194,7 @@ end function gr_display(plt::Plot{GRBackend}, clear=true, update=true, subplot=[0, 1, 0, 1]) - d = plt.plotargs + d = plt.attr clear && GR.clearws() @@ -879,10 +879,10 @@ end # end function _add_annotations{X,Y,V}(plt::Plot{GRBackend}, anns::AVec{@compat(Tuple{X,Y,V})}) - if haskey(plt.plotargs, :anns) - append!(plt.plotargs[:anns], anns) + if haskey(plt.attr, :anns) + append!(plt.attr[:anns], anns) else - plt.plotargs[:anns] = anns + plt.attr[:anns] = anns end end @@ -893,7 +893,7 @@ end function _update_plot(plt::Plot{GRBackend}, d::KW) for k in (:title, :xguide, :yguide) - haskey(d, k) && (plt.plotargs[k] = d[k]) + haskey(d, k) && (plt.attr[k] = d[k]) end end diff --git a/src/backends/immerse.jl b/src/backends/immerse.jl index a1bab77b..42576158 100644 --- a/src/backends/immerse.jl +++ b/src/backends/immerse.jl @@ -21,7 +21,7 @@ end function createImmerseFigure(d::KW) w,h = d[:size] - figidx = Immerse.figure(; name = d[:windowtitle], width = w, height = h) + figidx = Immerse.figure(; name = d[:window_title], width = w, height = h) Immerse.Figure(figidx) end @@ -37,7 +37,7 @@ end # Plot((nothing,gplt), pkg, 0, d, KW[]) # end function _create_backend_figure(plt::Plot{ImmerseBackend}) - (nothing, createGadflyPlotObject(plt.plotargs)) + (nothing, createGadflyPlotObject(plt.attr)) end @@ -95,10 +95,10 @@ end # # function showSubplotObject(subplt::Subplot{ImmerseBackend}) # # create the Gtk window with vertical box vsep -# d = getplotargs(subplt,1) +# d = getattr(subplt,1) # w,h = d[:size] # vsep = Gtk.GtkBoxLeaf(:v) -# win = Gtk.GtkWindowLeaf(vsep, d[:windowtitle], w, h) +# win = Gtk.GtkWindowLeaf(vsep, d[:window_title], w, h) # # figindices = [] # row = Gtk.GtkBoxLeaf(:h) @@ -158,7 +158,7 @@ function Base.display(::PlotsDisplay, plt::Plot{ImmerseBackend}) fig, gplt = plt.o if fig == nothing - fig = createImmerseFigure(plt.plotargs) + fig = createImmerseFigure(plt.attr) Gtk.on_signal_destroy((x...) -> (Immerse.dropfig(Immerse._display, fig.figno); plt.o = (nothing,gplt)), fig.canvas) plt.o = (fig, gplt) end diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 96a25299..fb351306 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -36,7 +36,7 @@ supportedArgs(::PGFPlotsBackend) = [ # :show, :size, :title, - # :windowtitle, + # :window_title, :x, :xguide, :xlims, @@ -246,10 +246,10 @@ end function _add_annotations{X,Y,V}(plt::Plot{PGFPlotsBackend}, anns::AVec{@compat(Tuple{X,Y,V})}) # set or add to the annotation_list - if haskey(plt.plotargs, :annotation_list) - append!(plt.plotargs[:annotation_list], anns) + if haskey(plt.attr, :annotation_list) + append!(plt.attr[:annotation_list], anns) else - plt.plotargs[:annotation_list] = anns + plt.attr[:annotation_list] = anns end end @@ -362,11 +362,11 @@ function _make_pgf_plot(plt::Plot{PGFPlotsBackend}) os = Any[] # We need to send the :legend KW to the axis for plt_series in plt.seriesargs - plt_series[:legend] = plt.plotargs[:legend] + plt_series[:legend] = plt.attr[:legend] push!(os, _pgfplots_axis(plt_series)) end - axisargs =_pgfplots_get_axis_kwargs(plt.plotargs) - w, h = map(px2mm, plt.plotargs[:size]) + axisargs =_pgfplots_get_axis_kwargs(plt.attr) + w, h = map(px2mm, plt.attr[:size]) plt.o = PGFPlots.Axis([os...]; width = "$w mm", height = "$h mm", axisargs...) end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 19cecc45..9c6e0a42 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -18,7 +18,7 @@ supportedArgs(::PlotlyBackend) = [ :bins, :n, :nc, :nr, :layout, # :smooth, - :title, :windowtitle, :show, :size, + :title, :window_title, :show, :size, :x, :xguide, :xlims, :xticks, :xscale, :xflip, :xrotation, :y, :yguide, :ylims, :yticks, :yscale, :yflip, :yrotation, :z, :zguide, :zlims, :zticks, :zscale, :zflip, :zrotation, @@ -97,26 +97,26 @@ end # plt # end -function _add_annotations{X,Y,V}(plt::Plot{PlotlyBackend}, anns::AVec{@compat(Tuple{X,Y,V})}) - # set or add to the annotation_list - if haskey(plt.plotargs, :annotation_list) - append!(plt.plotargs[:annotation_list], anns) - else - plt.plotargs[:annotation_list] = anns - end -end +# function _add_annotations{X,Y,V}(plt::Plot{PlotlyBackend}, anns::AVec{@compat(Tuple{X,Y,V})}) +# # set or add to the annotation_list +# if haskey(plt.attr, :annotation_list) +# append!(plt.attr[:annotation_list], anns) +# else +# plt.attr[:annotation_list] = anns +# end +# end # ---------------------------------------------------------------- -function _before_update_plot(plt::Plot{PlotlyBackend}) -end +# function _before_update_plot(plt::Plot{PlotlyBackend}) +# end +# +# # TODO: override this to update plot items (title, xlabel, etc) after creation +# function _update_plot(plt::Plot{PlotlyBackend}, d::KW) +# end -# TODO: override this to update plot items (title, xlabel, etc) after creation -function _update_plot(plt::Plot{PlotlyBackend}, d::KW) -end - -function _update_plot_pos_size(plt::AbstractPlot{PlotlyBackend}, d::KW) -end +# function _update_plot_pos_size(plt::AbstractPlot{PlotlyBackend}, d::KW) +# end # ---------------------------------------------------------------- @@ -140,41 +140,41 @@ end # true # end -function _expand_limits(lims, plt::Plot{PlotlyBackend}, isx::Bool) - # TODO: call expand limits for each plot data -end - -function _remove_axis(plt::Plot{PlotlyBackend}, isx::Bool) - # TODO: if plot is inner subplot, might need to remove ticks or axis labels -end +# function _expand_limits(lims, plt::Plot{PlotlyBackend}, isx::Bool) +# # TODO: call expand limits for each plot data +# end +# +# function _remove_axis(plt::Plot{PlotlyBackend}, isx::Bool) +# # TODO: if plot is inner subplot, might need to remove ticks or axis labels +# end # ---------------------------------------------------------------- function plotlyfont(font::Font, color = font.color) - KW( - :family => font.family, - :size => round(Int, font.pointsize*1.4), - :color => webcolor(color), + KW( + :family => font.family, + :size => round(Int, font.pointsize*1.4), + :color => webcolor(color), ) end function get_annotation_dict(x, y, val::Union{AbstractString,Symbol}) - KW( - :text => val, - :xref => "x", - :x => x, - :yref => "y", - :y => y, - :showarrow => false, + KW( + :text => val, + :xref => "x", + :x => x, + :yref => "y", + :y => y, + :showarrow => false, ) end function get_annotation_dict(x, y, ptxt::PlotText) - merge(get_annotation_dict(x, y, ptxt.str), KW( - :font => plotlyfont(ptxt.font), - :xanchor => ptxt.font.halign == :hcenter ? :center : ptxt.font.halign, - :yanchor => ptxt.font.valign == :vcenter ? :middle : ptxt.font.valign, - :rotation => ptxt.font.rotation, + merge(get_annotation_dict(x, y, ptxt.str), KW( + :font => plotlyfont(ptxt.font), + :xanchor => ptxt.font.halign == :hcenter ? :center : ptxt.font.halign, + :yanchor => ptxt.font.valign == :vcenter ? :middle : ptxt.font.valign, + :rotation => ptxt.font.rotation, )) end @@ -202,118 +202,133 @@ end # end function plotlyscale(scale::Symbol) - if scale == :log10 - "log" - else - "-" - end + if scale == :log10 + "log" + else + "-" + end end use_axis_field(ticks) = !(ticks in (nothing, :none)) -tickssym(letter) = symbol(letter * "ticks") -limssym(letter) = symbol(letter * "lims") -flipsym(letter) = symbol(letter * "flip") -scalesym(letter) = symbol(letter * "scale") -labelsym(letter) = symbol(letter * "label") -rotationsym(letter) = symbol(letter * "rotation") +# tickssym(letter) = symbol(letter * "ticks") +# limssym(letter) = symbol(letter * "lims") +# flipsym(letter) = symbol(letter * "flip") +# scalesym(letter) = symbol(letter * "scale") +# labelsym(letter) = symbol(letter * "label") +# rotationsym(letter) = symbol(letter * "rotation") -function plotlyaxis(d::KW, letter) - ax = KW( - :title => d[labelsym(letter)], - :showgrid => d[:grid], - :zeroline => false, +function plotlyaxis(axis::Axis, sp::Subplot{PlotlyBackend}) + letter = axis[:letter] + d = axis.d + ax = KW( + :title => d[:guide], + :showgrid => sp.attr[:grid], + :zeroline => false, ) - fgcolor = webcolor(d[:foreground_color]) - tsym = tickssym(letter) + # fgcolor = webcolor(d[:foreground_color]) + # tsym = tickssym(letter) - rot = d[rotationsym(letter)] - if rot != 0 - ax[:tickangle] = rot - end - - if use_axis_field(d[tsym]) - ax[:titlefont] = plotlyfont(d[:guidefont], fgcolor) - ax[:type] = plotlyscale(d[scalesym(letter)]) - ax[:tickfont] = plotlyfont(d[:tickfont], fgcolor) - ax[:tickcolor] = fgcolor - ax[:linecolor] = fgcolor - - # xlims - lims = d[limssym(letter)] - if lims != :auto && limsType(lims) == :limits - ax[:range] = lims + rot = d[:rotation] + if rot != 0 + ax[:tickangle] = rot end - # xflip - if d[flipsym(letter)] - ax[:autorange] = "reversed" - end + if use_axis_field(d[:ticks]) + ax[:titlefont] = plotlyfont(d[:guidefont], webcolor(d[:foreground_color_guide])) + ax[:type] = plotlyscale(d[:scale]) + ax[:tickfont] = plotlyfont(d[:tickfont], webcolor(d[:foreground_color_text])) + ax[:tickcolor] = webcolor(d[:foreground_color_border]) + ax[:linecolor] = webcolor(d[:foreground_color_border]) - # xticks - ticks = d[tsym] - if ticks != :auto - ttype = ticksType(ticks) - if ttype == :ticks - ax[:tickmode] = "array" - ax[:tickvals] = ticks - elseif ttype == :ticks_and_labels - ax[:tickmode] = "array" - ax[:tickvals], ax[:ticktext] = ticks - end + # lims + lims = d[:lims] + if lims != :auto && limsType(lims) == :limits + ax[:range] = lims + end + + # flip + if d[:flip] + ax[:autorange] = "reversed" + end + + # ticks + ticks = d[:ticks] + if ticks != :auto + ttype = ticksType(ticks) + if ttype == :ticks + ax[:tickmode] = "array" + ax[:tickvals] = ticks + elseif ttype == :ticks_and_labels + ax[:tickmode] = "array" + ax[:tickvals], ax[:ticktext] = ticks + end + end + else + ax[:showticklabels] = false + ax[:showgrid] = false end ax - else - ax[:showticklabels] = false - ax[:showgrid] = false - end - - ax end # function get_plot_json(plt::Plot{PlotlyBackend}) -# d = plt.plotargs -function plotly_layout(d::KW, seriesargs::AVec{KW}) +# d = plt.attr +# function plotly_layout(d::KW, seriesargs::AVec{KW}) +function plotly_layout(plt::Plot{PlotlyBackend}) d_out = KW() - d_out[:width], d_out[:height] = d[:size] + # for now, we only support 1 subplot + if length(plt.subplots) > 1 + warn("Subplots not supported yet") + end + sp = plt.subplots[1] - bgcolor = webcolor(d[:background_color]) - fgcolor = webcolor(d[:foreground_color]) + d_out[:width], d_out[:height] = plt.attr[:size] # set the fields for the plot - d_out[:title] = d[:title] - d_out[:titlefont] = plotlyfont(d[:guidefont], fgcolor) + d_out[:title] = sp.attr[:title] + d_out[:titlefont] = plotlyfont(sp.attr[:titlefont], webcolor(sp.attr[:foreground_color_title])) + + # TODO: use subplot positioning logic d_out[:margin] = KW(:l=>35, :b=>30, :r=>8, :t=>20) - d_out[:plot_bgcolor] = bgcolor - d_out[:paper_bgcolor] = bgcolor + + d_out[:plot_bgcolor] = webcolor(sp.attr[:background_color_inside]) + d_out[:paper_bgcolor] = webcolor(plt.attr[:background_color_outside]) # TODO: x/y axis tick values/labels - if any(is3d, seriesargs) + + # if any(is3d, seriesargs) + if is3d(sp) d_out[:scene] = KW( - :xaxis => plotlyaxis(d, "x"), - :yaxis => plotlyaxis(d, "y"), - :xzxis => plotlyaxis(d, "z"), + :xaxis => plotlyaxis(sp.attr[:xaxis], sp), + :yaxis => plotlyaxis(sp.attr[:yaxis], sp), + :xzxis => plotlyaxis(sp.attr[:zaxis], sp), ) else - d_out[:xaxis] = plotlyaxis(d, "x") - d_out[:yaxis] = plotlyaxis(d, "y") + d_out[:xaxis] = plotlyaxis(sp.attr[:xaxis], sp) + d_out[:yaxis] = plotlyaxis(sp.attr[:yaxis], sp) end # legend - d_out[:showlegend] = d[:legend] != :none - if d[:legend] != :none + d_out[:showlegend] = sp.attr[:legend] != :none + if sp.attr[:legend] != :none d_out[:legend] = KW( - :bgcolor => bgcolor, - :bordercolor => fgcolor, - :font => plotlyfont(d[:legendfont]), + :bgcolor => webcolor(sp.attr[:background_color_legend]), + :bordercolor => webcolor(sp.attr[:foreground_color_legend]), + :font => plotlyfont(sp.attr[:legendfont]), ) end + # if haskey(plt.attr, :annotation_list) + # append!(plt.attr[:annotation_list], anns) + # else + # plt.attr[:annotation_list] = anns + # end + # annotations - anns = get(d, :annotation_list, []) + anns = get(sp.attr, :annotations, []) d_out[:annotations] = if isempty(anns) KW[] else @@ -332,7 +347,7 @@ function plotly_layout(d::KW, seriesargs::AVec{KW}) # dumpdict(d_out,"",true) # @show d_out[:annotations] - if get(d, :polar, false) + if ispolar(sp) d_out[:direction] = "counterclockwise" end @@ -340,12 +355,12 @@ function plotly_layout(d::KW, seriesargs::AVec{KW}) end function get_plot_json(plt::Plot{PlotlyBackend}) - JSON.json(plotly_layout(plt.plotargs, plt.seriesargs)) + JSON.json(plotly_layout(plt)) end function plotly_colorscale(grad::ColorGradient, alpha = nothing) - [[grad.values[i], webcolor(grad.colors[i], alpha)] for i in 1:length(grad.colors)] + [[grad.values[i], webcolor(grad.colors[i], alpha)] for i in 1:length(grad.colors)] end plotly_colorscale(c, alpha = nothing) = plotly_colorscale(default_gradient(), alpha) @@ -357,196 +372,178 @@ const _plotly_markers = KW( :star5 => "star-triangle-up", :vline => "line-ns", :hline => "line-ew", - ) +) # get a dictionary representing the series params (d is the Plots-dict, d_out is the Plotly-dict) -function plotly_series(d::KW, plotargs::KW; plot_index = nothing) - # dumpdict(d,"series",true) - d_out = KW() +function plotly_series(plt::Plot{PlotlyBackend}, series::Series) + d = series.d + d_out = KW() - x, y = collect(d[:x]), collect(d[:y]) - d_out[:name] = d[:label] + x, y = collect(d[:x]), collect(d[:y]) + d_out[:name] = d[:label] - st = d[:seriestype] - isscatter = st in (:scatter, :scatter3d) - hasmarker = isscatter || d[:markershape] != :none - hasline = !isscatter + st = d[:seriestype] + isscatter = st in (:scatter, :scatter3d) + hasmarker = isscatter || d[:markershape] != :none + hasline = !isscatter - # set the "type" - if st in (:line, :path, :scatter, :steppre, :steppost) - d_out[:type] = "scatter" - d_out[:mode] = if hasmarker - hasline ? "lines+markers" : "markers" - else - hasline ? "lines" : "none" - end - if d[:fillrange] == true || d[:fillrange] == 0 - d_out[:fill] = "tozeroy" - d_out[:fillcolor] = webcolor(d[:fillcolor], d[:fillalpha]) - elseif !(d[:fillrange] in (false, nothing)) - warn("fillrange ignored... plotly only supports filling to zero. fillrange: $(d[:fillrange])") - end - d_out[:x], d_out[:y] = x, y - - elseif st == :bar - d_out[:type] = "bar" - d_out[:x], d_out[:y] = x, y - - elseif st == :hist2d - d_out[:type] = "histogram2d" - d_out[:x], d_out[:y] = x, y - if isa(d[:bins], Tuple) - xbins, ybins = d[:bins] - else - xbins = ybins = d[:bins] - end - d_out[:nbinsx] = xbins - d_out[:nbinsy] = ybins - - elseif st in (:hist, :density) - d_out[:type] = "histogram" - isvert = isvertical(d) - d_out[isvert ? :x : :y] = y - d_out[isvert ? :nbinsx : :nbinsy] = d[:bins] - if st == :density - d_out[:histnorm] = "probability density" - end - - elseif st == :heatmap - d_out[:type] = "heatmap" - d_out[:x], d_out[:y] = x, y - d_out[:z] = d[:z].surf - d_out[:colorscale] = plotly_colorscale(d[:fillcolor], d[:fillalpha]) - - elseif st == :contour - d_out[:type] = "contour" - d_out[:x], d_out[:y] = x, y - d_out[:z] = d[:z].surf - # d_out[:showscale] = d[:colorbar] != :none - d_out[:ncontours] = d[:levels] - d_out[:contours] = KW(:coloring => d[:fillrange] != nothing ? "fill" : "lines") - d_out[:colorscale] = plotly_colorscale(d[:linecolor], d[:linealpha]) - - elseif st in (:surface, :wireframe) - d_out[:type] = "surface" - d_out[:x], d_out[:y] = x, y - d_out[:z] = d[:z].surf - d_out[:colorscale] = plotly_colorscale(d[:fillcolor], d[:fillalpha]) - - elseif st == :pie - d_out[:type] = "pie" - d_out[:labels] = x - d_out[:values] = y - d_out[:hoverinfo] = "label+percent+name" - - elseif st in (:path3d, :scatter3d) - d_out[:type] = "scatter3d" - d_out[:mode] = if hasmarker - hasline ? "lines+markers" : "markers" - else - hasline ? "lines" : "none" - end - d_out[:x], d_out[:y] = x, y - d_out[:z] = collect(d[:z]) - - else - warn("Plotly: seriestype $st isn't supported.") - return KW() - end - - # add "marker" - if hasmarker - d_out[:marker] = KW( - :symbol => get(_plotly_markers, d[:markershape], string(d[:markershape])), - :opacity => d[:markeralpha], - :size => 2 * d[:markersize], - :color => webcolor(d[:markercolor], d[:markeralpha]), - :line => KW( - :color => webcolor(d[:markerstrokecolor], d[:markerstrokealpha]), - :width => d[:markerstrokewidth], - ), - ) - - # gotta hack this (for now?) since plotly can't handle rgba values inside the gradient - if d[:marker_z] != nothing - # d_out[:marker][:color] = d[:marker_z] - # d_out[:marker][:colorscale] = plotly_colorscale(d[:markercolor], d[:markeralpha]) - # d_out[:showscale] = true - grad = ColorGradient(d[:markercolor], alpha=d[:markeralpha]) - zmin, zmax = extrema(d[:marker_z]) - d_out[:marker][:color] = [webcolor(getColorZ(grad, (zi - zmin) / (zmax - zmin))) for zi in d[:marker_z]] - end - - end - - # add "line" - if hasline - d_out[:line] = KW( - :color => webcolor(d[:linecolor], d[:linealpha]), - :width => d[:linewidth], - :shape => if st == :steppre - "vh" - elseif st == :steppost - "hv" + # set the "type" + if st in (:line, :path, :scatter, :steppre, :steppost) + d_out[:type] = "scatter" + d_out[:mode] = if hasmarker + hasline ? "lines+markers" : "markers" else - "linear" - end, - :dash => string(d[:linestyle]), - # :dash => "solid", - ) - end + hasline ? "lines" : "none" + end + if d[:fillrange] == true || d[:fillrange] == 0 + d_out[:fill] = "tozeroy" + d_out[:fillcolor] = webcolor(d[:fillcolor], d[:fillalpha]) + elseif !(d[:fillrange] in (false, nothing)) + warn("fillrange ignored... plotly only supports filling to zero. fillrange: $(d[:fillrange])") + end + d_out[:x], d_out[:y] = x, y - # convert polar plots x/y to theta/radius - if get(plotargs, :polar, false) - d_out[:t] = rad2deg(pop!(d_out, :x)) - d_out[:r] = pop!(d_out, :y) - end + elseif st == :bar + d_out[:type] = "bar" + d_out[:x], d_out[:y] = x, y - # # for subplots, we need to add the xaxis/yaxis fields - # if plot_index != nothing - # d_out[:xaxis] = "x$(plot_index)" - # d_out[:yaxis] = "y$(plot_index)" - # end + elseif st == :hist2d + d_out[:type] = "histogram2d" + d_out[:x], d_out[:y] = x, y + if isa(d[:bins], Tuple) + xbins, ybins = d[:bins] + else + xbins = ybins = d[:bins] + end + d_out[:nbinsx] = xbins + d_out[:nbinsy] = ybins - d_out + elseif st in (:hist, :density) + d_out[:type] = "histogram" + isvert = isvertical(d) + d_out[isvert ? :x : :y] = y + d_out[isvert ? :nbinsx : :nbinsy] = d[:bins] + if st == :density + d_out[:histnorm] = "probability density" + end + + elseif st == :heatmap + d_out[:type] = "heatmap" + d_out[:x], d_out[:y] = x, y + d_out[:z] = d[:z].surf + d_out[:colorscale] = plotly_colorscale(d[:fillcolor], d[:fillalpha]) + + elseif st == :contour + d_out[:type] = "contour" + d_out[:x], d_out[:y] = x, y + d_out[:z] = d[:z].surf + # d_out[:showscale] = d[:colorbar] != :none + d_out[:ncontours] = d[:levels] + d_out[:contours] = KW(:coloring => d[:fillrange] != nothing ? "fill" : "lines") + d_out[:colorscale] = plotly_colorscale(d[:linecolor], d[:linealpha]) + + elseif st in (:surface, :wireframe) + d_out[:type] = "surface" + d_out[:x], d_out[:y] = x, y + d_out[:z] = d[:z].surf + d_out[:colorscale] = plotly_colorscale(d[:fillcolor], d[:fillalpha]) + + elseif st == :pie + d_out[:type] = "pie" + d_out[:labels] = x + d_out[:values] = y + d_out[:hoverinfo] = "label+percent+name" + + elseif st in (:path3d, :scatter3d) + d_out[:type] = "scatter3d" + d_out[:mode] = if hasmarker + hasline ? "lines+markers" : "markers" + else + hasline ? "lines" : "none" + end + d_out[:x], d_out[:y] = x, y + d_out[:z] = collect(d[:z]) + + else + warn("Plotly: seriestype $st isn't supported.") + return KW() + end + + # add "marker" + if hasmarker + d_out[:marker] = KW( + :symbol => get(_plotly_markers, d[:markershape], string(d[:markershape])), + :opacity => d[:markeralpha], + :size => 2 * d[:markersize], + :color => webcolor(d[:markercolor], d[:markeralpha]), + :line => KW( + :color => webcolor(d[:markerstrokecolor], d[:markerstrokealpha]), + :width => d[:markerstrokewidth], + ), + ) + + # gotta hack this (for now?) since plotly can't handle rgba values inside the gradient + if d[:marker_z] != nothing + # d_out[:marker][:color] = d[:marker_z] + # d_out[:marker][:colorscale] = plotly_colorscale(d[:markercolor], d[:markeralpha]) + # d_out[:showscale] = true + grad = ColorGradient(d[:markercolor], alpha=d[:markeralpha]) + zmin, zmax = extrema(d[:marker_z]) + d_out[:marker][:color] = [webcolor(getColorZ(grad, (zi - zmin) / (zmax - zmin))) for zi in d[:marker_z]] + end + end + + # add "line" + if hasline + d_out[:line] = KW( + :color => webcolor(d[:linecolor], d[:linealpha]), + :width => d[:linewidth], + :shape => if st == :steppre + "vh" + elseif st == :steppost + "hv" + else + "linear" + end, + :dash => string(d[:linestyle]), + # :dash => "solid", + ) + end + + # convert polar plots x/y to theta/radius + if ispolar(d[:subplot]) + d_out[:t] = rad2deg(pop!(d_out, :x)) + d_out[:r] = pop!(d_out, :y) + end + + d_out end # get a list of dictionaries, each representing the series params function get_series_json(plt::Plot{PlotlyBackend}) - JSON.json(map(d -> plotly_series(d, plt.plotargs), plt.seriesargs)) + JSON.json(map(series -> plotly_series(plt, series), plt.series_list)) end -# function get_series_json(subplt::Subplot{PlotlyBackend}) -# ds = KW[] -# for (i,plt) in enumerate(subplt.plts) -# for d in plt.seriesargs -# push!(ds, plotly_series(d, plt.plotargs, plot_index = i)) -# end -# end -# JSON.json(ds) -# end - # ---------------------------------------------------------------- function html_head(plt::AbstractPlot{PlotlyBackend}) - "" + "" end function html_body(plt::Plot{PlotlyBackend}, style = nothing) - if style == nothing - w, h = plt.plotargs[:size] - style = "width:$(w)px;height:$(h)px;" - end - uuid = Base.Random.uuid4() - html = """ -
- - """ - # @show html - html + if style == nothing + w, h = plt.attr[:size] + style = "width:$(w)px;height:$(h)px;" + end + uuid = Base.Random.uuid4() + html = """ +
+ + """ + html end function js_body(plt::Plot{PlotlyBackend}, uuid) @@ -557,31 +554,6 @@ function js_body(plt::Plot{PlotlyBackend}, uuid) end -# function html_body(subplt::Subplot{PlotlyBackend}) -# w, h = subplt.plts[1].plotargs[:size] -# html = ["
"] -# nr = nrows(subplt.layout) -# ph = h / nr -# -# for r in 1:nr -# push!(html, "
") -# -# nc = ncols(subplt.layout, r) -# pw = w / nc -# -# for c in 1:nc -# plt = subplt[r,c] -# push!(html, html_body(plt, "float:left; width:$(pw)px; height:$(ph)px;")) -# end -# -# push!(html, "
") -# end -# push!(html, "
") -# -# join(html) -# end - - # ---------------------------------------------------------------- function Base.writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{PlotlyBackend}) @@ -590,13 +562,8 @@ end function Base.writemime(io::IO, ::MIME"text/html", plt::AbstractPlot{PlotlyBackend}) write(io, html_head(plt) * html_body(plt)) - # write(io, html_body(plt)) end function Base.display(::PlotsDisplay, plt::AbstractPlot{PlotlyBackend}) standalone_html_window(plt) end - -# function Base.display(::PlotsDisplay, plt::Subplot{PlotlyBackend}) -# # TODO: display/show the subplot -# end diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 2e6b2d65..1c7c65e3 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -36,7 +36,7 @@ supportedArgs(::PlotlyJSBackend) = [ :show, :size, :title, - :windowtitle, + :window_title, :x, :xguide, :xlims, @@ -118,7 +118,7 @@ function _series_added(plt::Plot{PlotlyJSBackend}, series::Series) syncplot = plt.o # add to the data array - pdict = plotly_series(d, plt.plotargs) + pdict = plotly_series(d, plt.attr) typ = pop!(pdict, :type) gt = PlotlyJS.GenericTrace(typ; pdict...) PlotlyJS.addtraces!(syncplot, gt) @@ -133,10 +133,10 @@ end function _add_annotations{X,Y,V}(plt::Plot{PlotlyJSBackend}, anns::AVec{@compat(Tuple{X,Y,V})}) # set or add to the annotation_list - if !haskey(plt.plotargs, :annotation_list) - plt.plotargs[:annotation_list] = Any[] + if !haskey(plt.attr, :annotation_list) + plt.attr[:annotation_list] = Any[] end - append!(plt.plotargs[:annotation_list], anns) + append!(plt.attr[:annotation_list], anns) end # ---------------------------------------------------------------- @@ -146,7 +146,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(plt.plotargs, plt.seriesargs) + pdict = plotly_layout(plt.attr, plt.seriesargs) syncplot = plt.o w,h = d[:size] PlotlyJS.relayout!(syncplot, pdict, width = w, height = h) @@ -167,7 +167,7 @@ end function setxy!{X,Y}(plt::Plot{PlotlyJSBackend}, xy::Tuple{X,Y}, i::Integer) d = plt.seriesargs[i] - ispolar = get(plt.plotargs, :polar, false) + ispolar = get(plt.attr, :polar, false) xsym = ispolar ? :t : :x ysym = ispolar ? :r : :y d[xsym], d[ysym] = xy diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 0f0f4a11..65f6a1b8 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -19,7 +19,7 @@ supportedArgs(::PyPlotBackend) = [ :bins, :bar_width, :bar_edges, :n, :nc, :nr, :layout, :smooth, - :title, :windowtitle, :show, :size, + :title, :window_title, :show, :size, :x, :xguide, :xlims, :xticks, :xscale, :xflip, :xrotation, :y, :yguide, :ylims, :yticks, :yscale, :yflip, :yrotation, # :axis, :yrightlabel, @@ -354,11 +354,11 @@ end # --------------------------------------------------------------------------- -function pyplot_figure(plotargs::KW) - w,h = map(px2inch, plotargs[:size]) +function pyplot_figure(attr::KW) + w,h = map(px2inch, attr[:size]) # reuse the current figure? - fig = if plotargs[:overwrite_figure] + fig = if attr[:overwrite_figure] PyPlot.gcf() else PyPlot.figure() @@ -366,7 +366,7 @@ function pyplot_figure(plotargs::KW) # update the specs fig[:set_size_inches](w, h, forward = true) - fig[:set_facecolor](getPyPlotColor(plotargs[:background_color_outside])) + fig[:set_facecolor](getPyPlotColor(attr[:background_color_outside])) fig[:set_dpi](DPI) # fig[:set_tight_layout](true) @@ -374,7 +374,7 @@ function pyplot_figure(plotargs::KW) PyPlot.clf() # resize the window - PyPlot.plt[:get_current_fig_manager]()[:resize](plotargs[:size]...) + PyPlot.plt[:get_current_fig_manager]()[:resize](attr[:size]...) fig end @@ -382,7 +382,7 @@ end # Create the window/figure for this backend. function _create_backend_figure(plt::Plot{PyPlotBackend}) - pyplot_figure(plt.plotargs) + pyplot_figure(plt.attr) end # Set up the subplot within the backend object. @@ -1212,7 +1212,7 @@ for (mime, fmt) in _pyplot_mimeformats io, format=$fmt, # bbox_inches = "tight", - # figsize = map(px2inch, plt.plotargs[:size]), + # figsize = map(px2inch, plt.attr[:size]), facecolor = fig.o["get_facecolor"](), edgecolor = "none", dpi = DPI diff --git a/src/backends/qwt.jl b/src/backends/qwt.jl index efdc0af9..e7651341 100644 --- a/src/backends/qwt.jl +++ b/src/backends/qwt.jl @@ -31,7 +31,7 @@ supportedArgs(::QwtBackend) = [ :show, :size, :title, - :windowtitle, + :window_title, :x, :xguide, :xlims, @@ -130,9 +130,9 @@ end # function _create_plot(pkg::QwtBackend, d::KW) function _create_backend_figure(plt::Plot{QwtBackend}) - fixcolors(plt.plotargs) - dumpdict(plt.plotargs,"\n\n!!! plot") - o = Qwt.plot(zeros(0,0); plt.plotargs..., show=false) + fixcolors(plt.attr) + dumpdict(plt.attr,"\n\n!!! plot") + o = Qwt.plot(zeros(0,0); plt.attr..., show=false) # plt = Plot(o, pkg, 0, d, KW[]) # plt end @@ -287,7 +287,7 @@ end # # i += rowcnt # # end # subplt.o = Qwt.vsplitter(rows...) -# # Qwt.resizewidget(subplt.o, getplotargs(subplt,1)[:size]...) +# # Qwt.resizewidget(subplt.o, getattr(subplt,1)[:size]...) # # Qwt.moveToLastScreen(subplt.o) # hack so it goes to my center monitor... sorry # true # end diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 6800e841..fb8ae0a6 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -35,7 +35,7 @@ supportedArgs(::UnicodePlotsBackend) = [ :show, :size, :title, - :windowtitle, + :window_title, :x, :xguide, :xlims, @@ -78,7 +78,7 @@ function rebuildUnicodePlot!(plt::Plot) # figure out the plotting area xlim = [xmin, xmax] and ylim = [ymin, ymax] sargs = plt.seriesargs - iargs = plt.plotargs + iargs = plt.attr # get the x/y limits if get(iargs, :xlims, :auto) == :auto @@ -186,10 +186,10 @@ end function _create_backend_figure(plt::Plot{UnicodePlotsBackend}) # do we want to give a new default size? - if !haskey(plt.plotargs, :size) || plt.plotargs[:size] == default(:size) - plt.plotargs[:size] = (60,20) + if !haskey(plt.attr, :size) || plt.attr[:size] == default(:size) + plt.attr[:size] = (60,20) end - plt.plotargs[:color_palette] = [RGB(0,0,0)] + plt.attr[:color_palette] = [RGB(0,0,0)] nothing # plt @@ -211,7 +211,7 @@ end function _update_plot(plt::Plot{UnicodePlotsBackend}, d::KW) for k in (:title, :xguide, :yguide, :xlims, :ylims) if haskey(d, k) - plt.plotargs[k] = d[k] + plt.attr[k] = d[k] end end end diff --git a/src/backends/web.jl b/src/backends/web.jl index 26f0f752..2920ba68 100644 --- a/src/backends/web.jl +++ b/src/backends/web.jl @@ -4,7 +4,7 @@ # CREDIT: parts of this implementation were inspired by @joshday's PlotlyLocal.jl -function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.plotargs, :window_title, "Plots.jl")) +function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr, :window_title, "Plots.jl")) """ @@ -27,7 +27,7 @@ function open_browser_window(filename::AbstractString) end function write_temp_html(plt::AbstractPlot) - html = standalone_html(plt; title = plt.plotargs[:title]) + html = standalone_html(plt; title = plt.attr[:window_title]) filename = string(tempname(), ".html") output = open(filename, "w") write(output, html) @@ -51,7 +51,7 @@ function writemime_png_from_html(io::IO, plt::AbstractPlot) # convert that html file to a temporary png file using wkhtmltoimage png_fn = tempname() * ".png" - w, h = plt.plotargs[:size] + w, h = plt.attr[:size] html_to_png(html_fn, png_fn, w, h) # now read that file data into io diff --git a/src/backends/winston.jl b/src/backends/winston.jl index c0a43fc8..93f8cf2c 100644 --- a/src/backends/winston.jl +++ b/src/backends/winston.jl @@ -39,7 +39,7 @@ supportedArgs(::WinstonBackend) = [ :show, :size, :title, - :windowtitle, + :window_title, :x, :xguide, :xlims, @@ -104,9 +104,9 @@ end function _create_backend_figure(plt::Plot{WinstonBackend}) Winston.FramedPlot( - title = plt.plotargs[:title], - xlabel = plt.plotargs[:xguide], - ylabel = plt.plotargs[:yguide] + title = plt.attr[:title], + xlabel = plt.attr[:xguide], + ylabel = plt.attr[:yguide] ) end @@ -268,7 +268,7 @@ end # ---------------------------------------------------------------- function addWinstonLegend(plt::Plot, wplt) - if plt.plotargs[:legend] != :none + if plt.attr[:legend] != :none Winston.legend(wplt, [sd[:label] for sd in plt.seriesargs]) end end @@ -289,9 +289,9 @@ function Base.display(::PlotsDisplay, plt::Plot{WinstonBackend}) error("Gtk is the only supported display for Winston in Plots. Set `output_surface = gtk` in src/Winston.ini") end # initialize window - w,h = plt.plotargs[:size] + w,h = plt.attr[:size] canvas = Gtk.GtkCanvasLeaf() - window = Gtk.GtkWindowLeaf(canvas, plt.plotargs[:windowtitle], w, h) + window = Gtk.GtkWindowLeaf(canvas, plt.attr[:window_title], w, h) plt.o = (window, canvas, wplt) end diff --git a/src/colors.jl b/src/colors.jl index f13ff41d..a62f1bf1 100644 --- a/src/colors.jl +++ b/src/colors.jl @@ -348,10 +348,10 @@ end make255(x) = round(Int, 255 * x) function webcolor(c::Color) - @sprintf("rgb(%d, %d, %d)", [make255(f(c)) for f in [red,green,blue]]...) + @sprintf("rgb(%d, %d, %d)", [make255(f(c)) for f in [red,green,blue]]...) end function webcolor(c::TransparentColor) - @sprintf("rgba(%d, %d, %d, %1.3f)", [make255(f(c)) for f in [red,green,blue]]..., alpha(c)) + @sprintf("rgba(%d, %d, %d, %1.3f)", [make255(f(c)) for f in [red,green,blue]]..., alpha(c)) end webcolor(cs::ColorScheme) = webcolor(getColor(cs)) webcolor(c) = webcolor(convertColor(c)) @@ -412,10 +412,10 @@ webcolor(c, α) = webcolor(convertColor(getColor(c), α)) # end # converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically -function getSeriesRGBColor(c, plotargs::KW, n::Int) +function getSeriesRGBColor(c, attr::KW, n::Int) if c == :auto - c = autopick(plotargs[:color_palette], n) + c = autopick(attr[:color_palette], n) end # c should now be a subtype of ColorScheme diff --git a/src/plot.jl b/src/plot.jl index 765382a0..70187997 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -22,7 +22,7 @@ Base.print(io::IO, plt::Plot) = print(io, string(plt)) Base.show(io::IO, plt::Plot) = print(io, string(plt)) getplot(plt::Plot) = plt -getplotargs(plt::Plot, idx::Int = 1) = plt.plotargs +getattr(plt::Plot, idx::Int = 1) = plt.attr convertSeriesIndex(plt::Plot, n::Int) = n # --------------------------------------------------------- @@ -54,7 +54,7 @@ function plot(args...; kw...) plt.o = _create_backend_figure(plt) # create the layout and subplots from the inputs - plt.layout, plt.subplots, plt.spmap = build_layout(plt.plotargs) + plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr) for (idx,sp) in enumerate(plt.subplots) sp.plt = plt _update_subplot_args(plt, sp, copy(d), idx) @@ -146,7 +146,12 @@ function _apply_series_recipe(plt::Plot, d::KW) # assuming there was no error, recursively apply the series recipes for series in series_list - _apply_series_recipe(plt, series.d) + if isa(series, Series) + _apply_series_recipe(plt, series.d) + else + warn("Unhandled series: $(series_list)") + break + end end end end @@ -284,7 +289,7 @@ function _plot!(plt::Plot, d::KW, args...) end # TODO just need to pass plt... and we should do all non-series updates here - _update_plot(plt, plt.plotargs) + _update_plot(plt, plt.attr) current(plt) @@ -317,7 +322,7 @@ end # function setTicksFromStringVector(plt::Plot, d::KW, di::KW, letter) # sym = symbol(letter) # ticksym = symbol(letter * "ticks") -# pargs = plt.plotargs +# pargs = plt.attr # v = di[sym] # # # do we really want to do this? @@ -345,7 +350,7 @@ end # end # # d[ticksym] = ticks, labels -# plt.plotargs[ticksym] = ticks, labels +# plt.attr[ticksym] = ticks, labels # # # add an origsym field so that later on we can re-compute the x vector if ticks change # origsym = symbol(letter * "orig") @@ -373,7 +378,7 @@ annotations(anns) = Any[anns] # function Base.copy(plt::Plot) # backend(plt.backend) -# plt2 = plot(; plt.plotargs...) +# plt2 = plot(; plt.attr...) # for sargs in plt.seriesargs # sargs = filter((k,v) -> haskey(_series_defaults,k), sargs) # plot!(plt2; sargs...) diff --git a/src/recipes.jl b/src/recipes.jl index a5f55f9a..236de2c8 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -550,7 +550,7 @@ type OHLC{T<:Real} close::T end Base.convert(::Type{OHLC}, tup::Tuple) = OHLC(tup...) -tuple(ohlc::OHLC) = (ohlc.open, ohlc.high, ohlc.low, ohlc.close) +# Base.tuple(ohlc::OHLC) = (ohlc.open, ohlc.high, ohlc.low, ohlc.close) # get one OHLC path function get_xy(o::OHLC, x, xdiff) diff --git a/src/series_args.jl b/src/series_args.jl index b70392db..94b8377d 100644 --- a/src/series_args.jl +++ b/src/series_args.jl @@ -138,7 +138,7 @@ compute_xyz(x::Void, y::Void, z::Void) = error("x/y/z are all nothing!") # n = plt.n + i # # dumpdict(d, "before getSeriesArgs") -# d = getSeriesArgs(plt.backend, getplotargs(plt, n), d, commandIndex, convertSeriesIndex(plt, n), n) +# d = getSeriesArgs(plt.backend, getattr(plt, n), d, commandIndex, convertSeriesIndex(plt, n), n) # dumpdict(d, "after getSeriesArgs") # # d[:x], d[:y], d[:z] = compute_xyz(xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)]) @@ -384,7 +384,7 @@ compute_xyz(x::Void, y::Void, z::Void) = error("x/y/z are all nothing!") # # # special handling... xmin/xmax with function(s) # function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs, xmin::Number, xmax::Number) -# width = get(plt.plotargs, :size, (100,))[1] +# width = get(plt.attr, :size, (100,))[1] # x = linspace(xmin, xmax, width) # process_inputs(plt, d, x, f) # end diff --git a/src/series_new.jl b/src/series_new.jl index 6275d156..bb590e23 100644 --- a/src/series_new.jl +++ b/src/series_new.jl @@ -5,7 +5,7 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) pkg = plt.backend # n = plt.n - # plotargs = getplotargs(plt, n) + # attr = getattr(plt, n) # plotIndex = convertSeriesIndex(plt, n) globalIndex = plt.n @@ -380,7 +380,7 @@ end # # # special handling... xmin/xmax with function(s) # function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs, xmin::Number, xmax::Number) -# width = get(plt.plotargs, :size, (100,))[1] +# width = get(plt.attr, :size, (100,))[1] # x = linspace(xmin, xmax, width) # process_inputs(plt, d, x, f) # end diff --git a/src/types.jl b/src/types.jl index 3012704f..8304dbfc 100644 --- a/src/types.jl +++ b/src/types.jl @@ -58,7 +58,7 @@ attr!(series::Series, v, k::Symbol) = (series.d[k] = v) type Plot{T<:AbstractBackend} <: AbstractPlot{T} backend::T # the backend type n::Int # number of series - plotargs::KW # arguments for the whole plot + attr::KW # arguments for the whole plot series_list::Vector{Series} # arguments for each series o # the backend's plot object subplots::Vector{Subplot} @@ -75,8 +75,8 @@ end # Base.getindex(plt::Plot, i::Integer) = plt.subplots[i] Base.getindex(plt::Plot, s::Symbol) = plt.spmap[s] Base.getindex(plt::Plot, r::Integer, c::Integer) = plt.layout[r,c] -attr(plt::Plot, k::Symbol) = plt.plotargs[k] -attr!(plt::Plot, v, k::Symbol) = (plt.plotargs[k] = v) +attr(plt::Plot, k::Symbol) = plt.attr[k] +attr!(plt::Plot, v, k::Symbol) = (plt.attr[k] = v) # -----------------------------------------------------------------------