Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3bd9e70fa9 | |||
| 54bd2c620e | |||
| 121640b1b3 | |||
| 55e388513c | |||
| b153dcbd63 | |||
| 242cbe5ecb | |||
| f1cca13796 | |||
| 918ba72107 | |||
| e596f27666 | |||
| a40d0000c5 | |||
| fb82da74a1 | |||
| b0991a0624 | |||
| 6236acea02 | |||
| 391c7e8570 | |||
| 58041cc64e | |||
| 8c7d3a6e92 | |||
| ae1982369c | |||
| 5f85ac01f7 | |||
| cca263fb2b | |||
| 809ed02b85 | |||
| 9eab1083ab | |||
| 60523bef80 | |||
| 46b959ff3c |
@@ -18,7 +18,7 @@ Plots is a plotting API and toolset. My goals with the package are:
|
||||
|
||||
Use the preprocessing pipeline in Plots to fully describe your visualization before it calls the backend code. This maintains modularity and allows for efficient separation of front end code, algorithms, and backend graphics. New graphical backends can be added with minimal effort.
|
||||
|
||||
Check out the [summary graphs](https://github.com/tbreloff/ExamplePlots.jl/tree/master/img/supported/supported.md) for the features that each backend supports.
|
||||
Check out the [summary graphs](img/supported/supported.md) for the features that each backend supports.
|
||||
|
||||
Please add wishlist items, bugs, or any other comments/questions to the issues list.
|
||||
|
||||
@@ -52,7 +52,8 @@ Pkg.add("Gadfly")
|
||||
Pkg.add("Immerse")
|
||||
Pkg.add("PyPlot")
|
||||
Pkg.add("UnicodePlots")
|
||||
Pkg.clone("https://github.com/tbreloff/Qwt.jl.git")
|
||||
Pkg.add("Qwt")
|
||||
Pkg.add("Bokeh")
|
||||
```
|
||||
|
||||
## Use
|
||||
@@ -206,14 +207,13 @@ Keyword | Default | Type | Aliases
|
||||
---- | ---- | ---- | ----
|
||||
`:annotation` | `nothing` | Series | `:ann`, `:annotate`, `:annotations`, `:anns`
|
||||
`:axis` | `left` | Series | `:axiss`
|
||||
`:background_color` | `RGB{U8}(1.0,1.0,1.0)` | Plot | `:background`, `:bg`, `:bg_color`, `:bgcolor`
|
||||
`:color` | `auto` | Series | `:c`, `:colors`
|
||||
`:background_color` | `RGB{U8}(1.0,1.0,1.0)` | Plot | `:background`, `:background_colour`, `:bg`, `:bg_color`, `:bgcolor`
|
||||
`:color_palette` | `auto` | Plot | `:palette`
|
||||
`:fill` | `nothing` | Series | `:area`, `:f`
|
||||
`:fillcolor` | `match` | Series | `:fc`, `:fcolor`, `:fillcolors`
|
||||
`:fillopacity` | `nothing` | Series | `:fillopacitys`, `:fo`
|
||||
`:fillalpha` | `nothing` | Series | `:fa`, `:fillalphas`, `:fillopacity`
|
||||
`:fillcolor` | `match` | Series | `:fc`, `:fcolor`, `:fillcolors`, `:fillcolour`
|
||||
`:fillrange` | `nothing` | Series | `:fillranges`, `:fillrng`
|
||||
`:foreground_color` | `auto` | Plot | `:fg`, `:fg_color`, `:fgcolor`, `:foreground`
|
||||
`:foreground_color` | `auto` | Plot | `:fg`, `:fg_color`, `:fgcolor`, `:foreground`, `:foreground_colour`
|
||||
`:grid` | `true` | Plot |
|
||||
`:group` | `nothing` | Series | `:g`, `:groups`
|
||||
`:guidefont` | `Plots.Font("Helvetica",11,:hcenter,:vcenter,0.0,RGB{U8}(0.0,0.0,0.0))` | Plot |
|
||||
@@ -222,7 +222,8 @@ Keyword | Default | Type | Aliases
|
||||
`:legend` | `true` | Plot | `:leg`
|
||||
`:legendfont` | `Plots.Font("Helvetica",8,:hcenter,:vcenter,0.0,RGB{U8}(0.0,0.0,0.0))` | Plot |
|
||||
`:line` | `nothing` | Series | `:l`
|
||||
`:lineopacity` | `nothing` | Series | `:lineopacitys`, `:lo`
|
||||
`:linealpha` | `nothing` | Series | `:la`, `:linealphas`, `:lineopacity`
|
||||
`:linecolor` | `auto` | Series | `:c`, `:color`, `:colour`, `:linecolors`
|
||||
`:linestyle` | `solid` | Series | `:linestyles`, `:ls`, `:s`, `:style`
|
||||
`:linetype` | `path` | Series | `:linetypes`, `:lt`, `:t`, `:type`
|
||||
`:linewidth` | `1` | Series | `:linewidths`, `:lw`, `:w`, `:width`
|
||||
@@ -231,18 +232,24 @@ Keyword | Default | Type | Aliases
|
||||
`:linkx` | `false` | Plot | `:xlink`
|
||||
`:linky` | `false` | Plot | `:ylink`
|
||||
`:marker` | `nothing` | Series | `:m`, `:mark`
|
||||
`:markercolor` | `match` | Series | `:markercolors`, `:mc`, `:mcolor`
|
||||
`:markeropacity` | `nothing` | Series | `:alpha`, `:markeropacitys`, `:mo`, `:opacity`
|
||||
`:markeralpha` | `nothing` | Series | `:alpha`, `:ma`, `:markeralphas`, `:markeropacity`, `:opacity`
|
||||
`:markercolor` | `match` | Series | `:markercolors`, `:markercolour`, `:mc`, `:mcolor`
|
||||
`:markershape` | `none` | Series | `:markershapes`, `:shape`
|
||||
`:markersize` | `6` | Series | `:markersizes`, `:ms`, `:msize`
|
||||
`:markerstrokealpha` | `nothing` | Series | `:markerstrokealphas`
|
||||
`:markerstrokecolor` | `match` | Series | `:markerstrokecolors`
|
||||
`:markerstrokestyle` | `solid` | Series | `:markerstrokestyles`
|
||||
`:markerstrokewidth` | `1` | Series | `:markerstrokewidths`
|
||||
`:n` | `-1` | Plot |
|
||||
`:nbins` | `100` | Series | `:nb`, `:nbin`, `:nbinss`
|
||||
`:nbins` | `30` | Series | `:nb`, `:nbin`, `:nbinss`
|
||||
`:nc` | `-1` | Plot |
|
||||
`:nlevels` | `15` | Series | `:nlevelss`
|
||||
`:nr` | `-1` | Plot |
|
||||
`:pos` | `(0,0)` | Plot |
|
||||
`:show` | `false` | Plot | `:display`, `:gui`
|
||||
`:size` | `(500,300)` | Plot | `:windowsize`, `:wsize`
|
||||
`:smooth` | `false` | Series | `:reg`, `:regression`, `:smooths`
|
||||
`:surface` | `nothing` | Series | `:surfaces`
|
||||
`:tickfont` | `Plots.Font("Helvetica",8,:hcenter,:vcenter,0.0,RGB{U8}(0.0,0.0,0.0))` | Plot |
|
||||
`:title` | `` | Plot |
|
||||
`:windowtitle` | `Plots.jl` | Plot | `:wtitle`
|
||||
@@ -280,6 +287,9 @@ Type | Desc | Aliases
|
||||
`:hline` | Horizontal line (doesn't use x) |
|
||||
`:vline` | Vertical line (doesn't use x) |
|
||||
`:ohlc` | Open/High/Low/Close chart (expects y is AbstractVector{Plots.OHLC}) |
|
||||
`:contour` | Contour lines (uses z) |
|
||||
`:path3d` | 3D path (uses z) | `:line3d`
|
||||
`:scatter3d` | 3D scatter plot (uses z) |
|
||||
|
||||
|
||||
### Line styles:
|
||||
|
||||
@@ -31,7 +31,7 @@ const examples = PlotExample[
|
||||
[
|
||||
:(p = plot([sin,cos], zeros(0), leg=false)),
|
||||
:(anim = Animation()),
|
||||
:(for x in linspace(0, 10π, 200)
|
||||
:(for x in linspace(0, 10π, 100)
|
||||
push!(p, x, Float64[sin(x), cos(x)])
|
||||
frame(anim)
|
||||
end)
|
||||
@@ -46,12 +46,15 @@ const examples = PlotExample[
|
||||
[
|
||||
:(y = rand(100)),
|
||||
:(plot(0:10:100,rand(11,4),lab="lines",w=3, palette=:grays, fill=(0.5,:auto))),
|
||||
:(scatter!(y, z=abs(y-.5), m=(10,:heat), lab="grad"))
|
||||
:(scatter!(y, zcolor=abs(y-.5), m=(:heat,0.8,stroke(3,:green)), ms=10*abs(y-0.5)+3, lab="grad"))
|
||||
]),
|
||||
PlotExample("Global",
|
||||
"Change the guides/background/limits/ticks. Convenience args `xaxis` and `yaxis` allow you to pass a tuple or value which will be mapped to the relevant args automatically. The `xaxis` below will be replaced with `xlabel` and `xlims` args automatically during the preprocessing step. You can also use shorthand functions: `title!`, `xaxis!`, `yaxis!`, `xlabel!`, `ylabel!`, `xlims!`, `ylims!`, `xticks!`, `yticks!`",
|
||||
[
|
||||
:(plot(rand(20,3), xaxis=("XLABEL",(-5,30),0:2:20,:flip), background_color = RGB(0.2,0.2,0.2), leg=false)),
|
||||
:(y = rand(20,3)),
|
||||
:(plot(y, xaxis=("XLABEL",(-5,30),0:2:20,:flip), background_color = RGB(0.2,0.2,0.2), leg=false)),
|
||||
:(hline!(mean(y,1)+rand(1,3), line=(4,:dash,0.6,[:lightgreen :green :darkgreen]))),
|
||||
:(vline!([5,10])),
|
||||
:(title!("TITLE")),
|
||||
:(yaxis!("YLABEL", :log10))
|
||||
]),
|
||||
@@ -63,7 +66,8 @@ const examples = PlotExample[
|
||||
PlotExample("Arguments",
|
||||
"Plot multiple series with different numbers of points. Mix arguments that apply to all series (marker/markersize) with arguments unique to each series (colors). Special arguments `line`, `marker`, and `fill` will automatically figure out what arguments to set (for example, we are setting the `linestyle`, `linewidth`, and `color` arguments with `line`.) Note that we pass a matrix of colors, and this applies the colors to each series.",
|
||||
[
|
||||
:(plot(Vector[rand(10), rand(20)], marker=(:ellipse,8), line=(:dot,3,[:black :orange])))
|
||||
:(ys = Vector[rand(10), rand(20)]),
|
||||
:(plot(ys, line=(:dot,4,[:black :orange]), marker=([:hex :d],12,0.8,stroke(3,:gray))))
|
||||
]),
|
||||
PlotExample("Build plot in pieces",
|
||||
"Start with a base plot...",
|
||||
@@ -78,7 +82,7 @@ const examples = PlotExample[
|
||||
PlotExample("Heatmaps",
|
||||
"",
|
||||
[
|
||||
:(heatmap(randn(10000),randn(10000), nbins=100))
|
||||
:(heatmap(randn(10000),randn(10000), nbins=20))
|
||||
]),
|
||||
PlotExample("Line types",
|
||||
"",
|
||||
@@ -112,7 +116,7 @@ const examples = PlotExample[
|
||||
PlotExample("Histogram",
|
||||
"",
|
||||
[
|
||||
:(histogram(randn(1000), nbins=50))
|
||||
:(histogram(randn(1000), nbins=20))
|
||||
]),
|
||||
PlotExample("Subplots",
|
||||
"""
|
||||
@@ -301,20 +305,23 @@ end
|
||||
|
||||
|
||||
@compat const _ltdesc = Dict(
|
||||
:none => "No line",
|
||||
:line => "Lines with sorted x-axis",
|
||||
:path => "Lines",
|
||||
:steppre => "Step plot (vertical then horizontal)",
|
||||
:steppost => "Step plot (horizontal then vertical)",
|
||||
:sticks => "Vertical lines",
|
||||
:scatter => "Points, no lines",
|
||||
:heatmap => "Colored regions by density",
|
||||
:hexbin => "Similar to heatmap",
|
||||
:hist => "Histogram (doesn't use x)",
|
||||
:bar => "Bar plot (centered on x values)",
|
||||
:hline => "Horizontal line (doesn't use x)",
|
||||
:vline => "Vertical line (doesn't use x)",
|
||||
:ohlc => "Open/High/Low/Close chart (expects y is AbstractVector{Plots.OHLC})",
|
||||
:none => "No line",
|
||||
:line => "Lines with sorted x-axis",
|
||||
:path => "Lines",
|
||||
:steppre => "Step plot (vertical then horizontal)",
|
||||
:steppost => "Step plot (horizontal then vertical)",
|
||||
:sticks => "Vertical lines",
|
||||
:scatter => "Points, no lines",
|
||||
:heatmap => "Colored regions by density",
|
||||
:hexbin => "Similar to heatmap",
|
||||
:hist => "Histogram (doesn't use x)",
|
||||
:bar => "Bar plot (centered on x values)",
|
||||
:hline => "Horizontal line (doesn't use x)",
|
||||
:vline => "Vertical line (doesn't use x)",
|
||||
:ohlc => "Open/High/Low/Close chart (expects y is AbstractVector{Plots.OHLC})",
|
||||
:contour => "Contour lines (uses z)",
|
||||
:path3d => "3D path (uses z)",
|
||||
:scatter3d => "3D scatter plot (uses z)",
|
||||
)
|
||||
|
||||
function buildReadme()
|
||||
|
||||
@@ -18,7 +18,7 @@ Plots is a plotting API and toolset. My goals with the package are:
|
||||
|
||||
Use the preprocessing pipeline in Plots to fully describe your visualization before it calls the backend code. This maintains modularity and allows for efficient separation of front end code, algorithms, and backend graphics. New graphical backends can be added with minimal effort.
|
||||
|
||||
Check out the [summary graphs](https://github.com/tbreloff/ExamplePlots.jl/tree/master/img/supported/supported.md) for the features that each backend supports.
|
||||
Check out the [summary graphs](img/supported/supported.md) for the features that each backend supports.
|
||||
|
||||
Please add wishlist items, bugs, or any other comments/questions to the issues list.
|
||||
|
||||
@@ -52,7 +52,8 @@ Pkg.add("Gadfly")
|
||||
Pkg.add("Immerse")
|
||||
Pkg.add("PyPlot")
|
||||
Pkg.add("UnicodePlots")
|
||||
Pkg.clone("https://github.com/tbreloff/Qwt.jl.git")
|
||||
Pkg.add("Qwt")
|
||||
Pkg.add("Bokeh")
|
||||
```
|
||||
|
||||
## Use
|
||||
|
||||
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 28 KiB |
@@ -19,6 +19,7 @@ export
|
||||
|
||||
current,
|
||||
default,
|
||||
with,
|
||||
|
||||
scatter,
|
||||
scatter!,
|
||||
@@ -62,6 +63,8 @@ export
|
||||
Shape,
|
||||
text,
|
||||
font,
|
||||
stroke,
|
||||
brush,
|
||||
OHLC,
|
||||
|
||||
colorscheme,
|
||||
@@ -104,6 +107,7 @@ const IMG_DIR = Pkg.dir("Plots") * "/img/"
|
||||
include("types.jl")
|
||||
include("utils.jl")
|
||||
include("colors.jl")
|
||||
include("components.jl")
|
||||
include("plotter.jl")
|
||||
include("args.jl")
|
||||
include("plot.jl")
|
||||
|
||||
@@ -7,8 +7,11 @@ const _allAxes = [:auto, :left, :right]
|
||||
:r => :right
|
||||
)
|
||||
|
||||
const _allTypes = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
||||
:heatmap, :hexbin, :hist, :bar, :hline, :vline, :ohlc, :contour]
|
||||
const _3dTypes = [:path3d, :scatter3d]
|
||||
const _allTypes = vcat([
|
||||
:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
||||
:heatmap, :hexbin, :hist, :bar, :hline, :vline, :ohlc, :contour
|
||||
], _3dTypes)
|
||||
@compat const _typeAliases = Dict(
|
||||
:n => :none,
|
||||
:no => :none,
|
||||
@@ -27,8 +30,10 @@ const _allTypes = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
||||
:dots => :scatter,
|
||||
:histogram => :hist,
|
||||
:contours => :contours,
|
||||
:line3d => :path3d,
|
||||
)
|
||||
|
||||
|
||||
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||
@compat const _styleAliases = Dict(
|
||||
:a => :auto,
|
||||
@@ -105,34 +110,38 @@ subplotSupported() = subplotSupported(backend())
|
||||
const _seriesDefaults = Dict{Symbol, Any}()
|
||||
|
||||
# series-specific
|
||||
_seriesDefaults[:axis] = :left
|
||||
_seriesDefaults[:color] = :auto
|
||||
_seriesDefaults[:label] = "AUTO"
|
||||
_seriesDefaults[:linetype] = :path
|
||||
_seriesDefaults[:linestyle] = :solid
|
||||
_seriesDefaults[:linewidth] = 1
|
||||
_seriesDefaults[:lineopacity] = nothing
|
||||
_seriesDefaults[:markershape] = :none
|
||||
_seriesDefaults[:markercolor] = :match
|
||||
_seriesDefaults[:markeropacity] = nothing
|
||||
_seriesDefaults[:markersize] = 6
|
||||
_seriesDefaults[:fillrange] = nothing # ribbons, areas, etc
|
||||
_seriesDefaults[:fillcolor] = :match
|
||||
_seriesDefaults[:fillopacity] = nothing
|
||||
# _seriesDefaults[:ribbon] = nothing
|
||||
# _seriesDefaults[:ribboncolor] = :match
|
||||
_seriesDefaults[:nbins] = 30 # number of bins for heatmaps and hists
|
||||
# _seriesDefaults[:heatmap_c] = (0.15, 0.5) # TODO: this should be replaced with a ColorGradient
|
||||
# _seriesDefaults[:fill] = nothing # fills in the area
|
||||
_seriesDefaults[:smooth] = false # regression line?
|
||||
_seriesDefaults[:group] = nothing # groupby vector
|
||||
_seriesDefaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation)
|
||||
_seriesDefaults[:z] = nothing # depth for contour, color scale, etc
|
||||
# _seriesDefaults[:args] = [] # additional args to pass to the backend
|
||||
# _seriesDefaults[:kwargs] = [] # additional keyword args to pass to the backend
|
||||
# # note: can be Vector{Dict} or Vector{Tuple}
|
||||
_seriesDefaults[:surface] = nothing
|
||||
_seriesDefaults[:nlevels] = 15
|
||||
_seriesDefaults[:axis] = :left
|
||||
_seriesDefaults[:label] = "AUTO"
|
||||
_seriesDefaults[:linetype] = :path
|
||||
_seriesDefaults[:linestyle] = :solid
|
||||
_seriesDefaults[:linewidth] = 1
|
||||
_seriesDefaults[:linecolor] = :auto
|
||||
_seriesDefaults[:linealpha] = nothing
|
||||
# _seriesDefaults[:linestroke] = Stroke(1, :auto, nothing, :solid) # linewidth, linecolor, linealpha, linestyle
|
||||
# _seriesDefaults[:fillbrush] = Brush(nothing, :match, nothing) # fillrange, fillcolor, fillalpha
|
||||
_seriesDefaults[:fillrange] = nothing # ribbons, areas, etc
|
||||
_seriesDefaults[:fillcolor] = :match
|
||||
_seriesDefaults[:fillalpha] = nothing
|
||||
_seriesDefaults[:markershape] = :none
|
||||
# _seriesDefaults[:markerstroke] = Stroke(1, :match_foreground, nothing, :solid)
|
||||
# _seriesDefaults[:markerbrush] = Brush(6, :match, nothing)
|
||||
_seriesDefaults[:markercolor] = :match
|
||||
_seriesDefaults[:markeralpha] = nothing
|
||||
_seriesDefaults[:markersize] = 6
|
||||
_seriesDefaults[:markerstrokestyle] = :solid
|
||||
_seriesDefaults[:markerstrokewidth] = 1
|
||||
_seriesDefaults[:markerstrokecolor] = :match
|
||||
_seriesDefaults[:markerstrokealpha] = nothing
|
||||
# _seriesDefaults[:ribbon] = nothing
|
||||
# _seriesDefaults[:ribboncolor] = :match
|
||||
_seriesDefaults[:nbins] = 30 # number of bins for heatmaps and hists
|
||||
_seriesDefaults[:smooth] = false # regression line?
|
||||
_seriesDefaults[:group] = nothing # groupby vector
|
||||
_seriesDefaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation)
|
||||
_seriesDefaults[:z] = nothing # depth for contour, surface, etc
|
||||
_seriesDefaults[:zcolor] = nothing # value for color scale
|
||||
_seriesDefaults[:surface] = nothing
|
||||
_seriesDefaults[:nlevels] = 15
|
||||
|
||||
|
||||
const _plotDefaults = Dict{Symbol, Any}()
|
||||
@@ -180,12 +189,6 @@ supportedArgs(::PlottingPackage) = _allArgs
|
||||
supportedArgs() = supportedArgs(backend())
|
||||
|
||||
|
||||
@compat const _argNotes = Dict(
|
||||
:color => "Series color. To have different marker and/or fill colors, optionally set the markercolor and fillcolor args.",
|
||||
:z => "Determines the depth. For color gradients, we expect 0 ≤ z ≤ 1.",
|
||||
# :heatmap_c => "For Qwt heatmaps only... will be deprecated eventually.",
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@@ -215,79 +218,88 @@ end
|
||||
# Alternate args
|
||||
|
||||
@compat const _keyAliases = Dict(
|
||||
:c => :color,
|
||||
:lab => :label,
|
||||
:l => :line,
|
||||
:w => :linewidth,
|
||||
:width => :linewidth,
|
||||
:lw => :linewidth,
|
||||
:lo => :lineopacity,
|
||||
:type => :linetype,
|
||||
:lt => :linetype,
|
||||
:t => :linetype,
|
||||
:style => :linestyle,
|
||||
:s => :linestyle,
|
||||
:ls => :linestyle,
|
||||
:m => :marker,
|
||||
:mark => :marker,
|
||||
:shape => :markershape,
|
||||
:mc => :markercolor,
|
||||
:mcolor => :markercolor,
|
||||
:ms => :markersize,
|
||||
:msize => :markersize,
|
||||
:mo => :markeropacity,
|
||||
:opacity => :markeropacity,
|
||||
:alpha => :markeropacity,
|
||||
:f => :fill,
|
||||
:area => :fill,
|
||||
:fillrng => :fillrange,
|
||||
:fc => :fillcolor,
|
||||
:fcolor => :fillcolor,
|
||||
:fo => :fillopacity,
|
||||
:g => :group,
|
||||
:nb => :nbins,
|
||||
:nbin => :nbins,
|
||||
:rib => :ribbon,
|
||||
:ann => :annotation,
|
||||
:anns => :annotation,
|
||||
:annotate => :annotation,
|
||||
:annotations => :annotation,
|
||||
:xlab => :xlabel,
|
||||
:ylab => :ylabel,
|
||||
:yrlab => :yrightlabel,
|
||||
:ylabr => :yrightlabel,
|
||||
:y2lab => :yrightlabel,
|
||||
:ylab2 => :yrightlabel,
|
||||
:ylabelright => :yrightlabel,
|
||||
:ylabel2 => :yrightlabel,
|
||||
:y2label => :yrightlabel,
|
||||
:leg => :legend,
|
||||
:bg => :background_color,
|
||||
:bgcolor => :background_color,
|
||||
:bg_color => :background_color,
|
||||
:background => :background_color,
|
||||
:fg => :foreground_color,
|
||||
:fgcolor => :foreground_color,
|
||||
:fg_color => :foreground_color,
|
||||
:foreground => :foreground_color,
|
||||
:regression => :smooth,
|
||||
:reg => :smooth,
|
||||
:xlim => :xlims,
|
||||
:xlimit => :xlims,
|
||||
:xlimits => :xlims,
|
||||
:ylim => :ylims,
|
||||
:ylimit => :ylims,
|
||||
:ylimits => :ylims,
|
||||
:xtick => :xticks,
|
||||
:ytick => :yticks,
|
||||
:windowsize => :size,
|
||||
:wsize => :size,
|
||||
:wtitle => :windowtitle,
|
||||
:gui => :show,
|
||||
:display => :show,
|
||||
:palette => :color_palette,
|
||||
:xlink => :linkx,
|
||||
:ylink => :linky,
|
||||
:c => :linecolor,
|
||||
:color => :linecolor,
|
||||
:colour => :linecolor,
|
||||
:lab => :label,
|
||||
:l => :line,
|
||||
:w => :linewidth,
|
||||
:width => :linewidth,
|
||||
:lw => :linewidth,
|
||||
:la => :linealpha,
|
||||
:lineopacity => :linealpha,
|
||||
:type => :linetype,
|
||||
:lt => :linetype,
|
||||
:t => :linetype,
|
||||
:style => :linestyle,
|
||||
:s => :linestyle,
|
||||
:ls => :linestyle,
|
||||
:m => :marker,
|
||||
:mark => :marker,
|
||||
:shape => :markershape,
|
||||
:mc => :markercolor,
|
||||
:mcolor => :markercolor,
|
||||
:markercolour => :markercolor,
|
||||
:ms => :markersize,
|
||||
:msize => :markersize,
|
||||
:ma => :markeralpha,
|
||||
:alpha => :markeralpha,
|
||||
:opacity => :markeralpha,
|
||||
:markeropacity => :markeralpha,
|
||||
:f => :fill,
|
||||
:area => :fill,
|
||||
:fillrng => :fillrange,
|
||||
:fc => :fillcolor,
|
||||
:fcolor => :fillcolor,
|
||||
:fillcolour => :fillcolor,
|
||||
:fa => :fillalpha,
|
||||
:fillopacity => :fillalpha,
|
||||
:g => :group,
|
||||
:nb => :nbins,
|
||||
:nbin => :nbins,
|
||||
:rib => :ribbon,
|
||||
:ann => :annotation,
|
||||
:anns => :annotation,
|
||||
:annotate => :annotation,
|
||||
:annotations => :annotation,
|
||||
:xlab => :xlabel,
|
||||
:ylab => :ylabel,
|
||||
:yrlab => :yrightlabel,
|
||||
:ylabr => :yrightlabel,
|
||||
:y2lab => :yrightlabel,
|
||||
:ylab2 => :yrightlabel,
|
||||
:ylabelright => :yrightlabel,
|
||||
:ylabel2 => :yrightlabel,
|
||||
:y2label => :yrightlabel,
|
||||
:leg => :legend,
|
||||
:bg => :background_color,
|
||||
:bgcolor => :background_color,
|
||||
:bg_color => :background_color,
|
||||
:background => :background_color,
|
||||
:background_colour => :background_color,
|
||||
:fg => :foreground_color,
|
||||
:fgcolor => :foreground_color,
|
||||
:fg_color => :foreground_color,
|
||||
:foreground => :foreground_color,
|
||||
:foreground_colour => :foreground_color,
|
||||
:regression => :smooth,
|
||||
:reg => :smooth,
|
||||
:xlim => :xlims,
|
||||
:xlimit => :xlims,
|
||||
:xlimits => :xlims,
|
||||
:ylim => :ylims,
|
||||
:ylimit => :ylims,
|
||||
:ylimits => :ylims,
|
||||
:xtick => :xticks,
|
||||
:ytick => :yticks,
|
||||
:windowsize => :size,
|
||||
:wsize => :size,
|
||||
:wtitle => :windowtitle,
|
||||
:gui => :show,
|
||||
:display => :show,
|
||||
:palette => :color_palette,
|
||||
:xlink => :linkx,
|
||||
:ylink => :linky,
|
||||
)
|
||||
|
||||
# add all pluralized forms to the _keyAliases dict
|
||||
@@ -401,16 +413,27 @@ function processLineArg(d::Dict, arg)
|
||||
elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
|
||||
d[:linestyle] = arg
|
||||
|
||||
elseif typeof(arg) <: Stroke
|
||||
arg.width == nothing || (d[:linewidth] = arg.width)
|
||||
arg.color == nothing || (d[:linecolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||
arg.alpha == nothing || (d[:linealpha] = arg.alpha)
|
||||
arg.style == nothing || (d[:linestyle] = arg.style)
|
||||
|
||||
elseif typeof(arg) <: Brush
|
||||
arg.size == nothing || (d[:fillrange] = arg.size)
|
||||
arg.color == nothing || (d[:fillcolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||
arg.alpha == nothing || (d[:fillalpha] = arg.alpha)
|
||||
|
||||
# linealpha
|
||||
elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
|
||||
d[:linealpha] = arg
|
||||
|
||||
# linewidth
|
||||
elseif trueOrAllTrue(a -> typeof(a) <: Integer, arg)
|
||||
elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
|
||||
d[:linewidth] = arg
|
||||
|
||||
# lineopacity
|
||||
elseif trueOrAllTrue(a -> typeof(a) <: Real && a >= 0 && a <= 1, arg)
|
||||
d[:lineopacity] = arg
|
||||
|
||||
# color
|
||||
elseif !handleColors!(d, arg, :color)
|
||||
elseif !handleColors!(d, arg, :linecolor)
|
||||
warn("Skipped line arg $arg.")
|
||||
|
||||
end
|
||||
@@ -424,15 +447,30 @@ function processMarkerArg(d::Dict, arg)
|
||||
d[:markershape] = arg
|
||||
elseif trueOrAllTrue(a -> isa(a, Shape), arg)
|
||||
d[:markershape] = arg
|
||||
|
||||
# stroke style
|
||||
elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
|
||||
d[:markerstrokestyle] = arg
|
||||
|
||||
elseif typeof(arg) <: Stroke
|
||||
arg.width == nothing || (d[:markerstrokewidth] = arg.width)
|
||||
arg.color == nothing || (d[:markerstrokecolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||
arg.alpha == nothing || (d[:markerstrokealpha] = arg.alpha)
|
||||
arg.style == nothing || (d[:markerstrokestyle] = arg.style)
|
||||
|
||||
elseif typeof(arg) <: Brush
|
||||
arg.size == nothing || (d[:markersize] = arg.size)
|
||||
arg.color == nothing || (d[:markercolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||
arg.alpha == nothing || (d[:markeralpha] = arg.alpha)
|
||||
|
||||
# linealpha
|
||||
elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
|
||||
d[:markeralpha] = arg
|
||||
|
||||
# markersize
|
||||
elseif trueOrAllTrue(a -> typeof(a) <: Integer, arg)
|
||||
elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
|
||||
d[:markersize] = arg
|
||||
|
||||
# lineopacity
|
||||
elseif trueOrAllTrue(a -> typeof(a) <: Real && a >= 0 && a <= 1, arg)
|
||||
d[:markeropacity] = arg
|
||||
|
||||
# markercolor
|
||||
elseif !handleColors!(d, arg, :markercolor)
|
||||
warn("Skipped marker arg $arg.")
|
||||
@@ -442,7 +480,13 @@ end
|
||||
|
||||
|
||||
function processFillArg(d::Dict, arg)
|
||||
if !handleColors!(d, arg, :fillcolor)
|
||||
|
||||
if typeof(arg) <: Brush
|
||||
arg.size == nothing || (d[:fillrange] = arg.size)
|
||||
arg.color == nothing || (d[:fillcolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||
arg.alpha == nothing || (d[:fillalpha] = arg.alpha)
|
||||
|
||||
elseif !handleColors!(d, arg, :fillcolor)
|
||||
d[:fillrange] = arg
|
||||
end
|
||||
end
|
||||
@@ -483,6 +527,8 @@ function preprocessArgs!(d::Dict)
|
||||
end
|
||||
delete!(d, :fill)
|
||||
|
||||
# convert into strokes and brushes
|
||||
|
||||
# handle subplot links
|
||||
if haskey(d, :link)
|
||||
l = d[:link]
|
||||
@@ -623,7 +669,7 @@ end
|
||||
|
||||
|
||||
# build the argument dictionary for a series
|
||||
function getSeriesArgs(pkg::PlottingPackage, initargs::Dict, kw, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in initargs, not plt
|
||||
function getSeriesArgs(pkg::PlottingPackage, plotargs::Dict, kw, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in plotargs, not plt
|
||||
kwdict = Dict(kw)
|
||||
d = Dict()
|
||||
|
||||
@@ -648,17 +694,24 @@ function getSeriesArgs(pkg::PlottingPackage, initargs::Dict, kw, commandIndex::I
|
||||
aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex)
|
||||
|
||||
# update color
|
||||
d[:color] = getSeriesRGBColor(d[:color], initargs, plotIndex)
|
||||
d[:linecolor] = getSeriesRGBColor(d[:linecolor], plotargs, plotIndex)
|
||||
|
||||
# update markercolor
|
||||
mc = d[:markercolor]
|
||||
mc = (mc == :match ? d[:color] : getSeriesRGBColor(mc, initargs, plotIndex))
|
||||
d[:markercolor] = mc
|
||||
c = d[:markercolor]
|
||||
c = (c == :match ? d[:linecolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||||
d[:markercolor] = c
|
||||
|
||||
# update markerstrokecolor
|
||||
c = d[:markerstrokecolor]
|
||||
c = (c == :match ? plotargs[:foreground_color] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||||
d[:markerstrokecolor] = c
|
||||
|
||||
# update fillcolor
|
||||
mc = d[:fillcolor]
|
||||
mc = (mc == :match ? d[:color] : getSeriesRGBColor(mc, initargs, plotIndex))
|
||||
d[:fillcolor] = mc
|
||||
c = d[:fillcolor]
|
||||
c = (c == :match ? d[:linecolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||||
d[:fillcolor] = c
|
||||
|
||||
# TODO: rebuild
|
||||
|
||||
# set label
|
||||
label = d[:label]
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
|
||||
# https://github.com/bokeh/Bokeh.jl
|
||||
|
||||
make255(x) = round(Int, 255 * x)
|
||||
|
||||
function bokehcolor(c::Colorant)
|
||||
@sprintf("rgba(%d, %d, %d, %1.3f)", [make255(f(c)) for f in [red,green,blue]]..., alpha(c))
|
||||
end
|
||||
bokehcolor(cs::ColorScheme) = bokehcolor(getColor(cs))
|
||||
|
||||
|
||||
const _glyphtypes = Dict(
|
||||
:ellipse => :Circle,
|
||||
:rect => :Square,
|
||||
:diamond => :Diamond,
|
||||
:utriangle => :Triangle,
|
||||
:dtriangle => :InvertedTriangle,
|
||||
# :pentagon =>
|
||||
# :hexagon =>
|
||||
# :heptagon =>
|
||||
# :octagon =>
|
||||
:cross => :Cross,
|
||||
:xcross => :X,
|
||||
:star5 => :Asterisk,
|
||||
)
|
||||
|
||||
|
||||
function bokeh_glyph_type(d::Dict)
|
||||
lt = d[:linetype]
|
||||
mt = d[:markershape]
|
||||
if lt == :scatter && mt == :none
|
||||
mt = :ellipse
|
||||
end
|
||||
|
||||
# if we have a marker, use that
|
||||
if lt == :scatter || mt != :none
|
||||
return _glyphtypes[mt]
|
||||
end
|
||||
|
||||
# otherwise return a line
|
||||
return :Line
|
||||
end
|
||||
|
||||
function get_stroke_vector(linestyle::Symbol)
|
||||
dash = 12
|
||||
dot = 3
|
||||
gap = 2
|
||||
linestyle == :solid && return Int[]
|
||||
linestyle == :dash && return Int[dash, gap]
|
||||
linestyle == :dot && return Int[dot, gap]
|
||||
linestyle == :dashdot && return Int[dash, gap, dot, gap]
|
||||
linestyle == :dashdotdot && return Int[dash, gap, dot, gap, dot, gap]
|
||||
error("unsupported linestyle: ", linestyle)
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
function _create_plot(pkg::BokehPackage; kw...)
|
||||
d = Dict(kw)
|
||||
|
||||
# dumpdict(d, "plot", true)
|
||||
|
||||
# TODO: create the window/canvas/context that is the plot within the backend (call it `o`)
|
||||
# TODO: initialize the plot... title, xlabel, bgcolor, etc
|
||||
|
||||
datacolumns = Bokeh.BokehDataSet[]
|
||||
tools = Bokeh.tools()
|
||||
filename = tempname() * ".html"
|
||||
title = d[:title]
|
||||
w, h = d[:size]
|
||||
xaxis_type = d[:xscale] == :log ? :log : :auto
|
||||
yaxis_type = d[:yscale] == :log ? :log : :auto
|
||||
# legend = d[:legend] ? xxxx : nothing
|
||||
legend = nothing
|
||||
extra_args = Dict() # TODO: we'll put extra settings (xlim, etc) here
|
||||
bplt = Bokeh.Plot(datacolumns, tools, filename, title, w, h, xaxis_type, yaxis_type, legend) #, extra_args)
|
||||
|
||||
Plot(bplt, pkg, 0, d, Dict[])
|
||||
end
|
||||
|
||||
|
||||
function _add_series(::BokehPackage, plt::Plot; kw...)
|
||||
d = Dict(kw)
|
||||
|
||||
# dumpdict(d, "plot!", true)
|
||||
|
||||
bdata = Dict{Symbol, Vector}(:x => collect(d[:x]), :y => collect(d[:y]))
|
||||
|
||||
glyph = Bokeh.Bokehjs.Glyph(
|
||||
glyphtype = bokeh_glyph_type(d),
|
||||
linecolor = bokehcolor(d[:linecolor]), # shape's stroke or line color
|
||||
linewidth = d[:linewidth], # shape's stroke width or line width
|
||||
fillcolor = bokehcolor(d[:markercolor]),
|
||||
size = ceil(Int, d[:markersize] * 2.5), # magic number 2.5 to keep in same scale as other backends
|
||||
dash = get_stroke_vector(d[:linestyle])
|
||||
)
|
||||
|
||||
legend = nothing # TODO
|
||||
push!(plt.o.datacolumns, Bokeh.BokehDataSet(bdata, glyph, legend))
|
||||
|
||||
push!(plt.seriesargs, d)
|
||||
plt
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# TODO: override this to update plot items (title, xlabel, etc) after creation
|
||||
function _update_plot(plt::Plot{BokehPackage}, d::Dict)
|
||||
end
|
||||
|
||||
function _update_plot_pos_size(plt::PlottingObject{BokehPackage}, d::Dict)
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# accessors for x/y data
|
||||
|
||||
function Base.getindex(plt::Plot{BokehPackage}, i::Int)
|
||||
series = plt.o.datacolumns[i].data
|
||||
series[:x], series[:y]
|
||||
end
|
||||
|
||||
function Base.setindex!(plt::Plot{BokehPackage}, xy::Tuple, i::Integer)
|
||||
series = plt.o.datacolumns[i].data
|
||||
series[:x], series[:y] = xy
|
||||
plt
|
||||
end
|
||||
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function _add_annotations{X,Y,V}(plt::Plot{BokehPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
for ann in anns
|
||||
# TODO: add the annotation to the plot
|
||||
end
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function _create_subplot(subplt::Subplot{BokehPackage}, isbefore::Bool)
|
||||
# TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
|
||||
|
||||
end
|
||||
|
||||
|
||||
function _expand_limits(lims, plt::Plot{BokehPackage}, isx::Bool)
|
||||
# TODO: call expand limits for each plot data
|
||||
end
|
||||
|
||||
function _remove_axis(plt::Plot{BokehPackage}, isx::Bool)
|
||||
# TODO: if plot is inner subplot, might need to remove ticks or axis labels
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function Base.writemime(io::IO, ::MIME"image/png", plt::PlottingObject{BokehPackage})
|
||||
# TODO: write a png to io
|
||||
warn("mime png not implemented")
|
||||
end
|
||||
|
||||
function Base.display(::PlotsDisplay, plt::Plot{BokehPackage})
|
||||
Bokeh.showplot(plt.o)
|
||||
end
|
||||
|
||||
function Base.display(::PlotsDisplay, plt::Subplot{BokehPackage})
|
||||
# TODO: display/show the subplot
|
||||
end
|
||||
@@ -7,7 +7,7 @@
|
||||
function createGadflyPlotObject(d::Dict)
|
||||
gplt = Gadfly.Plot()
|
||||
gplt.mapping = Dict()
|
||||
gplt.data_source = DataFrames.DataFrame()
|
||||
gplt.data_source = Gadfly.DataFrames.DataFrame()
|
||||
gplt.layers = gplt.layers[1:0]
|
||||
gplt.guides = Gadfly.GuideElement[Gadfly.Guide.xlabel(d[:xlabel]),
|
||||
Gadfly.Guide.ylabel(d[:ylabel]),
|
||||
@@ -36,9 +36,9 @@ function getLineGeom(d::Dict)
|
||||
elseif lt == :steppre
|
||||
Gadfly.Geom.step(direction = :vh)
|
||||
elseif lt == :hline
|
||||
Gadfly.Geom.hline(color = getColor(d[:color]), size = d[:linewidth] * Gadfly.px)
|
||||
Gadfly.Geom.hline
|
||||
elseif lt == :vline
|
||||
Gadfly.Geom.vline(color = getColor(d[:color]), size = d[:linewidth] * Gadfly.px)
|
||||
Gadfly.Geom.vline
|
||||
elseif lt == :contour
|
||||
Gadfly.Geom.contour(levels = d[:nlevels])
|
||||
else
|
||||
@@ -46,32 +46,51 @@ function getLineGeom(d::Dict)
|
||||
end
|
||||
end
|
||||
|
||||
function get_extra_theme_args(d::Dict, k::Symbol)
|
||||
# gracefully handles old Gadfly versions
|
||||
extra_theme_args = Dict()
|
||||
try
|
||||
extra_theme_args[:line_style] = Gadfly.get_stroke_vector(d[k])
|
||||
catch err
|
||||
if string(err) == "UndefVarError(:get_stroke_vector)"
|
||||
Base.warn_once("Gadfly.get_stroke_vector failed... do you have an old version of Gadfly?")
|
||||
else
|
||||
rethrow()
|
||||
end
|
||||
end
|
||||
extra_theme_args
|
||||
end
|
||||
|
||||
function getGadflyLineTheme(d::Dict)
|
||||
|
||||
lc = getColor(d[:color])
|
||||
α = d[:lineopacity]
|
||||
if α != nothing
|
||||
lc = RGBA(lc, α)
|
||||
end
|
||||
lc = convertColor(getColor(d[:linecolor]), d[:linealpha])
|
||||
# lc = getColor(d[:linecolor])
|
||||
# α = d[:linealpha]
|
||||
# if α != nothing
|
||||
# lc = RGBA(lc, α)
|
||||
# end
|
||||
|
||||
fc = convertColor(getColor(d[:fillcolor]), d[:fillalpha])
|
||||
# fc = getColor(d[:fillcolor])
|
||||
# α = d[:fillalpha]
|
||||
# if α != nothing
|
||||
# fc = RGBA(fc, α)
|
||||
# end
|
||||
|
||||
fc = getColor(d[:fillcolor])
|
||||
α = d[:fillopacity]
|
||||
if α != nothing
|
||||
fc = RGBA(fc, α)
|
||||
end
|
||||
|
||||
Gadfly.Theme(;
|
||||
default_color = lc,
|
||||
line_width = (d[:linetype] == :sticks ? 1 : d[:linewidth]) * Gadfly.px,
|
||||
line_style = Gadfly.get_stroke_vector(d[:linestyle]),
|
||||
# line_style = Gadfly.get_stroke_vector(d[:linestyle]),
|
||||
lowlight_color = x->RGB(fc), # fill/ribbon
|
||||
lowlight_opacity = alpha(fc), # fill/ribbon
|
||||
bar_highlight = RGB(lc), # bars
|
||||
get_extra_theme_args(d, :linestyle)...
|
||||
)
|
||||
end
|
||||
|
||||
# add a line as a new layer
|
||||
function addGadflyLine!(plt::Plot, d::Dict, geoms...)
|
||||
function addGadflyLine!(plt::Plot, numlayers::Int, d::Dict, geoms...)
|
||||
gplt = getGadflyContext(plt)
|
||||
gfargs = vcat(geoms...,
|
||||
getGadflyLineTheme(d))
|
||||
@@ -87,23 +106,49 @@ function addGadflyLine!(plt::Plot, d::Dict, geoms...)
|
||||
push!(gfargs, Gadfly.Geom.ribbon)
|
||||
end
|
||||
|
||||
# h/vlines
|
||||
if lt == :hline
|
||||
kwargs[:yintercept] = d[:y]
|
||||
elseif lt == :vline
|
||||
kwargs[:xintercept] = d[:y]
|
||||
elseif lt == :sticks
|
||||
w = 0.01 * mean(diff(d[:x]))
|
||||
kwargs[:xmin] = d[:x] - w
|
||||
kwargs[:xmax] = d[:x] + w
|
||||
elseif lt == :contour
|
||||
d[:y] = reverse(d[:y])
|
||||
kwargs[:z] = d[:surface]
|
||||
if lt in (:hline, :vline)
|
||||
kwargs[lt == :hline ? :yintercept : :xintercept] = d[:y]
|
||||
|
||||
else
|
||||
if lt == :sticks
|
||||
w = 0.01 * mean(diff(d[:x]))
|
||||
kwargs[:xmin] = d[:x] - w
|
||||
kwargs[:xmax] = d[:x] + w
|
||||
elseif lt == :contour
|
||||
d[:y] = reverse(d[:y])
|
||||
kwargs[:z] = d[:surface]
|
||||
end
|
||||
|
||||
kwargs[:x] = d[lt == :hist ? :y : :x]
|
||||
kwargs[:y] = d[:y]
|
||||
|
||||
end
|
||||
|
||||
# # h/vlines
|
||||
# if lt == :hline
|
||||
# kwargs[:yintercept] = d[:y]
|
||||
# elseif lt == :vline
|
||||
# kwargs[:xintercept] = d[:y]
|
||||
# elseif lt == :sticks
|
||||
# w = 0.01 * mean(diff(d[:x]))
|
||||
# kwargs[:xmin] = d[:x] - w
|
||||
# kwargs[:xmax] = d[:x] + w
|
||||
# elseif lt == :contour
|
||||
# d[:y] = reverse(d[:y])
|
||||
# kwargs[:z] = d[:surface]
|
||||
# end
|
||||
|
||||
# if lt == :hist
|
||||
# kwargs[:x] = kwargs[:y] = d[:y]
|
||||
# elseif lt != :hline && lt != :vline
|
||||
# kwargs[:x] = d[:x]
|
||||
# kwargs[:y] = d[:y]
|
||||
# end
|
||||
|
||||
# add the layer
|
||||
x = d[d[:linetype] == :hist ? :y : :x]
|
||||
Gadfly.layer(gfargs...; x = x, y = d[:y], kwargs...)
|
||||
# # add the layer
|
||||
# x = d[d[:linetype] == :hist ? :y : :x]
|
||||
# Gadfly.layer(gfargs...; x = x, y = d[:y], order=numlayers, kwargs...)
|
||||
Gadfly.layer(gfargs...; order=numlayers, kwargs...)
|
||||
end
|
||||
|
||||
|
||||
@@ -116,39 +161,48 @@ function getMarkerGeom(d::Dict)
|
||||
end
|
||||
|
||||
|
||||
function getGadflyMarkerTheme(d::Dict, initargs::Dict)
|
||||
function getGadflyMarkerTheme(d::Dict, plotargs::Dict)
|
||||
c = getColor(d[:markercolor])
|
||||
α = d[:markeropacity]
|
||||
α = d[:markeralpha]
|
||||
if α != nothing
|
||||
c = RGBA(RGB(c), α)
|
||||
end
|
||||
|
||||
fg = getColor(initargs[:foreground_color])
|
||||
Gadfly.Theme(
|
||||
ms = d[:markersize]
|
||||
ms = if typeof(ms) <: AVec
|
||||
warn("Gadfly doesn't support variable marker sizes... using the average: $(mean(ms))")
|
||||
mean(ms) * Gadfly.px
|
||||
else
|
||||
ms * Gadfly.px
|
||||
end
|
||||
|
||||
# fg = getColor(plotargs[:foreground_color])
|
||||
Gadfly.Theme(;
|
||||
default_color = c,
|
||||
default_point_size = d[:markersize] * Gadfly.px,
|
||||
discrete_highlight_color = c -> RGB(fg),
|
||||
highlight_width = d[:linewidth] * Gadfly.px,
|
||||
default_point_size = ms,
|
||||
discrete_highlight_color = c -> RGB(getColor(d[:markerstrokecolor])),
|
||||
highlight_width = d[:markerstrokewidth] * Gadfly.px,
|
||||
# get_extra_theme_args(d, :markerstrokestyle)...
|
||||
)
|
||||
end
|
||||
|
||||
function addGadflyMarker!(plt::Plot, d::Dict, initargs::Dict, geoms...)
|
||||
function addGadflyMarker!(plt::Plot, numlayers::Int, d::Dict, plotargs::Dict, geoms...)
|
||||
gfargs = vcat(geoms...,
|
||||
getGadflyMarkerTheme(d, initargs),
|
||||
getGadflyMarkerTheme(d, plotargs),
|
||||
getMarkerGeom(d))
|
||||
kwargs = Dict()
|
||||
|
||||
# handle continuous color scales for the markers
|
||||
z = d[:z]
|
||||
if z != nothing && typeof(z) <: AVec
|
||||
kwargs[:color] = z
|
||||
zcolor = d[:zcolor]
|
||||
if zcolor != nothing && typeof(zcolor) <: AVec
|
||||
kwargs[:color] = zcolor
|
||||
if !isa(d[:markercolor], ColorGradient)
|
||||
d[:markercolor] = colorscheme(:bluesreds)
|
||||
end
|
||||
push!(getGadflyContext(plt).scales, Gadfly.Scale.ContinuousColorScale(p -> RGB(getColorZ(d[:markercolor], p))))
|
||||
end
|
||||
|
||||
Gadfly.layer(gfargs...; x = d[:x], y = d[:y], kwargs...)
|
||||
Gadfly.layer(gfargs...; x = d[:x], y = d[:y], order=numlayers, kwargs...)
|
||||
end
|
||||
|
||||
|
||||
@@ -157,7 +211,7 @@ end
|
||||
function addToGadflyLegend(plt::Plot, d::Dict)
|
||||
|
||||
# add the legend?
|
||||
if plt.initargs[:legend]
|
||||
if plt.plotargs[:legend]
|
||||
gplt = getGadflyContext(plt)
|
||||
|
||||
# add the legend if needed
|
||||
@@ -172,7 +226,7 @@ function addToGadflyLegend(plt::Plot, d::Dict)
|
||||
# since gadfly will call unique(colors), but doesn't also merge the rows that match
|
||||
# Should ensure from this side that colors which are the same are merged together
|
||||
|
||||
c = getColor(d[d[:markershape] == :none ? :color : :markercolor])
|
||||
c = getColor(d[d[:markershape] == :none ? :linecolor : :markercolor])
|
||||
foundit = false
|
||||
|
||||
# extend the label if we found this color
|
||||
@@ -202,6 +256,7 @@ getGadflySmoothing(smooth::Real) = [Gadfly.Geom.smooth(method=:loess, smoothing=
|
||||
function addGadflySeries!(plt::Plot, d::Dict)
|
||||
|
||||
layers = Gadfly.Layer[]
|
||||
gplt = getGadflyContext(plt)
|
||||
|
||||
# add a regression line?
|
||||
# TODO: make more flexible
|
||||
@@ -210,7 +265,7 @@ function addGadflySeries!(plt::Plot, d::Dict)
|
||||
# lines
|
||||
geom = getLineGeom(d)
|
||||
if geom != nothing
|
||||
prepend!(layers, addGadflyLine!(plt, d, geom, smooth...))
|
||||
prepend!(layers, addGadflyLine!(plt, length(gplt.layers), d, geom, smooth...))
|
||||
|
||||
# don't add a regression for markers too
|
||||
smooth = Any[]
|
||||
@@ -226,14 +281,14 @@ function addGadflySeries!(plt::Plot, d::Dict)
|
||||
|
||||
# markers
|
||||
if d[:markershape] != :none
|
||||
prepend!(layers, addGadflyMarker!(plt, d, plt.initargs, smooth...))
|
||||
prepend!(layers, addGadflyMarker!(plt, length(gplt.layers), d, plt.plotargs, smooth...))
|
||||
end
|
||||
|
||||
lt in (:hist, :heatmap, :hexbin, :contour) || addToGadflyLegend(plt, d)
|
||||
|
||||
# now save the layers that apply to this series
|
||||
d[:gadflylayers] = layers
|
||||
prepend!(getGadflyContext(plt).layers, layers)
|
||||
prepend!(gplt.layers, layers)
|
||||
end
|
||||
|
||||
|
||||
@@ -245,7 +300,7 @@ end
|
||||
# z = d[:z]
|
||||
|
||||
# # handle line segments of different colors
|
||||
# cscheme = d[:color]
|
||||
# cscheme = d[:linecolor]
|
||||
# if isa(cscheme, ColorVector)
|
||||
# # create a color scale, and set the color group to the index of the color
|
||||
# push!(gplt.scales, Gadfly.Scale.color_discrete_manual(cscheme.v...))
|
||||
@@ -257,7 +312,7 @@ end
|
||||
# cs = collect(repmat(csindices', 2, 1))[1:end-1]
|
||||
# grp = collect(repmat((1:length(d[:y]))', 2, 1))[1:end-1]
|
||||
# d[:x], d[:y] = map(createSegments, (d[:x], d[:y]))
|
||||
# colorgroup = [(:color, cs), (:group, grp)]
|
||||
# colorgroup = [(:linecolor, cs), (:group, grp)]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -385,13 +440,13 @@ function updateGadflyGuides(plt::Plot, d::Dict)
|
||||
|
||||
ticks = get(d, :xticks, :auto)
|
||||
if ticks == :none
|
||||
handleLinkInner(plt, true)
|
||||
_remove_axis(plt, true)
|
||||
else
|
||||
addGadflyTicksGuide(gplt, ticks, true)
|
||||
end
|
||||
ticks = get(d, :yticks, :auto)
|
||||
if ticks == :none
|
||||
handleLinkInner(plt, false)
|
||||
_remove_axis(plt, false)
|
||||
else
|
||||
addGadflyTicksGuide(gplt, ticks, false)
|
||||
end
|
||||
@@ -403,9 +458,9 @@ end
|
||||
function updateGadflyPlotTheme(plt::Plot, d::Dict)
|
||||
kwargs = Dict()
|
||||
|
||||
# # get the full initargs, overriding any new settings
|
||||
# # get the full plotargs, overriding any new settings
|
||||
# # TODO: should this be part of the main `plot` command in plot.jl???
|
||||
# d = merge!(plt.initargs, d)
|
||||
# d = merge!(plt.plotargs, d)
|
||||
|
||||
# hide the legend?
|
||||
if !get(d, :legend, true)
|
||||
@@ -463,7 +518,7 @@ function createGadflyAnnotationObject(x, y, txt::PlotText)
|
||||
))
|
||||
end
|
||||
|
||||
function addAnnotations{X,Y,V}(plt::Plot{GadflyPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
function _add_annotations{X,Y,V}(plt::Plot{GadflyPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
for ann in anns
|
||||
push!(plt.o.guides, createGadflyAnnotationObject(ann...))
|
||||
end
|
||||
@@ -473,7 +528,7 @@ end
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# create a blank Gadfly.Plot object
|
||||
function plot(pkg::GadflyPackage; kw...)
|
||||
function _create_plot(pkg::GadflyPackage; kw...)
|
||||
d = Dict(kw)
|
||||
gplt = createGadflyPlotObject(d)
|
||||
Plot(gplt, pkg, 0, d, Dict[])
|
||||
@@ -481,7 +536,7 @@ end
|
||||
|
||||
|
||||
# plot one data series
|
||||
function plot!(::GadflyPackage, plt::Plot; kw...)
|
||||
function _add_series(::GadflyPackage, plt::Plot; kw...)
|
||||
d = Dict(kw)
|
||||
addGadflySeries!(plt, d)
|
||||
push!(plt.seriesargs, d)
|
||||
@@ -490,7 +545,7 @@ end
|
||||
|
||||
|
||||
|
||||
function updatePlotItems(plt::Plot{GadflyPackage}, d::Dict)
|
||||
function _update_plot(plt::Plot{GadflyPackage}, d::Dict)
|
||||
updateGadflyGuides(plt, d)
|
||||
updateGadflyPlotTheme(plt, d)
|
||||
end
|
||||
@@ -522,22 +577,22 @@ end
|
||||
|
||||
|
||||
# create the underlying object (each backend will do this differently)
|
||||
function buildSubplotObject!(subplt::Subplot{GadflyPackage}, isbefore::Bool)
|
||||
function _create_subplot(subplt::Subplot{GadflyPackage}, isbefore::Bool)
|
||||
isbefore && return false # wait until after plotting to create the subplots
|
||||
subplt.o = nothing
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
function handleLinkInner(plt::Plot{GadflyPackage}, isx::Bool)
|
||||
function _remove_axis(plt::Plot{GadflyPackage}, isx::Bool)
|
||||
gplt = getGadflyContext(plt)
|
||||
addOrReplace(gplt.guides, isx ? Gadfly.Guide.xticks : Gadfly.Guide.yticks; label=false)
|
||||
addOrReplace(gplt.guides, isx ? Gadfly.Guide.xlabel : Gadfly.Guide.ylabel, "")
|
||||
end
|
||||
|
||||
function expandLimits!(lims, plt::Plot{GadflyPackage}, isx::Bool)
|
||||
function _expand_limits(lims, plt::Plot{GadflyPackage}, isx::Bool)
|
||||
for l in getGadflyContext(plt).layers
|
||||
expandLimits!(lims, l.mapping[isx ? :x : :y])
|
||||
_expand_limits(lims, l.mapping[isx ? :x : :y])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -569,8 +624,8 @@ function buildGadflySubplotContext(subplt::Subplot)
|
||||
end
|
||||
|
||||
setGadflyDisplaySize(w,h) = Compose.set_default_graphic_size(w * Compose.px, h * Compose.px)
|
||||
setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.initargs[:size]...)
|
||||
setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getinitargs(subplt, 1)[:size]...)
|
||||
setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.plotargs[:size]...)
|
||||
setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getplotargs(subplt, 1)[:size]...)
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -597,14 +652,14 @@ end
|
||||
|
||||
|
||||
function Base.display(::PlotsDisplay, plt::Plot{GadflyPackage})
|
||||
setGadflyDisplaySize(plt.initargs[:size]...)
|
||||
setGadflyDisplaySize(plt.plotargs[:size]...)
|
||||
display(plt.o)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function Base.display(::PlotsDisplay, subplt::Subplot{GadflyPackage})
|
||||
setGadflyDisplaySize(getinitargs(subplt,1)[:size]...)
|
||||
setGadflyDisplaySize(getplotargs(subplt,1)[:size]...)
|
||||
ctx = buildGadflySubplotContext(subplt)
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,6 @@
|
||||
|
||||
# https://github.com/JuliaGraphics/Immerse.jl
|
||||
|
||||
# immutable ImmersePackage <: PlottingPackage end
|
||||
|
||||
# export immerse
|
||||
# immerse() = backend(:immerse)
|
||||
|
||||
|
||||
# supportedArgs(::ImmersePackage) = supportedArgs(GadflyPackage())
|
||||
# supportedAxes(::ImmersePackage) = supportedAxes(GadflyPackage())
|
||||
# supportedTypes(::ImmersePackage) = supportedTypes(GadflyPackage())
|
||||
# supportedStyles(::ImmersePackage) = supportedStyles(GadflyPackage())
|
||||
# supportedMarkers(::ImmersePackage) = supportedMarkers(GadflyPackage())
|
||||
# supportedScales(::ImmersePackage) = supportedScales(GadflyPackage())
|
||||
|
||||
|
||||
function createImmerseFigure(d::Dict)
|
||||
w,h = d[:size]
|
||||
@@ -21,9 +8,11 @@ function createImmerseFigure(d::Dict)
|
||||
Immerse.Figure(figidx)
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
|
||||
# create a blank Gadfly.Plot object
|
||||
function plot(pkg::ImmersePackage; kw...)
|
||||
function _create_plot(pkg::ImmersePackage; kw...)
|
||||
d = Dict(kw)
|
||||
|
||||
# create the underlying Gadfly.Plot object
|
||||
@@ -35,7 +24,7 @@ end
|
||||
|
||||
|
||||
# plot one data series
|
||||
function plot!(::ImmersePackage, plt::Plot; kw...)
|
||||
function _add_series(::ImmersePackage, plt::Plot; kw...)
|
||||
d = Dict(kw)
|
||||
addGadflySeries!(plt, d)
|
||||
push!(plt.seriesargs, d)
|
||||
@@ -43,7 +32,7 @@ function plot!(::ImmersePackage, plt::Plot; kw...)
|
||||
end
|
||||
|
||||
|
||||
function updatePlotItems(plt::Plot{ImmersePackage}, d::Dict)
|
||||
function _update_plot(plt::Plot{ImmersePackage}, d::Dict)
|
||||
updateGadflyGuides(plt, d)
|
||||
updateGadflyPlotTheme(plt, d)
|
||||
end
|
||||
@@ -52,7 +41,7 @@ end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function addAnnotations{X,Y,V}(plt::Plot{ImmersePackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
function _add_annotations{X,Y,V}(plt::Plot{ImmersePackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
for ann in anns
|
||||
push!(getGadflyContext(plt).guides, createGadflyAnnotationObject(ann...))
|
||||
end
|
||||
@@ -78,14 +67,14 @@ end
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
|
||||
function buildSubplotObject!(subplt::Subplot{ImmersePackage}, isbefore::Bool)
|
||||
function _create_subplot(subplt::Subplot{ImmersePackage}, isbefore::Bool)
|
||||
return false
|
||||
# isbefore && return false
|
||||
end
|
||||
|
||||
function showSubplotObject(subplt::Subplot{ImmersePackage})
|
||||
# create the Gtk window with vertical box vsep
|
||||
d = getinitargs(subplt,1)
|
||||
d = getplotargs(subplt,1)
|
||||
w,h = d[:size]
|
||||
vsep = Gtk.GtkBoxLeaf(:v)
|
||||
win = Gtk.GtkWindowLeaf(vsep, d[:windowtitle], w, h)
|
||||
@@ -125,15 +114,15 @@ function showSubplotObject(subplt::Subplot{ImmersePackage})
|
||||
end
|
||||
|
||||
|
||||
function handleLinkInner(plt::Plot{ImmersePackage}, isx::Bool)
|
||||
function _remove_axis(plt::Plot{ImmersePackage}, isx::Bool)
|
||||
gplt = getGadflyContext(plt)
|
||||
addOrReplace(gplt.guides, isx ? Gadfly.Guide.xticks : Gadfly.Guide.yticks; label=false)
|
||||
addOrReplace(gplt.guides, isx ? Gadfly.Guide.xlabel : Gadfly.Guide.ylabel, "")
|
||||
end
|
||||
|
||||
function expandLimits!(lims, plt::Plot{ImmersePackage}, isx::Bool)
|
||||
function _expand_limits(lims, plt::Plot{ImmersePackage}, isx::Bool)
|
||||
for l in getGadflyContext(plt).layers
|
||||
expandLimits!(lims, l.mapping[isx ? :x : :y])
|
||||
_expand_limits(lims, l.mapping[isx ? :x : :y])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -148,7 +137,7 @@ function Base.display(::PlotsDisplay, plt::Plot{ImmersePackage})
|
||||
|
||||
fig, gplt = plt.o
|
||||
if fig == nothing
|
||||
fig = createImmerseFigure(plt.initargs)
|
||||
fig = createImmerseFigure(plt.plotargs)
|
||||
Gtk.on_signal_destroy((x...) -> (Immerse.dropfig(Immerse._display, fig.figno); plt.o = (nothing,gplt)), fig.canvas)
|
||||
plt.o = (fig, gplt)
|
||||
end
|
||||
|
||||
@@ -77,6 +77,7 @@ end
|
||||
|
||||
immutable PyPlotFigWrapper
|
||||
fig
|
||||
kwargs # for add_subplot
|
||||
end
|
||||
|
||||
immutable PyPlotAxisWrapper
|
||||
@@ -92,7 +93,7 @@ getfig(wrap::@compat(Union{PyPlotAxisWrapper,PyPlotFigWrapper})) = wrap.fig
|
||||
function getLeftAxis(wrap::PyPlotFigWrapper)
|
||||
axes = wrap.fig.o[:axes]
|
||||
if isempty(axes)
|
||||
return wrap.fig.o[:add_subplot](111)
|
||||
return wrap.fig.o[:add_subplot](111; wrap.kwargs...)
|
||||
end
|
||||
axes[1]
|
||||
end
|
||||
@@ -106,15 +107,16 @@ function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol)
|
||||
|
||||
# in the 2-axis case we need to get: <rightaxis>[:<func>]
|
||||
ax = getAxis(plt, axis)
|
||||
ax[:set_ylabel](plt.initargs[:yrightlabel])
|
||||
ax[:set_ylabel](plt.plotargs[:yrightlabel])
|
||||
fmap = @compat Dict(
|
||||
:hist => :hist,
|
||||
:sticks => :bar,
|
||||
:bar => :bar,
|
||||
:heatmap => :hexbin,
|
||||
:hexbin => :hexbin,
|
||||
:scatter => :scatter,
|
||||
:contour => :contour,
|
||||
:hist => :hist,
|
||||
:sticks => :bar,
|
||||
:bar => :bar,
|
||||
:heatmap => :hexbin,
|
||||
:hexbin => :hexbin,
|
||||
:scatter => :scatter,
|
||||
:contour => :contour,
|
||||
:scatter3d => :scatter,
|
||||
)
|
||||
return ax[get(fmap, linetype, :plot)]
|
||||
end
|
||||
@@ -138,7 +140,7 @@ function handleSmooth(plt::Plot{PyPlotPackage}, ax, d::Dict, smooth::Bool)
|
||||
xs, ys = regressionXY(d[:x], d[:y])
|
||||
ax[:plot](xs, ys,
|
||||
# linestyle = getPyPlotLineStyle(:path, :dashdot),
|
||||
color = getPyPlotColor(d[:color]),
|
||||
color = getPyPlotColor(d[:linecolor]),
|
||||
linewidth = 2
|
||||
)
|
||||
end
|
||||
@@ -146,7 +148,6 @@ end
|
||||
handleSmooth(plt::Plot{PyPlotPackage}, ax, d::Dict, smooth::Real) = handleSmooth(plt, ax, d, true)
|
||||
|
||||
|
||||
nop() = nothing
|
||||
|
||||
|
||||
makePyPlotCurrent(wrap::PyPlotFigWrapper) = PyPlot.figure(wrap.fig.o[:number])
|
||||
@@ -154,7 +155,7 @@ makePyPlotCurrent(wrap::PyPlotAxisWrapper) = nothing #PyPlot.sca(wrap.ax.o)
|
||||
makePyPlotCurrent(plt::Plot{PyPlotPackage}) = makePyPlotCurrent(plt.o)
|
||||
|
||||
|
||||
function preparePlotUpdate(plt::Plot{PyPlotPackage})
|
||||
function _before_add_series(plt::Plot{PyPlotPackage})
|
||||
makePyPlotCurrent(plt)
|
||||
end
|
||||
|
||||
@@ -169,7 +170,7 @@ end
|
||||
# screen # Integer, move enclosing window to this screen number (for multiscreen desktops)
|
||||
# show # true or false, show the plot (in case you don't want the window to pop up right away)
|
||||
|
||||
function plot(pkg::PyPlotPackage; kw...)
|
||||
function _create_plot(pkg::PyPlotPackage; kw...)
|
||||
# create the figure
|
||||
d = Dict(kw)
|
||||
|
||||
@@ -179,7 +180,7 @@ function plot(pkg::PyPlotPackage; kw...)
|
||||
else
|
||||
w,h = map(px2inch, d[:size])
|
||||
bgcolor = getPyPlotColor(d[:background_color])
|
||||
wrap = PyPlotFigWrapper(PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = 96))
|
||||
wrap = PyPlotFigWrapper(PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = 96), [])
|
||||
end
|
||||
|
||||
plt = Plot(wrap, pkg, 0, d, Dict[])
|
||||
@@ -187,22 +188,26 @@ function plot(pkg::PyPlotPackage; kw...)
|
||||
end
|
||||
|
||||
|
||||
function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
function _add_series(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
d = Dict(kw)
|
||||
|
||||
ax = getAxis(plt, d[:axis])
|
||||
lt = d[:linetype]
|
||||
if lt in _3dTypes && isa(plt.o, PyPlotFigWrapper)
|
||||
push!(plt.o.kwargs, (:projection, "3d"))
|
||||
end
|
||||
|
||||
ax = getAxis(plt, d[:axis])
|
||||
if !(lt in supportedTypes(pkg))
|
||||
error("linetype $(lt) is unsupported in PyPlot. Choose from: $(supportedTypes(pkg))")
|
||||
end
|
||||
|
||||
color = getPyPlotColor(d[:color], d[:lineopacity])
|
||||
color = getPyPlotColor(d[:linecolor], d[:linealpha])
|
||||
|
||||
|
||||
if lt == :sticks
|
||||
d,_ = sticksHack(;d...)
|
||||
|
||||
elseif lt == :scatter
|
||||
elseif lt in (:scatter, :scatter3d)
|
||||
if d[:markershape] == :none
|
||||
d[:markershape] = :ellipse
|
||||
end
|
||||
@@ -212,7 +217,7 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
linecolor = color
|
||||
linestyle = getPyPlotLineStyle(lt, d[:linestyle])
|
||||
for yi in d[:y]
|
||||
func = ax[lt == :hline ? :axhline : axvline]
|
||||
func = ax[lt == :hline ? :axhline : :axvline]
|
||||
func(yi, linewidth=d[:linewidth], color=linecolor, linestyle=linestyle)
|
||||
end
|
||||
|
||||
@@ -237,10 +242,10 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
|
||||
elseif lt in (:heatmap, :hexbin)
|
||||
extra_kwargs[:gridsize] = d[:nbins]
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(d[:color])
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(d[:linecolor])
|
||||
|
||||
elseif lt == :contour
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(d[:color])
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(d[:linecolor])
|
||||
extra_kwargs[:linewidths] = d[:linewidth]
|
||||
extra_kwargs[:linestyles] = getPyPlotLineStyle(lt, d[:linestyle])
|
||||
# TODO: will need to call contourf to fill in the contours
|
||||
@@ -250,29 +255,42 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
extra_kwargs[:linestyle] = getPyPlotLineStyle(lt, d[:linestyle])
|
||||
extra_kwargs[:marker] = getPyPlotMarker(d[:markershape])
|
||||
|
||||
if lt == :scatter
|
||||
extra_kwargs[:s] = d[:markersize]^2
|
||||
if lt in (:scatter, :scatter3d)
|
||||
extra_kwargs[:s] = d[:markersize].^2
|
||||
c = d[:markercolor]
|
||||
if isa(c, ColorGradient) && d[:z] != nothing
|
||||
extra_kwargs[:c] = convert(Vector{Float64}, d[:z])
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(c, d[:markeropacity])
|
||||
if isa(c, ColorGradient) && d[:zcolor] != nothing
|
||||
extra_kwargs[:c] = convert(Vector{Float64}, d[:zcolor])
|
||||
extra_kwargs[:cmap] = getPyPlotColorMap(c, d[:markeralpha])
|
||||
else
|
||||
extra_kwargs[:c] = getPyPlotColor(c, d[:markeropacity])
|
||||
extra_kwargs[:c] = getPyPlotColor(c, d[:markeralpha])
|
||||
end
|
||||
if d[:markeralpha] != nothing
|
||||
extra_kwargs[:alpha] = d[:markeralpha]
|
||||
end
|
||||
extra_kwargs[:edgecolors] = getPyPlotColor(d[:markerstrokecolor], d[:markerstrokealpha])
|
||||
else
|
||||
extra_kwargs[:markersize] = d[:markersize]
|
||||
extra_kwargs[:markerfacecolor] = getPyPlotColor(d[:markercolor], d[:markeropacity])
|
||||
extra_kwargs[:markeredgecolor] = getPyPlotColor(plt.initargs[:foreground_color])
|
||||
extra_kwargs[:markeredgewidth] = d[:linewidth]
|
||||
extra_kwargs[:markerfacecolor] = getPyPlotColor(d[:markercolor], d[:markeralpha])
|
||||
extra_kwargs[:markeredgecolor] = getPyPlotColor(d[:markerstrokecolor], d[:markerstrokealpha])
|
||||
extra_kwargs[:markeredgewidth] = d[:markerstrokewidth]
|
||||
extra_kwargs[:drawstyle] = getPyPlotStepStyle(lt)
|
||||
end
|
||||
end
|
||||
|
||||
# if d[:markeralpha] != nothing
|
||||
# extra_kwargs[:alpha] = d[:markeralpha]
|
||||
# elseif d[:linealpha] != nothing
|
||||
# extra_kwargs[:alpha] = d[:linealpha]
|
||||
# end
|
||||
|
||||
# set these for all types
|
||||
if lt != :contour
|
||||
extra_kwargs[:color] = color
|
||||
extra_kwargs[:linewidth] = d[:linewidth]
|
||||
if !(lt in (:scatter, :scatter3d))
|
||||
extra_kwargs[:color] = color
|
||||
extra_kwargs[:linewidth] = d[:linewidth]
|
||||
end
|
||||
extra_kwargs[:label] = d[:label]
|
||||
extra_kwargs[:zorder] = plt.n
|
||||
end
|
||||
|
||||
# do the plot
|
||||
@@ -285,9 +303,11 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
surf = d[:surface]'
|
||||
handle = plotfunc(x, y, surf, d[:nlevels]; extra_kwargs...)
|
||||
if d[:fillrange] != nothing
|
||||
handle = ax[:contourf](x, y, surf, d[:nlevels]; cmap = getPyPlotColorMap(d[:fillcolor], d[:fillopacity]))
|
||||
handle = ax[:contourf](x, y, surf, d[:nlevels]; cmap = getPyPlotColorMap(d[:fillcolor], d[:fillalpha]))
|
||||
end
|
||||
handle
|
||||
elseif lt in _3dTypes
|
||||
plotfunc(d[:x], d[:y], d[:z]; extra_kwargs...)
|
||||
elseif lt in (:scatter, :heatmap, :hexbin)
|
||||
plotfunc(d[:x], d[:y]; extra_kwargs...)
|
||||
else
|
||||
@@ -297,20 +317,22 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
|
||||
handleSmooth(plt, ax, d, d[:smooth])
|
||||
|
||||
# add the colorbar legend
|
||||
if plt.initargs[:legend] && haskey(extra_kwargs, :cmap)
|
||||
if plt.plotargs[:legend] && haskey(extra_kwargs, :cmap)
|
||||
PyPlot.colorbar(d[:serieshandle])
|
||||
end
|
||||
|
||||
# @show extra_kwargs
|
||||
|
||||
# this sets the bg color inside the grid
|
||||
ax[:set_axis_bgcolor](getPyPlotColor(plt.initargs[:background_color]))
|
||||
ax[:set_axis_bgcolor](getPyPlotColor(plt.plotargs[:background_color]))
|
||||
|
||||
fillrange = d[:fillrange]
|
||||
if fillrange != nothing && lt != :contour
|
||||
fillcolor = getPyPlotColor(d[:fillcolor], d[:fillopacity])
|
||||
fillcolor = getPyPlotColor(d[:fillcolor], d[:fillalpha])
|
||||
if typeof(fillrange) <: @compat(Union{Real, AVec})
|
||||
ax[:fill_between](d[:x], fillrange, d[:y], facecolor = fillcolor)
|
||||
ax[:fill_between](d[:x], fillrange, d[:y], facecolor = fillcolor, zorder = plt.n)
|
||||
else
|
||||
ax[:fill_between](d[:x], fillrange..., facecolor = fillcolor)
|
||||
ax[:fill_between](d[:x], fillrange..., facecolor = fillcolor, zorder = plt.n)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -343,11 +365,11 @@ function Base.setindex!(plt::Plot{PyPlotPackage}, xy::Tuple, i::Integer)
|
||||
end
|
||||
|
||||
ax = series[:axes]
|
||||
if plt.initargs[:xlims] == :auto
|
||||
if plt.plotargs[:xlims] == :auto
|
||||
xmin, xmax = ax[:get_xlim]()
|
||||
ax[:set_xlim](min(xmin, minimum(xy[1])), max(xmax, maximum(xy[1])))
|
||||
end
|
||||
if plt.initargs[:ylims] == :auto
|
||||
if plt.plotargs[:ylims] == :auto
|
||||
ymin, ymax = ax[:get_ylim]()
|
||||
ax[:set_ylim](min(ymin, minimum(xy[2])), max(ymax, maximum(xy[2])))
|
||||
end
|
||||
@@ -390,7 +412,7 @@ end
|
||||
|
||||
usingRightAxis(plt::Plot{PyPlotPackage}) = any(args -> args[:axis] in (:right,:auto), plt.seriesargs)
|
||||
|
||||
function updatePlotItems(plt::Plot{PyPlotPackage}, d::Dict)
|
||||
function _update_plot(plt::Plot{PyPlotPackage}, d::Dict)
|
||||
figorax = plt.o
|
||||
ax = getLeftAxis(figorax)
|
||||
# PyPlot.sca(ax)
|
||||
@@ -435,13 +457,13 @@ function updatePlotItems(plt::Plot{PyPlotPackage}, d::Dict)
|
||||
|
||||
|
||||
# guides
|
||||
sz = get(d, :guidefont, plt.initargs[:guidefont]).pointsize
|
||||
sz = get(d, :guidefont, plt.plotargs[:guidefont]).pointsize
|
||||
ax[:title][:set_fontsize](sz)
|
||||
ax[:xaxis][:label][:set_fontsize](sz)
|
||||
ax[:yaxis][:label][:set_fontsize](sz)
|
||||
|
||||
# ticks
|
||||
sz = get(d, :tickfont, plt.initargs[:tickfont]).pointsize
|
||||
sz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize
|
||||
for sym in (:get_xticklabels, :get_yticklabels)
|
||||
for lab in ax[sym]()
|
||||
lab[:set_fontsize](sz)
|
||||
@@ -488,7 +510,7 @@ function createPyPlotAnnotationObject(plt::Plot{PyPlotPackage}, x, y, val::PlotT
|
||||
)
|
||||
end
|
||||
|
||||
function addAnnotations{X,Y,V}(plt::Plot{PyPlotPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
function _add_annotations{X,Y,V}(plt::Plot{PyPlotPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
for ann in anns
|
||||
createPyPlotAnnotationObject(plt, ann...)
|
||||
end
|
||||
@@ -497,11 +519,11 @@ end
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# NOTE: pyplot needs to build before
|
||||
function buildSubplotObject!(subplt::Subplot{PyPlotPackage}, isbefore::Bool)
|
||||
function _create_subplot(subplt::Subplot{PyPlotPackage}, isbefore::Bool)
|
||||
l = subplt.layout
|
||||
|
||||
w,h = map(px2inch, getinitargs(subplt,1)[:size])
|
||||
bgcolor = getPyPlotColor(getinitargs(subplt,1)[:background_color])
|
||||
w,h = map(px2inch, getplotargs(subplt,1)[:size])
|
||||
bgcolor = getPyPlotColor(getplotargs(subplt,1)[:background_color])
|
||||
fig = PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = 96)
|
||||
|
||||
nr = nrows(l)
|
||||
@@ -515,7 +537,7 @@ function buildSubplotObject!(subplt::Subplot{PyPlotPackage}, isbefore::Bool)
|
||||
subplt.plts[i].o = PyPlotAxisWrapper(ax, fig)
|
||||
end
|
||||
|
||||
subplt.o = PyPlotFigWrapper(fig)
|
||||
subplt.o = PyPlotFigWrapper(fig, [])
|
||||
true
|
||||
end
|
||||
|
||||
@@ -528,26 +550,26 @@ function subplot(plts::AVec{Plot{PyPlotPackage}}, layout::SubplotLayout, d::Dict
|
||||
n = sum([plt.n for plt in plts])
|
||||
|
||||
pkg = PyPlotPackage()
|
||||
newplts = Plot{PyPlotPackage}[plot(pkg; subplot=true, plt.initargs...) for plt in plts]
|
||||
newplts = Plot{PyPlotPackage}[plot(pkg; subplot=true, plt.plotargs...) for plt in plts]
|
||||
|
||||
subplt = Subplot(nothing, newplts, PyPlotPackage(), p, n, layout, d, true, false, false, (r,c) -> (nothing,nothing))
|
||||
|
||||
preprocessSubplot(subplt, d)
|
||||
buildSubplotObject!(subplt, true)
|
||||
_preprocess_subplot(subplt, d)
|
||||
_create_subplot(subplt, true)
|
||||
|
||||
for (i,plt) in enumerate(plts)
|
||||
for seriesargs in plt.seriesargs
|
||||
_plot_from_subplot!(newplts[i]; seriesargs...)
|
||||
_add_series_subplot(newplts[i]; seriesargs...)
|
||||
end
|
||||
end
|
||||
|
||||
postprocessSubplot(subplt, d)
|
||||
_postprocess_subplot(subplt, d)
|
||||
|
||||
subplt
|
||||
end
|
||||
|
||||
|
||||
function handleLinkInner(plt::Plot{PyPlotPackage}, isx::Bool)
|
||||
function _remove_axis(plt::Plot{PyPlotPackage}, isx::Bool)
|
||||
if isx
|
||||
plot!(plt, xticks=zeros(0), xlabel="")
|
||||
else
|
||||
@@ -555,23 +577,23 @@ function handleLinkInner(plt::Plot{PyPlotPackage}, isx::Bool)
|
||||
end
|
||||
end
|
||||
|
||||
function expandLimits!(lims, plt::Plot{PyPlotPackage}, isx::Bool)
|
||||
function _expand_limits(lims, plt::Plot{PyPlotPackage}, isx::Bool)
|
||||
pltlims = plt.o.ax[isx ? :get_xbound : :get_ybound]()
|
||||
expandLimits!(lims, pltlims)
|
||||
_expand_limits(lims, pltlims)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# function addPyPlotLegend(plt::Plot)
|
||||
function addPyPlotLegend(plt::Plot, ax)
|
||||
if plt.initargs[:legend]
|
||||
if plt.plotargs[:legend]
|
||||
# gotta do this to ensure both axes are included
|
||||
args = filter(x -> !(x[:linetype] in (:hist,:hexbin,:heatmap,:hline,:vline,:contour)), plt.seriesargs)
|
||||
args = filter(x -> !(x[:linetype] in (:hist,:hexbin,:heatmap,:hline,:vline,:contour, :path3d, :scatter3d)), plt.seriesargs)
|
||||
if length(args) > 0
|
||||
ax[:legend]([d[:serieshandle] for d in args],
|
||||
[d[:label] for d in args],
|
||||
loc="best",
|
||||
fontsize = plt.initargs[:legendfont].pointsize
|
||||
fontsize = plt.plotargs[:legendfont].pointsize
|
||||
# framealpha = 0.6
|
||||
)
|
||||
end
|
||||
@@ -581,7 +603,7 @@ end
|
||||
function finalizePlot(plt::Plot{PyPlotPackage})
|
||||
ax = getLeftAxis(plt)
|
||||
addPyPlotLegend(plt, ax)
|
||||
updateAxisColors(ax, getPyPlotColor(plt.initargs[:foreground_color]))
|
||||
updateAxisColors(ax, getPyPlotColor(plt.plotargs[:foreground_color]))
|
||||
PyPlot.draw()
|
||||
end
|
||||
|
||||
@@ -590,7 +612,7 @@ function finalizePlot(subplt::Subplot{PyPlotPackage})
|
||||
for (i,plt) in enumerate(subplt.plts)
|
||||
ax = getLeftAxis(plt)
|
||||
addPyPlotLegend(plt, ax)
|
||||
updateAxisColors(ax, getPyPlotColor(plt.initargs[:foreground_color]))
|
||||
updateAxisColors(ax, getPyPlotColor(plt.plotargs[:foreground_color]))
|
||||
end
|
||||
PyPlot.draw()
|
||||
end
|
||||
|
||||
@@ -70,7 +70,7 @@ function adjustQwtKeywords(plt::Plot{QwtPackage}, iscreating::Bool; kw...)
|
||||
d
|
||||
end
|
||||
|
||||
function plot(pkg::QwtPackage; kw...)
|
||||
function _create_plot(pkg::QwtPackage; kw...)
|
||||
d = Dict(kw)
|
||||
fixcolors(d)
|
||||
dumpdict(d,"\n\n!!! plot")
|
||||
@@ -79,7 +79,7 @@ function plot(pkg::QwtPackage; kw...)
|
||||
plt
|
||||
end
|
||||
|
||||
function plot!(::QwtPackage, plt::Plot; kw...)
|
||||
function _add_series(::QwtPackage, plt::Plot; kw...)
|
||||
d = adjustQwtKeywords(plt, false; kw...)
|
||||
fixcolors(d)
|
||||
dumpdict(d,"\n\n!!! plot!")
|
||||
@@ -131,7 +131,7 @@ function updateLimsAndTicks(plt::Plot{QwtPackage}, d::Dict, isx::Bool)
|
||||
end
|
||||
|
||||
|
||||
function updatePlotItems(plt::Plot{QwtPackage}, d::Dict)
|
||||
function _update_plot(plt::Plot{QwtPackage}, d::Dict)
|
||||
haskey(d, :title) && Qwt.title(plt.o, d[:title])
|
||||
haskey(d, :xlabel) && Qwt.xlabel(plt.o, d[:xlabel])
|
||||
haskey(d, :ylabel) && Qwt.ylabel(plt.o, d[:ylabel])
|
||||
@@ -139,7 +139,7 @@ function updatePlotItems(plt::Plot{QwtPackage}, d::Dict)
|
||||
updateLimsAndTicks(plt, d, false)
|
||||
end
|
||||
|
||||
function updatePositionAndSize(plt::PlottingObject{QwtPackage}, d::Dict)
|
||||
function _update_plot_pos_size(plt::PlottingObject{QwtPackage}, d::Dict)
|
||||
haskey(d, :size) && Qwt.resizewidget(plt.o, d[:size]...)
|
||||
haskey(d, :pos) && Qwt.movewidget(plt.o, d[:pos]...)
|
||||
end
|
||||
@@ -154,7 +154,7 @@ function addLineMarker(plt::Plot{QwtPackage}, d::Dict)
|
||||
ishorizontal = (d[:linetype] == :hline)
|
||||
marker[:setLineStyle](ishorizontal ? 1 : 2)
|
||||
marker[ishorizontal ? :setYValue : :setXValue](yi)
|
||||
qcolor = Qwt.convertRGBToQColor(getColor(d[:color]))
|
||||
qcolor = Qwt.convertRGBToQColor(getColor(d[:linecolor]))
|
||||
linestyle = plt.o.widget[:getLineStyle](string(d[:linestyle]))
|
||||
marker[:setLinePen](Qwt.QT.QPen(qcolor, d[:linewidth], linestyle))
|
||||
marker[:attach](plt.o.widget)
|
||||
@@ -182,7 +182,7 @@ function createQwtAnnotation(plt::Plot, x, y, val::@compat(AbstractString))
|
||||
marker[:attach](plt.o.widget)
|
||||
end
|
||||
|
||||
function addAnnotations{X,Y,V}(plt::Plot{QwtPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
function _add_annotations{X,Y,V}(plt::Plot{QwtPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
for ann in anns
|
||||
createQwtAnnotation(plt, ann...)
|
||||
end
|
||||
@@ -211,7 +211,7 @@ end
|
||||
# -------------------------------
|
||||
|
||||
# create the underlying object (each backend will do this differently)
|
||||
function buildSubplotObject!(subplt::Subplot{QwtPackage}, isbefore::Bool)
|
||||
function _create_subplot(subplt::Subplot{QwtPackage}, isbefore::Bool)
|
||||
isbefore && return false
|
||||
i = 0
|
||||
rows = Any[]
|
||||
@@ -228,23 +228,19 @@ function buildSubplotObject!(subplt::Subplot{QwtPackage}, isbefore::Bool)
|
||||
# i += rowcnt
|
||||
# end
|
||||
subplt.o = Qwt.vsplitter(rows...)
|
||||
# Qwt.resizewidget(subplt.o, getinitargs(subplt,1)[:size]...)
|
||||
# Qwt.resizewidget(subplt.o, getplotargs(subplt,1)[:size]...)
|
||||
# Qwt.moveToLastScreen(subplt.o) # hack so it goes to my center monitor... sorry
|
||||
true
|
||||
end
|
||||
|
||||
function handleLinkInner(plt::Plot{QwtPackage}, isx::Bool)
|
||||
warn("handleLinkInner isn't implemented for qwt")
|
||||
end
|
||||
|
||||
function expandLimits!(lims, plt::Plot{QwtPackage}, isx::Bool)
|
||||
function _expand_limits(lims, plt::Plot{QwtPackage}, isx::Bool)
|
||||
for series in plt.o.lines
|
||||
expandLimits!(lims, isx ? series.x : series.y)
|
||||
_expand_limits(lims, isx ? series.x : series.y)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function handleLinkInner(plt::Plot{QwtPackage}, isx::Bool)
|
||||
function _remove_axis(plt::Plot{QwtPackage}, isx::Bool)
|
||||
end
|
||||
|
||||
|
||||
@@ -274,10 +270,6 @@ function Base.display(::PlotsDisplay, subplt::Subplot{QwtPackage})
|
||||
for plt in subplt.plts
|
||||
Qwt.refresh(plt.o)
|
||||
end
|
||||
# iargs = getinitargs(subplt,1)
|
||||
# # iargs = subplt.initargs
|
||||
# Qwt.resizewidget(subplt.o, iargs[:size]...)
|
||||
# Qwt.movewidget(subplt.o, iargs[:pos]...)
|
||||
Qwt.showwidget(subplt.o)
|
||||
end
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ supportedArgs(::GadflyPackage) = [
|
||||
:annotation,
|
||||
# :axis,
|
||||
:background_color,
|
||||
:color,
|
||||
:linecolor,
|
||||
:color_palette,
|
||||
:fillrange,
|
||||
:fillcolor,
|
||||
:fillopacity,
|
||||
:fillalpha,
|
||||
:foreground_color,
|
||||
:group,
|
||||
:label,
|
||||
@@ -16,11 +16,14 @@ supportedArgs(::GadflyPackage) = [
|
||||
:linestyle,
|
||||
:linetype,
|
||||
:linewidth,
|
||||
:lineopacity,
|
||||
:linealpha,
|
||||
:markershape,
|
||||
:markercolor,
|
||||
:markersize,
|
||||
:markeropacity,
|
||||
:markeralpha,
|
||||
:markerstrokewidth,
|
||||
:markerstrokecolor,
|
||||
# :markerstrokestyle,
|
||||
:n,
|
||||
:nbins,
|
||||
:nc,
|
||||
@@ -45,6 +48,7 @@ supportedArgs(::GadflyPackage) = [
|
||||
:xflip,
|
||||
:yflip,
|
||||
:z,
|
||||
:zcolor,
|
||||
:tickfont,
|
||||
:guidefont,
|
||||
:legendfont,
|
||||
@@ -77,7 +81,7 @@ supportedArgs(::PyPlotPackage) = [
|
||||
:annotation,
|
||||
:axis,
|
||||
:background_color,
|
||||
:color,
|
||||
:linecolor,
|
||||
:color_palette,
|
||||
:fillrange,
|
||||
:fillcolor,
|
||||
@@ -92,6 +96,9 @@ supportedArgs(::PyPlotPackage) = [
|
||||
:markershape,
|
||||
:markercolor,
|
||||
:markersize,
|
||||
:markerstrokewidth,
|
||||
:markerstrokecolor,
|
||||
# :markerstrokestyle,
|
||||
:n,
|
||||
:nbins,
|
||||
:nc,
|
||||
@@ -117,18 +124,19 @@ supportedArgs(::PyPlotPackage) = [
|
||||
:xflip,
|
||||
:yflip,
|
||||
:z,
|
||||
:zcolor, # only supported for scatter/scatter3d
|
||||
:tickfont,
|
||||
:guidefont,
|
||||
:legendfont,
|
||||
:grid,
|
||||
:surface,
|
||||
:nlevels,
|
||||
:fillopacity,
|
||||
:lineopacity,
|
||||
:markeropacity,
|
||||
:fillalpha,
|
||||
:linealpha,
|
||||
:markeralpha,
|
||||
]
|
||||
supportedAxes(::PyPlotPackage) = _allAxes
|
||||
supportedTypes(::PyPlotPackage) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :contour]
|
||||
supportedTypes(::PyPlotPackage) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :contour, :path3d, :scatter3d]
|
||||
supportedStyles(::PyPlotPackage) = [:auto, :solid, :dash, :dot, :dashdot]
|
||||
# supportedMarkers(::PyPlotPackage) = [:none, :auto, :rect, :ellipse, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :hexagon]
|
||||
supportedMarkers(::PyPlotPackage) = vcat(_allMarkers, Shape)
|
||||
@@ -145,7 +153,7 @@ supportedArgs(::QwtPackage) = [
|
||||
# :args,
|
||||
:axis,
|
||||
:background_color,
|
||||
:color,
|
||||
:linecolor,
|
||||
:color_palette,
|
||||
:fillrange,
|
||||
:fillcolor,
|
||||
@@ -162,6 +170,9 @@ supportedArgs(::QwtPackage) = [
|
||||
:markershape,
|
||||
:markercolor,
|
||||
:markersize,
|
||||
# :markerstrokewidth,
|
||||
# :markerstrokecolor,
|
||||
# :markerstrokestyle,
|
||||
:n,
|
||||
:nbins,
|
||||
:nc,
|
||||
@@ -201,7 +212,7 @@ supportedArgs(::UnicodePlotsPackage) = [
|
||||
# :args,
|
||||
# :axis,
|
||||
# :background_color,
|
||||
# :color,
|
||||
# :linecolor,
|
||||
# :fill,
|
||||
# :foreground_color,
|
||||
:group,
|
||||
@@ -216,6 +227,9 @@ supportedArgs(::UnicodePlotsPackage) = [
|
||||
:markershape,
|
||||
# :markercolor,
|
||||
# :markersize,
|
||||
# :markerstrokewidth,
|
||||
# :markerstrokecolor,
|
||||
# :markerstrokestyle,
|
||||
# :n,
|
||||
:nbins,
|
||||
# :nc,
|
||||
@@ -259,7 +273,7 @@ supportedArgs(::WinstonPackage) = [
|
||||
# :args,
|
||||
# :axis,
|
||||
# :background_color,
|
||||
:color,
|
||||
:linecolor,
|
||||
:color_palette,
|
||||
:fillrange,
|
||||
:fillcolor,
|
||||
@@ -276,6 +290,9 @@ supportedArgs(::WinstonPackage) = [
|
||||
:markershape,
|
||||
:markercolor,
|
||||
:markersize,
|
||||
# :markerstrokewidth,
|
||||
# :markerstrokecolor,
|
||||
# :markerstrokestyle,
|
||||
# :n,
|
||||
:nbins,
|
||||
# :nc,
|
||||
@@ -310,4 +327,70 @@ supportedScales(::WinstonPackage) = [:identity, :log10]
|
||||
subplotSupported(::WinstonPackage) = false
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------
|
||||
# --------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
supportedArgs(::BokehPackage) = [
|
||||
# :annotation,
|
||||
# :axis,
|
||||
# :background_color,
|
||||
:linecolor,
|
||||
# :color_palette,
|
||||
# :fillrange,
|
||||
# :fillcolor,
|
||||
# :fillalpha,
|
||||
# :foreground_color,
|
||||
:group,
|
||||
# :label,
|
||||
# :layout,
|
||||
# :legend,
|
||||
:linestyle,
|
||||
:linetype,
|
||||
:linewidth,
|
||||
# :linealpha,
|
||||
:markershape,
|
||||
:markercolor,
|
||||
:markersize,
|
||||
# :markeralpha,
|
||||
# :markerstrokewidth,
|
||||
# :markerstrokecolor,
|
||||
# :markerstrokestyle,
|
||||
# :n,
|
||||
# :nbins,
|
||||
# :nc,
|
||||
# :nr,
|
||||
# :pos,
|
||||
# :smooth,
|
||||
# :show,
|
||||
:size,
|
||||
:title,
|
||||
# :windowtitle,
|
||||
:x,
|
||||
# :xlabel,
|
||||
# :xlims,
|
||||
# :xticks,
|
||||
:y,
|
||||
# :ylabel,
|
||||
# :ylims,
|
||||
# :yrightlabel,
|
||||
# :yticks,
|
||||
# :xscale,
|
||||
# :yscale,
|
||||
# :xflip,
|
||||
# :yflip,
|
||||
# :z,
|
||||
# :tickfont,
|
||||
# :guidefont,
|
||||
# :legendfont,
|
||||
# :grid,
|
||||
# :surface,
|
||||
# :nlevels,
|
||||
]
|
||||
supportedAxes(::BokehPackage) = [:auto, :left]
|
||||
supportedTypes(::BokehPackage) = [:none, :path, :scatter] #,:steppre, :steppost, :sticks, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :contour]
|
||||
supportedStyles(::BokehPackage) = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||
supportedMarkers(::BokehPackage) = [:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5] #vcat(_allMarkers, Shape)
|
||||
supportedScales(::BokehPackage) = [:identity, :log] #, :log, :log2, :log10, :asinh, :sqrt]
|
||||
|
||||
|
||||
|
||||
@@ -5,64 +5,7 @@
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# supportedArgs(::[PkgName]Package) = _allArgs
|
||||
supportedArgs(::[PkgName]Package) = [
|
||||
:annotation,
|
||||
# :args,
|
||||
:axis,
|
||||
:background_color,
|
||||
:color,
|
||||
:fillrange,
|
||||
:fillcolor,
|
||||
:foreground_color,
|
||||
:group,
|
||||
# :heatmap_c,
|
||||
# :kwargs,
|
||||
:label,
|
||||
:layout,
|
||||
:legend,
|
||||
:linestyle,
|
||||
:linetype,
|
||||
:linewidth,
|
||||
:markershape,
|
||||
:markercolor,
|
||||
:markersize,
|
||||
:n,
|
||||
:nbins,
|
||||
:nc,
|
||||
:nr,
|
||||
# :pos,
|
||||
:smooth,
|
||||
# :ribbon,
|
||||
:show,
|
||||
:size,
|
||||
:title,
|
||||
:windowtitle,
|
||||
:x,
|
||||
:xlabel,
|
||||
:xlims,
|
||||
:xticks,
|
||||
:y,
|
||||
:ylabel,
|
||||
:ylims,
|
||||
# :yrightlabel,
|
||||
:yticks,
|
||||
# :xscale,
|
||||
# :yscale,
|
||||
# :xflip,
|
||||
# :yflip,
|
||||
# :z,
|
||||
]
|
||||
supportedAxes(::[PkgName]Package) = _allAxes
|
||||
supportedTypes(::[PkgName]Package) = _allTypes
|
||||
supportedStyles(::[PkgName]Package) = _allStyles
|
||||
supportedMarkers(::[PkgName]Package) = _allMarkers
|
||||
supportedScales(::[PkgName]Package) = _allScales
|
||||
subplotSupported(::[PkgName]Package) = false
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
function plot(pkg::[PkgName]Package; kw...)
|
||||
function _create_plot(pkg::[PkgName]Package; kw...)
|
||||
d = Dict(kw)
|
||||
# TODO: create the window/canvas/context that is the plot within the backend (call it `o`)
|
||||
# TODO: initialize the plot... title, xlabel, bgcolor, etc
|
||||
@@ -70,25 +13,60 @@ function plot(pkg::[PkgName]Package; kw...)
|
||||
end
|
||||
|
||||
|
||||
function plot!(::[PkgName]Package, plt::Plot; kw...)
|
||||
function _add_series(::[PkgName]Package, plt::Plot; kw...)
|
||||
d = Dict(kw)
|
||||
# TODO: add one series to the underlying package
|
||||
push!(plt.seriesargs, d)
|
||||
plt
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# TODO: override this to update plot items (title, xlabel, etc) after creation
|
||||
function updatePlotItems(plt::Plot{[PkgName]Package}, d::Dict)
|
||||
function _add_annotations{X,Y,V}(plt::Plot{[PkgName]Package}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
for ann in anns
|
||||
# TODO: add the annotation to the plot
|
||||
end
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function buildSubplotObject!(subplt::Subplot{[PkgName]Package})
|
||||
function _before_update_plot(plt::Plot{[PkgName]Package})
|
||||
end
|
||||
|
||||
# TODO: override this to update plot items (title, xlabel, etc) after creation
|
||||
function _update_plot(plt::Plot{[PkgName]Package}, d::Dict)
|
||||
end
|
||||
|
||||
function _update_plot_pos_size(plt::PlottingObject{[PkgName]Package}, d::Dict)
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# accessors for x/y data
|
||||
|
||||
function Base.getindex(plt::Plot{[PkgName]Package}, i::Int)
|
||||
series = plt.o.lines[i]
|
||||
series.x, series.y
|
||||
end
|
||||
|
||||
function Base.setindex!(plt::Plot{[PkgName]Package}, xy::Tuple, i::Integer)
|
||||
series = plt.o.lines[i]
|
||||
series.x, series.y = xy
|
||||
plt
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function _create_subplot(subplt::Subplot{[PkgName]Package})
|
||||
# TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
|
||||
end
|
||||
|
||||
function _expand_limits(lims, plt::Plot{[PkgName]Package}, isx::Bool)
|
||||
# TODO: call expand limits for each plot data
|
||||
end
|
||||
|
||||
function _remove_axis(plt::Plot{[PkgName]Package}, isx::Bool)
|
||||
# TODO: if plot is inner subplot, might need to remove ticks or axis labels
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function Base.writemime(io::IO, ::MIME"image/png", plt::PlottingObject{[PkgName]Package})
|
||||
|
||||
@@ -9,13 +9,13 @@ function rebuildUnicodePlot!(plt::Plot)
|
||||
|
||||
# figure out the plotting area xlim = [xmin, xmax] and ylim = [ymin, ymax]
|
||||
sargs = plt.seriesargs
|
||||
iargs = plt.initargs
|
||||
iargs = plt.plotargs
|
||||
|
||||
# get the x/y limits
|
||||
if get(iargs, :xlims, :auto) == :auto
|
||||
xlim = [Inf, -Inf]
|
||||
for d in sargs
|
||||
expandLimits!(xlim, d[:x])
|
||||
_expand_limits(xlim, d[:x])
|
||||
end
|
||||
else
|
||||
xmin, xmax = iargs[:xlims]
|
||||
@@ -25,7 +25,7 @@ function rebuildUnicodePlot!(plt::Plot)
|
||||
if get(iargs, :ylims, :auto) == :auto
|
||||
ylim = [Inf, -Inf]
|
||||
for d in sargs
|
||||
expandLimits!(ylim, d[:y])
|
||||
_expand_limits(ylim, d[:y])
|
||||
end
|
||||
else
|
||||
ymin, ymax = iargs[:ylims]
|
||||
@@ -39,7 +39,7 @@ function rebuildUnicodePlot!(plt::Plot)
|
||||
|
||||
# create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds
|
||||
width, height = iargs[:size]
|
||||
o = UnicodePlots.createPlotWindow(x, y; width = width,
|
||||
o = UnicodePlots.Plot(x, y; width = width,
|
||||
height = height,
|
||||
title = iargs[:title],
|
||||
# labels = iargs[:legend],
|
||||
@@ -97,7 +97,7 @@ function addUnicodeSeries!(o, d::Dict, addlegend::Bool, xlim, ylim)
|
||||
label = addlegend ? d[:label] : ""
|
||||
|
||||
# if we happen to pass in allowed color symbols, great... otherwise let UnicodePlots decide
|
||||
color = d[:color] in UnicodePlots.autoColors ? d[:color] : :auto
|
||||
color = d[:linecolor] in UnicodePlots.autoColors ? d[:linecolor] : :auto
|
||||
|
||||
# add the series
|
||||
func(o, x, y; color = color, name = label, style = stepstyle)
|
||||
@@ -112,18 +112,18 @@ end
|
||||
# -------------------------------
|
||||
|
||||
|
||||
function plot(pkg::UnicodePlotsPackage; kw...)
|
||||
function _create_plot(pkg::UnicodePlotsPackage; kw...)
|
||||
plt = Plot(nothing, pkg, 0, Dict(kw), Dict[])
|
||||
|
||||
# do we want to give a new default size?
|
||||
if !haskey(plt.initargs, :size) || plt.initargs[:size] == _plotDefaults[:size]
|
||||
plt.initargs[:size] = (60,20)
|
||||
if !haskey(plt.plotargs, :size) || plt.plotargs[:size] == _plotDefaults[:size]
|
||||
plt.plotargs[:size] = (60,20)
|
||||
end
|
||||
|
||||
plt
|
||||
end
|
||||
|
||||
function plot!(::UnicodePlotsPackage, plt::Plot; kw...)
|
||||
function _add_series(::UnicodePlotsPackage, plt::Plot; kw...)
|
||||
d = Dict(kw)
|
||||
if d[:linetype] in (:sticks, :bar)
|
||||
d = barHack(; d...)
|
||||
@@ -135,10 +135,10 @@ function plot!(::UnicodePlotsPackage, plt::Plot; kw...)
|
||||
end
|
||||
|
||||
|
||||
function updatePlotItems(plt::Plot{UnicodePlotsPackage}, d::Dict)
|
||||
function _update_plot(plt::Plot{UnicodePlotsPackage}, d::Dict)
|
||||
for k in (:title, :xlabel, :ylabel, :xlims, :ylims)
|
||||
if haskey(d, k)
|
||||
plt.initargs[k] = d[k]
|
||||
plt.plotargs[k] = d[k]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -175,7 +175,7 @@ end
|
||||
|
||||
# we don't do very much for subplots... just stack them vertically
|
||||
|
||||
function buildSubplotObject!(subplt::Subplot{UnicodePlotsPackage}, isbefore::Bool)
|
||||
function _create_subplot(subplt::Subplot{UnicodePlotsPackage}, isbefore::Bool)
|
||||
isbefore && return false
|
||||
true
|
||||
end
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
:star5 => "asterisk"
|
||||
)
|
||||
|
||||
function preparePlotUpdate(plt::Plot{WinstonPackage})
|
||||
function _before_add_series(plt::Plot{WinstonPackage})
|
||||
Winston.ghf(plt.o)
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
function plot(pkg::WinstonPackage; kw...)
|
||||
function _create_plot(pkg::WinstonPackage; kw...)
|
||||
d = Dict(kw)
|
||||
wplt = Winston.FramedPlot(title = d[:title], xlabel = d[:xlabel], ylabel = d[:ylabel])
|
||||
|
||||
@@ -56,7 +56,7 @@ function getWinstonItems(plt::Plot)
|
||||
window, canvas, wplt
|
||||
end
|
||||
|
||||
function plot!(::WinstonPackage, plt::Plot; kw...)
|
||||
function _add_series(::WinstonPackage, plt::Plot; kw...)
|
||||
d = Dict(kw)
|
||||
|
||||
window, canvas, wplt = getWinstonItems(plt)
|
||||
@@ -68,7 +68,7 @@ function plot!(::WinstonPackage, plt::Plot; kw...)
|
||||
|
||||
|
||||
e = Dict()
|
||||
e[:color] = getColor(d[:color])
|
||||
e[:color] = getColor(d[:linecolor])
|
||||
e[:linewidth] = d[:linewidth]
|
||||
e[:kind] = winston_linestyle[d[:linestyle]]
|
||||
e[:symbolkind] = winston_marker[d[:markershape]]
|
||||
@@ -157,7 +157,7 @@ end
|
||||
:yscale => :ylog,
|
||||
)
|
||||
|
||||
function updatePlotItems(plt::Plot{WinstonPackage}, d::Dict)
|
||||
function _update_plot(plt::Plot{WinstonPackage}, d::Dict)
|
||||
window, canvas, wplt = getWinstonItems(plt)
|
||||
for k in (:xlabel, :ylabel, :title, :xlims, :ylims)
|
||||
if haskey(d, k)
|
||||
@@ -182,7 +182,7 @@ function createWinstonAnnotationObject(plt::Plot{WinstonPackage}, x, y, val::@co
|
||||
Winston.text(x, y, val)
|
||||
end
|
||||
|
||||
function addAnnotations{X,Y,V}(plt::Plot{WinstonPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
function _add_annotations{X,Y,V}(plt::Plot{WinstonPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||
for ann in anns
|
||||
createWinstonAnnotationObject(plt, ann...)
|
||||
end
|
||||
@@ -191,14 +191,14 @@ end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function buildSubplotObject!(subplt::Subplot{WinstonPackage}, isbefore::Bool)
|
||||
function _create_subplot(subplt::Subplot{WinstonPackage}, isbefore::Bool)
|
||||
# TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
function addWinstonLegend(plt::Plot, wplt)
|
||||
if plt.initargs[:legend]
|
||||
if plt.plotargs[:legend]
|
||||
Winston.legend(wplt, [sd[:label] for sd in plt.seriesargs])
|
||||
end
|
||||
end
|
||||
@@ -219,9 +219,9 @@ function Base.display(::PlotsDisplay, plt::Plot{WinstonPackage})
|
||||
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.initargs[:size]
|
||||
w,h = plt.plotargs[:size]
|
||||
canvas = Gtk.GtkCanvasLeaf()
|
||||
window = Gtk.GtkWindowLeaf(canvas, plt.initargs[:windowtitle], w, h)
|
||||
window = Gtk.GtkWindowLeaf(canvas, plt.plotargs[:windowtitle], w, h)
|
||||
plt.o = (window, canvas, wplt)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,88 +1,4 @@
|
||||
|
||||
# note: I found this list of hex values in a comment by Tatarize here: http://stackoverflow.com/a/12224359
|
||||
const _masterColorList = [
|
||||
0xFFFFFF,
|
||||
0x000000,
|
||||
0x0000FF,
|
||||
0x00FF00,
|
||||
0xFF0000,
|
||||
0x01FFFE,
|
||||
0xFFA6FE,
|
||||
0xFFDB66,
|
||||
0x006401,
|
||||
0x010067,
|
||||
0x95003A,
|
||||
0x007DB5,
|
||||
0xFF00F6,
|
||||
0xFFEEE8,
|
||||
0x774D00,
|
||||
0x90FB92,
|
||||
0x0076FF,
|
||||
0xD5FF00,
|
||||
0xFF937E,
|
||||
0x6A826C,
|
||||
0xFF029D,
|
||||
0xFE8900,
|
||||
0x7A4782,
|
||||
0x7E2DD2,
|
||||
0x85A900,
|
||||
0xFF0056,
|
||||
0xA42400,
|
||||
0x00AE7E,
|
||||
0x683D3B,
|
||||
0xBDC6FF,
|
||||
0x263400,
|
||||
0xBDD393,
|
||||
0x00B917,
|
||||
0x9E008E,
|
||||
0x001544,
|
||||
0xC28C9F,
|
||||
0xFF74A3,
|
||||
0x01D0FF,
|
||||
0x004754,
|
||||
0xE56FFE,
|
||||
0x788231,
|
||||
0x0E4CA1,
|
||||
0x91D0CB,
|
||||
0xBE9970,
|
||||
0x968AE8,
|
||||
0xBB8800,
|
||||
0x43002C,
|
||||
0xDEFF74,
|
||||
0x00FFC6,
|
||||
0xFFE502,
|
||||
0x620E00,
|
||||
0x008F9C,
|
||||
0x98FF52,
|
||||
0x7544B1,
|
||||
0xB500FF,
|
||||
0x00FF78,
|
||||
0xFF6E41,
|
||||
0x005F39,
|
||||
0x6B6882,
|
||||
0x5FAD4E,
|
||||
0xA75740,
|
||||
0xA5FFD2,
|
||||
0xFFB167,
|
||||
0x009BFF,
|
||||
0xE85EBE,
|
||||
]
|
||||
|
||||
|
||||
function darken(c, v=0.1)
|
||||
rgba = convert(RGBA, c)
|
||||
r = max(0, min(rgba.r - v, 1))
|
||||
g = max(0, min(rgba.g - v, 1))
|
||||
b = max(0, min(rgba.b - v, 1))
|
||||
RGBA(r,g,b,rgba.alpha)
|
||||
end
|
||||
function lighten(c, v=0.3)
|
||||
darken(c, -v)
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------
|
||||
|
||||
|
||||
abstract ColorScheme
|
||||
|
||||
getColor(scheme::ColorScheme) = getColor(scheme, 1)
|
||||
@@ -119,6 +35,19 @@ getColor(c) = convertColor(c)
|
||||
|
||||
# --------------------------------------------------------------
|
||||
|
||||
function darken(c, v=0.1)
|
||||
rgba = convert(RGBA, c)
|
||||
r = max(0, min(rgba.r - v, 1))
|
||||
g = max(0, min(rgba.g - v, 1))
|
||||
b = max(0, min(rgba.b - v, 1))
|
||||
RGBA(r,g,b,rgba.alpha)
|
||||
end
|
||||
function lighten(c, v=0.3)
|
||||
darken(c, -v)
|
||||
end
|
||||
|
||||
# --------------------------------------------------------------
|
||||
|
||||
const _rainbowColors = [colorant"blue", colorant"purple", colorant"green", colorant"orange", colorant"red"]
|
||||
const _testColors = [colorant"darkblue", colorant"blueviolet", colorant"darkcyan",colorant"green",
|
||||
darken(colorant"yellow",0.3), colorant"orange", darken(colorant"red",0.2)]
|
||||
@@ -286,6 +215,16 @@ function convertHexToRGB(h::Unsigned)
|
||||
RGB([(x & mask) / 0xFF for x in (h >> 16, h >> 8, h)]...)
|
||||
end
|
||||
|
||||
# note: I found this list of hex values in a comment by Tatarize here: http://stackoverflow.com/a/12224359
|
||||
const _masterColorList = [
|
||||
0xFFFFFF, 0x000000, 0x0000FF, 0x00FF00, 0xFF0000, 0x01FFFE, 0xFFA6FE, 0xFFDB66, 0x006401, 0x010067,
|
||||
0x95003A, 0x007DB5, 0xFF00F6, 0xFFEEE8, 0x774D00, 0x90FB92, 0x0076FF, 0xD5FF00, 0xFF937E, 0x6A826C,
|
||||
0xFF029D, 0xFE8900, 0x7A4782, 0x7E2DD2, 0x85A900, 0xFF0056, 0xA42400, 0x00AE7E, 0x683D3B, 0xBDC6FF,
|
||||
0x263400, 0xBDD393, 0x00B917, 0x9E008E, 0x001544, 0xC28C9F, 0xFF74A3, 0x01D0FF, 0x004754, 0xE56FFE,
|
||||
0x788231, 0x0E4CA1, 0x91D0CB, 0xBE9970, 0x968AE8, 0xBB8800, 0x43002C, 0xDEFF74, 0x00FFC6, 0xFFE502,
|
||||
0x620E00, 0x008F9C, 0x98FF52, 0x7544B1, 0xB500FF, 0x00FF78, 0xFF6E41, 0x005F39, 0x6B6882, 0x5FAD4E,
|
||||
0xA75740, 0xA5FFD2, 0xFFB167, 0x009BFF, 0xE85EBE
|
||||
]
|
||||
const _allColors = map(convertHexToRGB, _masterColorList)
|
||||
const _darkColors = filter(isdark, _allColors)
|
||||
const _lightColors = filter(islight, _allColors)
|
||||
@@ -382,7 +321,6 @@ end
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
# TODO: try to use the algorithms from https://github.com/timothyrenner/ColorBrewer.jl
|
||||
# TODO: allow the setting of the algorithm, either by passing a symbol (:colordiff, :fixed, etc) or a function?
|
||||
|
||||
# function getBackgroundRGBColor(c, d::Dict)
|
||||
@@ -415,10 +353,10 @@ function handlePlotColors(::PlottingPackage, d::Dict)
|
||||
end
|
||||
|
||||
# converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically
|
||||
function getSeriesRGBColor(c, initargs::Dict, n::Int)
|
||||
function getSeriesRGBColor(c, plotargs::Dict, n::Int)
|
||||
|
||||
if c == :auto
|
||||
c = autopick(initargs[:color_palette], n)
|
||||
c = autopick(plotargs[:color_palette], n)
|
||||
end
|
||||
|
||||
# c should now be a subtype of ColorScheme
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
|
||||
immutable Shape
|
||||
vertices::AVec
|
||||
end
|
||||
|
||||
"get an array of tuples of points on a circle with radius `r`"
|
||||
function partialcircle(start_θ, end_θ, n = 20, r=1)
|
||||
@compat(Tuple{Float64,Float64})[(r*cos(u),r*sin(u)) for u in linspace(start_θ, end_θ, n)]
|
||||
end
|
||||
|
||||
"interleave 2 vectors into each other (like a zipper's teeth)"
|
||||
function weave(x,y; ordering = Vector[x,y])
|
||||
ret = eltype(x)[]
|
||||
done = false
|
||||
while !done
|
||||
for o in ordering
|
||||
try
|
||||
push!(ret, shift!(o))
|
||||
end
|
||||
# try
|
||||
# push!(ret, shift!(y))
|
||||
# end
|
||||
end
|
||||
done = isempty(x) && isempty(y)
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
|
||||
"create a star by weaving together points from an outer and inner circle. `n` is the number of arms"
|
||||
function makestar(n; offset = -0.5, radius = 1.0)
|
||||
z1 = offset * π
|
||||
z2 = z1 + π / (n)
|
||||
outercircle = partialcircle(z1, z1 + 2π, n+1, radius)
|
||||
innercircle = partialcircle(z2, z2 + 2π, n+1, 0.4radius)
|
||||
Shape(weave(outercircle, innercircle)[1:end-2])
|
||||
end
|
||||
|
||||
"create a shape by picking points around the unit circle. `n` is the number of point/sides, `offset` is the starting angle"
|
||||
function makeshape(n; offset = -0.5, radius = 1.0)
|
||||
z = offset * π
|
||||
Shape(partialcircle(z, z + 2π, n+1, radius)[1:end-1])
|
||||
end
|
||||
|
||||
|
||||
function makecross(; offset = -0.5, radius = 1.0)
|
||||
z2 = offset * π
|
||||
z1 = z2 - π/8
|
||||
outercircle = partialcircle(z1, z1 + 2π, 9, radius)
|
||||
innercircle = partialcircle(z2, z2 + 2π, 5, 0.5radius)
|
||||
Shape(weave(outercircle, innercircle,
|
||||
ordering=Vector[outercircle,innercircle,outercircle])[1:end-2])
|
||||
end
|
||||
|
||||
|
||||
const _shapes = @compat Dict(
|
||||
:ellipse => makeshape(20),
|
||||
:rect => makeshape(4, offset=-0.25),
|
||||
:diamond => makeshape(4),
|
||||
:utriangle => makeshape(3),
|
||||
:dtriangle => makeshape(3, offset=0.5),
|
||||
:pentagon => makeshape(5),
|
||||
:hexagon => makeshape(6),
|
||||
:heptagon => makeshape(7),
|
||||
:octagon => makeshape(8),
|
||||
:cross => makecross(offset=-0.25),
|
||||
:xcross => makecross(),
|
||||
)
|
||||
|
||||
for n in [4,5,6,7,8]
|
||||
_shapes[symbol("star$n")] = makestar(n)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
|
||||
immutable Font
|
||||
family::AbstractString
|
||||
pointsize::Int
|
||||
halign::Symbol
|
||||
valign::Symbol
|
||||
rotation::Float64
|
||||
color::Colorant
|
||||
end
|
||||
|
||||
"Create a Font from a list of unordered features"
|
||||
function font(args...)
|
||||
|
||||
# defaults
|
||||
family = "Helvetica"
|
||||
pointsize = 14
|
||||
halign = :hcenter
|
||||
valign = :vcenter
|
||||
rotation = 0.0
|
||||
color = colorant"black"
|
||||
|
||||
for arg in args
|
||||
T = typeof(arg)
|
||||
|
||||
if arg == :center
|
||||
halign = :hcenter
|
||||
valign = :vcenter
|
||||
elseif arg in (:hcenter, :left, :right)
|
||||
halign = arg
|
||||
elseif arg in (:vcenter, :top, :bottom)
|
||||
valign = arg
|
||||
elseif T <: Colorant
|
||||
color = arg
|
||||
elseif T <: @compat Union{Symbol,AbstractString}
|
||||
try
|
||||
color = parse(Colorant, string(arg))
|
||||
catch
|
||||
family = string(arg)
|
||||
end
|
||||
elseif typeof(arg) <: Integer
|
||||
pointsize = arg
|
||||
elseif typeof(arg) <: Real
|
||||
rotation = convert(Float64, arg)
|
||||
else
|
||||
warn("Unused font arg: $arg ($(typeof(arg)))")
|
||||
end
|
||||
end
|
||||
|
||||
Font(family, pointsize, halign, valign, rotation, color)
|
||||
end
|
||||
|
||||
"Wrap a string with font info"
|
||||
immutable PlotText
|
||||
str::@compat(AbstractString)
|
||||
font::Font
|
||||
end
|
||||
|
||||
function text(str, args...)
|
||||
PlotText(string(str), font(args...))
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
immutable Stroke
|
||||
width
|
||||
color
|
||||
alpha
|
||||
style
|
||||
end
|
||||
|
||||
function stroke(args...; alpha = nothing)
|
||||
# defaults
|
||||
# width = 1
|
||||
# color = colorant"black"
|
||||
# style = :solid
|
||||
width = nothing
|
||||
color = nothing
|
||||
style = nothing
|
||||
|
||||
for arg in args
|
||||
T = typeof(arg)
|
||||
|
||||
if arg in _allStyles
|
||||
style = arg
|
||||
elseif T <: Colorant
|
||||
color = arg
|
||||
elseif T <: @compat Union{Symbol,AbstractString}
|
||||
try
|
||||
color = parse(Colorant, string(arg))
|
||||
end
|
||||
elseif typeof(arg) <: Real
|
||||
width = arg
|
||||
else
|
||||
warn("Unused stroke arg: $arg ($(typeof(arg)))")
|
||||
end
|
||||
end
|
||||
|
||||
Stroke(width, color, alpha, style)
|
||||
end
|
||||
|
||||
|
||||
immutable Brush
|
||||
size # fillrange, markersize, or any other sizey attribute
|
||||
color
|
||||
alpha
|
||||
end
|
||||
|
||||
function brush(args...; alpha = nothing)
|
||||
# defaults
|
||||
# sz = 1
|
||||
# color = colorant"black"
|
||||
size = nothing
|
||||
color = nothing
|
||||
|
||||
for arg in args
|
||||
T = typeof(arg)
|
||||
|
||||
if T <: Colorant
|
||||
color = arg
|
||||
elseif T <: @compat Union{Symbol,AbstractString}
|
||||
try
|
||||
color = parse(Colorant, string(arg))
|
||||
end
|
||||
elseif typeof(arg) <: Real
|
||||
size = arg
|
||||
else
|
||||
warn("Unused brush arg: $arg ($(typeof(arg)))")
|
||||
end
|
||||
end
|
||||
|
||||
Brush(size, color, alpha)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
"type which represents z-values for colors and sizes (and anything else that might come up)"
|
||||
immutable ZValues
|
||||
values::Vector{Float64}
|
||||
zrange::Tuple{Float64,Float64}
|
||||
end
|
||||
|
||||
function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (minimum(values), maximum(values)))
|
||||
ZValues(collect(float(values)), map(Float64, zrange))
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
type OHLC{T<:Real}
|
||||
open::T
|
||||
high::T
|
||||
low::T
|
||||
close::T
|
||||
end
|
||||
@@ -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
|
||||
getinitargs(plt::Plot, idx::Int = 1) = plt.initargs
|
||||
getplotargs(plt::Plot, idx::Int = 1) = plt.plotargs
|
||||
convertSeriesIndex(plt::Plot, n::Int) = n
|
||||
|
||||
# ---------------------------------------------------------
|
||||
@@ -50,7 +50,7 @@ function plot(args...; kw...)
|
||||
|
||||
plotargs = getPlotArgs(pkg, d, 1)
|
||||
dumpdict(plotargs, "Plot args")
|
||||
plt = plot(pkg; plotargs...) # create a new, blank plot
|
||||
plt = _create_plot(pkg; plotargs...) # create a new, blank plot
|
||||
|
||||
delete!(d, :background_color)
|
||||
plot!(plt, args...; d...) # add to it
|
||||
@@ -87,18 +87,18 @@ function plot!(plt::Plot, args...; kw...)
|
||||
groupargs = get(d, :group, nothing) == nothing ? [] : [extractGroupArgs(d[:group], args...)]
|
||||
|
||||
# just in case the backend needs to set up the plot (make it current or something)
|
||||
preparePlotUpdate(plt)
|
||||
_before_add_series(plt)
|
||||
|
||||
# get the list of dictionaries, one per series
|
||||
kwList, xmeta, ymeta = createKWargsList(plt, groupargs..., args...; d...)
|
||||
seriesArgList, xmeta, ymeta = createKWargsList(plt, groupargs..., args...; d...)
|
||||
|
||||
# if we were able to extract guide information from the series inputs, then update the plot
|
||||
# @show xmeta, ymeta
|
||||
updateDictWithMeta(d, plt.initargs, xmeta, true)
|
||||
updateDictWithMeta(d, plt.initargs, ymeta, false)
|
||||
updateDictWithMeta(d, plt.plotargs, xmeta, true)
|
||||
updateDictWithMeta(d, plt.plotargs, ymeta, false)
|
||||
|
||||
# now we can plot the series
|
||||
for (i,di) in enumerate(kwList)
|
||||
for (i,di) in enumerate(seriesArgList)
|
||||
plt.n += 1
|
||||
|
||||
setTicksFromStringVector(d, di, :x, :xticks)
|
||||
@@ -111,22 +111,22 @@ function plot!(plt::Plot, args...; kw...)
|
||||
|
||||
dumpdict(di, "Series $i")
|
||||
|
||||
plot!(plt.backend, plt; di...)
|
||||
_add_series(plt.backend, plt; di...)
|
||||
end
|
||||
|
||||
addAnnotations(plt, d)
|
||||
_add_annotations(plt, d)
|
||||
|
||||
warnOnUnsupportedScales(plt.backend, d)
|
||||
|
||||
|
||||
# add title, axis labels, ticks, etc
|
||||
if !haskey(d, :subplot)
|
||||
merge!(plt.initargs, d)
|
||||
dumpdict(plt.initargs, "Updating plot items")
|
||||
updatePlotItems(plt, plt.initargs)
|
||||
merge!(plt.plotargs, d)
|
||||
dumpdict(plt.plotargs, "Updating plot items")
|
||||
_update_plot(plt, plt.plotargs)
|
||||
end
|
||||
|
||||
updatePositionAndSize(plt, d)
|
||||
_update_plot_pos_size(plt, d)
|
||||
|
||||
current(plt)
|
||||
|
||||
@@ -163,18 +163,18 @@ end
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
preparePlotUpdate(plt::Plot) = nothing
|
||||
_before_add_series(plt::Plot) = nothing
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
# should we update the x/y label given the meta info during input slicing?
|
||||
function updateDictWithMeta(d::Dict, initargs::Dict, meta::Symbol, isx::Bool)
|
||||
function updateDictWithMeta(d::Dict, plotargs::Dict, meta::Symbol, isx::Bool)
|
||||
lsym = isx ? :xlabel : :ylabel
|
||||
if initargs[lsym] == default(lsym)
|
||||
if plotargs[lsym] == default(lsym)
|
||||
d[lsym] = string(meta)
|
||||
end
|
||||
end
|
||||
updateDictWithMeta(d::Dict, initargs::Dict, meta, isx::Bool) = nothing
|
||||
updateDictWithMeta(d::Dict, plotargs::Dict, meta, isx::Bool) = nothing
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
@@ -184,10 +184,10 @@ annotations{X,Y,V}(t::@compat(Tuple{X,Y,V})) = [t]
|
||||
annotations(anns) = error("Expecting a tuple (or vector of tuples) for annotations: ",
|
||||
"(x, y, annotation)\n got: $(typeof(anns))")
|
||||
|
||||
function addAnnotations(plt::Plot, d::Dict)
|
||||
function _add_annotations(plt::Plot, d::Dict)
|
||||
anns = annotations(get(d, :annotation, nothing))
|
||||
if !isempty(anns)
|
||||
addAnnotations(plt, anns)
|
||||
_add_annotations(plt, anns)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -225,7 +225,15 @@ convertToAnyVector(f::Function; kw...) = Any[f], nothing
|
||||
convertToAnyVector(v::AVec{OHLC}; kw...) = Any[v], nothing
|
||||
|
||||
# list of things (maybe other vectors, functions, or something else)
|
||||
convertToAnyVector(v::AVec; kw...) = Any[vi for vi in v], nothing
|
||||
function convertToAnyVector(v::AVec; kw...)
|
||||
if all(x -> typeof(x) <: Real, v)
|
||||
# all real numbers wrap the whole vector as one item
|
||||
Any[convert(Vector{Float64}, v)], nothing
|
||||
else
|
||||
# something else... treat each element as an item
|
||||
Any[vi for vi in v], nothing
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
@@ -254,8 +262,6 @@ function createKWargsList(plt::PlottingObject, x, y; kw...)
|
||||
xs, xmeta = convertToAnyVector(x; kw...)
|
||||
ys, ymeta = convertToAnyVector(y; kw...)
|
||||
|
||||
# _debugMode.on && dumpcallstack()
|
||||
|
||||
mx = length(xs)
|
||||
my = length(ys)
|
||||
ret = Any[]
|
||||
@@ -275,7 +281,7 @@ function createKWargsList(plt::PlottingObject, x, y; kw...)
|
||||
numUncounted = get(d, :numUncounted, 0)
|
||||
n = plt.n + i + numUncounted
|
||||
dumpdict(d, "before getSeriesArgs")
|
||||
d = getSeriesArgs(plt.backend, getinitargs(plt, n), d, i + numUncounted, convertSeriesIndex(plt, n), n)
|
||||
d = getSeriesArgs(plt.backend, getplotargs(plt, n), d, i + numUncounted, convertSeriesIndex(plt, n), n)
|
||||
dumpdict(d, "after getSeriesArgs")
|
||||
d[:x], d[:y] = computeXandY(xs[mod1(i,mx)], ys[mod1(i,my)])
|
||||
|
||||
@@ -363,7 +369,7 @@ end
|
||||
|
||||
# special handling... xmin/xmax with function(s)
|
||||
function createKWargsList(plt::PlottingObject, f::FuncOrFuncs, xmin::Real, xmax::Real; kw...)
|
||||
width = plt.initargs[:size][1]
|
||||
width = plt.plotargs[:size][1]
|
||||
x = collect(linspace(xmin, xmax, width)) # we don't need more than the width
|
||||
createKWargsList(plt, x, f; kw...)
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ immutable PyPlotPackage <: PlottingPackage end
|
||||
immutable QwtPackage <: PlottingPackage end
|
||||
immutable UnicodePlotsPackage <: PlottingPackage end
|
||||
immutable WinstonPackage <: PlottingPackage end
|
||||
immutable BokehPackage <: PlottingPackage end
|
||||
|
||||
typealias GadflyOrImmerse @compat(Union{GadflyPackage, ImmersePackage})
|
||||
|
||||
@@ -14,7 +15,8 @@ export
|
||||
immerse,
|
||||
pyplot,
|
||||
qwt,
|
||||
unicodeplots
|
||||
unicodeplots,
|
||||
bokeh
|
||||
# winston
|
||||
|
||||
gadfly() = backend(:gadfly)
|
||||
@@ -22,6 +24,7 @@ immerse() = backend(:immerse)
|
||||
pyplot() = backend(:pyplot)
|
||||
qwt() = backend(:qwt)
|
||||
unicodeplots() = backend(:unicodeplots)
|
||||
bokeh() = backend(:bokeh)
|
||||
# winston() = backend(:winston)
|
||||
|
||||
backend_name(::GadflyPackage) = :gadfly
|
||||
@@ -29,6 +32,7 @@ backend_name(::ImmersePackage) = :immerse
|
||||
backend_name(::PyPlotPackage) = :pyplot
|
||||
backend_name(::UnicodePlotsPackage) = :unicodeplots
|
||||
backend_name(::QwtPackage) = :qwt
|
||||
backend_name(::BokehPackage) = :bokeh
|
||||
|
||||
include("backends/supported.jl")
|
||||
|
||||
@@ -38,6 +42,7 @@ include("backends/unicodeplots.jl")
|
||||
include("backends/pyplot.jl")
|
||||
include("backends/immerse.jl")
|
||||
include("backends/winston.jl")
|
||||
include("backends/bokeh.jl")
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
@@ -45,10 +50,10 @@ include("backends/winston.jl")
|
||||
|
||||
plot(pkg::PlottingPackage; kw...) = error("plot($pkg; kw...) is not implemented")
|
||||
plot!(pkg::PlottingPackage, plt::Plot; kw...) = error("plot!($pkg, plt; kw...) is not implemented")
|
||||
updatePlotItems(pkg::PlottingPackage, plt::Plot, d::Dict) = error("updatePlotItems($pkg, plt, d) is not implemented")
|
||||
_update_plot(pkg::PlottingPackage, plt::Plot, d::Dict) = error("_update_plot($pkg, plt, d) is not implemented")
|
||||
# Base.display(pkg::PlottingPackage, plt::Plot) = error("display($pkg, plt) is not implemented")
|
||||
|
||||
updatePositionAndSize{P<:PlottingPackage}(plt::PlottingObject{P}, d::Dict) = nothing #error("updatePositionAndSize(plt,d) is not implemented for $P")
|
||||
_update_plot_pos_size{P<:PlottingPackage}(plt::PlottingObject{P}, d::Dict) = nothing #error("_update_plot_pos_size(plt,d) is not implemented for $P")
|
||||
|
||||
subplot(pkg::PlottingPackage; kw...) = error("subplot($pkg; kw...) is not implemented")
|
||||
subplot!(pkg::PlottingPackage, subplt::Subplot; kw...) = error("subplot!($pkg, subplt; kw...) is not implemented")
|
||||
@@ -57,7 +62,7 @@ subplot!(pkg::PlottingPackage, subplt::Subplot; kw...) = error("subplot!($pkg, s
|
||||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
const BACKENDS = [:qwt, :gadfly, :unicodeplots, :pyplot, :immerse]
|
||||
const BACKENDS = [:qwt, :gadfly, :unicodeplots, :pyplot, :immerse, :bokeh]
|
||||
const INITIALIZED_BACKENDS = Set{Symbol}()
|
||||
backends() = BACKENDS
|
||||
|
||||
@@ -69,6 +74,7 @@ function backendInstance(sym::Symbol)
|
||||
sym == :pyplot && return PyPlotPackage()
|
||||
sym == :immerse && return ImmersePackage()
|
||||
sym == :winston && return WinstonPackage()
|
||||
sym == :bokeh && return BokehPackage()
|
||||
error("Unsupported backend $sym")
|
||||
end
|
||||
|
||||
@@ -82,6 +88,11 @@ CurrentBackend(sym::Symbol) = CurrentBackend(sym, backendInstance(sym))
|
||||
# ---------------------------------------------------------
|
||||
|
||||
function pickDefaultBackend()
|
||||
try
|
||||
if Pkg.installed("PyPlot") != nothing
|
||||
return CurrentBackend(:pyplot)
|
||||
end
|
||||
end
|
||||
try
|
||||
if Pkg.installed("Immerse") != nothing
|
||||
return CurrentBackend(:immerse)
|
||||
@@ -92,11 +103,6 @@ function pickDefaultBackend()
|
||||
return CurrentBackend(:qwt)
|
||||
end
|
||||
end
|
||||
try
|
||||
if Pkg.installed("PyPlot") != nothing
|
||||
return CurrentBackend(:pyplot)
|
||||
end
|
||||
end
|
||||
try
|
||||
if Pkg.installed("Gadfly") != nothing
|
||||
return CurrentBackend(:gadfly)
|
||||
@@ -107,6 +113,11 @@ function pickDefaultBackend()
|
||||
return CurrentBackend(:unicodeplots)
|
||||
end
|
||||
end
|
||||
try
|
||||
if Pkg.installed("Bokeh") != nothing
|
||||
return CurrentBackend(:bokeh)
|
||||
end
|
||||
end
|
||||
try
|
||||
if Pkg.installed("Winston") != nothing
|
||||
return CurrentBackend(:winston)
|
||||
@@ -115,8 +126,6 @@ function pickDefaultBackend()
|
||||
warn("You don't have any of the supported backends installed! Chose from ", backends())
|
||||
return CurrentBackend(:gadfly)
|
||||
end
|
||||
# const CURRENT_BACKEND = pickDefaultBackend()
|
||||
# println("[Plots.jl] Default backend: ", CURRENT_BACKEND.sym)
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
@@ -125,7 +134,6 @@ end
|
||||
Returns the current plotting package name. Initializes package on first call.
|
||||
"""
|
||||
function backend()
|
||||
# error()
|
||||
|
||||
currentBackendSymbol = CURRENT_BACKEND.sym
|
||||
if !(currentBackendSymbol in INITIALIZED_BACKENDS)
|
||||
@@ -143,8 +151,8 @@ function backend()
|
||||
|
||||
elseif currentBackendSymbol == :gadfly
|
||||
try
|
||||
@eval import Gadfly, Compose, DataFrames
|
||||
@eval export Gadfly, Compose, DataFrames
|
||||
@eval import Gadfly, Compose
|
||||
@eval export Gadfly, Compose
|
||||
@eval include(joinpath(Pkg.dir("Plots"), "src", "backends", "gadfly_shapes.jl"))
|
||||
catch err
|
||||
warn("Couldn't import Gadfly. Install it with: Pkg.add(\"Gadfly\").")
|
||||
@@ -166,6 +174,7 @@ function backend()
|
||||
@eval export PyPlot
|
||||
@eval const pycolors = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colors"))
|
||||
@eval const pypath = PyPlot.pywrap(PyPlot.pyimport("matplotlib.path"))
|
||||
@eval const mplot3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d"))
|
||||
# @eval const pycolorbar = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colorbar"))
|
||||
if !isa(Base.Multimedia.displays[end], Base.REPL.REPLDisplay)
|
||||
PyPlot.ioff() # stops wierd behavior of displaying incomplete graphs in IJulia
|
||||
@@ -198,6 +207,15 @@ function backend()
|
||||
rethrow(err)
|
||||
end
|
||||
|
||||
elseif currentBackendSymbol == :bokeh
|
||||
try
|
||||
@eval import Bokeh
|
||||
@eval export Bokeh
|
||||
catch err
|
||||
warn("Couldn't import Bokeh. Install it with: Pkg.add(\"Bokeh\").")
|
||||
rethrow(err)
|
||||
end
|
||||
|
||||
elseif currentBackendSymbol == :winston
|
||||
warn("Winston support is deprecated and broken. Try another backend: $BACKENDS")
|
||||
try
|
||||
@@ -242,6 +260,8 @@ function backend(modname)
|
||||
CURRENT_BACKEND.pkg = ImmersePackage()
|
||||
elseif modname == :winston
|
||||
CURRENT_BACKEND.pkg = WinstonPackage()
|
||||
elseif modname == :bokeh
|
||||
CURRENT_BACKEND.pkg = BokehPackage()
|
||||
else
|
||||
error("Unknown backend $modname. Choose from: $BACKENDS")
|
||||
end
|
||||
|
||||
@@ -81,8 +81,8 @@ Base.getindex(layout::GridLayout, r::Int, c::Int) = (r-1) * layout.nc + c
|
||||
Base.getindex(subplt::Subplot, args...) = subplt.plts[subplt.layout[args...]]
|
||||
|
||||
# handle "linking" the subplot axes together
|
||||
# each backend should implement the handleLinkInner and expandLimits! methods
|
||||
function linkAxis(subplt::Subplot, isx::Bool)
|
||||
# each backend should implement the _remove_axis and _expand_limits methods
|
||||
function link_axis(subplt::Subplot, isx::Bool)
|
||||
|
||||
# collect the list of plots and the expanded limits for those plots that should be linked on this axis
|
||||
includedPlots = Any[]
|
||||
@@ -104,7 +104,7 @@ function linkAxis(subplt::Subplot, isx::Bool)
|
||||
isinner = (isx && r < nrows(subplt.layout)) || (!isx && !firstone)
|
||||
push!(includedPlots, (plt, isinner, k))
|
||||
|
||||
expandLimits!(lims[k], plt, isx)
|
||||
_expand_limits(lims[k], plt, isx)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -112,7 +112,7 @@ function linkAxis(subplt::Subplot, isx::Bool)
|
||||
# do the axis adjustments
|
||||
for (plt, isinner, k) in includedPlots
|
||||
if isinner
|
||||
handleLinkInner(plt, isx)
|
||||
_remove_axis(plt, isx)
|
||||
end
|
||||
(isx ? xlims! : ylims!)(plt, lims[k]...)
|
||||
end
|
||||
@@ -128,7 +128,7 @@ Base.print(io::IO, subplt::Subplot) = print(io, string(subplt))
|
||||
Base.show(io::IO, subplt::Subplot) = print(io, string(subplt))
|
||||
|
||||
getplot(subplt::Subplot, idx::Int = subplt.n) = subplt.plts[mod1(idx, subplt.p)]
|
||||
getinitargs(subplt::Subplot, idx::Int) = getplot(subplt, idx).initargs
|
||||
getplotargs(subplt::Subplot, idx::Int) = getplot(subplt, idx).plotargs
|
||||
convertSeriesIndex(subplt::Subplot, n::Int) = ceil(Int, n / subplt.p)
|
||||
|
||||
# ------------------------------------------------------------
|
||||
@@ -175,7 +175,7 @@ function subplot(args...; kw...)
|
||||
di = getPlotArgs(pkg, d, i)
|
||||
di[:subplot] = true
|
||||
dumpdict(di, "Plot args (subplot $i)")
|
||||
push!(plts, plot(pkg; di...))
|
||||
push!(plts, _create_plot(pkg; di...))
|
||||
end
|
||||
|
||||
# create the object and do the plotting
|
||||
@@ -209,29 +209,8 @@ function subplot{P<:PlottingPackage}(plts::AVec{Plot{P}}, layout::SubplotLayout,
|
||||
n = sum([plt.n for plt in plts])
|
||||
subplt = Subplot(nothing, collect(plts), P(), p, n, layout, Dict(), false, false, false, (r,c) -> (nothing,nothing))
|
||||
|
||||
# preprocessArgs!(d)
|
||||
|
||||
# #
|
||||
# for (i,plt) in enumerate(plts)
|
||||
# di = copy(plt.initargs)
|
||||
|
||||
# for ck in (:background_color, :foreground_color, :color_palette)
|
||||
# # if we have a value to override, do it
|
||||
# if haskey(d, ck)
|
||||
# di[ck] = get_mod(d[ck], i)
|
||||
# end
|
||||
|
||||
|
||||
|
||||
# # build a new dict from the initargs of the plots
|
||||
# iargs = Dict()
|
||||
# for k in keys(_plotDefaults)
|
||||
# iargs[k] = Any[plt.initargs[k] for plt in plts]'
|
||||
# end
|
||||
# merge!(iargs, d)
|
||||
|
||||
preprocessSubplot(subplt, d)
|
||||
postprocessSubplot(subplt, d)
|
||||
_preprocess_subplot(subplt, d)
|
||||
_postprocess_subplot(subplt, d)
|
||||
|
||||
subplt
|
||||
end
|
||||
@@ -241,26 +220,24 @@ end
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
function preprocessSubplot(subplt::Subplot, d::Dict)
|
||||
function _preprocess_subplot(subplt::Subplot, d::Dict)
|
||||
validateSubplotSupported()
|
||||
preprocessArgs!(d)
|
||||
dumpdict(d, "After subplot! preprocessing")
|
||||
|
||||
# get the full initargs, overriding any new settings
|
||||
# TODO: subplt.initargs should probably be merged sooner and actually used
|
||||
# get the full plotargs, overriding any new settings
|
||||
# TODO: subplt.plotargs should probably be merged sooner and actually used
|
||||
# for color selection, etc. (i.e. if we overwrite the subplot palettes to [:heat :rainbow])
|
||||
# then we need to overwrite plt[1].initargs[:color_palette] to :heat before it's actually used
|
||||
# then we need to overwrite plt[1].plotargs[:color_palette] to :heat before it's actually used
|
||||
# for color selection!
|
||||
|
||||
# first merge the new args into the subplot's initargs. then process the plot args and merge
|
||||
# those into the plot's initargs. (example... `palette = [:blues :reds]` goes into subplt.initargs,
|
||||
# then the ColorGradient for :blues/:reds is merged into plot 1/2 initargs, which is then used for color selection)
|
||||
# first merge the new args into the subplot's plotargs. then process the plot args and merge
|
||||
# those into the plot's plotargs. (example... `palette = [:blues :reds]` goes into subplt.plotargs,
|
||||
# then the ColorGradient for :blues/:reds is merged into plot 1/2 plotargs, which is then used for color selection)
|
||||
for i in 1:length(subplt.layout)
|
||||
# di = getPlotArgs(backend(), subplt.initargs, i)
|
||||
# merge!(subplt.plts[i].initargs, di)
|
||||
subplt.plts[i].initargs = getPlotArgs(backend(), merge(subplt.plts[i].initargs, d), i)
|
||||
subplt.plts[i].plotargs = getPlotArgs(backend(), merge(subplt.plts[i].plotargs, d), i)
|
||||
end
|
||||
merge!(subplt.initargs, d)
|
||||
merge!(subplt.plotargs, d)
|
||||
|
||||
# process links. TODO: extract to separate function
|
||||
for s in (:linkx, :linky, :linkfunc)
|
||||
@@ -271,41 +248,24 @@ function preprocessSubplot(subplt::Subplot, d::Dict)
|
||||
end
|
||||
end
|
||||
|
||||
function postprocessSubplot(subplt::Subplot, d::Dict)
|
||||
function _postprocess_subplot(subplt::Subplot, d::Dict)
|
||||
# init (after plot creation)
|
||||
if !subplt.initialized
|
||||
subplt.initialized = buildSubplotObject!(subplt, false)
|
||||
subplt.initialized = _create_subplot(subplt, false)
|
||||
end
|
||||
|
||||
# add title, axis labels, ticks, etc
|
||||
for (i,plt) in enumerate(subplt.plts)
|
||||
|
||||
# # # get the full initargs, overriding any new settings
|
||||
# # di = copy(merge(plt.initargs, d))
|
||||
# di = copy(d)
|
||||
|
||||
# for (k,v) in di
|
||||
# if typeof(v) <: AVec
|
||||
# di[k] = v[mod1(i, length(v))]
|
||||
# elseif typeof(v) <: AMat
|
||||
# m = size(v,2)
|
||||
# di[k] = (size(v,1) == 1 ? v[1, mod1(i, m)] : v[:, mod1(i, m)])
|
||||
# end
|
||||
# end
|
||||
|
||||
# di = merge!(plt.initargs, di)
|
||||
|
||||
di = plt.initargs
|
||||
|
||||
di = plt.plotargs
|
||||
dumpdict(di, "Updating sp $i")
|
||||
updatePlotItems(plt, di)
|
||||
_update_plot(plt, di)
|
||||
end
|
||||
|
||||
updatePositionAndSize(subplt, d)
|
||||
_update_plot_pos_size(subplt, d)
|
||||
|
||||
# handle links
|
||||
subplt.linkx && linkAxis(subplt, true)
|
||||
subplt.linky && linkAxis(subplt, false)
|
||||
subplt.linkx && link_axis(subplt, true)
|
||||
subplt.linky && link_axis(subplt, false)
|
||||
|
||||
# set this to be current
|
||||
current(subplt)
|
||||
@@ -335,14 +295,14 @@ function subplot!(subplt::Subplot, args...; kw...)
|
||||
# validateSubplotSupported()
|
||||
|
||||
d = Dict(kw)
|
||||
preprocessSubplot(subplt, d)
|
||||
_preprocess_subplot(subplt, d)
|
||||
|
||||
# create the underlying object (each backend will do this differently)
|
||||
# note: we call it once before doing the individual plots, and once after
|
||||
# this is because some backends need to set up the subplots and then plot,
|
||||
# and others need to do it the other way around
|
||||
if !subplt.initialized
|
||||
subplt.initialized = buildSubplotObject!(subplt, true)
|
||||
subplt.initialized = _create_subplot(subplt, true)
|
||||
end
|
||||
|
||||
# handle grouping
|
||||
@@ -365,17 +325,6 @@ function subplot!(subplt::Subplot, args...; kw...)
|
||||
plt = getplot(subplt)
|
||||
plt.n += 1
|
||||
|
||||
# # update the plot's initargs for things such as palettes, etc
|
||||
# for (k,v) in subplt.initargs
|
||||
# haskey(_plotDefaults, k) || continue
|
||||
# if typeof(v) <: AVec
|
||||
# plt.initargs[k] = v[mod1(i, length(v))]
|
||||
# elseif typeof(v) <: AMat
|
||||
# m = size(v,2)
|
||||
# plt.initargs[k] = (size(v,1) == 1 ? v[1, mod1(i, m)] : v[:, mod1(i, m)])
|
||||
# end
|
||||
# end
|
||||
|
||||
# cleanup the dictionary that we pass into the plot! command
|
||||
di[:show] = false
|
||||
di[:subplot] = true
|
||||
@@ -384,12 +333,12 @@ function subplot!(subplt::Subplot, args...; kw...)
|
||||
delete!(di, k)
|
||||
end
|
||||
dumpdict(di, "subplot! kwList $i")
|
||||
dumpdict(plt.initargs, "plt.initargs before plotting")
|
||||
dumpdict(plt.plotargs, "plt.plotargs before plotting")
|
||||
|
||||
_plot_from_subplot!(plt; di...)
|
||||
_add_series_subplot(plt; di...)
|
||||
end
|
||||
|
||||
postprocessSubplot(subplt, d)
|
||||
_postprocess_subplot(subplt, d)
|
||||
|
||||
# show it automatically?
|
||||
if haskey(d, :show) && d[:show]
|
||||
@@ -401,16 +350,15 @@ end
|
||||
|
||||
|
||||
|
||||
function _plot_from_subplot!(plt::Plot, args...; kw...)
|
||||
function _add_series_subplot(plt::Plot, args...; kw...)
|
||||
d = Dict(kw)
|
||||
|
||||
setTicksFromStringVector(d, d, :x, :xticks)
|
||||
setTicksFromStringVector(d, d, :y, :yticks)
|
||||
|
||||
# dumpdict(d, "Plot from subplot")
|
||||
plot!(plt.backend, plt; d...)
|
||||
_add_series(plt.backend, plt; d...)
|
||||
|
||||
addAnnotations(plt, d)
|
||||
_add_annotations(plt, d)
|
||||
warnOnUnsupportedScales(plt.backend, d)
|
||||
end
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ type Plot{T<:PlottingPackage} <: PlottingObject{T}
|
||||
n::Int # number of series
|
||||
|
||||
# store these just in case
|
||||
initargs::Dict
|
||||
plotargs::Dict
|
||||
seriesargs::Vector{Dict} # args for each series
|
||||
end
|
||||
|
||||
@@ -38,8 +38,8 @@ type Subplot{T<:PlottingPackage, L<:SubplotLayout} <: PlottingObject{T}
|
||||
p::Int # number of plots
|
||||
n::Int # number of series
|
||||
layout::L
|
||||
# initargs::Vector{Dict}
|
||||
initargs::Dict
|
||||
# plotargs::Vector{Dict}
|
||||
plotargs::Dict
|
||||
initialized::Bool
|
||||
linkx::Bool
|
||||
linky::Bool
|
||||
@@ -47,148 +47,3 @@ type Subplot{T<:PlottingPackage, L<:SubplotLayout} <: PlottingObject{T}
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
immutable Shape
|
||||
vertices::AVec
|
||||
end
|
||||
|
||||
"get an array of tuples of points on a circle with radius `r`"
|
||||
function partialcircle(start_θ, end_θ, n = 20, r=1)
|
||||
@compat(Tuple{Float64,Float64})[(r*cos(u),r*sin(u)) for u in linspace(start_θ, end_θ, n)]
|
||||
end
|
||||
|
||||
"interleave 2 vectors into each other (like a zipper's teeth)"
|
||||
function weave(x,y; ordering = Vector[x,y])
|
||||
ret = eltype(x)[]
|
||||
done = false
|
||||
while !done
|
||||
for o in ordering
|
||||
try
|
||||
push!(ret, shift!(o))
|
||||
end
|
||||
# try
|
||||
# push!(ret, shift!(y))
|
||||
# end
|
||||
end
|
||||
done = isempty(x) && isempty(y)
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
|
||||
"create a star by weaving together points from an outer and inner circle. `n` is the number of arms"
|
||||
function makestar(n; offset = -0.5, radius = 1.0)
|
||||
z1 = offset * π
|
||||
z2 = z1 + π / (n)
|
||||
outercircle = partialcircle(z1, z1 + 2π, n+1, radius)
|
||||
innercircle = partialcircle(z2, z2 + 2π, n+1, 0.4radius)
|
||||
Shape(weave(outercircle, innercircle)[1:end-2])
|
||||
end
|
||||
|
||||
"create a shape by picking points around the unit circle. `n` is the number of point/sides, `offset` is the starting angle"
|
||||
function makeshape(n; offset = -0.5, radius = 1.0)
|
||||
z = offset * π
|
||||
Shape(partialcircle(z, z + 2π, n+1, radius)[1:end-1])
|
||||
end
|
||||
|
||||
|
||||
function makecross(; offset = -0.5, radius = 1.0)
|
||||
z2 = offset * π
|
||||
z1 = z2 - π/8
|
||||
outercircle = partialcircle(z1, z1 + 2π, 9, radius)
|
||||
innercircle = partialcircle(z2, z2 + 2π, 5, 0.5radius)
|
||||
Shape(weave(outercircle, innercircle,
|
||||
ordering=Vector[outercircle,innercircle,outercircle])[1:end-2])
|
||||
end
|
||||
|
||||
|
||||
const _shapes = @compat Dict(
|
||||
:ellipse => makeshape(20),
|
||||
:rect => makeshape(4, offset=-0.25),
|
||||
:diamond => makeshape(4),
|
||||
:utriangle => makeshape(3),
|
||||
:dtriangle => makeshape(3, offset=0.5),
|
||||
:pentagon => makeshape(5),
|
||||
:hexagon => makeshape(6),
|
||||
:heptagon => makeshape(7),
|
||||
:octagon => makeshape(8),
|
||||
:cross => makecross(offset=-0.25),
|
||||
:xcross => makecross(),
|
||||
)
|
||||
|
||||
for n in [4,5,6,7,8]
|
||||
_shapes[symbol("star$n")] = makestar(n)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
|
||||
immutable Font
|
||||
family::AbstractString
|
||||
pointsize::Int
|
||||
halign::Symbol
|
||||
valign::Symbol
|
||||
rotation::Float64
|
||||
color::Colorant
|
||||
end
|
||||
|
||||
"Create a Font from a list of unordered features"
|
||||
function font(args...)
|
||||
|
||||
# defaults
|
||||
family = "Helvetica"
|
||||
pointsize = 14
|
||||
halign = :hcenter
|
||||
valign = :vcenter
|
||||
rotation = 0.0
|
||||
color = colorant"black"
|
||||
|
||||
for arg in args
|
||||
T = typeof(arg)
|
||||
|
||||
if arg == :center
|
||||
halign = :hcenter
|
||||
valign = :vcenter
|
||||
elseif arg in (:hcenter, :left, :right)
|
||||
halign = arg
|
||||
elseif arg in (:vcenter, :top, :bottom)
|
||||
valign = arg
|
||||
elseif T <: Colorant
|
||||
color = arg
|
||||
elseif T <: @compat Union{Symbol,AbstractString}
|
||||
try
|
||||
color = parse(Colorant, string(arg))
|
||||
catch
|
||||
family = string(arg)
|
||||
end
|
||||
elseif typeof(arg) <: Integer
|
||||
pointsize = arg
|
||||
elseif typeof(arg) <: Real
|
||||
rotation = convert(Float64, arg)
|
||||
else
|
||||
warn("Unused font arg: $arg ($(typeof(arg)))")
|
||||
end
|
||||
end
|
||||
|
||||
Font(family, pointsize, halign, valign, rotation, color)
|
||||
end
|
||||
|
||||
"Wrap a string with font info"
|
||||
immutable PlotText
|
||||
str::@compat(AbstractString)
|
||||
font::Font
|
||||
end
|
||||
|
||||
function text(str, args...)
|
||||
PlotText(string(str), font(args...))
|
||||
end
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
type OHLC{T<:Real}
|
||||
open::T
|
||||
high::T
|
||||
low::T
|
||||
close::T
|
||||
end
|
||||
|
||||
@@ -116,6 +116,9 @@ end
|
||||
|
||||
# ------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
nop() = nothing
|
||||
|
||||
get_mod(v::AVec, idx::Int) = v[mod1(idx, length(v))]
|
||||
get_mod(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))]
|
||||
get_mod(v, idx::Int) = v
|
||||
@@ -131,7 +134,7 @@ maketuple{T,S}(x::@compat(Tuple{T,S})) = x
|
||||
unzip{T,S}(v::AVec{@compat(Tuple{T,S})}) = [vi[1] for vi in v], [vi[2] for vi in v]
|
||||
|
||||
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
|
||||
function expandLimits!(lims, x)
|
||||
function _expand_limits(lims, x)
|
||||
try
|
||||
e1, e2 = extrema(x)
|
||||
lims[1] = min(lims[1], e1)
|
||||
@@ -162,7 +165,6 @@ end
|
||||
|
||||
function replaceAliases!(d::Dict, aliases::Dict)
|
||||
ks = collect(keys(d))
|
||||
# for (k,v) in d
|
||||
for k in ks
|
||||
if haskey(aliases, k)
|
||||
d[aliases[k]] = d[k]
|
||||
@@ -198,6 +200,86 @@ limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
|
||||
limsType(lims) = :invalid
|
||||
|
||||
|
||||
Base.convert{T<:Real}(::Type{Vector{T}}, rng::Range{T}) = T[x for x in rng]
|
||||
Base.convert{T<:Real,S<:Real}(::Type{Vector{T}}, rng::Range{S}) = T[x for x in rng]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
"""
|
||||
Allows temporary setting of backend and defaults for Plots. Settings apply only for the `do` block. Example:
|
||||
```
|
||||
with(:gadfly, size=(400,400), type=:hist) do
|
||||
plot(rand(10))
|
||||
plot(rand(10))
|
||||
end
|
||||
```
|
||||
"""
|
||||
function with(f::Function, args...; kw...)
|
||||
|
||||
# dict to store old and new keyword args for anything that changes
|
||||
newdefs = Dict(kw)
|
||||
olddefs = Dict()
|
||||
for k in keys(newdefs)
|
||||
olddefs[k] = default(k)
|
||||
end
|
||||
|
||||
# save the backend
|
||||
oldbackend = CURRENT_BACKEND.sym
|
||||
|
||||
for arg in args
|
||||
|
||||
# change backend?
|
||||
if arg in backends()
|
||||
backend(arg)
|
||||
end
|
||||
|
||||
# # TODO: generalize this strategy to allow args as much as possible
|
||||
# # as in: with(:gadfly, :scatter, :legend, :grid) do; ...; end
|
||||
# # TODO: can we generalize this enough to also do something similar in the plot commands??
|
||||
|
||||
# k = :linetype
|
||||
# if arg in _allTypes
|
||||
# olddefs[k] = default(k)
|
||||
# newdefs[k] = arg
|
||||
# elseif haskey(_typeAliases, arg)
|
||||
# olddefs[k] = default(k)
|
||||
# newdefs[k] = _typeAliases[arg]
|
||||
# end
|
||||
|
||||
k = :legend
|
||||
if arg in (k, :leg)
|
||||
olddefs[k] = default(k)
|
||||
newdefs[k] = true
|
||||
end
|
||||
|
||||
k = :grid
|
||||
if arg == k
|
||||
olddefs[k] = default(k)
|
||||
newdefs[k] = true
|
||||
end
|
||||
end
|
||||
|
||||
# display(olddefs)
|
||||
# display(newdefs)
|
||||
|
||||
# now set all those defaults
|
||||
default(; newdefs...)
|
||||
|
||||
# call the function
|
||||
ret = f()
|
||||
|
||||
# put the defaults back
|
||||
default(; olddefs...)
|
||||
|
||||
# revert the backend
|
||||
if CURRENT_BACKEND.sym != oldbackend
|
||||
backend(oldbackend)
|
||||
end
|
||||
|
||||
# return the result of the function
|
||||
ret
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
@@ -213,8 +295,8 @@ end
|
||||
debugshow(x) = show(x)
|
||||
debugshow(x::AbstractArray) = print(summary(x))
|
||||
|
||||
function dumpdict(d::Dict, prefix = "")
|
||||
_debugMode.on || return
|
||||
function dumpdict(d::Dict, prefix = "", alwaysshow = false)
|
||||
_debugMode.on || alwaysshow || return
|
||||
println()
|
||||
if prefix != ""
|
||||
println(prefix, ":")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
julia 0.3
|
||||
julia 0.4
|
||||
|
||||
Colors
|
||||
Reexport
|
||||
|
||||
@@ -54,13 +54,21 @@ end
|
||||
|
||||
"Show a Gtk popup with both images and a confirmation whether we should replace the new image with the old one"
|
||||
function compareToReferenceImage(tmpfn, reffn)
|
||||
@eval import Gtk
|
||||
# println("here000")
|
||||
# @eval import Gtk
|
||||
# Gtk.gtk_main()
|
||||
# println("huh0")
|
||||
# sleep(2)
|
||||
|
||||
# add the images
|
||||
imgbox = Gtk.GtkBoxLeaf(:h)
|
||||
# println("huh")
|
||||
push!(imgbox, makeImageWidget(tmpfn))
|
||||
# println("huh2")
|
||||
push!(imgbox, makeImageWidget(reffn))
|
||||
|
||||
# println("here00")
|
||||
|
||||
# add the buttons
|
||||
# doNothingButton = Gtk.GtkButtonLeaf("Skip")
|
||||
# replaceReferenceButton = Gtk.GtkButtonLeaf("Replace reference image")
|
||||
@@ -75,14 +83,28 @@ function compareToReferenceImage(tmpfn, reffn)
|
||||
win = Gtk.GtkWindowLeaf("Should we make this the new reference image?")
|
||||
push!(win, Gtk.GtkFrameLeaf(imgbox))
|
||||
|
||||
# println("here01")
|
||||
|
||||
# ################
|
||||
# # TODO: remove this when it's fixed in Gtk... see http://stackoverflow.com/questions/33549485/julia-gtk-windows-do-not-display-outside-repl
|
||||
# signal_connect(win, :destroy) do widget
|
||||
# Gtk.gtk_quit()
|
||||
# end
|
||||
# ################
|
||||
|
||||
# println("here02")
|
||||
showall(win)
|
||||
|
||||
# println("here1")
|
||||
|
||||
# now ask the question
|
||||
if Gtk.ask_dialog("Should we make this the new reference image?", "No", "Yes")
|
||||
replaceReferenceImage(tmpfn, reffn)
|
||||
end
|
||||
|
||||
# println("here2")
|
||||
destroy(win)
|
||||
# println("here3")
|
||||
|
||||
# # we'll wait on this condition
|
||||
# c = Condition()
|
||||
@@ -156,13 +178,14 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, sigma = [1
|
||||
|
||||
catch err
|
||||
warn("Image did not match reference image $reffn. err: $err")
|
||||
showerror(Base.STDERR, err)
|
||||
# showerror(Base.STDERR, err)
|
||||
|
||||
if isinteractive()
|
||||
|
||||
# if we're in interactive mode, open a popup and give us a chance to examine the images
|
||||
warn("Should we make this the new reference image?")
|
||||
compareToReferenceImage(tmpfn, reffn)
|
||||
println("exited")
|
||||
return
|
||||
|
||||
else
|
||||
|
||||
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 201 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 31 KiB |