renamed plotargs to attr; working on plotly backend
This commit is contained in:
parent
abbd8635dd
commit
cf635cbdd9
30
src/args.jl
30
src/args.jl
@ -57,6 +57,9 @@ is3d(seriestype::Symbol) = seriestype in _3dTypes
|
|||||||
is3d(series::Series) = is3d(series.d)
|
is3d(series::Series) = is3d(series.d)
|
||||||
is3d(d::KW) = trueOrAllTrue(is3d, d[:seriestype])
|
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]
|
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||||
@compat const _styleAliases = KW(
|
@compat const _styleAliases = KW(
|
||||||
:a => :auto,
|
:a => :auto,
|
||||||
@ -171,7 +174,7 @@ const _plot_defaults = KW(
|
|||||||
:foreground_color => :auto, # default for all foregrounds, and title color,
|
:foreground_color => :auto, # default for all foregrounds, and title color,
|
||||||
:size => (600,400),
|
:size => (600,400),
|
||||||
:pos => (0,0),
|
:pos => (0,0),
|
||||||
:windowtitle => "Plots.jl",
|
:window_title => "Plots.jl",
|
||||||
:show => false,
|
:show => false,
|
||||||
:layout => 1,
|
:layout => 1,
|
||||||
# :num_subplots => -1,
|
# :num_subplots => -1,
|
||||||
@ -231,6 +234,7 @@ const _suppress_warnings = KW(
|
|||||||
:x_discrete_indices => nothing,
|
:x_discrete_indices => nothing,
|
||||||
:y_discrete_indices => nothing,
|
:y_discrete_indices => nothing,
|
||||||
:z_discrete_indices => nothing,
|
:z_discrete_indices => nothing,
|
||||||
|
:subplot => nothing,
|
||||||
)
|
)
|
||||||
|
|
||||||
# add defaults for the letter versions
|
# add defaults for the letter versions
|
||||||
@ -381,7 +385,7 @@ add_aliases(:colorbar, :cb, :cbar, :colorkey)
|
|||||||
add_aliases(:smooth, :regression, :reg)
|
add_aliases(:smooth, :regression, :reg)
|
||||||
add_aliases(:levels, :nlevels, :nlev, :levs)
|
add_aliases(:levels, :nlevels, :nlev, :levs)
|
||||||
add_aliases(:size, :windowsize, :wsize)
|
add_aliases(:size, :windowsize, :wsize)
|
||||||
add_aliases(:windowtitle, :wtitle)
|
add_aliases(:window_title, :windowtitle, :wtitle)
|
||||||
add_aliases(:show, :gui, :display)
|
add_aliases(:show, :gui, :display)
|
||||||
add_aliases(:color_palette, :palette)
|
add_aliases(:color_palette, :palette)
|
||||||
add_aliases(:linkx, :xlink)
|
add_aliases(:linkx, :xlink)
|
||||||
@ -627,7 +631,7 @@ function preprocessArgs!(d::KW)
|
|||||||
end
|
end
|
||||||
# delete!(d, asym)
|
# 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
|
# # turn :labels into :ticks_and_labels
|
||||||
# tsym = symbol(letter * "ticks")
|
# tsym = symbol(letter * "ticks")
|
||||||
# if haskey(d, tsym) && ticksType(d[tsym]) == :labels
|
# if haskey(d, tsym) && ticksType(d[tsym]) == :labels
|
||||||
@ -913,9 +917,9 @@ function color_or_match!(d::KW, k::Symbol, match_color)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# update plotargs from an input dictionary
|
# update attr from an input dictionary
|
||||||
function _update_plot_args(plt::Plot, d_in::KW)
|
function _update_plot_args(plt::Plot, d_in::KW)
|
||||||
pargs = plt.plotargs
|
pargs = plt.attr
|
||||||
for (k,v) in _plot_defaults
|
for (k,v) in _plot_defaults
|
||||||
slice_arg!(d_in, pargs, k, v)
|
slice_arg!(d_in, pargs, k, v)
|
||||||
end
|
end
|
||||||
@ -934,7 +938,7 @@ end
|
|||||||
|
|
||||||
# update a subplots args and axes
|
# update a subplots args and axes
|
||||||
function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::Integer)
|
function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::Integer)
|
||||||
pargs = plt.plotargs
|
pargs = plt.attr
|
||||||
spargs = sp.attr
|
spargs = sp.attr
|
||||||
# @show subplot_index, sp
|
# @show subplot_index, sp
|
||||||
for (k,v) in _subplot_defaults
|
for (k,v) in _subplot_defaults
|
||||||
@ -1040,7 +1044,7 @@ function has_black_border_for_default(st::Symbol)
|
|||||||
end
|
end
|
||||||
#
|
#
|
||||||
# # build the argument dictionary for a series
|
# # 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)
|
# kwdict = KW(kw)
|
||||||
# d = KW()
|
# d = KW()
|
||||||
#
|
#
|
||||||
@ -1065,21 +1069,21 @@ end
|
|||||||
# aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex)
|
# aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex)
|
||||||
#
|
#
|
||||||
# # update color
|
# # update color
|
||||||
# d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], plotargs, plotIndex)
|
# d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], attr, plotIndex)
|
||||||
#
|
#
|
||||||
# # # update linecolor
|
# # # update linecolor
|
||||||
# # c = d[: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
|
# # d[:linecolor] = c
|
||||||
#
|
#
|
||||||
# # # update markercolor
|
# # # update markercolor
|
||||||
# # c = d[: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
|
# # d[:markercolor] = c
|
||||||
#
|
#
|
||||||
# # # update fillcolor
|
# # # update fillcolor
|
||||||
# # c = d[: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
|
# # d[:fillcolor] = c
|
||||||
#
|
#
|
||||||
# # update colors
|
# # update colors
|
||||||
@ -1091,13 +1095,13 @@ end
|
|||||||
# d[:seriescolor]
|
# d[:seriescolor]
|
||||||
# end
|
# end
|
||||||
# else
|
# else
|
||||||
# getSeriesRGBColor(d[csym], plotargs, plotIndex)
|
# getSeriesRGBColor(d[csym], attr, plotIndex)
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# # update markerstrokecolor
|
# # update markerstrokecolor
|
||||||
# c = d[: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
|
# d[:markerstrokecolor] = c
|
||||||
#
|
#
|
||||||
# # update alphas
|
# # update alphas
|
||||||
|
|||||||
@ -48,15 +48,16 @@ include("backends/web.jl")
|
|||||||
plot(pkg::AbstractBackend; kw...) = error("plot($pkg; kw...) is not implemented")
|
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")
|
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")
|
_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
|
# don't do anything as a default
|
||||||
_create_backend_figure(plt::Plot) = nothing
|
_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
|
_before_update(plt::Plot) = nothing
|
||||||
_series_added(plt::Plot) = nothing
|
_series_added(plt::Plot, series::Series) = nothing
|
||||||
# _add_annotations{X,Y,V}(plt::Plot, anns::AVec{Tuple{X,Y,V}}) = nothing
|
_update_plot(plt::Plot, d::KW) = nothing
|
||||||
# _update_plot_pos_size(plt::AbstractPlot, d::KW) = nothing
|
_series_updated(plt::Plot, series::Series) = nothing
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ supportedArgs(::BokehBackend) = [
|
|||||||
# :show,
|
# :show,
|
||||||
:size,
|
:size,
|
||||||
:title,
|
:title,
|
||||||
# :windowtitle,
|
# :window_title,
|
||||||
:x,
|
:x,
|
||||||
# :xguide,
|
# :xguide,
|
||||||
# :xlims,
|
# :xlims,
|
||||||
@ -134,11 +134,11 @@ function _create_backend_figure(plt::Plot{BokehBackend})
|
|||||||
datacolumns = Bokeh.BokehDataSet[]
|
datacolumns = Bokeh.BokehDataSet[]
|
||||||
tools = Bokeh.tools()
|
tools = Bokeh.tools()
|
||||||
filename = tempname() * ".html"
|
filename = tempname() * ".html"
|
||||||
title = plt.plotargs[:title]
|
title = plt.attr[:title]
|
||||||
w, h = plt.plotargs[:size]
|
w, h = plt.attr[:size]
|
||||||
xaxis_type = plt.plotargs[:xscale] == :log10 ? :log : :auto
|
xaxis_type = plt.attr[:xscale] == :log10 ? :log : :auto
|
||||||
yaxis_type = plt.plotargs[:yscale] == :log10 ? :log : :auto
|
yaxis_type = plt.attr[:yscale] == :log10 ? :log : :auto
|
||||||
# legend = plt.plotargs[:legend] ? xxxx : nothing
|
# legend = plt.attr[:legend] ? xxxx : nothing
|
||||||
legend = nothing
|
legend = nothing
|
||||||
extra_args = KW() # TODO: we'll put extra settings (xlim, etc) here
|
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)
|
Bokeh.Plot(datacolumns, tools, filename, title, w, h, xaxis_type, yaxis_type, legend) #, extra_args)
|
||||||
|
|||||||
@ -12,7 +12,7 @@ supportedArgs(::GadflyBackend) = [
|
|||||||
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
|
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
|
||||||
:fillrange, :fillcolor, :fillalpha,
|
:fillrange, :fillcolor, :fillalpha,
|
||||||
:bins, :n, :nc, :nr, :layout, :smooth,
|
:bins, :n, :nc, :nr, :layout, :smooth,
|
||||||
:title, :windowtitle, :show, :size,
|
:title, :window_title, :show, :size,
|
||||||
:x, :xguide, :xlims, :xticks, :xscale, :xflip,
|
:x, :xguide, :xlims, :xticks, :xscale, :xflip,
|
||||||
:y, :yguide, :ylims, :yticks, :yscale, :yflip,
|
:y, :yguide, :ylims, :yticks, :yscale, :yflip,
|
||||||
# :z, :zguide, :zlims, :zticks, :zscale, :zflip,
|
# :z, :zguide, :zlims, :zticks, :zscale, :zflip,
|
||||||
@ -190,7 +190,7 @@ function getMarkerGeom(d::KW)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function getGadflyMarkerTheme(d::KW, plotargs::KW)
|
function getGadflyMarkerTheme(d::KW, attr::KW)
|
||||||
c = getColor(d[:markercolor])
|
c = getColor(d[:markercolor])
|
||||||
α = d[:markeralpha]
|
α = d[:markeralpha]
|
||||||
if α != nothing
|
if α != nothing
|
||||||
@ -216,15 +216,15 @@ function getGadflyMarkerTheme(d::KW, plotargs::KW)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function addGadflyContColorScale(plt::Plot{GadflyBackend}, c)
|
function addGadflyContColorScale(plt::Plot{GadflyBackend}, c)
|
||||||
plt.plotargs[:colorbar] == :none && return
|
plt.attr[:colorbar] == :none && return
|
||||||
if !isa(c, ColorGradient)
|
if !isa(c, ColorGradient)
|
||||||
c = default_gradient()
|
c = default_gradient()
|
||||||
end
|
end
|
||||||
push!(getGadflyContext(plt).scales, Gadfly.Scale.ContinuousColorScale(p -> RGB(getColorZ(c, p))))
|
push!(getGadflyContext(plt).scales, Gadfly.Scale.ContinuousColorScale(p -> RGB(getColorZ(c, p))))
|
||||||
end
|
end
|
||||||
|
|
||||||
function addGadflyMarker!(plt::Plot, numlayers::Int, d::KW, plotargs::KW, geoms...)
|
function addGadflyMarker!(plt::Plot, numlayers::Int, d::KW, attr::KW, geoms...)
|
||||||
gfargs = vcat(geoms..., getGadflyMarkerTheme(d, plotargs), getMarkerGeom(d))
|
gfargs = vcat(geoms..., getGadflyMarkerTheme(d, attr), getMarkerGeom(d))
|
||||||
kwargs = KW()
|
kwargs = KW()
|
||||||
|
|
||||||
# handle continuous color scales for the markers
|
# handle continuous color scales for the markers
|
||||||
@ -241,7 +241,7 @@ end
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function addToGadflyLegend(plt::Plot, d::KW)
|
function addToGadflyLegend(plt::Plot, d::KW)
|
||||||
if plt.plotargs[:legend] != :none && d[:label] != ""
|
if plt.attr[:legend] != :none && d[:label] != ""
|
||||||
gplt = getGadflyContext(plt)
|
gplt = getGadflyContext(plt)
|
||||||
|
|
||||||
# add the legend if needed
|
# add the legend if needed
|
||||||
@ -308,7 +308,7 @@ function addGadflySeries!(plt::Plot, d::KW)
|
|||||||
|
|
||||||
# markers
|
# markers
|
||||||
if d[:markershape] != :none || st == :shape
|
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
|
end
|
||||||
|
|
||||||
st in (:hist2d, :hexbin, :contour) || addToGadflyLegend(plt, d)
|
st in (:hist2d, :hexbin, :contour) || addToGadflyLegend(plt, d)
|
||||||
@ -575,7 +575,7 @@ end
|
|||||||
# Plot(gplt, pkg, 0, d, KW[])
|
# Plot(gplt, pkg, 0, d, KW[])
|
||||||
# end
|
# end
|
||||||
function _create_backend_figure(plt::Plot{GadflyBackend})
|
function _create_backend_figure(plt::Plot{GadflyBackend})
|
||||||
createGadflyPlotObject(plt.plotargs)
|
createGadflyPlotObject(plt.attr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -674,8 +674,8 @@ getGadflyContext(plt::Plot{GadflyBackend}) = plt.o
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
setGadflyDisplaySize(w,h) = Compose.set_default_graphic_size(w * Compose.px, h * Compose.px)
|
setGadflyDisplaySize(w,h) = Compose.set_default_graphic_size(w * Compose.px, h * Compose.px)
|
||||||
setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.plotargs[:size]...)
|
setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.attr[:size]...)
|
||||||
# setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getplotargs(subplt, 1)[:size]...)
|
# setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getattr(subplt, 1)[:size]...)
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@ -703,13 +703,13 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function Base.display(::PlotsDisplay, plt::Plot{GadflyBackend})
|
function Base.display(::PlotsDisplay, plt::Plot{GadflyBackend})
|
||||||
setGadflyDisplaySize(plt.plotargs[:size]...)
|
setGadflyDisplaySize(plt.attr[:size]...)
|
||||||
display(plt.o)
|
display(plt.o)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# function Base.display(::PlotsDisplay, subplt::Subplot{GadflyBackend})
|
# function Base.display(::PlotsDisplay, subplt::Subplot{GadflyBackend})
|
||||||
# setGadflyDisplaySize(getplotargs(subplt,1)[:size]...)
|
# setGadflyDisplaySize(getattr(subplt,1)[:size]...)
|
||||||
# ctx = buildGadflySubplotContext(subplt)
|
# ctx = buildGadflySubplotContext(subplt)
|
||||||
#
|
#
|
||||||
# # taken from Gadfly since I couldn't figure out how to do it directly
|
# # taken from Gadfly since I couldn't figure out how to do it directly
|
||||||
|
|||||||
@ -37,7 +37,7 @@ supportedArgs(::GLVisualizeBackend) = [
|
|||||||
# :show,
|
# :show,
|
||||||
# :size,
|
# :size,
|
||||||
# :title,
|
# :title,
|
||||||
# :windowtitle,
|
# :window_title,
|
||||||
# :x,
|
# :x,
|
||||||
# :xguide,
|
# :xguide,
|
||||||
# :xlims,
|
# :xlims,
|
||||||
|
|||||||
@ -19,7 +19,7 @@ supportedArgs(::GRBackend) = [
|
|||||||
:bins,
|
:bins,
|
||||||
:n, :nc, :nr, :layout,
|
:n, :nc, :nr, :layout,
|
||||||
:smooth,
|
:smooth,
|
||||||
:title, :windowtitle, :show, :size,
|
:title, :window_title, :show, :size,
|
||||||
:x, :xguide, :xlims, :xticks, :xscale, :xflip,
|
:x, :xguide, :xlims, :xticks, :xscale, :xflip,
|
||||||
:y, :yguide, :ylims, :yticks, :yscale, :yflip,
|
:y, :yguide, :ylims, :yticks, :yscale, :yflip,
|
||||||
# :axis, :yrightlabel,
|
# :axis, :yrightlabel,
|
||||||
@ -194,7 +194,7 @@ end
|
|||||||
|
|
||||||
function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
|
function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
|
||||||
subplot=[0, 1, 0, 1])
|
subplot=[0, 1, 0, 1])
|
||||||
d = plt.plotargs
|
d = plt.attr
|
||||||
|
|
||||||
clear && GR.clearws()
|
clear && GR.clearws()
|
||||||
|
|
||||||
@ -879,10 +879,10 @@ end
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
function _add_annotations{X,Y,V}(plt::Plot{GRBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
function _add_annotations{X,Y,V}(plt::Plot{GRBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||||
if haskey(plt.plotargs, :anns)
|
if haskey(plt.attr, :anns)
|
||||||
append!(plt.plotargs[:anns], anns)
|
append!(plt.attr[:anns], anns)
|
||||||
else
|
else
|
||||||
plt.plotargs[:anns] = anns
|
plt.attr[:anns] = anns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -893,7 +893,7 @@ end
|
|||||||
|
|
||||||
function _update_plot(plt::Plot{GRBackend}, d::KW)
|
function _update_plot(plt::Plot{GRBackend}, d::KW)
|
||||||
for k in (:title, :xguide, :yguide)
|
for k in (:title, :xguide, :yguide)
|
||||||
haskey(d, k) && (plt.plotargs[k] = d[k])
|
haskey(d, k) && (plt.attr[k] = d[k])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ end
|
|||||||
|
|
||||||
function createImmerseFigure(d::KW)
|
function createImmerseFigure(d::KW)
|
||||||
w,h = d[:size]
|
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)
|
Immerse.Figure(figidx)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ end
|
|||||||
# Plot((nothing,gplt), pkg, 0, d, KW[])
|
# Plot((nothing,gplt), pkg, 0, d, KW[])
|
||||||
# end
|
# end
|
||||||
function _create_backend_figure(plt::Plot{ImmerseBackend})
|
function _create_backend_figure(plt::Plot{ImmerseBackend})
|
||||||
(nothing, createGadflyPlotObject(plt.plotargs))
|
(nothing, createGadflyPlotObject(plt.attr))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -95,10 +95,10 @@ end
|
|||||||
#
|
#
|
||||||
# function showSubplotObject(subplt::Subplot{ImmerseBackend})
|
# function showSubplotObject(subplt::Subplot{ImmerseBackend})
|
||||||
# # create the Gtk window with vertical box vsep
|
# # create the Gtk window with vertical box vsep
|
||||||
# d = getplotargs(subplt,1)
|
# d = getattr(subplt,1)
|
||||||
# w,h = d[:size]
|
# w,h = d[:size]
|
||||||
# vsep = Gtk.GtkBoxLeaf(:v)
|
# vsep = Gtk.GtkBoxLeaf(:v)
|
||||||
# win = Gtk.GtkWindowLeaf(vsep, d[:windowtitle], w, h)
|
# win = Gtk.GtkWindowLeaf(vsep, d[:window_title], w, h)
|
||||||
#
|
#
|
||||||
# figindices = []
|
# figindices = []
|
||||||
# row = Gtk.GtkBoxLeaf(:h)
|
# row = Gtk.GtkBoxLeaf(:h)
|
||||||
@ -158,7 +158,7 @@ function Base.display(::PlotsDisplay, plt::Plot{ImmerseBackend})
|
|||||||
|
|
||||||
fig, gplt = plt.o
|
fig, gplt = plt.o
|
||||||
if fig == nothing
|
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)
|
Gtk.on_signal_destroy((x...) -> (Immerse.dropfig(Immerse._display, fig.figno); plt.o = (nothing,gplt)), fig.canvas)
|
||||||
plt.o = (fig, gplt)
|
plt.o = (fig, gplt)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -36,7 +36,7 @@ supportedArgs(::PGFPlotsBackend) = [
|
|||||||
# :show,
|
# :show,
|
||||||
:size,
|
:size,
|
||||||
:title,
|
:title,
|
||||||
# :windowtitle,
|
# :window_title,
|
||||||
:x,
|
:x,
|
||||||
:xguide,
|
:xguide,
|
||||||
:xlims,
|
:xlims,
|
||||||
@ -246,10 +246,10 @@ end
|
|||||||
|
|
||||||
function _add_annotations{X,Y,V}(plt::Plot{PGFPlotsBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
function _add_annotations{X,Y,V}(plt::Plot{PGFPlotsBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||||
# set or add to the annotation_list
|
# set or add to the annotation_list
|
||||||
if haskey(plt.plotargs, :annotation_list)
|
if haskey(plt.attr, :annotation_list)
|
||||||
append!(plt.plotargs[:annotation_list], anns)
|
append!(plt.attr[:annotation_list], anns)
|
||||||
else
|
else
|
||||||
plt.plotargs[:annotation_list] = anns
|
plt.attr[:annotation_list] = anns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -362,11 +362,11 @@ function _make_pgf_plot(plt::Plot{PGFPlotsBackend})
|
|||||||
os = Any[]
|
os = Any[]
|
||||||
# We need to send the :legend KW to the axis
|
# We need to send the :legend KW to the axis
|
||||||
for plt_series in plt.seriesargs
|
for plt_series in plt.seriesargs
|
||||||
plt_series[:legend] = plt.plotargs[:legend]
|
plt_series[:legend] = plt.attr[:legend]
|
||||||
push!(os, _pgfplots_axis(plt_series))
|
push!(os, _pgfplots_axis(plt_series))
|
||||||
end
|
end
|
||||||
axisargs =_pgfplots_get_axis_kwargs(plt.plotargs)
|
axisargs =_pgfplots_get_axis_kwargs(plt.attr)
|
||||||
w, h = map(px2mm, plt.plotargs[:size])
|
w, h = map(px2mm, plt.attr[:size])
|
||||||
plt.o = PGFPlots.Axis([os...]; width = "$w mm", height = "$h mm", axisargs...)
|
plt.o = PGFPlots.Axis([os...]; width = "$w mm", height = "$h mm", axisargs...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ supportedArgs(::PlotlyBackend) = [
|
|||||||
:bins,
|
:bins,
|
||||||
:n, :nc, :nr, :layout,
|
:n, :nc, :nr, :layout,
|
||||||
# :smooth,
|
# :smooth,
|
||||||
:title, :windowtitle, :show, :size,
|
:title, :window_title, :show, :size,
|
||||||
:x, :xguide, :xlims, :xticks, :xscale, :xflip, :xrotation,
|
:x, :xguide, :xlims, :xticks, :xscale, :xflip, :xrotation,
|
||||||
:y, :yguide, :ylims, :yticks, :yscale, :yflip, :yrotation,
|
:y, :yguide, :ylims, :yticks, :yscale, :yflip, :yrotation,
|
||||||
:z, :zguide, :zlims, :zticks, :zscale, :zflip, :zrotation,
|
:z, :zguide, :zlims, :zticks, :zscale, :zflip, :zrotation,
|
||||||
@ -97,26 +97,26 @@ end
|
|||||||
# plt
|
# plt
|
||||||
# end
|
# end
|
||||||
|
|
||||||
function _add_annotations{X,Y,V}(plt::Plot{PlotlyBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
# function _add_annotations{X,Y,V}(plt::Plot{PlotlyBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||||
# set or add to the annotation_list
|
# # set or add to the annotation_list
|
||||||
if haskey(plt.plotargs, :annotation_list)
|
# if haskey(plt.attr, :annotation_list)
|
||||||
append!(plt.plotargs[:annotation_list], anns)
|
# append!(plt.attr[:annotation_list], anns)
|
||||||
else
|
# else
|
||||||
plt.plotargs[:annotation_list] = anns
|
# plt.attr[:annotation_list] = anns
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
function _before_update_plot(plt::Plot{PlotlyBackend})
|
# function _before_update_plot(plt::Plot{PlotlyBackend})
|
||||||
end
|
# 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_pos_size(plt::AbstractPlot{PlotlyBackend}, d::KW)
|
||||||
function _update_plot(plt::Plot{PlotlyBackend}, d::KW)
|
# end
|
||||||
end
|
|
||||||
|
|
||||||
function _update_plot_pos_size(plt::AbstractPlot{PlotlyBackend}, d::KW)
|
|
||||||
end
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
@ -140,41 +140,41 @@ end
|
|||||||
# true
|
# true
|
||||||
# end
|
# end
|
||||||
|
|
||||||
function _expand_limits(lims, plt::Plot{PlotlyBackend}, isx::Bool)
|
# function _expand_limits(lims, plt::Plot{PlotlyBackend}, 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{PlotlyBackend}, isx::Bool)
|
# function _remove_axis(plt::Plot{PlotlyBackend}, 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
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
function plotlyfont(font::Font, color = font.color)
|
function plotlyfont(font::Font, color = font.color)
|
||||||
KW(
|
KW(
|
||||||
:family => font.family,
|
:family => font.family,
|
||||||
:size => round(Int, font.pointsize*1.4),
|
:size => round(Int, font.pointsize*1.4),
|
||||||
:color => webcolor(color),
|
:color => webcolor(color),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_annotation_dict(x, y, val::Union{AbstractString,Symbol})
|
function get_annotation_dict(x, y, val::Union{AbstractString,Symbol})
|
||||||
KW(
|
KW(
|
||||||
:text => val,
|
:text => val,
|
||||||
:xref => "x",
|
:xref => "x",
|
||||||
:x => x,
|
:x => x,
|
||||||
:yref => "y",
|
:yref => "y",
|
||||||
:y => y,
|
:y => y,
|
||||||
:showarrow => false,
|
:showarrow => false,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_annotation_dict(x, y, ptxt::PlotText)
|
function get_annotation_dict(x, y, ptxt::PlotText)
|
||||||
merge(get_annotation_dict(x, y, ptxt.str), KW(
|
merge(get_annotation_dict(x, y, ptxt.str), KW(
|
||||||
:font => plotlyfont(ptxt.font),
|
:font => plotlyfont(ptxt.font),
|
||||||
:xanchor => ptxt.font.halign == :hcenter ? :center : ptxt.font.halign,
|
:xanchor => ptxt.font.halign == :hcenter ? :center : ptxt.font.halign,
|
||||||
:yanchor => ptxt.font.valign == :vcenter ? :middle : ptxt.font.valign,
|
:yanchor => ptxt.font.valign == :vcenter ? :middle : ptxt.font.valign,
|
||||||
:rotation => ptxt.font.rotation,
|
:rotation => ptxt.font.rotation,
|
||||||
))
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -202,118 +202,133 @@ end
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
function plotlyscale(scale::Symbol)
|
function plotlyscale(scale::Symbol)
|
||||||
if scale == :log10
|
if scale == :log10
|
||||||
"log"
|
"log"
|
||||||
else
|
else
|
||||||
"-"
|
"-"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
use_axis_field(ticks) = !(ticks in (nothing, :none))
|
use_axis_field(ticks) = !(ticks in (nothing, :none))
|
||||||
|
|
||||||
tickssym(letter) = symbol(letter * "ticks")
|
# tickssym(letter) = symbol(letter * "ticks")
|
||||||
limssym(letter) = symbol(letter * "lims")
|
# limssym(letter) = symbol(letter * "lims")
|
||||||
flipsym(letter) = symbol(letter * "flip")
|
# flipsym(letter) = symbol(letter * "flip")
|
||||||
scalesym(letter) = symbol(letter * "scale")
|
# scalesym(letter) = symbol(letter * "scale")
|
||||||
labelsym(letter) = symbol(letter * "label")
|
# labelsym(letter) = symbol(letter * "label")
|
||||||
rotationsym(letter) = symbol(letter * "rotation")
|
# rotationsym(letter) = symbol(letter * "rotation")
|
||||||
|
|
||||||
function plotlyaxis(d::KW, letter)
|
function plotlyaxis(axis::Axis, sp::Subplot{PlotlyBackend})
|
||||||
ax = KW(
|
letter = axis[:letter]
|
||||||
:title => d[labelsym(letter)],
|
d = axis.d
|
||||||
:showgrid => d[:grid],
|
ax = KW(
|
||||||
:zeroline => false,
|
:title => d[:guide],
|
||||||
|
:showgrid => sp.attr[:grid],
|
||||||
|
:zeroline => false,
|
||||||
)
|
)
|
||||||
|
|
||||||
fgcolor = webcolor(d[:foreground_color])
|
# fgcolor = webcolor(d[:foreground_color])
|
||||||
tsym = tickssym(letter)
|
# tsym = tickssym(letter)
|
||||||
|
|
||||||
rot = d[rotationsym(letter)]
|
rot = d[:rotation]
|
||||||
if rot != 0
|
if rot != 0
|
||||||
ax[:tickangle] = rot
|
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# xflip
|
if use_axis_field(d[:ticks])
|
||||||
if d[flipsym(letter)]
|
ax[:titlefont] = plotlyfont(d[:guidefont], webcolor(d[:foreground_color_guide]))
|
||||||
ax[:autorange] = "reversed"
|
ax[:type] = plotlyscale(d[:scale])
|
||||||
end
|
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
|
# lims
|
||||||
ticks = d[tsym]
|
lims = d[:lims]
|
||||||
if ticks != :auto
|
if lims != :auto && limsType(lims) == :limits
|
||||||
ttype = ticksType(ticks)
|
ax[:range] = lims
|
||||||
if ttype == :ticks
|
end
|
||||||
ax[:tickmode] = "array"
|
|
||||||
ax[:tickvals] = ticks
|
# flip
|
||||||
elseif ttype == :ticks_and_labels
|
if d[:flip]
|
||||||
ax[:tickmode] = "array"
|
ax[:autorange] = "reversed"
|
||||||
ax[:tickvals], ax[:ticktext] = ticks
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
ax
|
ax
|
||||||
else
|
|
||||||
ax[:showticklabels] = false
|
|
||||||
ax[:showgrid] = false
|
|
||||||
end
|
|
||||||
|
|
||||||
ax
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# function get_plot_json(plt::Plot{PlotlyBackend})
|
# function get_plot_json(plt::Plot{PlotlyBackend})
|
||||||
# d = plt.plotargs
|
# d = plt.attr
|
||||||
function plotly_layout(d::KW, seriesargs::AVec{KW})
|
# function plotly_layout(d::KW, seriesargs::AVec{KW})
|
||||||
|
function plotly_layout(plt::Plot{PlotlyBackend})
|
||||||
d_out = KW()
|
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])
|
d_out[:width], d_out[:height] = plt.attr[:size]
|
||||||
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] = sp.attr[:title]
|
||||||
d_out[:titlefont] = plotlyfont(d[:guidefont], fgcolor)
|
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[: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
|
# TODO: x/y axis tick values/labels
|
||||||
if any(is3d, seriesargs)
|
|
||||||
|
# if any(is3d, seriesargs)
|
||||||
|
if is3d(sp)
|
||||||
d_out[:scene] = KW(
|
d_out[:scene] = KW(
|
||||||
:xaxis => plotlyaxis(d, "x"),
|
:xaxis => plotlyaxis(sp.attr[:xaxis], sp),
|
||||||
:yaxis => plotlyaxis(d, "y"),
|
:yaxis => plotlyaxis(sp.attr[:yaxis], sp),
|
||||||
:xzxis => plotlyaxis(d, "z"),
|
:xzxis => plotlyaxis(sp.attr[:zaxis], sp),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
d_out[:xaxis] = plotlyaxis(d, "x")
|
d_out[:xaxis] = plotlyaxis(sp.attr[:xaxis], sp)
|
||||||
d_out[:yaxis] = plotlyaxis(d, "y")
|
d_out[:yaxis] = plotlyaxis(sp.attr[:yaxis], sp)
|
||||||
end
|
end
|
||||||
|
|
||||||
# legend
|
# legend
|
||||||
d_out[:showlegend] = d[:legend] != :none
|
d_out[:showlegend] = sp.attr[:legend] != :none
|
||||||
if d[:legend] != :none
|
if sp.attr[:legend] != :none
|
||||||
d_out[:legend] = KW(
|
d_out[:legend] = KW(
|
||||||
:bgcolor => bgcolor,
|
:bgcolor => webcolor(sp.attr[:background_color_legend]),
|
||||||
:bordercolor => fgcolor,
|
:bordercolor => webcolor(sp.attr[:foreground_color_legend]),
|
||||||
:font => plotlyfont(d[:legendfont]),
|
:font => plotlyfont(sp.attr[:legendfont]),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# if haskey(plt.attr, :annotation_list)
|
||||||
|
# append!(plt.attr[:annotation_list], anns)
|
||||||
|
# else
|
||||||
|
# plt.attr[:annotation_list] = anns
|
||||||
|
# end
|
||||||
|
|
||||||
# annotations
|
# annotations
|
||||||
anns = get(d, :annotation_list, [])
|
anns = get(sp.attr, :annotations, [])
|
||||||
d_out[:annotations] = if isempty(anns)
|
d_out[:annotations] = if isempty(anns)
|
||||||
KW[]
|
KW[]
|
||||||
else
|
else
|
||||||
@ -332,7 +347,7 @@ function plotly_layout(d::KW, seriesargs::AVec{KW})
|
|||||||
# dumpdict(d_out,"",true)
|
# dumpdict(d_out,"",true)
|
||||||
# @show d_out[:annotations]
|
# @show d_out[:annotations]
|
||||||
|
|
||||||
if get(d, :polar, false)
|
if ispolar(sp)
|
||||||
d_out[:direction] = "counterclockwise"
|
d_out[:direction] = "counterclockwise"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -340,12 +355,12 @@ function plotly_layout(d::KW, seriesargs::AVec{KW})
|
|||||||
end
|
end
|
||||||
|
|
||||||
function get_plot_json(plt::Plot{PlotlyBackend})
|
function get_plot_json(plt::Plot{PlotlyBackend})
|
||||||
JSON.json(plotly_layout(plt.plotargs, plt.seriesargs))
|
JSON.json(plotly_layout(plt))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function plotly_colorscale(grad::ColorGradient, alpha = nothing)
|
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
|
end
|
||||||
plotly_colorscale(c, alpha = nothing) = plotly_colorscale(default_gradient(), alpha)
|
plotly_colorscale(c, alpha = nothing) = plotly_colorscale(default_gradient(), alpha)
|
||||||
|
|
||||||
@ -357,196 +372,178 @@ const _plotly_markers = KW(
|
|||||||
:star5 => "star-triangle-up",
|
:star5 => "star-triangle-up",
|
||||||
:vline => "line-ns",
|
:vline => "line-ns",
|
||||||
:hline => "line-ew",
|
:hline => "line-ew",
|
||||||
)
|
)
|
||||||
|
|
||||||
# get a dictionary representing the series params (d is the Plots-dict, d_out is the Plotly-dict)
|
# 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)
|
function plotly_series(plt::Plot{PlotlyBackend}, series::Series)
|
||||||
# dumpdict(d,"series",true)
|
d = series.d
|
||||||
d_out = KW()
|
d_out = KW()
|
||||||
|
|
||||||
x, y = collect(d[:x]), collect(d[:y])
|
x, y = collect(d[:x]), collect(d[:y])
|
||||||
d_out[:name] = d[:label]
|
d_out[:name] = d[:label]
|
||||||
|
|
||||||
st = d[:seriestype]
|
st = d[:seriestype]
|
||||||
isscatter = st in (:scatter, :scatter3d)
|
isscatter = st in (:scatter, :scatter3d)
|
||||||
hasmarker = isscatter || d[:markershape] != :none
|
hasmarker = isscatter || d[:markershape] != :none
|
||||||
hasline = !isscatter
|
hasline = !isscatter
|
||||||
|
|
||||||
# set the "type"
|
# set the "type"
|
||||||
if st in (:line, :path, :scatter, :steppre, :steppost)
|
if st in (:line, :path, :scatter, :steppre, :steppost)
|
||||||
d_out[:type] = "scatter"
|
d_out[:type] = "scatter"
|
||||||
d_out[:mode] = if hasmarker
|
d_out[:mode] = if hasmarker
|
||||||
hasline ? "lines+markers" : "markers"
|
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"
|
|
||||||
else
|
else
|
||||||
"linear"
|
hasline ? "lines" : "none"
|
||||||
end,
|
end
|
||||||
:dash => string(d[:linestyle]),
|
if d[:fillrange] == true || d[:fillrange] == 0
|
||||||
# :dash => "solid",
|
d_out[:fill] = "tozeroy"
|
||||||
)
|
d_out[:fillcolor] = webcolor(d[:fillcolor], d[:fillalpha])
|
||||||
end
|
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
|
elseif st == :bar
|
||||||
if get(plotargs, :polar, false)
|
d_out[:type] = "bar"
|
||||||
d_out[:t] = rad2deg(pop!(d_out, :x))
|
d_out[:x], d_out[:y] = x, y
|
||||||
d_out[:r] = pop!(d_out, :y)
|
|
||||||
end
|
|
||||||
|
|
||||||
# # for subplots, we need to add the xaxis/yaxis fields
|
elseif st == :hist2d
|
||||||
# if plot_index != nothing
|
d_out[:type] = "histogram2d"
|
||||||
# d_out[:xaxis] = "x$(plot_index)"
|
d_out[:x], d_out[:y] = x, y
|
||||||
# d_out[:yaxis] = "y$(plot_index)"
|
if isa(d[:bins], Tuple)
|
||||||
# end
|
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
|
end
|
||||||
|
|
||||||
# get a list of dictionaries, each representing the series params
|
# get a list of dictionaries, each representing the series params
|
||||||
function get_series_json(plt::Plot{PlotlyBackend})
|
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
|
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})
|
function html_head(plt::AbstractPlot{PlotlyBackend})
|
||||||
"<script src=\"$(Pkg.dir("Plots","deps","plotly-latest.min.js"))\"></script>"
|
"<script src=\"$(Pkg.dir("Plots","deps","plotly-latest.min.js"))\"></script>"
|
||||||
end
|
end
|
||||||
|
|
||||||
function html_body(plt::Plot{PlotlyBackend}, style = nothing)
|
function html_body(plt::Plot{PlotlyBackend}, style = nothing)
|
||||||
if style == nothing
|
if style == nothing
|
||||||
w, h = plt.plotargs[:size]
|
w, h = plt.attr[:size]
|
||||||
style = "width:$(w)px;height:$(h)px;"
|
style = "width:$(w)px;height:$(h)px;"
|
||||||
end
|
end
|
||||||
uuid = Base.Random.uuid4()
|
uuid = Base.Random.uuid4()
|
||||||
html = """
|
html = """
|
||||||
<div id=\"$(uuid)\" style=\"$(style)\"></div>
|
<div id=\"$(uuid)\" style=\"$(style)\"></div>
|
||||||
<script>
|
<script>
|
||||||
PLOT = document.getElementById('$(uuid)');
|
PLOT = document.getElementById('$(uuid)');
|
||||||
Plotly.plot(PLOT, $(get_series_json(plt)), $(get_plot_json(plt)));
|
Plotly.plot(PLOT, $(get_series_json(plt)), $(get_plot_json(plt)));
|
||||||
</script>
|
</script>
|
||||||
"""
|
"""
|
||||||
# @show html
|
html
|
||||||
html
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function js_body(plt::Plot{PlotlyBackend}, uuid)
|
function js_body(plt::Plot{PlotlyBackend}, uuid)
|
||||||
@ -557,31 +554,6 @@ function js_body(plt::Plot{PlotlyBackend}, uuid)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# function html_body(subplt::Subplot{PlotlyBackend})
|
|
||||||
# w, h = subplt.plts[1].plotargs[:size]
|
|
||||||
# html = ["<div style=\"width:$(w)px;height:$(h)px;\">"]
|
|
||||||
# nr = nrows(subplt.layout)
|
|
||||||
# ph = h / nr
|
|
||||||
#
|
|
||||||
# for r in 1:nr
|
|
||||||
# push!(html, "<div style=\"clear:both;\">")
|
|
||||||
#
|
|
||||||
# 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, "</div>")
|
|
||||||
# end
|
|
||||||
# push!(html, "</div>")
|
|
||||||
#
|
|
||||||
# join(html)
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
function Base.writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{PlotlyBackend})
|
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})
|
function Base.writemime(io::IO, ::MIME"text/html", plt::AbstractPlot{PlotlyBackend})
|
||||||
write(io, html_head(plt) * html_body(plt))
|
write(io, html_head(plt) * html_body(plt))
|
||||||
# write(io, html_body(plt))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Base.display(::PlotsDisplay, plt::AbstractPlot{PlotlyBackend})
|
function Base.display(::PlotsDisplay, plt::AbstractPlot{PlotlyBackend})
|
||||||
standalone_html_window(plt)
|
standalone_html_window(plt)
|
||||||
end
|
end
|
||||||
|
|
||||||
# function Base.display(::PlotsDisplay, plt::Subplot{PlotlyBackend})
|
|
||||||
# # TODO: display/show the subplot
|
|
||||||
# end
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ supportedArgs(::PlotlyJSBackend) = [
|
|||||||
:show,
|
:show,
|
||||||
:size,
|
:size,
|
||||||
:title,
|
:title,
|
||||||
:windowtitle,
|
:window_title,
|
||||||
:x,
|
:x,
|
||||||
:xguide,
|
:xguide,
|
||||||
:xlims,
|
:xlims,
|
||||||
@ -118,7 +118,7 @@ function _series_added(plt::Plot{PlotlyJSBackend}, series::Series)
|
|||||||
syncplot = plt.o
|
syncplot = plt.o
|
||||||
|
|
||||||
# add to the data array
|
# add to the data array
|
||||||
pdict = plotly_series(d, plt.plotargs)
|
pdict = plotly_series(d, plt.attr)
|
||||||
typ = pop!(pdict, :type)
|
typ = pop!(pdict, :type)
|
||||||
gt = PlotlyJS.GenericTrace(typ; pdict...)
|
gt = PlotlyJS.GenericTrace(typ; pdict...)
|
||||||
PlotlyJS.addtraces!(syncplot, gt)
|
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})})
|
function _add_annotations{X,Y,V}(plt::Plot{PlotlyJSBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||||
# set or add to the annotation_list
|
# set or add to the annotation_list
|
||||||
if !haskey(plt.plotargs, :annotation_list)
|
if !haskey(plt.attr, :annotation_list)
|
||||||
plt.plotargs[:annotation_list] = Any[]
|
plt.attr[:annotation_list] = Any[]
|
||||||
end
|
end
|
||||||
append!(plt.plotargs[:annotation_list], anns)
|
append!(plt.attr[:annotation_list], anns)
|
||||||
end
|
end
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
@ -146,7 +146,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(plt.plotargs, plt.seriesargs)
|
pdict = plotly_layout(plt.attr, 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)
|
||||||
@ -167,7 +167,7 @@ end
|
|||||||
|
|
||||||
function setxy!{X,Y}(plt::Plot{PlotlyJSBackend}, xy::Tuple{X,Y}, i::Integer)
|
function setxy!{X,Y}(plt::Plot{PlotlyJSBackend}, xy::Tuple{X,Y}, i::Integer)
|
||||||
d = plt.seriesargs[i]
|
d = plt.seriesargs[i]
|
||||||
ispolar = get(plt.plotargs, :polar, false)
|
ispolar = get(plt.attr, :polar, false)
|
||||||
xsym = ispolar ? :t : :x
|
xsym = ispolar ? :t : :x
|
||||||
ysym = ispolar ? :r : :y
|
ysym = ispolar ? :r : :y
|
||||||
d[xsym], d[ysym] = xy
|
d[xsym], d[ysym] = xy
|
||||||
|
|||||||
@ -19,7 +19,7 @@ supportedArgs(::PyPlotBackend) = [
|
|||||||
:bins, :bar_width, :bar_edges,
|
:bins, :bar_width, :bar_edges,
|
||||||
:n, :nc, :nr, :layout,
|
:n, :nc, :nr, :layout,
|
||||||
:smooth,
|
:smooth,
|
||||||
:title, :windowtitle, :show, :size,
|
:title, :window_title, :show, :size,
|
||||||
:x, :xguide, :xlims, :xticks, :xscale, :xflip, :xrotation,
|
:x, :xguide, :xlims, :xticks, :xscale, :xflip, :xrotation,
|
||||||
:y, :yguide, :ylims, :yticks, :yscale, :yflip, :yrotation,
|
:y, :yguide, :ylims, :yticks, :yscale, :yflip, :yrotation,
|
||||||
# :axis, :yrightlabel,
|
# :axis, :yrightlabel,
|
||||||
@ -354,11 +354,11 @@ end
|
|||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function pyplot_figure(plotargs::KW)
|
function pyplot_figure(attr::KW)
|
||||||
w,h = map(px2inch, plotargs[:size])
|
w,h = map(px2inch, attr[:size])
|
||||||
|
|
||||||
# reuse the current figure?
|
# reuse the current figure?
|
||||||
fig = if plotargs[:overwrite_figure]
|
fig = if attr[:overwrite_figure]
|
||||||
PyPlot.gcf()
|
PyPlot.gcf()
|
||||||
else
|
else
|
||||||
PyPlot.figure()
|
PyPlot.figure()
|
||||||
@ -366,7 +366,7 @@ function pyplot_figure(plotargs::KW)
|
|||||||
|
|
||||||
# update the specs
|
# update the specs
|
||||||
fig[:set_size_inches](w, h, forward = true)
|
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_dpi](DPI)
|
||||||
# fig[:set_tight_layout](true)
|
# fig[:set_tight_layout](true)
|
||||||
|
|
||||||
@ -374,7 +374,7 @@ function pyplot_figure(plotargs::KW)
|
|||||||
PyPlot.clf()
|
PyPlot.clf()
|
||||||
|
|
||||||
# resize the window
|
# resize the window
|
||||||
PyPlot.plt[:get_current_fig_manager]()[:resize](plotargs[:size]...)
|
PyPlot.plt[:get_current_fig_manager]()[:resize](attr[:size]...)
|
||||||
fig
|
fig
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -382,7 +382,7 @@ end
|
|||||||
|
|
||||||
# Create the window/figure for this backend.
|
# Create the window/figure for this backend.
|
||||||
function _create_backend_figure(plt::Plot{PyPlotBackend})
|
function _create_backend_figure(plt::Plot{PyPlotBackend})
|
||||||
pyplot_figure(plt.plotargs)
|
pyplot_figure(plt.attr)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set up the subplot within the backend object.
|
# Set up the subplot within the backend object.
|
||||||
@ -1212,7 +1212,7 @@ for (mime, fmt) in _pyplot_mimeformats
|
|||||||
io,
|
io,
|
||||||
format=$fmt,
|
format=$fmt,
|
||||||
# bbox_inches = "tight",
|
# bbox_inches = "tight",
|
||||||
# figsize = map(px2inch, plt.plotargs[:size]),
|
# figsize = map(px2inch, plt.attr[:size]),
|
||||||
facecolor = fig.o["get_facecolor"](),
|
facecolor = fig.o["get_facecolor"](),
|
||||||
edgecolor = "none",
|
edgecolor = "none",
|
||||||
dpi = DPI
|
dpi = DPI
|
||||||
|
|||||||
@ -31,7 +31,7 @@ supportedArgs(::QwtBackend) = [
|
|||||||
:show,
|
:show,
|
||||||
:size,
|
:size,
|
||||||
:title,
|
:title,
|
||||||
:windowtitle,
|
:window_title,
|
||||||
:x,
|
:x,
|
||||||
:xguide,
|
:xguide,
|
||||||
:xlims,
|
:xlims,
|
||||||
@ -130,9 +130,9 @@ end
|
|||||||
|
|
||||||
# function _create_plot(pkg::QwtBackend, d::KW)
|
# function _create_plot(pkg::QwtBackend, d::KW)
|
||||||
function _create_backend_figure(plt::Plot{QwtBackend})
|
function _create_backend_figure(plt::Plot{QwtBackend})
|
||||||
fixcolors(plt.plotargs)
|
fixcolors(plt.attr)
|
||||||
dumpdict(plt.plotargs,"\n\n!!! plot")
|
dumpdict(plt.attr,"\n\n!!! plot")
|
||||||
o = Qwt.plot(zeros(0,0); plt.plotargs..., show=false)
|
o = Qwt.plot(zeros(0,0); plt.attr..., show=false)
|
||||||
# plt = Plot(o, pkg, 0, d, KW[])
|
# plt = Plot(o, pkg, 0, d, KW[])
|
||||||
# plt
|
# plt
|
||||||
end
|
end
|
||||||
@ -287,7 +287,7 @@ end
|
|||||||
# # i += rowcnt
|
# # i += rowcnt
|
||||||
# # end
|
# # end
|
||||||
# subplt.o = Qwt.vsplitter(rows...)
|
# 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
|
# # Qwt.moveToLastScreen(subplt.o) # hack so it goes to my center monitor... sorry
|
||||||
# true
|
# true
|
||||||
# end
|
# end
|
||||||
|
|||||||
@ -35,7 +35,7 @@ supportedArgs(::UnicodePlotsBackend) = [
|
|||||||
:show,
|
:show,
|
||||||
:size,
|
:size,
|
||||||
:title,
|
:title,
|
||||||
:windowtitle,
|
:window_title,
|
||||||
:x,
|
:x,
|
||||||
:xguide,
|
:xguide,
|
||||||
:xlims,
|
:xlims,
|
||||||
@ -78,7 +78,7 @@ function rebuildUnicodePlot!(plt::Plot)
|
|||||||
|
|
||||||
# figure out the plotting area xlim = [xmin, xmax] and ylim = [ymin, ymax]
|
# figure out the plotting area xlim = [xmin, xmax] and ylim = [ymin, ymax]
|
||||||
sargs = plt.seriesargs
|
sargs = plt.seriesargs
|
||||||
iargs = plt.plotargs
|
iargs = plt.attr
|
||||||
|
|
||||||
# get the x/y limits
|
# get the x/y limits
|
||||||
if get(iargs, :xlims, :auto) == :auto
|
if get(iargs, :xlims, :auto) == :auto
|
||||||
@ -186,10 +186,10 @@ end
|
|||||||
|
|
||||||
function _create_backend_figure(plt::Plot{UnicodePlotsBackend})
|
function _create_backend_figure(plt::Plot{UnicodePlotsBackend})
|
||||||
# do we want to give a new default size?
|
# do we want to give a new default size?
|
||||||
if !haskey(plt.plotargs, :size) || plt.plotargs[:size] == default(:size)
|
if !haskey(plt.attr, :size) || plt.attr[:size] == default(:size)
|
||||||
plt.plotargs[:size] = (60,20)
|
plt.attr[:size] = (60,20)
|
||||||
end
|
end
|
||||||
plt.plotargs[:color_palette] = [RGB(0,0,0)]
|
plt.attr[:color_palette] = [RGB(0,0,0)]
|
||||||
nothing
|
nothing
|
||||||
|
|
||||||
# plt
|
# plt
|
||||||
@ -211,7 +211,7 @@ end
|
|||||||
function _update_plot(plt::Plot{UnicodePlotsBackend}, d::KW)
|
function _update_plot(plt::Plot{UnicodePlotsBackend}, d::KW)
|
||||||
for k in (:title, :xguide, :yguide, :xlims, :ylims)
|
for k in (:title, :xguide, :yguide, :xlims, :ylims)
|
||||||
if haskey(d, k)
|
if haskey(d, k)
|
||||||
plt.plotargs[k] = d[k]
|
plt.attr[k] = d[k]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
# CREDIT: parts of this implementation were inspired by @joshday's PlotlyLocal.jl
|
# 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"))
|
||||||
"""
|
"""
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
@ -27,7 +27,7 @@ function open_browser_window(filename::AbstractString)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function write_temp_html(plt::AbstractPlot)
|
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")
|
filename = string(tempname(), ".html")
|
||||||
output = open(filename, "w")
|
output = open(filename, "w")
|
||||||
write(output, html)
|
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
|
# convert that html file to a temporary png file using wkhtmltoimage
|
||||||
png_fn = tempname() * ".png"
|
png_fn = tempname() * ".png"
|
||||||
w, h = plt.plotargs[:size]
|
w, h = plt.attr[:size]
|
||||||
html_to_png(html_fn, png_fn, w, h)
|
html_to_png(html_fn, png_fn, w, h)
|
||||||
|
|
||||||
# now read that file data into io
|
# now read that file data into io
|
||||||
|
|||||||
@ -39,7 +39,7 @@ supportedArgs(::WinstonBackend) = [
|
|||||||
:show,
|
:show,
|
||||||
:size,
|
:size,
|
||||||
:title,
|
:title,
|
||||||
:windowtitle,
|
:window_title,
|
||||||
:x,
|
:x,
|
||||||
:xguide,
|
:xguide,
|
||||||
:xlims,
|
:xlims,
|
||||||
@ -104,9 +104,9 @@ end
|
|||||||
|
|
||||||
function _create_backend_figure(plt::Plot{WinstonBackend})
|
function _create_backend_figure(plt::Plot{WinstonBackend})
|
||||||
Winston.FramedPlot(
|
Winston.FramedPlot(
|
||||||
title = plt.plotargs[:title],
|
title = plt.attr[:title],
|
||||||
xlabel = plt.plotargs[:xguide],
|
xlabel = plt.attr[:xguide],
|
||||||
ylabel = plt.plotargs[:yguide]
|
ylabel = plt.attr[:yguide]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ end
|
|||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
function addWinstonLegend(plt::Plot, wplt)
|
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])
|
Winston.legend(wplt, [sd[:label] for sd in plt.seriesargs])
|
||||||
end
|
end
|
||||||
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")
|
error("Gtk is the only supported display for Winston in Plots. Set `output_surface = gtk` in src/Winston.ini")
|
||||||
end
|
end
|
||||||
# initialize window
|
# initialize window
|
||||||
w,h = plt.plotargs[:size]
|
w,h = plt.attr[:size]
|
||||||
canvas = Gtk.GtkCanvasLeaf()
|
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)
|
plt.o = (window, canvas, wplt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -348,10 +348,10 @@ end
|
|||||||
make255(x) = round(Int, 255 * x)
|
make255(x) = round(Int, 255 * x)
|
||||||
|
|
||||||
function webcolor(c::Color)
|
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
|
end
|
||||||
function webcolor(c::TransparentColor)
|
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
|
end
|
||||||
webcolor(cs::ColorScheme) = webcolor(getColor(cs))
|
webcolor(cs::ColorScheme) = webcolor(getColor(cs))
|
||||||
webcolor(c) = webcolor(convertColor(c))
|
webcolor(c) = webcolor(convertColor(c))
|
||||||
@ -412,10 +412,10 @@ webcolor(c, α) = webcolor(convertColor(getColor(c), α))
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
# converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically
|
# 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
|
if c == :auto
|
||||||
c = autopick(plotargs[:color_palette], n)
|
c = autopick(attr[:color_palette], n)
|
||||||
end
|
end
|
||||||
|
|
||||||
# c should now be a subtype of ColorScheme
|
# c should now be a subtype of ColorScheme
|
||||||
|
|||||||
19
src/plot.jl
19
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))
|
Base.show(io::IO, plt::Plot) = print(io, string(plt))
|
||||||
|
|
||||||
getplot(plt::Plot) = 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
|
convertSeriesIndex(plt::Plot, n::Int) = n
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
@ -54,7 +54,7 @@ function plot(args...; kw...)
|
|||||||
plt.o = _create_backend_figure(plt)
|
plt.o = _create_backend_figure(plt)
|
||||||
|
|
||||||
# create the layout and subplots from the inputs
|
# 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)
|
for (idx,sp) in enumerate(plt.subplots)
|
||||||
sp.plt = plt
|
sp.plt = plt
|
||||||
_update_subplot_args(plt, sp, copy(d), idx)
|
_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
|
# assuming there was no error, recursively apply the series recipes
|
||||||
for series in series_list
|
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
|
end
|
||||||
end
|
end
|
||||||
@ -284,7 +289,7 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# 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.attr)
|
||||||
|
|
||||||
current(plt)
|
current(plt)
|
||||||
|
|
||||||
@ -317,7 +322,7 @@ end
|
|||||||
# function setTicksFromStringVector(plt::Plot, d::KW, di::KW, letter)
|
# function setTicksFromStringVector(plt::Plot, d::KW, di::KW, letter)
|
||||||
# sym = symbol(letter)
|
# sym = symbol(letter)
|
||||||
# ticksym = symbol(letter * "ticks")
|
# ticksym = symbol(letter * "ticks")
|
||||||
# pargs = plt.plotargs
|
# pargs = plt.attr
|
||||||
# v = di[sym]
|
# v = di[sym]
|
||||||
#
|
#
|
||||||
# # do we really want to do this?
|
# # do we really want to do this?
|
||||||
@ -345,7 +350,7 @@ end
|
|||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# d[ticksym] = ticks, labels
|
# 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
|
# # add an origsym field so that later on we can re-compute the x vector if ticks change
|
||||||
# origsym = symbol(letter * "orig")
|
# origsym = symbol(letter * "orig")
|
||||||
@ -373,7 +378,7 @@ annotations(anns) = Any[anns]
|
|||||||
|
|
||||||
# function Base.copy(plt::Plot)
|
# function Base.copy(plt::Plot)
|
||||||
# backend(plt.backend)
|
# backend(plt.backend)
|
||||||
# plt2 = plot(; plt.plotargs...)
|
# plt2 = plot(; plt.attr...)
|
||||||
# for sargs in plt.seriesargs
|
# for sargs in plt.seriesargs
|
||||||
# sargs = filter((k,v) -> haskey(_series_defaults,k), sargs)
|
# sargs = filter((k,v) -> haskey(_series_defaults,k), sargs)
|
||||||
# plot!(plt2; sargs...)
|
# plot!(plt2; sargs...)
|
||||||
|
|||||||
@ -550,7 +550,7 @@ type OHLC{T<:Real}
|
|||||||
close::T
|
close::T
|
||||||
end
|
end
|
||||||
Base.convert(::Type{OHLC}, tup::Tuple) = OHLC(tup...)
|
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
|
# get one OHLC path
|
||||||
function get_xy(o::OHLC, x, xdiff)
|
function get_xy(o::OHLC, x, xdiff)
|
||||||
|
|||||||
@ -138,7 +138,7 @@ compute_xyz(x::Void, y::Void, z::Void) = error("x/y/z are all nothing!")
|
|||||||
# n = plt.n + i
|
# n = plt.n + i
|
||||||
#
|
#
|
||||||
# dumpdict(d, "before getSeriesArgs")
|
# 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")
|
# dumpdict(d, "after getSeriesArgs")
|
||||||
#
|
#
|
||||||
# d[:x], d[:y], d[:z] = compute_xyz(xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)])
|
# 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)
|
# # special handling... xmin/xmax with function(s)
|
||||||
# function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs, xmin::Number, xmax::Number)
|
# 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)
|
# x = linspace(xmin, xmax, width)
|
||||||
# process_inputs(plt, d, x, f)
|
# process_inputs(plt, d, x, f)
|
||||||
# end
|
# end
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
|
||||||
pkg = plt.backend
|
pkg = plt.backend
|
||||||
# n = plt.n
|
# n = plt.n
|
||||||
# plotargs = getplotargs(plt, n)
|
# attr = getattr(plt, n)
|
||||||
# plotIndex = convertSeriesIndex(plt, n)
|
# plotIndex = convertSeriesIndex(plt, n)
|
||||||
globalIndex = plt.n
|
globalIndex = plt.n
|
||||||
|
|
||||||
@ -380,7 +380,7 @@ end
|
|||||||
#
|
#
|
||||||
# # special handling... xmin/xmax with function(s)
|
# # special handling... xmin/xmax with function(s)
|
||||||
# function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs, xmin::Number, xmax::Number)
|
# 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)
|
# x = linspace(xmin, xmax, width)
|
||||||
# process_inputs(plt, d, x, f)
|
# process_inputs(plt, d, x, f)
|
||||||
# end
|
# end
|
||||||
|
|||||||
@ -58,7 +58,7 @@ attr!(series::Series, v, k::Symbol) = (series.d[k] = v)
|
|||||||
type Plot{T<:AbstractBackend} <: AbstractPlot{T}
|
type Plot{T<:AbstractBackend} <: AbstractPlot{T}
|
||||||
backend::T # the backend type
|
backend::T # the backend type
|
||||||
n::Int # number of series
|
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
|
series_list::Vector{Series} # arguments for each series
|
||||||
o # the backend's plot object
|
o # the backend's plot object
|
||||||
subplots::Vector{Subplot}
|
subplots::Vector{Subplot}
|
||||||
@ -75,8 +75,8 @@ end
|
|||||||
# Base.getindex(plt::Plot, i::Integer) = plt.subplots[i]
|
# Base.getindex(plt::Plot, i::Integer) = plt.subplots[i]
|
||||||
Base.getindex(plt::Plot, s::Symbol) = plt.spmap[s]
|
Base.getindex(plt::Plot, s::Symbol) = plt.spmap[s]
|
||||||
Base.getindex(plt::Plot, r::Integer, c::Integer) = plt.layout[r,c]
|
Base.getindex(plt::Plot, r::Integer, c::Integer) = plt.layout[r,c]
|
||||||
attr(plt::Plot, k::Symbol) = plt.plotargs[k]
|
attr(plt::Plot, k::Symbol) = plt.attr[k]
|
||||||
attr!(plt::Plot, v, k::Symbol) = (plt.plotargs[k] = v)
|
attr!(plt::Plot, v, k::Symbol) = (plt.attr[k] = v)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user