Compare commits

..

54 Commits

Author SHA1 Message Date
Thomas Breloff 22fd25b30f readme 2015-09-23 13:36:51 -04:00
Thomas Breloff 610ddb09ff readme and cleanup 2015-09-23 13:33:12 -04:00
Thomas Breloff 33602aca11 fixed tests 2015-09-23 13:03:37 -04:00
Thomas Breloff a207856e99 lims/ticks for gadfly/immerse 2015-09-23 12:45:24 -04:00
Thomas Breloff 80e8b5b5e4 fixes 2015-09-23 11:35:08 -04:00
Thomas Breloff 273996aa91 working on ticks/lims 2015-09-23 00:14:32 -04:00
Thomas Breloff 646b88c5be working on ticks 2015-09-22 23:30:20 -04:00
Thomas Breloff 88cfd82a25 unicodeplots fixes 2015-09-22 17:19:37 -04:00
Thomas Breloff 2f8436be87 winston examples 2015-09-22 17:04:51 -04:00
Thomas Breloff a6237cdda3 qwt examples 2015-09-22 17:02:19 -04:00
Thomas Breloff eb93a767fc pyplot fixes and examples 2015-09-22 16:57:23 -04:00
Thomas Breloff 41852412ca gadfly/immerse fixes and examples 2015-09-22 16:46:54 -04:00
Thomas Breloff 224b2b7323 various fixes; readme 2015-09-22 16:30:40 -04:00
Thomas Breloff ec939f9f9a more display fun 2015-09-22 14:56:37 -04:00
Thomas Breloff eced15b712 working on display/writemime overhaul 2015-09-22 12:54:55 -04:00
Thomas Breloff f8fb473981 reexport Colors; move default backend choice into __init__; fixed pickDefaultBackend 2015-09-22 08:10:30 -04:00
Thomas Breloff f2bcb77cfb trying fgcolor gadfly 2015-09-22 00:04:35 -04:00
Thomas Breloff dc5da28176 initial dataframes support 2015-09-21 23:36:07 -04:00
Thomas Breloff be43e64743 foreground_color fixes and added support in pyplot 2015-09-21 23:04:37 -04:00
Thomas Breloff 454630dace qwt fixes 2015-09-21 22:14:59 -04:00
Thomas Breloff c9df244333 qwt fixes 2015-09-21 17:38:27 -04:00
Thomas Breloff 2649d97d69 readme 2015-09-21 17:31:36 -04:00
Thomas Breloff bcb9ac5501 readme 2015-09-21 17:29:51 -04:00
Thomas Breloff 76d1e26f7d readme 2015-09-21 17:04:20 -04:00
Thomas Breloff ba13ab9926 readme 2015-09-21 16:59:15 -04:00
Thomas Breloff c43b34b67f auto-generated readme 2015-09-21 16:49:45 -04:00
Thomas Breloff 3739c2881b fixed linetype aliases; for qwt as well 2015-09-21 16:18:58 -04:00
Thomas Breloff bc13b81351 working on readme_template; added path linetype and sorting logic for line 2015-09-21 16:03:59 -04:00
Thomas Breloff 86a56e487a working on aliases 2015-09-21 14:38:03 -04:00
Thomas Breloff 031058cd0c cleanup and renaming constants 2015-09-21 12:15:40 -04:00
Thomas Breloff 85040d6104 fix creating empty plot with plot() 2015-09-21 12:05:17 -04:00
Thomas Breloff efbf74b44c working on auto generated color palette 2015-09-21 11:45:37 -04:00
Thomas Breloff 774fc42e8e replaced creation of kw args 2015-09-20 23:48:45 -04:00
Thomas Breloff 692cfe4f52 added srand calls to tests and examples 2015-09-20 22:59:25 -04:00
Thomas Breloff 8b34d4417b gadfly display size and fix: check for line_style 2015-09-20 21:12:56 -04:00
Thomas Breloff c20a7b3c69 added fillto for gadfly/immerse 2015-09-19 17:23:18 -04:00
Thomas Breloff ff6e83c55e working on new plot logic 2015-09-19 14:39:25 -04:00
Thomas Breloff 6aa56fd30f fixed subplot bug 2015-09-19 00:38:50 -04:00
Thomas Breloff f5a6f129dd foreground_color 2015-09-19 00:05:24 -04:00
Thomas Breloff 5405c1d240 working on colors 2015-09-18 17:20:35 -04:00
Thomas Breloff 455f85e230 working on colors, args 2015-09-18 16:53:43 -04:00
Thomas Breloff fa899a67a7 added support for gadfly linestyles... depends on gadfly PR 695 2015-09-18 12:26:18 -04:00
Thomas Breloff 56cf25eebf gadfly shapes 2015-09-18 01:55:16 -04:00
Thomas Breloff 1a490551e6 working on arg aliases and reorg 2015-09-18 01:48:00 -04:00
Thomas Breloff 4514802e35 replacing String with AbstractString 2015-09-17 21:32:27 -04:00
Thomas Breloff a9062b0611 examples 2015-09-17 17:11:25 -04:00
Thomas Breloff eb6b30aab1 markers, fixes, and rerun examples 2015-09-17 17:05:08 -04:00
Thomas Breloff 922abd7ad3 examples 2015-09-17 16:21:13 -04:00
Thomas Breloff c4596dda75 more shape fun... completed gadfly's set 2015-09-17 16:18:48 -04:00
Thomas Breloff 168b77326b fixing markers 2015-09-17 15:44:01 -04:00
Thomas Breloff f674bba861 added gadfly shapes utriangle, dtriangle, and xcross 2015-09-17 15:28:54 -04:00
Thomas Breloff 6b2e65e738 ohlc example 2015-09-17 14:49:37 -04:00
Thomas Breloff 51021c799d accept vectors of tuples; implement ohlc for gadfly with an example 2015-09-17 14:44:29 -04:00
Thomas Breloff 01cb036976 added fillto support for winston 2015-09-17 11:26:26 -04:00
112 changed files with 2214 additions and 1041 deletions
+146 -107
View File
@@ -4,7 +4,12 @@
#### Author: Thomas Breloff (@tbreloff)
Plotting interface and wrapper for several plotting packages.
Plots is a plotting interface and wrapper for several plotting packages. My goals with the package are:
- Simple. The interface should be intuitive enough that someone coming from Matlab, Python, etc can immediately start generating complex plots without reading volumes of documentation.
- Automatic (if you want). There should be smart defaults for the most common functionality, and simple, high-level ways to override complex functionality.
- Flexible. You should be able to produce your favorite plot in your favorite package, but quicker and simpler.
- Consistent. Don't commit to one graphics package. One command will switch your backend, and the exact same plotting commands will work with a very different underlying backend.
Please add wishlist items, bugs, or any other comments/questions to the issues list.
@@ -52,8 +57,8 @@ Do a plot in Gadfly, then save a png:
# switch to Gadfly as a backend
gadfly!()
# This will bring up a browser window with the plot. Add a semicolon to skip display.
plot(rand(10,2); marker = :rect, markersizes=[10,30])
# This will bring up a browser window with the plot. Add a semicolon at the end to skip display.
plot(rand(10,2); marker = :rect, markersize = [10,30], style = :auto)
# save it as a PNG
savepng(Plots.IMG_DIR * "gadfly1.png")
@@ -86,55 +91,41 @@ plot!(plotobj, args...; kw...) # adds to the plot `plotobj`
```
Now that you know which plot object you're updating (new, current, or other), I'll leave it off for simplicity.
Here are some various args to supply, and the implicit mapping (AVec == AbstractVector and AMat == AbstractMatrix):
There are many ways to pass in data to the plot functions... some examples:
- Vector-like (subtypes of AbstractArray{T,1})
- Matrix-like (subtypes of AbstractArray{T,2})
- Vectors of Vectors
- Functions
- Vectors of Functions
- DataFrames with column symbols (initialize with `dataframes!()`)
In general, you can pass in a `y` only, or an `x` and `y`, both of whatever type(s) you want, and Plots will slice up the data as needed.
For matrices, data is split by columns. For functions, data is mapped. For DataFrames, a Symbol/Symbols in place of x/y will map to
the relevant column(s).
Here are some example usages... remember you can always use `plot!` to update an existing plot, and that, unless specified, you will update the `currentPlot()`.
```julia
# one line... x = 1:length(y)
plot(y::AVec; kw...)
plot() # empty plot object
plot(4) # initialize with 4 empty series
plot(rand(10)) # plot 1 series... x = 1:10
plot(rand(10,5)) # plot 5 series... x = 1:10
plot(rand(10), rand(10)) # plot 1 series
plot(rand(10,5), rand(10)) # plot 5 series... y is the same for all
plot(sin, rand(10)) # y = sin(x)
plot(rand(10), sin) # same... y = sin(x)
plot([sin,cos], 0:0.1:π) # plot 2 series, sin(x) and cos(x)
plot([sin,cos], 0, π) # plot sin and cos on the range [0, π]
plot(1:10, Any[rand(10), sin]) # plot 2 series, y = rand(10) for the first, y = sin(x) for the second... x = 1:10 for both
plot(dataset("Ecdat", "Airline"), :Cost) # plot from a DataFrame (call `dataframes!()` first to import DataFrames and initialize)
```
# one line (will assert length(x) == length(y))
plot(x::AVec, y::AVec; kw...)
You can update certain plot settings after plot creation (not supported on all backends):
# multiple lines (one per column of x), all sharing x = 1:size(y,1)
plot(y::AMat; kw...)
# multiple lines (one per column of x), all sharing x (will assert length(x) == size(y,1))
plot(x::AVec, y::AMat; kw...)
# multiple lines (one per column of x/y... will assert size(x) == size(y))
plot(x::AMat, y::AMat; kw...)
# one line, map function for range [xmin,xmax]
plot(f::Function, xmin::Real, xmax::Real; kw...)
# multiple lines, map functions for range [xmin,xmax]
plot(f::AVec{Function}, xmin::Real, xmax::Real; kw...)
# parametric plot... x = fx(u), y = fy(u)
plot(fx::Function, fy::Function, umin::Real, umax::Real; kw...)
# one line, y = f(x)... can swap x and f
plot(x::AVec, f::Function; kw...)
# multiple lines, yᵢⱼ = f(xᵢⱼ)... can swap f and x
plot(x::AMat, f::Function; kw...)
# multiple lines, yᵢⱼ = fⱼ(xᵢ)
plot(x::AVec, fs::AVec{Function}; kw...)
# multiple lines, each with x = 1:length(y[i])
plot(y::AVec{AVec}; kw...)
# multiple lines, will assert length(x) == length(y[i])
plot(x::AVec, y::AVec{AVec}; kw...)
# multiple lines, will assert length(x[i]) == length(y[i])
plot(x::AVec{AVec}, y::AVec{AVec}; kw...)
# n lines, all empty (for updating plots)
plot(n::Integer; kw...)
# TODO: DataFrames, categorical values
```julia
plot!(title = "New Title", xlabel = "New xlabel", ylabel = "New ylabel")
plot!(xlims = (0, 5.5), ylims = (-2.2, 6), xticks = 0:0.5:10, yticks = [0,1,5,10])
```
With `subplot`, create multiple plots at once, with flexible layout options:
@@ -164,81 +155,129 @@ heatmap(args...; kw...) = plot(args...; kw..., linetype = :heatmap)
heatmap!(args...; kw...) = plot!(args...; kw..., linetype = :heatmap)
sticks(args...; kw...) = plot(args...; kw..., linetype = :sticks, marker = :ellipse)
sticks!(args...; kw...) = plot!(args...; kw..., linetype = :sticks, marker = :ellipse)
hline(args...; kw...) = plot(args...; kw..., linetype = :hline)
hline!(args...; kw...) = plot!(args...; kw..., linetype = :hline)
vline(args...; kw...) = plot(args...; kw..., linetype = :vline)
vline!(args...; kw...) = plot!(args...; kw..., linetype = :vline)
ohlc(args...; kw...) = plot(args...; kw..., linetype = :ohlc)
ohlc!(args...; kw...) = plot!(args...; kw..., linetype = :ohlc)
title!(s::AbstractString) = plot!(title = s)
xlabel!(s::AbstractString) = plot!(xlabel = s)
ylabel!(s::AbstractString) = plot!(ylabel = s)
xlims!{T<:Real,S<:Real}(lims::Tuple{T,S}) = plot!(xlims = lims)
ylims!{T<:Real,S<:Real}(lims::Tuple{T,S}) = plot!(ylims = lims)
xticks!{T<:Real}(v::AVec{T}) = plot!(xticks = v)
yticks!{T<:Real}(v::AVec{T}) = plot!(yticks = v)
```
Some keyword arguments you can set:
```
axis # :left or :right
color # can be a string ("red") or a symbol (:red) or a ColorsTypes.jl
# Colorant (RGB(1,0,0)) or :auto (which lets the package pick)
label # string or symbol, applies to that line, may go in a legend
width # width of a line
linetype # :line, :step, :stepinverted, :sticks, :scatter, :none, :heatmap, :hexbin, :hist, :bar
linestyle # :solid, :dash, :dot, :dashdot, :dashdotdot
marker # :none, :ellipse, :rect, :diamond, :utriangle, :dtriangle,
# :cross, :xcross, :star1, :star2, :hexagon
markercolor # same choices as `color`, or :match will set the color to be the same as `color`
markersize # size of the marker
nbins # number of bins for heatmap/hexbin and histograms
heatmap_c # color cutoffs for Qwt heatmaps
fillto # fillto value for area plots
title # string or symbol, title of the plot
xlabel # string or symbol, label on the bottom (x) axis
ylabel # string or symbol, label on the left (y) axis
yrightlabel # string or symbol, label on the right (y) axis
reg # true or false, add a regression line for each line
size # (Int,Int), resize the enclosing window
pos # (Int,Int), move the enclosing window to this position
windowtitle # string or symbol, set the title of the enclosing windowtitle
screen # Integer, move enclosing window to this screen number (for multiscreen desktops)
```
Keyword | Default | Type | Aliases
---- | ---- | ---- | ----
`:args` | `Any[]` | Series | `:argss`
`:axis` | `left` | Series | `:axiss`
`:color` | `auto` | Series | `:c`, `:colors`
`:fillto` | `nothing` | Series | `:area`, `:fill`, `:filltos`
`:group` | `nothing` | Series | `:g`, `:groups`
`:heatmap_c` | `(0.15,0.5)` | Series | `:heatmap_cs`
`:kwargs` | `Any[]` | Series | `:kwargss`
`:label` | `AUTO` | Series | `:lab`, `:labels`
`:linestyle` | `solid` | Series | `:linestyles`, `:ls`, `:s`, `:style`
`:linetype` | `path` | Series | `:linetypes`, `:lt`, `:t`, `:type`
`:marker` | `none` | Series | `:m`, `:markers`
`:markercolor` | `match` | Series | `:markercolors`, `:mc`, `:mcolor`
`:markersize` | `6` | Series | `:markersizes`, `:ms`, `:msize`
`:nbins` | `100` | Series | `:nb`, `:nbin`, `:nbinss`
`:reg` | `false` | Series | `:regs`
`:ribbon` | `nothing` | Series | `:r`, `:ribbons`
`:width` | `1` | Series | `:linewidth`, `:w`, `:widths`
`:background_color` | `RGB{U8}(1.0,1.0,1.0)` | Plot | `:background`, `:bg`, `:bg_color`, `:bgcolor`
`:foreground_color` | `auto` | Plot | `:fg`, `:fg_color`, `:fgcolor`, `:foreground`
`:legend` | `true` | Plot | `:leg`
`:show` | `false` | Plot | `:display`
`:size` | `(800,600)` | Plot | `:windowsize`, `:wsize`
`:title` | `` | Plot |
`:windowtitle` | `Plots.jl` | Plot | `:wtitle`
`:xlabel` | `` | Plot | `:xlab`
`:xlims` | `auto` | Plot | `:xlim`, `:xlimit`, `:xlimits`
`:xticks` | `auto` | Plot | `:xtick`
`:ylabel` | `` | Plot | `:ylab`
`:ylims` | `auto` | Plot | `:ylim`, `:ylimit`, `:ylimits`
`:yrightlabel` | `` | Plot | `:y2lab`, `:y2label`, `:ylab2`, `:ylabel2`, `:ylabelright`, `:ylabr`, `:yrlab`
`:yticks` | `auto` | Plot | `:ytick`
Plot types:
Type | Desc | Aliases
---- | ---- | ----
`:none` | No line | `:n`, `:no`
`:line` | Lines with sorted x-axis | `:l`
`:path` | Lines | `:p`
`:steppre` | Step plot (vertical then horizontal) | `:stepinv`, `:stepinverted`, `:stepsinv`, `:stepsinverted`
`:steppost` | Step plot (horizontal then vertical) | `:stair`, `:stairs`, `:step`, `:steps`
`:sticks` | Vertical lines | `:stem`, `:stems`
`:scatter` | Points, no lines | `:dots`
`:heatmap` | Colored regions by density |
`:hexbin` | Similar to heatmap |
`:hist` | Histogram (doesn't use x) | `:histogram`
`: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}) |
Line styles:
Type | Aliases
---- | ----
`:auto` | `:a`
`:solid` | `:s`
`:dash` | `:d`
`:dot` |
`:dashdot` | `:dd`
`:dashdotdot` | `:ddd`
Markers:
Type | Aliases
---- | ----
`:none` | `:n`, `:no`
`:auto` | `:a`
`:ellipse` | `:c`, `:circle`
`:rect` | `:r`, `:sq`, `:square`
`:diamond` | `:d`
`:utriangle` | `:^`, `:uptri`, `:uptriangle`, `:ut`, `:utri`
`:dtriangle` | `:V`, `:downtri`, `:downtriangle`, `:dt`, `:dtri`, `:v`
`:cross` | `:+`, `:plus`
`:xcross` | `:X`, `:x`
`:star1` | `:s`, `:star`
`:star2` | `:s2`
`:hexagon` | `:h`, `:hex`
`:octagon` | `:o`, `:oct`
Note that not every backend supports all options.
If you don't include a keyword argument, these are the defaults:
```
axis = :left
color = :auto
label = automatically generated (y1, y2, ...., or y1 (R), y2 (R) for the right axis)
width = 1
linetype = :line
linestype = :solid
marker = :none
markercolor = :match
markersize = 3
nbins = 100
heatmap_c = (0.15, 0.5)
fillto = nothing
title = ""
xlabel = ""
ylabel = ""
yrightlabel = ""
reg = false
size = (600,400)
pos = (0,0)
windowtitle = "Plots.jl"
screen = 1
```
__Tip__: You can see the default value for a given argument with `plotDefault(arg::Symbol)`, and set the default value with `plotDefault!(arg::Symbol, value)`
__Tip__: When plotting multiple lines, you can give every line the same trait by using the singular, or add an "s" to pluralize.
(yes I know it's not gramatically correct, but it's easy to use and implement)
__Tip__: When plotting multiple lines, you can set all series to use the same value, or pass in an array to cycle through values. Example:
```julia
# Note: The same width is applied to both lines, whereas
# each line gets different color and axis.
plot(rand(100,2); colors = [:red, RGB(.5,.5,0)],
axiss = [:left, :right],
width = 5)
plot(rand(100,4); color = [:red, RGB(0,0,1)], # lines 1 and 3 are red, lines 2 and 4 are blue
axis = :auto, # lines 1 and 3 are on the left axis, lines 2 and 4 are on the right
width = 5) # all lines have a width of 5
```
__Tip__: Not all features are supported for each backend, but you can see what's supported by calling the functions: `supportedArgs()`, `supportedAxes()`, `supportedTypes()`, `supportedStyles()`, `supportedMarkers()`, `subplotSupported()`
__Tip__: Call `gui()` to display the plot in a window. Interactivity depends on backend. Plotting at the REPL (without semicolon) implicitly calls `gui()`.
## TODO features:
- [x] Plot vectors/matrices/functions
- [ ] Plot DataFrames
- [x] Plot DataFrames
- [ ] Scales
- [ ] Categorical Inputs (strings, etc... for hist, bar? or can split one series into multiple?)
- [ ] Custom markers
+1
View File
@@ -1,3 +1,4 @@
julia 0.4-
Colors
Reexport
+113 -21
View File
@@ -11,8 +11,8 @@ doc"""
Holds all data needed for a documentation example... header, description, and plotting expression (Expr)
"""
type PlotExample
header::String
desc::String
header::AbstractString
desc::AbstractString
exprs::Vector{Expr}
end
@@ -21,7 +21,7 @@ end
const examples = PlotExample[
PlotExample("Lines",
"A simple line plot of the 3 columns.",
[:(plot(rand(100,3)))]),
[:(plot(rand(50,5), w=3))]),
PlotExample("Functions",
"Plot multiple functions. You can also put the function first.",
[:(plot(0:0.01:4π, [sin,cos]))]),
@@ -30,13 +30,13 @@ const examples = PlotExample[
[:(plot([sin,cos], 0, 4π))]),
PlotExample("",
"Or make a parametric plot (i.e. plot: (fx(u), fy(u))) with plot(fx, fy, umin, umax).",
[:(plot(sin, x->sin(2x), 0, 2π))]),
[:(plot(sin, x->sin(2x), 0, 2π, legend=false, fillto=0))]),
PlotExample("Global",
"Change the guides/background without a separate call.",
[:(plot(rand(10); title="TITLE", xlabel="XLABEL", ylabel="YLABEL", background_color = RGB(0.5,0.5,0.5)))]),
[:(plot(rand(10); title="TITLE", xlabel="XLABEL", ylabel="YLABEL", background_color = RGB(0.2,0.2,0.2)))]),
PlotExample("Two-axis",
"Use the `axis` or `axiss` arguments.\n\nNote: Currently only supported with Qwt and PyPlot",
[:(plot(Vector[randn(100), randn(100)*100]; axiss = [:left,:right], ylabel="LEFT", yrightlabel="RIGHT"))]),
[:(plot(Vector[randn(100), randn(100)*100]; axis = [:l,:r], ylabel="LEFT", yrightlabel="RIGHT"))]),
PlotExample("Vectors w/ pluralized args",
"Plot multiple series with different numbers of points. Mix arguments that apply to all series (singular... see `marker`) with arguments unique to each series (pluralized... see `colors`).",
[:(plot(Vector[rand(10), rand(20)]; marker=:ellipse, markersize=8, colors=[:red,:blue]))]),
@@ -45,29 +45,29 @@ const examples = PlotExample[
[:(plot(rand(100)/3; reg=true, fillto=0))]),
PlotExample("",
"and add to it later.",
[:(scatter!(rand(100); markersize=6, color=:blue))]),
[:(scatter!(rand(100); markersize=6, c=:blue))]),
PlotExample("Heatmaps",
"",
[:(heatmap(randn(10000),randn(10000); nbins=100))]),
PlotExample("Suported line types",
"All options: (:line, :orderedline, :step, :stepinverted, :sticks, :scatter, :none, :heatmap, :hexbin, :hist, :bar)",
[:(types = intersect(supportedTypes(), [:line, :step, :stepinverted, :sticks, :scatter])),
PlotExample("Line types",
"",
[:(types = intersect(supportedTypes(), [:line, :path, :steppre, :steppost, :sticks, :scatter])),
:(n = length(types)),
:(x = Vector[sort(rand(20)) for i in 1:n]),
:(y = rand(20,n)),
:(plot(x, y; linetypes=types, labels=map(string,types)))]),
PlotExample("Supported line styles",
"All options: (:solid, :dash, :dot, :dashdot, :dashdotdot)",
[:(styles = setdiff(supportedStyles(), [:auto])), :(plot(rand(20,length(styles)); linestyle=:auto, labels=map(string,styles)))]),
PlotExample("Supported marker types",
"All options: (:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon)",
[:(markers = setdiff(supportedMarkers(), [:none,:auto])), :(plot([fill(i,10) for i=1:length(markers)]; marker=:auto, labels=map(string,markers), markersize=10))]),
:(plot(x, y; t=types, lab=map(string,types)))]),
PlotExample("Line styles",
"",
[:(styles = setdiff(supportedStyles(), [:auto])), :(plot(cumsum(randn(20,length(styles)),1); style=:auto, label=map(string,styles), w=5))]),
PlotExample("Marker types",
"",
[:(markers = setdiff(supportedMarkers(), [:none,:auto])), :(scatter(0.5:9.5, [fill(i-0.5,10) for i=length(markers):-1:1]; marker=:auto, label=map(string,markers), markersize=10))]),
PlotExample("Bar",
"x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)",
[:(bar(randn(1000)))]),
PlotExample("Histogram",
"note: fillto isn't supported on all backends",
[:(histogram(randn(1000); nbins=50, fillto=20))]),
"",
[:(histogram(randn(1000); nbins=50))]),
PlotExample("Subplots",
"""
subplot and subplot! are distinct commands which create many plots and add series to them in a circular fashion.
@@ -83,6 +83,9 @@ const examples = PlotExample[
PlotExample("",
"",
[:(subplot!(randn(100,3)))]),
PlotExample("Open/High/Low/Close",
"Create an OHLC chart. Pass in a vector of 4-tuples as your `y` argument. Adjust the tick width with arg `markersize`.",
[:(n=20), :(hgt=rand(n)+1), :(bot=randn(n)), :(openpct=rand(n)), :(closepct=rand(n)), :(y = [OHLC(openpct[i]*hgt[i]+bot[i], bot[i]+hgt[i], bot[i], closepct[i]*hgt[i]+bot[i]) for i in 1:n]), :(ohlc(y; markersize=8))]),
]
@@ -91,7 +94,7 @@ const examples = PlotExample[
function createStringOfMarkDownCodeValues(arr, prefix = "")
string("`", prefix, join(arr, "`, `$prefix"), "`")
end
createStringOfMarkDownSymbols(arr) = createStringOfMarkDownCodeValues(arr, ":")
createStringOfMarkDownSymbols(arr) = isempty(arr) ? "" : createStringOfMarkDownCodeValues(arr, ":")
function generate_markdown(pkgname::Symbol)
@@ -123,6 +126,9 @@ function generate_markdown(pkgname::Symbol)
try
# we want to always produce consistent results
srand(1234)
# run the code
map(eval, example.exprs)
@@ -130,7 +136,7 @@ function generate_markdown(pkgname::Symbol)
imgname = "$(pkgname)_example_$i.png"
# NOTE: uncomment this to overwrite the images as well
# savepng("$IMGDIR/$pkgname/$imgname")
savepng("$IMGDIR/$pkgname/$imgname")
# write out the header, description, code block, and image link
write(md, "### $(example.header)\n\n")
@@ -181,6 +187,92 @@ function test_all_examples(pkgname::Symbol)
plts
end
# axis # :left or :right
# color # can be a string ("red") or a symbol (:red) or a ColorsTypes.jl
# # Colorant (RGB(1,0,0)) or :auto (which lets the package pick)
# label # string or symbol, applies to that line, may go in a legend
# width # width of a line
# linetype # :line, :step, :stepinverted, :sticks, :scatter, :none, :heatmap, :hexbin, :hist, :bar
# linestyle # :solid, :dash, :dot, :dashdot, :dashdotdot
# marker # :none, :ellipse, :rect, :diamond, :utriangle, :dtriangle,
# # :cross, :xcross, :star1, :star2, :hexagon
# markercolor # same choices as `color`, or :match will set the color to be the same as `color`
# markersize # size of the marker
# nbins # number of bins for heatmap/hexbin and histograms
# heatmap_c # color cutoffs for Qwt heatmaps
# fillto # fillto value for area plots
# title # string or symbol, title of the plot
# xlabel # string or symbol, label on the bottom (x) axis
# ylabel # string or symbol, label on the left (y) axis
# yrightlabel # string or symbol, label on the right (y) axis
# reg # true or false, add a regression line for each line
# size # (Int,Int), resize the enclosing window
# pos # (Int,Int), move the enclosing window to this position
# windowtitle # string or symbol, set the title of the enclosing windowtitle
# screen # Integer, move enclosing window to this screen number (for multiscreen desktops)
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})",
)
function buildReadme()
readme = readall("$DOCDIR/readme_template.md")
# build keyword arg table
table = "Keyword | Default | Type | Aliases \n---- | ---- | ---- | ----\n"
for d in (Plots._seriesDefaults, Plots._plotDefaults)
for k in Plots.sortedkeys(d)
aliasstr = createStringOfMarkDownSymbols(aliases(Plots._keyAliases, k))
table = string(table, "`:$k` | `$(d[k])` | $(d==Plots._seriesDefaults ? "Series" : "Plot") | $aliasstr \n")
end
end
readme = replace(readme, "[[KEYWORD_ARGS_TABLE]]", table)
# build linetypes table
table = "Type | Desc | Aliases\n---- | ---- | ----\n"
for lt in Plots._allTypes
aliasstr = createStringOfMarkDownSymbols(aliases(Plots._typeAliases, lt))
table = string(table, "`:$lt` | $(_ltdesc[lt]) | $aliasstr \n")
end
readme = replace(readme, "[[LINETYPES_TABLE]]", table)
# build linestyles table
table = "Type | Aliases\n---- | ----\n"
for s in Plots._allStyles
aliasstr = createStringOfMarkDownSymbols(aliases(Plots._styleAliases, s))
table = string(table, "`:$s` | $aliasstr \n")
end
readme = replace(readme, "[[LINESTYLES_TABLE]]", table)
# build markers table
table = "Type | Aliases\n---- | ----\n"
for s in Plots._allMarkers
aliasstr = createStringOfMarkDownSymbols(aliases(Plots._markerAliases, s))
table = string(table, "`:$s` | $aliasstr \n")
end
readme = replace(readme, "[[MARKERS_TABLE]]", table)
readme_fn = Pkg.dir("Plots") * "/README.md"
f = open(readme_fn, "w")
write(f, readme)
close(f)
end
# run it!
# note: generate separately so it's easy to comment out
# @osx_only generate_markdown(:unicodeplots)
+37 -21
View File
@@ -1,10 +1,10 @@
# Examples for backend: gadfly
- Supported arguments: `args`, `axis`, `color`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markercolor`, `markersize`, `nbins`, `reg`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `ylabel`, `yrightlabel`
- Supported arguments: `args`, `axis`, `background_color`, `color`, `fillto`, `foreground_color`, `group`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markercolor`, `markersize`, `nbins`, `reg`, `ribbon`, `show`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `xticks`, `ylabel`, `yrightlabel`, `yticks`
- Supported values for axis: `:auto`, `:left`
- Supported values for linetype: `:line`, `:step`, `:sticks`, `:scatter`, `:heatmap`, `:hexbin`, `:hist`, `:bar`
- Supported values for linestyle: `:auto`, `:solid`
- Supported values for marker: `:none`, `:auto`, `:rect`, `:ellipse`, `:diamond`, `:cross`
- Supported values for linetype: `:none`, `:line`, `:path`, `:steppost`, `:sticks`, `:scatter`, `:heatmap`, `:hexbin`, `:hist`, `:bar`, `:hline`, `:vline`, `:ohlc`
- Supported values for linestyle: `:auto`, `:solid`, `:dash`, `:dot`, `:dashdot`, `:dashdotdot`
- Supported values for marker: `:none`, `:auto`, `:rect`, `:ellipse`, `:diamond`, `:utriangle`, `:dtriangle`, `:cross`, `:xcross`, `:star1`, `:star2`, `:hexagon`, `:octagon`
- Is `subplot`/`subplot!` supported? Yes
### Initialize
@@ -19,7 +19,7 @@ gadfly!()
A simple line plot of the 3 columns.
```julia
plot(rand(100,3))
plot(rand(50,5),w=3)
```
![](../img/gadfly/gadfly_example_1.png)
@@ -51,7 +51,7 @@ Or make a parametric plot (i.e. plot: (fx(u), fy(u))) with plot(fx, fy, umin, um
```julia
plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, line 33:
sin(2x)
end),0,2π)
end),0,2π,legend=false,fillto=0)
```
![](../img/gadfly/gadfly_example_4.png)
@@ -61,7 +61,7 @@ plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, li
Change the guides/background without a separate call.
```julia
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.5,0.5,0.5))
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.2,0.2,0.2))
```
![](../img/gadfly/gadfly_example_5.png)
@@ -73,7 +73,7 @@ Use the `axis` or `axiss` arguments.
Note: Currently only supported with Qwt and PyPlot
```julia
plot(Vector[randn(100),randn(100) * 100]; axiss=[:left,:right],ylabel="LEFT",yrightlabel="RIGHT")
plot(Vector[randn(100),randn(100) * 100]; axis=[:l,:r],ylabel="LEFT",yrightlabel="RIGHT")
```
![](../img/gadfly/gadfly_example_6.png)
@@ -103,7 +103,7 @@ plot(rand(100) / 3; reg=true,fillto=0)
and add to it later.
```julia
scatter!(rand(100); markersize=6,color=:blue)
scatter!(rand(100); markersize=6,c=:blue)
```
![](../img/gadfly/gadfly_example_9.png)
@@ -118,38 +118,38 @@ heatmap(randn(10000),randn(10000); nbins=100)
![](../img/gadfly/gadfly_example_10.png)
### Suported line types
### Line types
All options: (:line, :orderedline, :step, :stepinverted, :sticks, :scatter, :none, :heatmap, :hexbin, :hist, :bar)
```julia
types = intersect(supportedTypes(),[:line,:step,:stepinverted,:sticks,:scatter])
types = intersect(supportedTypes(),[:line,:path,:steppre,:steppost,:sticks,:scatter])
n = length(types)
x = Vector[sort(rand(20)) for i = 1:n]
y = rand(20,n)
plot(x,y; linetypes=types,labels=map(string,types))
plot(x,y; t=types,lab=map(string,types))
```
![](../img/gadfly/gadfly_example_11.png)
### Supported line styles
### Line styles
All options: (:solid, :dash, :dot, :dashdot, :dashdotdot)
```julia
styles = setdiff(supportedStyles(),[:auto])
plot(rand(20,length(styles)); linestyle=:auto,labels=map(string,styles))
plot(cumsum(randn(20,length(styles)),1); style=:auto,label=map(string,styles),w=5)
```
![](../img/gadfly/gadfly_example_12.png)
### Supported marker types
### Marker types
All options: (:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon)
```julia
markers = setdiff(supportedMarkers(),[:none,:auto])
plot([fill(i,10) for i = 1:length(markers)]; marker=:auto,labels=map(string,markers),markersize=10)
scatter(0.5:9.5,[fill(i - 0.5,10) for i = length(markers):-1:1]; marker=:auto,label=map(string,markers),markersize=10)
```
![](../img/gadfly/gadfly_example_13.png)
@@ -166,10 +166,10 @@ bar(randn(1000))
### Histogram
note: fillto isn't supported on all backends
```julia
histogram(randn(1000); nbins=50,fillto=20)
histogram(randn(1000); nbins=50)
```
![](../img/gadfly/gadfly_example_15.png)
@@ -209,3 +209,19 @@ subplot!(randn(100,3))
![](../img/gadfly/gadfly_example_18.png)
### Open/High/Low/Close
Create an OHLC chart. Pass in a vector of 4-tuples as your `y` argument. Adjust the tick width with arg `markersize`.
```julia
n = 20
hgt = rand(n) + 1
bot = randn(n)
openpct = rand(n)
closepct = rand(n)
y = [OHLC(openpct[i] * hgt[i] + bot[i],bot[i] + hgt[i],bot[i],closepct[i] * hgt[i] + bot[i]) for i = 1:n]
ohlc(y; markersize=8)
```
![](../img/gadfly/gadfly_example_19.png)
+37 -21
View File
@@ -1,10 +1,10 @@
# Examples for backend: immerse
- Supported arguments: `args`, `axis`, `color`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markercolor`, `markersize`, `nbins`, `reg`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `ylabel`, `yrightlabel`
- Supported arguments: `args`, `axis`, `background_color`, `color`, `fillto`, `foreground_color`, `group`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markercolor`, `markersize`, `nbins`, `reg`, `ribbon`, `show`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `xticks`, `ylabel`, `yrightlabel`, `yticks`
- Supported values for axis: `:auto`, `:left`
- Supported values for linetype: `:line`, `:step`, `:sticks`, `:scatter`, `:heatmap`, `:hexbin`, `:hist`, `:bar`
- Supported values for linestyle: `:auto`, `:solid`
- Supported values for marker: `:none`, `:auto`, `:rect`, `:ellipse`, `:diamond`, `:cross`
- Supported values for linetype: `:none`, `:line`, `:path`, `:steppost`, `:sticks`, `:scatter`, `:heatmap`, `:hexbin`, `:hist`, `:bar`, `:hline`, `:vline`, `:ohlc`
- Supported values for linestyle: `:auto`, `:solid`, `:dash`, `:dot`, `:dashdot`, `:dashdotdot`
- Supported values for marker: `:none`, `:auto`, `:rect`, `:ellipse`, `:diamond`, `:utriangle`, `:dtriangle`, `:cross`, `:xcross`, `:star1`, `:star2`, `:hexagon`, `:octagon`
- Is `subplot`/`subplot!` supported? Yes
### Initialize
@@ -19,7 +19,7 @@ immerse!()
A simple line plot of the 3 columns.
```julia
plot(rand(100,3))
plot(rand(50,5),w=3)
```
![](../img/immerse/immerse_example_1.png)
@@ -51,7 +51,7 @@ Or make a parametric plot (i.e. plot: (fx(u), fy(u))) with plot(fx, fy, umin, um
```julia
plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, line 33:
sin(2x)
end),0,2π)
end),0,2π,legend=false,fillto=0)
```
![](../img/immerse/immerse_example_4.png)
@@ -61,7 +61,7 @@ plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, li
Change the guides/background without a separate call.
```julia
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.5,0.5,0.5))
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.2,0.2,0.2))
```
![](../img/immerse/immerse_example_5.png)
@@ -73,7 +73,7 @@ Use the `axis` or `axiss` arguments.
Note: Currently only supported with Qwt and PyPlot
```julia
plot(Vector[randn(100),randn(100) * 100]; axiss=[:left,:right],ylabel="LEFT",yrightlabel="RIGHT")
plot(Vector[randn(100),randn(100) * 100]; axis=[:l,:r],ylabel="LEFT",yrightlabel="RIGHT")
```
![](../img/immerse/immerse_example_6.png)
@@ -103,7 +103,7 @@ plot(rand(100) / 3; reg=true,fillto=0)
and add to it later.
```julia
scatter!(rand(100); markersize=6,color=:blue)
scatter!(rand(100); markersize=6,c=:blue)
```
![](../img/immerse/immerse_example_9.png)
@@ -118,38 +118,38 @@ heatmap(randn(10000),randn(10000); nbins=100)
![](../img/immerse/immerse_example_10.png)
### Suported line types
### Line types
All options: (:line, :orderedline, :step, :stepinverted, :sticks, :scatter, :none, :heatmap, :hexbin, :hist, :bar)
```julia
types = intersect(supportedTypes(),[:line,:step,:stepinverted,:sticks,:scatter])
types = intersect(supportedTypes(),[:line,:path,:steppre,:steppost,:sticks,:scatter])
n = length(types)
x = Vector[sort(rand(20)) for i = 1:n]
y = rand(20,n)
plot(x,y; linetypes=types,labels=map(string,types))
plot(x,y; t=types,lab=map(string,types))
```
![](../img/immerse/immerse_example_11.png)
### Supported line styles
### Line styles
All options: (:solid, :dash, :dot, :dashdot, :dashdotdot)
```julia
styles = setdiff(supportedStyles(),[:auto])
plot(rand(20,length(styles)); linestyle=:auto,labels=map(string,styles))
plot(cumsum(randn(20,length(styles)),1); style=:auto,label=map(string,styles),w=5)
```
![](../img/immerse/immerse_example_12.png)
### Supported marker types
### Marker types
All options: (:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon)
```julia
markers = setdiff(supportedMarkers(),[:none,:auto])
plot([fill(i,10) for i = 1:length(markers)]; marker=:auto,labels=map(string,markers),markersize=10)
scatter(0.5:9.5,[fill(i - 0.5,10) for i = length(markers):-1:1]; marker=:auto,label=map(string,markers),markersize=10)
```
![](../img/immerse/immerse_example_13.png)
@@ -166,10 +166,10 @@ bar(randn(1000))
### Histogram
note: fillto isn't supported on all backends
```julia
histogram(randn(1000); nbins=50,fillto=20)
histogram(randn(1000); nbins=50)
```
![](../img/immerse/immerse_example_15.png)
@@ -209,3 +209,19 @@ subplot!(randn(100,3))
![](../img/immerse/immerse_example_18.png)
### Open/High/Low/Close
Create an OHLC chart. Pass in a vector of 4-tuples as your `y` argument. Adjust the tick width with arg `markersize`.
```julia
n = 20
hgt = rand(n) + 1
bot = randn(n)
openpct = rand(n)
closepct = rand(n)
y = [OHLC(openpct[i] * hgt[i] + bot[i],bot[i] + hgt[i],bot[i],closepct[i] * hgt[i] + bot[i]) for i = 1:n]
ohlc(y; markersize=8)
```
![](../img/immerse/immerse_example_19.png)
+20 -20
View File
@@ -1,10 +1,10 @@
# Examples for backend: pyplot
- Supported arguments: `args`, `axis`, `color`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markercolor`, `markersize`, `nbins`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `ylabel`, `yrightlabel`
- Supported arguments: `args`, `axis`, `background_color`, `color`, `foreground_color`, `group`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markercolor`, `markersize`, `nbins`, `ribbon`, `show`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `xticks`, `ylabel`, `yrightlabel`, `yticks`
- Supported values for axis: `:auto`, `:left`, `:right`
- Supported values for linetype: `:none`, `:line`, `:step`, `:stepinverted`, `:sticks`, `:scatter`, `:heatmap`, `:hexbin`, `:hist`, `:bar`
- Supported values for linetype: `:none`, `:line`, `:path`, `:step`, `:stepinverted`, `:sticks`, `:scatter`, `:heatmap`, `:hexbin`, `:hist`, `:bar`
- Supported values for linestyle: `:auto`, `:solid`, `:dash`, `:dot`, `:dashdot`
- Supported values for marker: `:none`, `:auto`, `:ellipse`, `:rect`, `:diamond`, `:utriangle`, `:dtriangle`, `:cross`, `:xcross`, `:star1`, `:hexagon`
- Supported values for marker: `:none`, `:auto`, `:rect`, `:ellipse`, `:diamond`, `:utriangle`, `:dtriangle`, `:cross`, `:xcross`, `:star1`, `:hexagon`
- Is `subplot`/`subplot!` supported? No
### Initialize
@@ -19,7 +19,7 @@ pyplot!()
A simple line plot of the 3 columns.
```julia
plot(rand(100,3))
plot(rand(50,5),w=3)
```
![](../img/pyplot/pyplot_example_1.png)
@@ -51,7 +51,7 @@ Or make a parametric plot (i.e. plot: (fx(u), fy(u))) with plot(fx, fy, umin, um
```julia
plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, line 33:
sin(2x)
end),0,2π)
end),0,2π,legend=false,fillto=0)
```
![](../img/pyplot/pyplot_example_4.png)
@@ -61,7 +61,7 @@ plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, li
Change the guides/background without a separate call.
```julia
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.5,0.5,0.5))
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.2,0.2,0.2))
```
![](../img/pyplot/pyplot_example_5.png)
@@ -73,7 +73,7 @@ Use the `axis` or `axiss` arguments.
Note: Currently only supported with Qwt and PyPlot
```julia
plot(Vector[randn(100),randn(100) * 100]; axiss=[:left,:right],ylabel="LEFT",yrightlabel="RIGHT")
plot(Vector[randn(100),randn(100) * 100]; axis=[:l,:r],ylabel="LEFT",yrightlabel="RIGHT")
```
![](../img/pyplot/pyplot_example_6.png)
@@ -103,7 +103,7 @@ plot(rand(100) / 3; reg=true,fillto=0)
and add to it later.
```julia
scatter!(rand(100); markersize=6,color=:blue)
scatter!(rand(100); markersize=6,c=:blue)
```
![](../img/pyplot/pyplot_example_9.png)
@@ -118,38 +118,38 @@ heatmap(randn(10000),randn(10000); nbins=100)
![](../img/pyplot/pyplot_example_10.png)
### Suported line types
### Line types
All options: (:line, :orderedline, :step, :stepinverted, :sticks, :scatter, :none, :heatmap, :hexbin, :hist, :bar)
```julia
types = intersect(supportedTypes(),[:line,:step,:stepinverted,:sticks,:scatter])
types = intersect(supportedTypes(),[:line,:path,:steppre,:steppost,:sticks,:scatter])
n = length(types)
x = Vector[sort(rand(20)) for i = 1:n]
y = rand(20,n)
plot(x,y; linetypes=types,labels=map(string,types))
plot(x,y; t=types,lab=map(string,types))
```
![](../img/pyplot/pyplot_example_11.png)
### Supported line styles
### Line styles
All options: (:solid, :dash, :dot, :dashdot, :dashdotdot)
```julia
styles = setdiff(supportedStyles(),[:auto])
plot(rand(20,length(styles)); linestyle=:auto,labels=map(string,styles))
plot(cumsum(randn(20,length(styles)),1); style=:auto,label=map(string,styles),w=5)
```
![](../img/pyplot/pyplot_example_12.png)
### Supported marker types
### Marker types
All options: (:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon)
```julia
markers = setdiff(supportedMarkers(),[:none,:auto])
plot([fill(i,10) for i = 1:length(markers)]; marker=:auto,labels=map(string,markers),markersize=10)
scatter(0.5:9.5,[fill(i - 0.5,10) for i = length(markers):-1:1]; marker=:auto,label=map(string,markers),markersize=10)
```
![](../img/pyplot/pyplot_example_13.png)
@@ -166,10 +166,10 @@ bar(randn(1000))
### Histogram
note: fillto isn't supported on all backends
```julia
histogram(randn(1000); nbins=50,fillto=20)
histogram(randn(1000); nbins=50)
```
![](../img/pyplot/pyplot_example_15.png)
+20 -20
View File
@@ -1,10 +1,10 @@
# Examples for backend: qwt
- Supported arguments: `args`, `axis`, `color`, `fillto`, `heatmap_c`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markercolor`, `markersize`, `nbins`, `reg`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `ylabel`, `yrightlabel`
- Supported arguments: `args`, `axis`, `background_color`, `color`, `fillto`, `foreground_color`, `group`, `heatmap_c`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markercolor`, `markersize`, `nbins`, `reg`, `ribbon`, `show`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `xticks`, `ylabel`, `yrightlabel`, `yticks`
- Supported values for axis: `:auto`, `:left`, `:right`
- Supported values for linetype: `:none`, `:line`, `:step`, `:stepinverted`, `:sticks`, `:scatter`, `:heatmap`, `:hexbin`, `:hist`, `:bar`
- Supported values for linetype: `:none`, `:line`, `:path`, `:steppre`, `:steppost`, `:sticks`, `:scatter`, `:heatmap`, `:hexbin`, `:hist`, `:bar`
- Supported values for linestyle: `:auto`, `:solid`, `:dash`, `:dot`, `:dashdot`, `:dashdotdot`
- Supported values for marker: `:none`, `:auto`, `:ellipse`, `:rect`, `:diamond`, `:utriangle`, `:dtriangle`, `:cross`, `:xcross`, `:star1`, `:star2`, `:hexagon`
- Supported values for marker: `:none`, `:auto`, `:rect`, `:ellipse`, `:diamond`, `:utriangle`, `:dtriangle`, `:cross`, `:xcross`, `:star1`, `:star2`, `:hexagon`
- Is `subplot`/`subplot!` supported? Yes
### Initialize
@@ -19,7 +19,7 @@ qwt!()
A simple line plot of the 3 columns.
```julia
plot(rand(100,3))
plot(rand(50,5),w=3)
```
![](../img/qwt/qwt_example_1.png)
@@ -51,7 +51,7 @@ Or make a parametric plot (i.e. plot: (fx(u), fy(u))) with plot(fx, fy, umin, um
```julia
plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, line 33:
sin(2x)
end),0,2π)
end),0,2π,legend=false,fillto=0)
```
![](../img/qwt/qwt_example_4.png)
@@ -61,7 +61,7 @@ plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, li
Change the guides/background without a separate call.
```julia
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.5,0.5,0.5))
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.2,0.2,0.2))
```
![](../img/qwt/qwt_example_5.png)
@@ -73,7 +73,7 @@ Use the `axis` or `axiss` arguments.
Note: Currently only supported with Qwt and PyPlot
```julia
plot(Vector[randn(100),randn(100) * 100]; axiss=[:left,:right],ylabel="LEFT",yrightlabel="RIGHT")
plot(Vector[randn(100),randn(100) * 100]; axis=[:l,:r],ylabel="LEFT",yrightlabel="RIGHT")
```
![](../img/qwt/qwt_example_6.png)
@@ -103,7 +103,7 @@ plot(rand(100) / 3; reg=true,fillto=0)
and add to it later.
```julia
scatter!(rand(100); markersize=6,color=:blue)
scatter!(rand(100); markersize=6,c=:blue)
```
![](../img/qwt/qwt_example_9.png)
@@ -118,38 +118,38 @@ heatmap(randn(10000),randn(10000); nbins=100)
![](../img/qwt/qwt_example_10.png)
### Suported line types
### Line types
All options: (:line, :orderedline, :step, :stepinverted, :sticks, :scatter, :none, :heatmap, :hexbin, :hist, :bar)
```julia
types = intersect(supportedTypes(),[:line,:step,:stepinverted,:sticks,:scatter])
types = intersect(supportedTypes(),[:line,:path,:steppre,:steppost,:sticks,:scatter])
n = length(types)
x = Vector[sort(rand(20)) for i = 1:n]
y = rand(20,n)
plot(x,y; linetypes=types,labels=map(string,types))
plot(x,y; t=types,lab=map(string,types))
```
![](../img/qwt/qwt_example_11.png)
### Supported line styles
### Line styles
All options: (:solid, :dash, :dot, :dashdot, :dashdotdot)
```julia
styles = setdiff(supportedStyles(),[:auto])
plot(rand(20,length(styles)); linestyle=:auto,labels=map(string,styles))
plot(cumsum(randn(20,length(styles)),1); style=:auto,label=map(string,styles),w=5)
```
![](../img/qwt/qwt_example_12.png)
### Supported marker types
### Marker types
All options: (:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon)
```julia
markers = setdiff(supportedMarkers(),[:none,:auto])
plot([fill(i,10) for i = 1:length(markers)]; marker=:auto,labels=map(string,markers),markersize=10)
scatter(0.5:9.5,[fill(i - 0.5,10) for i = length(markers):-1:1]; marker=:auto,label=map(string,markers),markersize=10)
```
![](../img/qwt/qwt_example_13.png)
@@ -166,10 +166,10 @@ bar(randn(1000))
### Histogram
note: fillto isn't supported on all backends
```julia
histogram(randn(1000); nbins=50,fillto=20)
histogram(randn(1000); nbins=50)
```
![](../img/qwt/qwt_example_15.png)
+248
View File
@@ -0,0 +1,248 @@
# Plots
[![Build Status](https://travis-ci.org/tbreloff/Plots.jl.svg?branch=master)](https://travis-ci.org/tbreloff/Plots.jl)
#### Author: Thomas Breloff (@tbreloff)
Plots is a plotting interface and wrapper for several plotting packages. My goals with the package are:
- Simple. The interface should be intuitive enough that someone coming from Matlab, Python, etc can immediately start generating complex plots without reading volumes of documentation.
- Automatic (if you want). There should be smart defaults for the most common functionality, and simple, high-level ways to override complex functionality.
- Flexible. You should be able to produce your favorite plot in your favorite package, but quicker and simpler.
- Consistent. Don't commit to one graphics package. One command will switch your backend, and the exact same plotting commands will work with a very different underlying backend.
Please add wishlist items, bugs, or any other comments/questions to the issues list.
## Examples for each implemented backend:
- [Qwt.jl](docs/qwt_examples.md)
- [Gadfly.jl](docs/gadfly_examples.md)
- [UnicodePlots.jl](docs/unicodeplots_examples.md)
- [PyPlot.jl](docs/pyplot_examples.md)
- [Immerse.jl](docs/immerse_examples.md)
- [Winston.jl](docs/winston_examples.md)
## Installation
First, add the package
```julia
Pkg.add("Plots")
```
then get any plotting packages you need (obviously, you should get at least one backend):
```julia
Pkg.add("Gadfly")
Pkg.add("Immerse")
Pkg.add("UnicodePlots")
Pkg.add("PyPlot") # requires python and matplotlib
Pkg.clone("https://github.com/tbreloff/Qwt.jl.git") # requires pyqt and pyqwt
Pkg.add("Winston")
```
## Use
Load it in. The underlying plotting backends are not imported until `plotter()` is called (which happens
on your first call to `plot` or `subplot`). This means that you don't need any backends to be installed when you call `using Plots`.
Plots will try to figure out a good default backend for you automatically based on what backends are installed.
```julia
using Plots
```
Do a plot in Gadfly, then save a png:
```julia
# switch to Gadfly as a backend
gadfly!()
# This will bring up a browser window with the plot. Add a semicolon at the end to skip display.
plot(rand(10,2); marker = :rect, markersize = [10,30], style = :auto)
# save it as a PNG
savepng(Plots.IMG_DIR * "gadfly1.png")
```
which saves:
![gadfly_plt](img/gadfly1.png)
See the examples pages for lots of examples of plots, and what those commands produce for each supported backend.
## API
Call `plotter!(backend::Symbol)` or the shorthands (`gadfly!()`, `qwt!()`, `unicodeplots!()`, etc) to set the current plotting backend.
Subsequent commands are converted into the relevant plotting commands for that package:
```julia
gadfly!()
plot(1:10) # this effectively calls `y = 1:10; Gadfly.plot(x=1:length(y), y=y)`
qwt!()
plot(1:10) # this effectively calls `Qwt.plot(1:10)`
```
Use `plot` to create a new plot object, and `plot!` to add to an existing one:
```julia
plot(args...; kw...) # creates a new plot window, and sets it to be the `currentPlot`
plot!(args...; kw...) # adds to the `currentPlot`
plot!(plotobj, args...; kw...) # adds to the plot `plotobj`
```
Now that you know which plot object you're updating (new, current, or other), I'll leave it off for simplicity.
There are many ways to pass in data to the plot functions... some examples:
- Vector-like (subtypes of AbstractArray{T,1})
- Matrix-like (subtypes of AbstractArray{T,2})
- Vectors of Vectors
- Functions
- Vectors of Functions
- DataFrames with column symbols (initialize with `dataframes!()`)
In general, you can pass in a `y` only, or an `x` and `y`, both of whatever type(s) you want, and Plots will slice up the data as needed.
For matrices, data is split by columns. For functions, data is mapped. For DataFrames, a Symbol/Symbols in place of x/y will map to
the relevant column(s).
Here are some example usages... remember you can always use `plot!` to update an existing plot, and that, unless specified, you will update the `currentPlot()`.
```julia
plot() # empty plot object
plot(4) # initialize with 4 empty series
plot(rand(10)) # plot 1 series... x = 1:10
plot(rand(10,5)) # plot 5 series... x = 1:10
plot(rand(10), rand(10)) # plot 1 series
plot(rand(10,5), rand(10)) # plot 5 series... y is the same for all
plot(sin, rand(10)) # y = sin(x)
plot(rand(10), sin) # same... y = sin(x)
plot([sin,cos], 0:0.1:π) # plot 2 series, sin(x) and cos(x)
plot([sin,cos], 0, π) # plot sin and cos on the range [0, π]
plot(1:10, Any[rand(10), sin]) # plot 2 series, y = rand(10) for the first, y = sin(x) for the second... x = 1:10 for both
plot(dataset("Ecdat", "Airline"), :Cost) # plot from a DataFrame (call `dataframes!()` first to import DataFrames and initialize)
```
You can update certain plot settings after plot creation (not supported on all backends):
```julia
plot!(title = "New Title", xlabel = "New xlabel", ylabel = "New ylabel")
plot!(xlims = (0, 5.5), ylims = (-2.2, 6), xticks = 0:0.5:10, yticks = [0,1,5,10])
```
With `subplot`, create multiple plots at once, with flexible layout options:
```julia
y = rand(100,3)
subplot(y; n = 3) # create an automatic grid, and let it figure out the shape
subplot(y; n = 3, nr = 1) # create an automatic grid, but fix the number of rows
subplot(y; n = 3, nc = 1) # create an automatic grid, but fix the number of columns
subplot(y; layout = [1, 2]) # explicit layout. Lists the number of plots in each row
```
__Tip__: You can call `subplot!(args...; kw...)` to add to an existing subplot.
__Tip__: Calling `subplot!` on a `Plot` object, or `plot!` on a `Subplot` object will throw an error.
Shorthands:
```julia
scatter(args...; kw...) = plot(args...; kw..., linetype = :scatter)
scatter!(args...; kw...) = plot!(args...; kw..., linetype = :scatter)
bar(args...; kw...) = plot(args...; kw..., linetype = :bar)
bar!(args...; kw...) = plot!(args...; kw..., linetype = :bar)
histogram(args...; kw...) = plot(args...; kw..., linetype = :hist)
histogram!(args...; kw...) = plot!(args...; kw..., linetype = :hist)
heatmap(args...; kw...) = plot(args...; kw..., linetype = :heatmap)
heatmap!(args...; kw...) = plot!(args...; kw..., linetype = :heatmap)
sticks(args...; kw...) = plot(args...; kw..., linetype = :sticks, marker = :ellipse)
sticks!(args...; kw...) = plot!(args...; kw..., linetype = :sticks, marker = :ellipse)
hline(args...; kw...) = plot(args...; kw..., linetype = :hline)
hline!(args...; kw...) = plot!(args...; kw..., linetype = :hline)
vline(args...; kw...) = plot(args...; kw..., linetype = :vline)
vline!(args...; kw...) = plot!(args...; kw..., linetype = :vline)
ohlc(args...; kw...) = plot(args...; kw..., linetype = :ohlc)
ohlc!(args...; kw...) = plot!(args...; kw..., linetype = :ohlc)
title!(s::AbstractString) = plot!(title = s)
xlabel!(s::AbstractString) = plot!(xlabel = s)
ylabel!(s::AbstractString) = plot!(ylabel = s)
xlims!{T<:Real,S<:Real}(lims::Tuple{T,S}) = plot!(xlims = lims)
ylims!{T<:Real,S<:Real}(lims::Tuple{T,S}) = plot!(ylims = lims)
xticks!{T<:Real}(v::AVec{T}) = plot!(xticks = v)
yticks!{T<:Real}(v::AVec{T}) = plot!(yticks = v)
```
Some keyword arguments you can set:
[[KEYWORD_ARGS_TABLE]]
Plot types:
[[LINETYPES_TABLE]]
Line styles:
[[LINESTYLES_TABLE]]
Markers:
[[MARKERS_TABLE]]
__Tip__: You can see the default value for a given argument with `plotDefault(arg::Symbol)`, and set the default value with `plotDefault!(arg::Symbol, value)`
__Tip__: When plotting multiple lines, you can set all series to use the same value, or pass in an array to cycle through values. Example:
```julia
plot(rand(100,4); color = [:red, RGB(0,0,1)], # lines 1 and 3 are red, lines 2 and 4 are blue
axis = :auto, # lines 1 and 3 are on the left axis, lines 2 and 4 are on the right
width = 5) # all lines have a width of 5
```
__Tip__: Not all features are supported for each backend, but you can see what's supported by calling the functions: `supportedArgs()`, `supportedAxes()`, `supportedTypes()`, `supportedStyles()`, `supportedMarkers()`, `subplotSupported()`
__Tip__: Call `gui()` to display the plot in a window. Interactivity depends on backend. Plotting at the REPL (without semicolon) implicitly calls `gui()`.
## TODO features:
- [x] Plot vectors/matrices/functions
- [x] Plot DataFrames
- [ ] Scales
- [ ] Categorical Inputs (strings, etc... for hist, bar? or can split one series into multiple?)
- [ ] Custom markers
- [ ] Special plots (boxplot, ohlc?)
- [x] Subplots
- [x] Histograms
- [ ] 3D plotting
- [ ] Scenes/Drawing
- [ ] Graphs
- [ ] Interactivity (GUIs)
## TODO backends:
- [x] Gadfly.jl
- [x] Immerse.jl
- [x] PyPlot.jl
- [x] UnicodePlots.jl
- [x] Qwt.jl
- [x] Winston.jl
- [ ] GLPlot.jl
- [ ] Bokeh.jl
- [ ] Vega.jl
- [ ] Gaston.jl
- [ ] Plotly.jl
- [ ] GoogleCharts.jl
- [ ] PLplot.jl
- [ ] TextPlots.jl
- [ ] ASCIIPlots.jl
- [ ] Sparklines.jl
- [ ] Hinton.jl
- [ ] ImageTerm.jl
- [ ] GraphViz.jl
- [ ] TikzGraphs.jl
- [ ] GraphLayout.jl
## More information on backends (both supported and unsupported)
See the wiki at: https://github.com/JuliaPlot/juliaplot_docs/wiki
+21 -21
View File
@@ -1,10 +1,10 @@
# Examples for backend: winston
- Supported arguments: `args`, `axis`, `color`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markersize`, `nbins`, `reg`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `ylabel`, `yrightlabel`
- Supported arguments: `args`, `axis`, `color`, `foreground_color`, `group`, `kwargs`, `label`, `legend`, `linestyle`, `linetype`, `marker`, `markersize`, `nbins`, `reg`, `ribbon`, `show`, `size`, `title`, `width`, `windowtitle`, `xlabel`, `xticks`, `ylabel`, `yrightlabel`, `yticks`
- Supported values for axis: `:auto`, `:left`
- Supported values for linetype: `:none`, `:line`, `:sticks`, `:scatter`, `:hist`, `:bar`
- Supported values for linestyle: `:auto`, `:solid`, `:dashdotdot`, `:dot`, `:dash`, `:dashdot`
- Supported values for marker: `:auto`, `:hexagon`, `:none`, `:dtriangle`, `:ellipse`, `:xcross`, `:rect`, `:star1`, `:star2`, `:cross`, `:utriangle`, `:diamond`
- Supported values for linetype: `:none`, `:line`, `:path`, `:sticks`, `:scatter`, `:hist`, `:bar`
- Supported values for linestyle: `:solid`, `:dash`, `:dot`, `:dashdot`
- Supported values for marker: `:none`, `:ellipse`, `:rect`, `:diamond`, `:utriangle`, `:dtriangle`, `:cross`, `:xcross`, `:star1`
- Is `subplot`/`subplot!` supported? No
### Initialize
@@ -19,7 +19,7 @@ winston!()
A simple line plot of the 3 columns.
```julia
plot(rand(100,3))
plot(rand(50,5),w=3)
```
![](../img/winston/winston_example_1.png)
@@ -51,7 +51,7 @@ Or make a parametric plot (i.e. plot: (fx(u), fy(u))) with plot(fx, fy, umin, um
```julia
plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, line 33:
sin(2x)
end),0,2π)
end),0,2π,legend=false,fillto=0)
```
![](../img/winston/winston_example_4.png)
@@ -61,7 +61,7 @@ plot(sin,(x->begin # /home/tom/.julia/v0.4/Plots/docs/example_generation.jl, li
Change the guides/background without a separate call.
```julia
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.5,0.5,0.5))
plot(rand(10); title="TITLE",xlabel="XLABEL",ylabel="YLABEL",background_color=RGB(0.2,0.2,0.2))
```
![](../img/winston/winston_example_5.png)
@@ -73,7 +73,7 @@ Use the `axis` or `axiss` arguments.
Note: Currently only supported with Qwt and PyPlot
```julia
plot(Vector[randn(100),randn(100) * 100]; axiss=[:left,:right],ylabel="LEFT",yrightlabel="RIGHT")
plot(Vector[randn(100),randn(100) * 100]; axis=[:l,:r],ylabel="LEFT",yrightlabel="RIGHT")
```
![](../img/winston/winston_example_6.png)
@@ -103,43 +103,43 @@ plot(rand(100) / 3; reg=true,fillto=0)
and add to it later.
```julia
scatter!(rand(100); markersize=6,color=:blue)
scatter!(rand(100); markersize=6,c=:blue)
```
![](../img/winston/winston_example_9.png)
### Suported line types
### Line types
All options: (:line, :orderedline, :step, :stepinverted, :sticks, :scatter, :none, :heatmap, :hexbin, :hist, :bar)
```julia
types = intersect(supportedTypes(),[:line,:step,:stepinverted,:sticks,:scatter])
types = intersect(supportedTypes(),[:line,:path,:steppre,:steppost,:sticks,:scatter])
n = length(types)
x = Vector[sort(rand(20)) for i = 1:n]
y = rand(20,n)
plot(x,y; linetypes=types,labels=map(string,types))
plot(x,y; t=types,lab=map(string,types))
```
![](../img/winston/winston_example_11.png)
### Supported line styles
### Line styles
All options: (:solid, :dash, :dot, :dashdot, :dashdotdot)
```julia
styles = setdiff(supportedStyles(),[:auto])
plot(rand(20,length(styles)); linestyle=:auto,labels=map(string,styles))
plot(cumsum(randn(20,length(styles)),1); style=:auto,label=map(string,styles),w=5)
```
![](../img/winston/winston_example_12.png)
### Supported marker types
### Marker types
All options: (:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon)
```julia
markers = setdiff(supportedMarkers(),[:none,:auto])
plot([fill(i,10) for i = 1:length(markers)]; marker=:auto,labels=map(string,markers),markersize=10)
scatter(0.5:9.5,[fill(i - 0.5,10) for i = length(markers):-1:1]; marker=:auto,label=map(string,markers),markersize=10)
```
![](../img/winston/winston_example_13.png)
@@ -156,10 +156,10 @@ bar(randn(1000))
### Histogram
note: fillto isn't supported on all backends
```julia
histogram(randn(1000); nbins=50,fillto=20)
histogram(randn(1000); nbins=50)
```
![](../img/winston/winston_example_15.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

+52 -3
View File
@@ -2,7 +2,8 @@ __precompile__()
module Plots
using Colors
using Reexport
@reexport using Colors
export
plotter,
@@ -32,10 +33,24 @@ export
hline!,
vline,
vline!,
ohlc,
ohlc!,
title!,
xlabel!,
ylabel!,
xlims!,
ylims!,
xticks!,
yticks!,
savepng,
gui,
backends,
aliases,
dataframes!,
OHLC,
supportedArgs,
supportedAxes,
@@ -54,6 +69,7 @@ const IMG_DIR = Pkg.dir("Plots") * "/img/"
include("types.jl")
include("utils.jl")
include("colors.jl")
include("plotter.jl")
include("args.jl")
include("plot.jl")
@@ -76,16 +92,49 @@ hline(args...; kw...) = plot(args...; kw..., linetype = :hline)
hline!(args...; kw...) = plot!(args...; kw..., linetype = :hline)
vline(args...; kw...) = plot(args...; kw..., linetype = :vline)
vline!(args...; kw...) = plot!(args...; kw..., linetype = :vline)
ohlc(args...; kw...) = plot(args...; kw..., linetype = :ohlc)
ohlc!(args...; kw...) = plot!(args...; kw..., linetype = :ohlc)
title!(s::AbstractString) = plot!(title = s)
xlabel!(s::AbstractString) = plot!(xlabel = s)
ylabel!(s::AbstractString) = plot!(ylabel = s)
xlims!{T<:Real,S<:Real}(lims::Tuple{T,S}) = plot!(xlims = lims)
ylims!{T<:Real,S<:Real}(lims::Tuple{T,S}) = plot!(ylims = lims)
xticks!{T<:Real}(v::AVec{T}) = plot!(xticks = v)
yticks!{T<:Real}(v::AVec{T}) = plot!(yticks = v)
title!(plt::Plot, s::AbstractString) = plot!(plt; title = s)
xlabel!(plt::Plot, s::AbstractString) = plot!(plt; xlabel = s)
ylabel!(plt::Plot, s::AbstractString) = plot!(plt; ylabel = s)
xlims!{T<:Real,S<:Real}(plt::Plot, lims::Tuple{T,S}) = plot!(plt; xlims = lims)
ylims!{T<:Real,S<:Real}(plt::Plot, lims::Tuple{T,S}) = plot!(plt; ylims = lims)
xticks!{T<:Real}(plt::Plot, v::AVec{T}) = plot!(plt; xticks = v)
yticks!{T<:Real}(plt::Plot, v::AVec{T}) = plot!(plt; yticks = v)
# ---------------------------------------------------------
savepng(args...; kw...) = savepng(currentPlot(), args...; kw...)
savepng(plt::PlottingObject, args...; kw...) = savepng(plt.plotter, plt, args...; kw...)
savepng(::PlottingPackage, plt::PlottingObject, fn::String, args...) = error("unsupported") # fallback so multiple dispatch doesn't get confused if it's missing
savepng(plt::PlottingObject, fn::AbstractString; kw...) = (io = open(fn, "w"); writemime(io, MIME("image/png"), plt); close(io))
# savepng(plt::PlottingObject, args...; kw...) = savepng(plt.plotter, plt, args...; kw...)
# savepng(::PlottingPackage, plt::PlottingObject, fn::AbstractString, args...) = error("unsupported") # fallback so multiple dispatch doesn't get confused if it's missing
gui(plt::PlottingObject = currentPlot()) = display(PlotsDisplay(), plt)
# override the REPL display to open a gui window
Base.display(::Base.REPL.REPLDisplay, ::MIME"text/plain", plt::PlottingObject) = gui(plt)
function __init__()
global const CURRENT_BACKEND = pickDefaultBackend()
println("[Plots.jl] Default backend: ", CURRENT_BACKEND.sym)
end
# ---------------------------------------------------------
end # module
+372 -157
View File
@@ -1,34 +1,82 @@
# const COLORS = [:black, :blue, :green, :red, :darkGray, :darkCyan, :darkYellow, :darkMagenta,
# :darkBlue, :darkGreen, :darkRed, :gray, :cyan, :yellow, :magenta]
const _allAxes = [:auto, :left, :right]
const _axesAliases = Dict(
:a => :auto,
:l => :left,
:r => :right
)
const COLORS = distinguishable_colors(20)
const AXES = [:left, :right]
const TYPES = [:line,
:step,
:stepinverted,
:sticks,
:scatter,
:heatmap,
:hexbin,
:hist,
:bar,
:hline,
:vline,
]
const STYLES = [:solid, :dash, :dot, :dashdot, :dashdotdot]
const MARKERS = [:ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon]
const _allTypes = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
:heatmap, :hexbin, :hist, :bar, :hline, :vline, :ohlc]
const _typeAliases = Dict(
:n => :none,
:no => :none,
:l => :line,
:p => :path,
:stepinv => :steppre,
:stepsinv => :steppre,
:stepinverted => :steppre,
:stepsinverted => :steppre,
:step => :steppost,
:steps => :steppost,
:stair => :steppost,
:stairs => :steppost,
:stem => :sticks,
:stems => :sticks,
:dots => :scatter,
:histogram => :hist,
)
const ALL_AXES = vcat(:auto, AXES)
const ALL_TYPES = vcat(:none, TYPES)
const ALL_STYLES = vcat(:auto, STYLES)
const ALL_MARKERS = vcat(:none, :auto, MARKERS)
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
const _styleAliases = Dict(
:a => :auto,
:s => :solid,
:d => :dash,
:dd => :dashdot,
:ddd => :dashdotdot,
)
supportedAxes(::PlottingPackage) = ALL_AXES
supportedTypes(::PlottingPackage) = ALL_TYPES
supportedStyles(::PlottingPackage) = ALL_STYLES
supportedMarkers(::PlottingPackage) = ALL_MARKERS
const _allMarkers = [:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle,
:cross, :xcross, :star1, :star2, :hexagon, :octagon]
const _markerAliases = Dict(
:n => :none,
:no => :none,
:a => :auto,
:circle => :ellipse,
:c => :ellipse,
:square => :rect,
:sq => :rect,
:r => :rect,
:d => :diamond,
:^ => :utriangle,
:ut => :utriangle,
:utri => :utriangle,
:uptri => :utriangle,
:uptriangle => :utriangle,
:v => :dtriangle,
:V => :dtriangle,
:dt => :dtriangle,
:dtri => :dtriangle,
:downtri => :dtriangle,
:downtriangle => :dtriangle,
:+ => :cross,
:plus => :cross,
:x => :xcross,
:X => :xcross,
:star => :star1,
:s => :star1,
:s2 => :star2,
:h => :hexagon,
:hex => :hexagon,
:o => :octagon,
:oct => :octagon,
)
supportedAxes(::PlottingPackage) = _allAxes
supportedTypes(::PlottingPackage) = _allTypes
supportedStyles(::PlottingPackage) = _allStyles
supportedMarkers(::PlottingPackage) = _allMarkers
subplotSupported(::PlottingPackage) = true
supportedAxes() = supportedAxes(plotter())
@@ -39,54 +87,56 @@ subplotSupported() = subplotSupported(plotter())
# -----------------------------------------------------------------------------
const PLOT_DEFAULTS = Dict{Symbol, Any}()
const _seriesDefaults = Dict{Symbol, Any}()
# series-specific
PLOT_DEFAULTS[:axis] = :left
PLOT_DEFAULTS[:color] = :auto
PLOT_DEFAULTS[:label] = "AUTO"
PLOT_DEFAULTS[:width] = 1
PLOT_DEFAULTS[:linetype] = :line
PLOT_DEFAULTS[:linestyle] = :solid
PLOT_DEFAULTS[:marker] = :none
PLOT_DEFAULTS[:markercolor] = :match
PLOT_DEFAULTS[:markersize] = 6
PLOT_DEFAULTS[:nbins] = 100 # number of bins for heatmaps and hists
PLOT_DEFAULTS[:heatmap_c] = (0.15, 0.5)
PLOT_DEFAULTS[:fillto] = nothing # fills in the area
PLOT_DEFAULTS[:reg] = false # regression line?
_seriesDefaults[:axis] = :left
_seriesDefaults[:color] = :auto
_seriesDefaults[:label] = "AUTO"
_seriesDefaults[:width] = 1
_seriesDefaults[:linetype] = :path
_seriesDefaults[:linestyle] = :solid
_seriesDefaults[:marker] = :none
_seriesDefaults[:markercolor] = :match
_seriesDefaults[:markersize] = 6
_seriesDefaults[:nbins] = 100 # number of bins for heatmaps and hists
_seriesDefaults[:heatmap_c] = (0.15, 0.5)
_seriesDefaults[:fillto] = nothing # fills in the area
_seriesDefaults[:reg] = false # regression line?
_seriesDefaults[:group] = nothing
_seriesDefaults[:ribbon] = nothing
_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}
const _plotDefaults = Dict{Symbol, Any}()
# plot globals
PLOT_DEFAULTS[:title] = ""
PLOT_DEFAULTS[:xlabel] = ""
PLOT_DEFAULTS[:ylabel] = ""
PLOT_DEFAULTS[:yrightlabel] = ""
PLOT_DEFAULTS[:legend] = true
# PLOT_DEFAULTS[:background_color] = nothing
# PLOT_DEFAULTS[:xticks] = true
# PLOT_DEFAULTS[:yticks] = true
PLOT_DEFAULTS[:size] = (600,400)
PLOT_DEFAULTS[:windowtitle] = "Plots.jl"
# PLOT_DEFAULTS[:show] = true
_plotDefaults[:title] = ""
_plotDefaults[:xlabel] = ""
_plotDefaults[:ylabel] = ""
_plotDefaults[:yrightlabel] = ""
_plotDefaults[:legend] = true
_plotDefaults[:background_color] = colorant"white"
_plotDefaults[:foreground_color] = :auto
_plotDefaults[:xlims] = :auto
_plotDefaults[:ylims] = :auto
_plotDefaults[:xticks] = :auto
_plotDefaults[:yticks] = :auto
_plotDefaults[:size] = (800,600)
_plotDefaults[:windowtitle] = "Plots.jl"
_plotDefaults[:show] = false
PLOT_DEFAULTS[:args] = [] # additional args to pass to the backend
PLOT_DEFAULTS[:kwargs] = [] # additional keyword args to pass to the backend
# note: can be Vector{Dict} or Vector{Tuple}
# TODO: x/y scales
const ARGS = sort(collect(keys(PLOT_DEFAULTS)))
supportedArgs(::PlottingPackage) = ARGS
const _allArgs = sort(collect(union(keys(_seriesDefaults), keys(_plotDefaults))))
supportedArgs(::PlottingPackage) = _allArgs
supportedArgs() = supportedArgs(plotter())
# -----------------------------------------------------------------------------
plotDefault(sym::Symbol) = PLOT_DEFAULTS[sym]
function plotDefault!(sym::Symbol, val)
PLOT_DEFAULTS[sym] = val
end
# -----------------------------------------------------------------------------
makeplural(s::Symbol) = Symbol(string(s,"s"))
@@ -97,32 +147,118 @@ autopick(notarr, idx::Integer) = notarr
autopick_ignore_none_auto(arr::AVec, idx::Integer) = autopick(setdiff(arr, [:none, :auto]), idx)
autopick_ignore_none_auto(notarr, idx::Integer) = notarr
# converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically
# note: if plt is nothing, we aren't doing anything with the color anyways
function getRGBColor(c, n::Int = 0)
# auto-assign a color based on plot index
if c == :auto && n > 0
c = autopick(COLORS, n)
function aliasesAndAutopick(d::Dict, sym::Symbol, aliases::Dict, options::AVec, plotIndex::Int)
if d[sym] == :auto
d[sym] = autopick_ignore_none_auto(options, plotIndex)
elseif haskey(aliases, d[sym])
d[sym] = aliases[d[sym]]
end
end
function aliases(aliasMap::Dict, val)
# sort(vcat(val, collect(keys(filter((k,v)-> v==val, aliasMap)))))
sortedkeys(filter((k,v)-> v==val, aliasMap))
end
# -----------------------------------------------------------------------------
# Alternate args
const _keyAliases = Dict(
:c => :color,
:lab => :label,
:w => :width,
:linewidth => :width,
:type => :linetype,
:lt => :linetype,
:t => :linetype,
:style => :linestyle,
:s => :linestyle,
:ls => :linestyle,
:m => :marker,
:mc => :markercolor,
:mcolor => :markercolor,
:ms => :markersize,
:msize => :markersize,
:nb => :nbins,
:nbin => :nbins,
:fill => :fillto,
:area => :fillto,
:g => :group,
:r => :ribbon,
: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,
:xlim => :xlims,
:xlimit => :xlims,
:xlimits => :xlims,
:ylim => :ylims,
:ylimit => :ylims,
:ylimits => :ylims,
:xtick => :xticks,
:ytick => :yticks,
:windowsize => :size,
:wsize => :size,
:wtitle => :windowtitle,
:display => :show,
)
# add all pluralized forms to the _keyAliases dict
for arg in keys(_seriesDefaults)
_keyAliases[makeplural(arg)] = arg
end
# -----------------------------------------------------------------------------
# update the defaults globally
function plotDefault(k::Symbol)
if haskey(_seriesDefaults, k)
return _seriesDefaults[k]
elseif haskey(_plotDefaults, k)
return _plotDefaults[k]
else
error("Unknown key: ", k)
end
end
function plotDefault!(k::Symbol, v)
if haskey(_seriesDefaults, k)
_seriesDefaults[k] = v
elseif haskey(_plotDefaults, k)
_plotDefaults[k] = v
else
error("Unknown key: ", k)
end
end
# -----------------------------------------------------------------------------
function warnOnUnsupportedArgs(pkg::PlottingPackage, d::Dict)
for k in sortedkeys(d)
if !(k in supportedArgs(pkg))
warn("Keyword argument $k not supported with $pkg. Choose from: $(supportedArgs(pkg))")
end
end
# convert it from a symbol/string
if isa(c, Symbol)
c = string(c)
end
if isa(c, String)
c = parse(Colorant, c)
end
# should be a RGB now... either it was passed in, generated automatically, or created from a string
@assert isa(c, RGB)
# return the RGB
c
end
# const ALT_ARG_NAMES = Dict{Tuple{Symbol,Symbol}, Any}()
# ALT_ARG_NAMES[(:linetype, :scatter)] = :scatter
function warnOnUnsupported(pkg::PlottingPackage, d::Dict)
d[:axis] in supportedAxes(pkg) || warn("axis $(d[:axis]) is unsupported with $pkg. Choose from: $(supportedAxes(pkg))")
@@ -132,93 +268,172 @@ function warnOnUnsupported(pkg::PlottingPackage, d::Dict)
end
# note: idx is the index of this series within this call, n is the index of the series from all calls to plot/subplot
function getPlotKeywordArgs(pkg::PlottingPackage, kw, idx::Int, n::Int)
# build the argument dictionary for the plot
function getPlotArgs(pkg::PlottingPackage, kw, idx::Int)
d = Dict(kw)
# # replace alternate names
# for tup in kw
# if haskey(ALT_ARG_NAMES, tup)
# d[tup[1]] = ALT_ARG_NAMES[tup]
# end
# end
# default to a white background, but only on the initial call (so we don't change the background automatically)
if haskey(d, :background_color)
d[:background_color] = getRGBColor(d[:background_color])
elseif n == 0
d[:background_color] = colorant"white"
end
# fill in d with either 1) plural value, 2) value, 3) default
for k in keys(PLOT_DEFAULTS)
plural = makeplural(k)
if !haskey(d, k)
if n == 0 || k != :size
d[k] = haskey(d, plural) ? autopick(d[plural], idx) : PLOT_DEFAULTS[k]
# add defaults?
for k in keys(_plotDefaults)
if haskey(d, k)
v = d[k]
if isa(v, AbstractVector) && !isempty(v)
# we got a vector, cycling through
d[k] = autopick(v, idx)
end
else
d[k] = _plotDefaults[k]
end
delete!(d, plural)
end
# auto-pick
if n > 0
if d[:axis] == :auto
d[:axis] = autopick_ignore_none_auto(supportedAxes(pkg), n)
# convert color
handlePlotColors(pkg, d)
# d[:background_color] = getBackgroundRGBColor(d[:background_color], d)
# no need for these
delete!(d, :x)
delete!(d, :y)
d
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
d = Dict(kw)
# add defaults?
for k in keys(_seriesDefaults)
if haskey(d, k)
v = d[k]
if isa(v, AbstractVector) && !isempty(v)
# we got a vector, cycling through
d[k] = autopick(v, commandIndex)
end
else
d[k] = _seriesDefaults[k]
end
# if d[:linetype] == :auto
# d[:linetype] = autopick_ignore_none_auto(supportedTypes(pkg), n)
# end
if d[:linestyle] == :auto
d[:linestyle] = autopick_ignore_none_auto(supportedStyles(pkg), n)
end
if d[:marker] == :auto
d[:marker] = autopick_ignore_none_auto(supportedMarkers(pkg), n)
end
end
# # swap out dots for no line and a marker
# if haskey(d, :linetype) && d[:linetype] == :scatter
# d[:linetype] = :none
# if d[:marker] == :none
# d[:marker] = :ellipse
# end
# end
# handle plot initialization differently
if n == 0
delete!(d, :x)
delete!(d, :y)
else
# once the plot is created, we can get line/marker colors
# update color
d[:color] = getRGBColor(d[:color], n)
# update markercolor
mc = d[:markercolor]
mc = (mc == :match ? d[:color] : getRGBColor(mc, n))
d[:markercolor] = mc
# set label
label = d[:label]
label = (label == "AUTO" ? "y_$n" : label)
if d[:axis] == :right && length(label) >= 4 && label[end-3:end] != " (R)"
label = string(label, " (R)")
end
d[:label] = label
warnOnUnsupported(pkg, d)
if haskey(_typeAliases, d[:linetype])
d[:linetype] = _typeAliases[d[:linetype]]
end
aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex)
aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex)
aliasesAndAutopick(d, :marker, _markerAliases, supportedMarkers(pkg), plotIndex)
# update color
d[:color] = getSeriesRGBColor(d[:color], initargs, plotIndex)
# update markercolor
mc = d[:markercolor]
mc = (mc == :match ? d[:color] : getSeriesRGBColor(mc, initargs, plotIndex))
d[:markercolor] = mc
# set label
label = d[:label]
label = (label == "AUTO" ? "y$globalIndex" : label)
if d[:axis] == :right && length(label) >= 4 && label[end-3:end] != " (R)"
label = string(label, " (R)")
end
d[:label] = label
warnOnUnsupported(pkg, d)
d
end
# # note: idx is the index of this series within this call, n is the index of the series from all calls to plot/subplot
# function getPlotKeywordArgs(pkg::PlottingPackage, kw, idx::Int, n::Int)
# d = Dict(kw)
# # # replace alternate names
# # for tup in kw
# # if haskey(ALT_ARG_NAMES, tup)
# # d[tup[1]] = ALT_ARG_NAMES[tup]
# # end
# # end
# # default to a white background, but only on the initial call (so we don't change the background automatically)
# if haskey(d, :background_color)
# d[:background_color] = getRGBColor(d[:background_color])
# elseif n == 0
# d[:background_color] = colorant"white"
# end
# # fill in d with either 1) plural value, 2) value, 3) default
# for k in keys(PLOT_DEFAULTS)
# plural = makeplural(k)
# if !haskey(d, k)
# if n == 0 || k != :size
# d[k] = haskey(d, plural) ? autopick(d[plural], idx) : PLOT_DEFAULTS[k]
# end
# end
# delete!(d, plural)
# end
# # auto-pick
# if n > 0
# if d[:axis] == :auto
# d[:axis] = autopick_ignore_none_auto(supportedAxes(pkg), n)
# end
# # if d[:linetype] == :auto
# # d[:linetype] = autopick_ignore_none_auto(supportedTypes(pkg), n)
# # end
# if d[:linestyle] == :auto
# d[:linestyle] = autopick_ignore_none_auto(supportedStyles(pkg), n)
# end
# if d[:marker] == :auto
# d[:marker] = autopick_ignore_none_auto(supportedMarkers(pkg), n)
# end
# end
# # # swap out dots for no line and a marker
# # if haskey(d, :linetype) && d[:linetype] == :scatter
# # d[:linetype] = :none
# # if d[:marker] == :none
# # d[:marker] = :ellipse
# # end
# # end
# # handle plot initialization differently
# if n == 0
# delete!(d, :x)
# delete!(d, :y)
# else
# # once the plot is created, we can get line/marker colors
# # update color
# d[:color] = getRGBColor(d[:color], n)
# # update markercolor
# mc = d[:markercolor]
# mc = (mc == :match ? d[:color] : getRGBColor(mc, n))
# d[:markercolor] = mc
# # set label
# label = d[:label]
# label = (label == "AUTO" ? "y$n" : label)
# if d[:axis] == :right && length(label) >= 4 && label[end-3:end] != " (R)"
# label = string(label, " (R)")
# end
# d[:label] = label
# warnOnUnsupported(pkg, d)
# end
# d
# end
# -----------------------------------------------------------------------------
+194 -99
View File
@@ -7,11 +7,11 @@ export gadfly!
gadfly!() = plotter!(:gadfly)
supportedArgs(::GadflyPackage) = setdiff(ARGS, [:heatmap_c, :fillto, :pos])
supportedAxes(::GadflyPackage) = setdiff(ALL_AXES, [:right])
supportedTypes(::GadflyPackage) = [:none, :line, :step, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline]
supportedStyles(::GadflyPackage) = [:auto, :solid]
supportedMarkers(::GadflyPackage) = [:none, :auto, :rect, :ellipse, :diamond, :cross]
supportedArgs(::GadflyPackage) = setdiff(_allArgs, [:heatmap_c, :pos, :screen, :yrightlabel])
supportedAxes(::GadflyPackage) = setdiff(_allAxes, [:right])
supportedTypes(::GadflyPackage) = [:none, :line, :path, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :ohlc]
supportedStyles(::GadflyPackage) = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
supportedMarkers(::GadflyPackage) = [:none, :auto, :rect, :ellipse, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon, :octagon]
include("gadfly_shapes.jl")
@@ -35,7 +35,7 @@ function createGadflyPlotObject(d::Dict)
unshift!(gplt.guides, Gadfly.Guide.manual_color_key("", AbstractString[], Color[]))
end
gplt.theme = Gadfly.Theme(background_color = (haskey(d, :background_color) ? d[:background_color] : colorant"white"))
gplt.theme = Gadfly.Theme(background_color = d[:background_color])
gplt
end
@@ -45,101 +45,94 @@ function getLineGeoms(d::Dict)
lt = d[:linetype]
lt in (:heatmap,:hexbin) && return [Gadfly.Geom.hexbin(xbincount = d[:nbins], ybincount = d[:nbins])]
lt == :hist && return [Gadfly.Geom.histogram(bincount = d[:nbins])]
lt == :none && return [Gadfly.Geom.path]
lt == :line && return [Gadfly.Geom.path]
# lt == :none && return [Gadfly.Geom.path]
lt == :path && return [Gadfly.Geom.path]
lt == :scatter && return [Gadfly.Geom.point]
lt == :bar && return [Gadfly.Geom.bar]
lt == :step && return [Gadfly.Geom.step]
lt == :steppost && return [Gadfly.Geom.step]
# NOTE: we won't actually show this (we'll set width to 0 later), but we need a geom so that Gadfly doesn't complain
if lt in (:none, :ohlc)
return [Gadfly.Geom.path]
end
# lt == :sticks && return [Gadfly.Geom.bar]
error("linetype $lt not currently supported with Gadfly")
end
# function createGadflyAnnotation(d::Dict)
# if d[:marker] == :rect
# # get the width/height of the square (both are sz)
# sz = d[:markersize] * Gadfly.px
# halfsz = sz/2
# # remap x/y to the corner position of the squares
# xs = map(z -> Gadfly.Compose.Measure(;cx=z) - halfsz, float(d[:x]))
# ys = map(z -> Gadfly.Compose.Measure(;cy=z) + halfsz, float(d[:y]))
# # return an Annotation which will add those shapes to each point in the series
# return Gadfly.Guide.annotation(Gadfly.compose(Gadfly.context(), Gadfly.rectangle(xs,ys,[sz],[sz]), Gadfly.fill(d[:markercolor]), Gadfly.stroke(nothing)))
# else
# # make circles
# sz = 0.5 * d[:markersize] * Gadfly.px
# xs = collect(float(d[:x]))
# ys = collect(float(d[:y]))
# # return an Annotation which will add those shapes to each point in the series
# return Gadfly.Guide.annotation(Gadfly.compose(Gadfly.context(), Gadfly.circle(xs,ys,[sz]), Gadfly.fill(d[:markercolor]), Gadfly.stroke(nothing)))
# end
# end
# serious hack (I think?) to draw my own shapes as annotations... will it work? who knows...
function getMarkerGeomsAndGuides(d::Dict)
marker = d[:marker]
if marker == :none
if marker == :none && d[:linetype] != :ohlc
return [],[]
end
return [], [createGadflyAnnotation(d)]
end
# # special handling for other marker shapes... gotta create Compose contexts and map them to series points using Guide.Annotation
# elseif marker == :rect
# # get the width/height of the square (both are sz)
# sz = d[:markersize] * Gadfly.px
# halfsz = sz/2
# # remap x/y to the corner position of the squares
# xs = map(z -> Gadfly.Compose.Measure(;cx=z) - halfsz, float(d[:x]))
# ys = map(z -> Gadfly.Compose.Measure(;cy=z) + halfsz, float(d[:y]))
# # return an Annotation which will add those shapes to each point in the series
# return [], [Gadfly.Guide.annotation(Gadfly.compose(Gadfly.context(), Gadfly.rectangle(xs,ys,[sz],[sz]), Gadfly.fill(d[:markercolor]), Gadfly.stroke(nothing)))]
# else
# # make circles
# sz = 0.5 * d[:markersize] * Gadfly.px
# xs = collect(float(d[:x]))
# ys = collect(float(d[:y]))
# # return an Annotation which will add those shapes to each point in the series
# return [], [Gadfly.Guide.annotation(Gadfly.compose(Gadfly.context(), Gadfly.circle(xs,ys,[sz]), Gadfly.fill(d[:markercolor]), Gadfly.stroke(nothing)))]
# end
# otherwise just return a Geom.point
# [Gadfly.Geom.point], []
# end
function addGadflyFixedLines!(gplt, d::Dict)
function addGadflyFixedLines!(gplt, d::Dict, theme)
sz = d[:width] * Gadfly.px
c = d[:color]
if d[:linetype] == :hline
geom = Gadfly.Geom.hline(color=c, size=sz)
layer = Gadfly.layer(yintercept = d[:y], geom)
layer = Gadfly.layer(yintercept = d[:y], geom, theme)
else
geom = Gadfly.Geom.vline(color=c, size=sz)
layer = Gadfly.layer(xintercept = d[:y], geom)
layer = Gadfly.layer(xintercept = d[:y], geom, theme)
end
prepend!(gplt.layers, layer)
end
function getGadflyStrokeVector(linestyle::Symbol)
dash = 12 * Compose.mm
dot = 3 * Compose.mm
gap = 2 * Compose.mm
linestyle == :solid && return nothing
linestyle == :dash && return [dash, gap]
linestyle == :dot && return [dot, gap]
linestyle == :dashdot && return [dash, gap, dot, gap]
linestyle == :dashdotdot && return [dash, gap, dot, gap, dot, gap]
error("unsupported linestyle: ", linestyle)
end
function addGadflySeries!(gplt, d::Dict)
function addGadflySeries!(gplt, d::Dict, initargs::Dict)
gfargs = []
# if my PR isn't present, don't set the line_style
local extra_theme_args
try
Gadfly.getStrokeVector(:solid)
extra_theme_args = [(:line_style, getGadflyStrokeVector(d[:linestyle]))]
catch
extra_theme_args = []
end
# extra_theme_args = Gadfly.isdefined(:getStrokeVector) ? [(:line_style, getGadflyStrokeVector(d[:linestyle]))] : []
# line_style = getGadflyStrokeVector(d[:linestyle])
# set theme: color, line width, and point size
line_width = d[:width] * (d[:linetype] in (:none, :ohlc) ? 0 : 1) * Gadfly.px # 0 width when we don't show a line
# fg = initargs[:foreground_color]
theme = Gadfly.Theme(; default_color = d[:color],
line_width = line_width,
default_point_size = 0.5 * d[:markersize] * Gadfly.px,
# grid_color = fg,
# minor_label_color = fg,
# major_label_color = fg,
# key_title_color = fg,
# key_label_color = fg,
extra_theme_args...)
# line_style = line_style)
push!(gfargs, theme)
# first things first... lets so the sticks hack
if d[:linetype] == :sticks
@@ -151,14 +144,26 @@ function addGadflySeries!(gplt, d::Dict)
end
elseif d[:linetype] in (:hline, :vline)
addGadflyFixedLines!(gplt, d)
addGadflyFixedLines!(gplt, d, theme)
return
end
gfargs = []
end
# add the Geoms
append!(gfargs, getLineGeoms(d))
# fillto
if d[:fillto] == nothing
yminmax = []
else
fillto = makevec(d[:fillto])
n = length(fillto)
yminmax = [
(:ymin, Float64[min(y, fillto[mod1(i,n)]) for (i,y) in enumerate(d[:y])]),
(:ymax, Float64[max(y, fillto[mod1(i,n)]) for (i,y) in enumerate(d[:y])])
]
push!(gfargs, Gadfly.Geom.ribbon)
end
# handle markers
geoms, guides = getMarkerGeomsAndGuides(d)
@@ -176,18 +181,6 @@ function addGadflySeries!(gplt, d::Dict)
push!(gplt.guides[1].colors, d[:marker] == :none ? d[:color] : d[:markercolor])
end
# # if we haven't added any geoms, we're probably just going to use annotations?
# isempty(gfargs) && return
# set theme: color, line width, and point size
line_width = d[:width] * (d[:linetype] == :none ? 0 : 1) * Gadfly.px # 0 width when we don't show a line
theme = Gadfly.Theme(default_color = d[:color],
line_width = line_width,
default_point_size = 0.5 * d[:markersize] * Gadfly.px)
push!(gfargs, theme)
# for histograms, set x=y
x = d[d[:linetype] == :hist ? :y : :x]
@@ -197,10 +190,40 @@ function addGadflySeries!(gplt, d::Dict)
# add the layer to the Gadfly.Plot
prepend!(gplt.layers, Gadfly.layer(unique(gfargs)..., d[:args]...; x = x, y = d[:y], d[:kwargs]...))
# prepend!(gplt.layers, Gadfly.layer(unique(gfargs)..., d[:args]...; x = x, y = d[:y], d[:kwargs]...))
prepend!(gplt.layers, Gadfly.layer(unique(gfargs)...; x = x, y = d[:y], yminmax...))
nothing
end
function addTicksGuide(gplt, ticks, isx::Bool)
ticks == :auto && return
ttype = ticksType(ticks)
if ttype == :ticks
gtype = isx ? Gadfly.Guide.xticks : Gadfly.Guide.yticks
filter!(x -> !isa(x, gtype), gplt.guides)
push!(gplt.guides, gtype(ticks = sort(collect(ticks))))
else
error("Invalid input for $(isx ? "xticks" : "yticks"): ", ticks)
end
end
isContinuousScale(scale, isx::Bool) = isa(scale, Gadfly.Scale.ContinuousScale) && scale.vars[1] == (isx ? :x : :y)
function addLimitsScale(gplt, lims, isx::Bool)
lims == :auto && return
ltype = limsType(lims)
if ltype == :limits
# remove any existing scales, then add a new one
gfunc = isx ? Gadfly.Scale.x_continuous : Gadfly.Scale.y_continuous
filter!(scale -> !isContinuousScale(scale,isx), gplt.scales)
push!(gplt.scales, gfunc(minvalue = min(lims...), maxvalue = max(lims...)))
else
error("Invalid input for $(isx ? "xlims" : "ylims"): ", lims)
end
end
# ---------------------------------------------------------------------------
# create a blank Gadfly.Plot object
@@ -214,27 +237,45 @@ end
# plot one data series
function plot!(::GadflyPackage, plt::Plot; kw...)
d = Dict(kw)
addGadflySeries!(plt.o, d)
addGadflySeries!(plt.o, d, plt.initargs)
push!(plt.seriesargs, d)
plt
end
function Base.display(::GadflyPackage, plt::Plot)
display(plt.o)
function findGuideAndSet(gplt, t::DataType, s::AbstractString)
for (i,guide) in enumerate(gplt.guides)
if isa(guide, t)
gplt.guides[i] = t(s)
# guide.label = s
end
end
end
# -------------------------------
function savepng(::GadflyPackage, plt::PlottingObject, fn::String;
w = 6 * Gadfly.inch,
h = 4 * Gadfly.inch)
o = getGadflyContext(plt.plotter, plt)
Gadfly.draw(Gadfly.PNG(fn, w, h), o)
function updateGadflyGuides(gplt, d::Dict)
haskey(d, :title) && findGuideAndSet(gplt, Gadfly.Guide.title, d[:title])
haskey(d, :xlabel) && findGuideAndSet(gplt, Gadfly.Guide.xlabel, d[:xlabel])
haskey(d, :ylabel) && findGuideAndSet(gplt, Gadfly.Guide.ylabel, d[:ylabel])
haskey(d, :xlims) && addLimitsScale(gplt, d[:xlims], true)
haskey(d, :ylims) && addLimitsScale(gplt, d[:ylims], false)
haskey(d, :xticks) && addTicksGuide(gplt, d[:xticks], true)
haskey(d, :yticks) && addTicksGuide(gplt, d[:yticks], false)
end
function updatePlotItems(plt::Plot{GadflyPackage}, d::Dict)
updateGadflyGuides(plt.o, d)
end
# ----------------------------------------------------------------
# create the underlying object (each backend will do this differently)
function buildSubplotObject!(subplt::Subplot{GadflyPackage})
subplt.o = nothing
end
# ----------------------------------------------------------------
# -------------------------------
getGadflyContext(::GadflyPackage, plt::Plot) = plt.o
getGadflyContext(::GadflyPackage, subplt::Subplot) = buildGadflySubplotContext(subplt)
@@ -250,12 +291,66 @@ function buildGadflySubplotContext(subplt::Subplot)
Gadfly.vstack(rows...)
end
# create the underlying object (each backend will do this differently)
function buildSubplotObject!(::GadflyPackage, subplt::Subplot)
subplt.o = nothing
function setGadflyDisplaySize(w,h)
Compose.set_default_graphic_size(w * Compose.px, h * Compose.px)
end
function Base.writemime(io::IO, ::MIME"image/png", plt::Plot{GadflyPackage})
gplt = getGadflyContext(plt.plotter, plt)
setGadflyDisplaySize(plt.initargs[:size]...)
Gadfly.draw(Gadfly.PNG(io, Compose.default_graphic_width, Compose.default_graphic_height), gplt)
end
function Base.display(::GadflyPackage, subplt::Subplot)
display(buildGadflySubplotContext(subplt))
function Base.display(::PlotsDisplay, plt::Plot{GadflyPackage})
setGadflyDisplaySize(plt.initargs[:size]...)
display(plt.o)
end
function Base.writemime(io::IO, ::MIME"image/png", plt::Subplot{GadflyPackage})
gplt = getGadflyContext(plt.plotter, plt)
setGadflyDisplaySize(plt.initargs[1][:size]...)
Gadfly.draw(Gadfly.PNG(io, Compose.default_graphic_width, Compose.default_graphic_height), gplt)
end
function Base.display(::PlotsDisplay, subplt::Subplot{GadflyPackage})
setGadflyDisplaySize(subplt.initargs[1][:size]...)
ctx = buildGadflySubplotContext(subplt)
# taken from Gadfly since I couldn't figure out how to do it directly
filename = string(Gadfly.tempname(), ".html")
output = open(filename, "w")
plot_output = IOBuffer()
Gadfly.draw(Gadfly.SVGJS(plot_output, Compose.default_graphic_width,
Compose.default_graphic_height, false), ctx)
plotsvg = takebuf_string(plot_output)
write(output,
"""
<!DOCTYPE html>
<html>
<head>
<title>Gadfly Plot</title>
<meta charset="utf-8">
</head>
<body>
<script charset="utf-8">
$(readall(Compose.snapsvgjs))
</script>
<script charset="utf-8">
$(readall(Gadfly.gadflyjs))
</script>
$(plotsvg)
</body>
</html>
""")
close(output)
Gadfly.open_file(filename)
# display(buildGadflySubplotContext(subplt))
end
+209 -19
View File
@@ -10,15 +10,42 @@ function createGadflyAnnotation(d::Dict)
x, y = d[:x], d[:y]
marker = d[:marker]
if marker == :rect
if d[:linetype] == :ohlc
shape = ohlcshape(x, y, d[:markersize])
d[:y] = Float64[z.open for z in y]
d[:linetype] = :none
return Gadfly.Guide.annotation(Gadfly.compose(Gadfly.context(), shape, Gadfly.fill(nothing), Gadfly.stroke(d[:color])))
elseif marker == :rect
shape = square(x, y, sz)
elseif marker == :diamond
shape = diamond(x, y, sz)
elseif marker == :utriangle
shape = utriangle(x, y, sz)
elseif marker == :dtriangle
shape = utriangle(x, y, sz, -1)
elseif marker == :cross
shape = cross(x, y, sz)
elseif marker == :xcross
shape = xcross(x, y, sz)
elseif marker == :star1
shape = star1(x, y, sz)
elseif marker == :star2
shape = star2(x, y, sz)
elseif marker == :hexagon
shape = hexagon(x, y, sz)
elseif marker == :octagon
shape = octagon(x, y, sz)
else
# make circles
sz = 0.8 * d[:markersize] * Gadfly.px
@@ -33,15 +60,14 @@ end
function square(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray)
n = max(length(xs), length(ys), length(rs))
rect_xs = Vector{Compose.Measure}(n)
rect_ys = Vector{Compose.Measure}(n)
rect_ws = Vector{Compose.Measure}(n)
s = 1/sqrt(2)
for i in 1:n
x = Compose.x_measure(xs[1 + i % length(xs)])
y = Compose.y_measure(ys[1 + i % length(ys)])
r = rs[1 + i % length(rs)]
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
rect_xs[i] = x - s*r
rect_ys[i] = y + s*r
@@ -54,12 +80,11 @@ end
function diamond(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray)
n = max(length(xs), length(ys), length(rs))
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
for i in 1:n
x = Compose.x_measure(xs[1 + i % length(xs)])
y = Compose.y_measure(ys[1 + i % length(ys)])
r = rs[1 + i % length(rs)]
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
polys[i] = Tuple{Compose.Measure, Compose.Measure}[(x, y - r), (x + r, y), (x, y + r), (x - r, y)]
end
@@ -67,22 +92,187 @@ function diamond(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray)
end
function cross(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray)
n = max(length(xs), length(ys), length(rs))
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
s = 1/sqrt(5)
for i in 1:n
x = Compose.x_measure(xs[1 + i % length(xs)])
y = Compose.y_measure(ys[1 + i % length(ys)])
r = rs[1 + i % length(rs)]
u = s*r
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
u = 0.4r
# make a "plus sign"
polys[i] = Tuple{Compose.Measure, Compose.Measure}[
(x, y - u), (x + u, y - 2u), (x + 2u, y - u),
(x + u, y), (x + 2u, y + u), (x + u, y + 2u),
(x, y + u), (x - u, y + 2u), (x - 2u, y + u),
(x - u, y), (x - 2u, y - u), (x - u, y - 2u) ]
(x-r, y-u), (x-r, y+u), # L edge
(x-u, y+u), # BL inside
(x-u, y+r), (x+u, y+r), # B edge
(x+u, y+u), # BR inside
(x+r, y+u), (x+r, y-u), # R edge
(x+u, y-u), # TR inside
(x+u, y-r), (x-u, y-r), # T edge
(x-u, y-u) # TL inside
]
end
return Gadfly.polygon(polys)
end
function xcross(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray)
n = max(length(xs), length(ys), length(rs))
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
s = 1/sqrt(5)
for i in 1:n
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
u = s*r
polys[i] = Tuple{Compose.Measure, Compose.Measure}[
(x, y - u), (x + u, y - 2u), (x + 2u, y - u),
(x + u, y), (x + 2u, y + u), (x + u, y + 2u),
(x, y + u), (x - u, y + 2u), (x - 2u, y + u),
(x - u, y), (x - 2u, y - u), (x - u, y - 2u)
]
end
return Gadfly.polygon(polys)
end
function utriangle(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray, scalar = 1)
n = max(length(xs), length(ys), length(rs))
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
s = 0.8
for i in 1:n
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
u = 0.8 * scalar * r
polys[i] = Tuple{Compose.Measure, Compose.Measure}[
(x - r, y + u),
(x + r, y + u),
(x, y - u)
]
end
return Gadfly.polygon(polys)
end
function star1(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray, scalar = 1)
n = max(length(xs), length(ys), length(rs))
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
# some magic scalars
sx = 0.7
sy1, sy2 = 1.2, 0.4
for i in 1:n
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
polys[i] = Tuple{Compose.Measure, Compose.Measure}[
(x-sx*r, y+r), # BL
(x, y-sy1*r), # T
(x+sx*r, y+r), # BR
(x-r, y-sy2*r), # L
(x+r, y-sy2*r) # R
]
end
return Gadfly.polygon(polys)
end
function star2(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray, scalar = 1)
n = max(length(xs), length(ys), length(rs))
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
for i in 1:n
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
u = 0.4r
polys[i] = Tuple{Compose.Measure, Compose.Measure}[
(x-u, y), (x-r, y-r), # TL
(x, y-u), (x+r, y-r), # TR
(x+u, y), (x+r, y+r), # BR
(x, y+u), (x-r, y+r) # BL
]
end
return Gadfly.polygon(polys)
end
function hexagon(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray)
n = max(length(xs), length(ys), length(rs))
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
for i in 1:n
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
u = 0.6r
polys[i] = Tuple{Compose.Measure, Compose.Measure}[
(x-r, y-u), (x-r, y+u), # L edge
(x, y+r), # B
(x+r, y+u), (x+r, y-u), # R edge
(x, y-r) # T
]
end
return Gadfly.polygon(polys)
end
function octagon(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray)
n = max(length(xs), length(ys), length(rs))
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
for i in 1:n
x = Compose.x_measure(xs[mod1(i, length(xs))])
y = Compose.y_measure(ys[mod1(i, length(ys))])
r = rs[mod1(i, length(rs))]
u = 0.4r
polys[i] = Tuple{Compose.Measure, Compose.Measure}[
(x-r, y-u), (x-r, y+u), # L edge
(x-u, y+r), (x+u, y+r), # B edge
(x+r, y+u), (x+r, y-u), # R edge
(x+u, y-r), (x-u, y-r), # T edge
]
end
return Gadfly.polygon(polys)
end
# ---------------------------
function ohlcshape(xs::AVec, ys::AVec{OHLC}, tickwidth::Real)
@assert length(xs) == length(ys)
n = length(xs)
u = tickwidth * Compose.px
polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n)
for i in 1:n
x = Compose.x_measure(xs[i])
o = Compose.y_measure(ys[i].open)
h = Compose.y_measure(ys[i].high)
l = Compose.y_measure(ys[i].low)
c = Compose.y_measure(ys[i].close)
# o,h,l,c = map(Compose.y_measure, ys[i])
polys[i] = Tuple{Compose.Measure, Compose.Measure}[
(x, o), (x - u, o), (x, o), # open tick
(x, l), (x, h), (x, c), # high/low bar
(x + u, c), (x, c) # close tick
]
end
return Gadfly.polygon(polys)
end
+36 -36
View File
@@ -38,47 +38,24 @@ end
function plot!(::ImmersePackage, plt::Plot; kw...)
d = Dict(kw)
gplt = plt.o[2]
addGadflySeries!(gplt, d)
addGadflySeries!(gplt, d, plt.initargs)
push!(plt.seriesargs, d)
plt
end
function Base.display(::ImmersePackage, plt::Plot)
fig, gplt = plt.o
if fig == nothing
fig = createImmerseFigure(plt.initargs)
plt.o = (fig, gplt)
end
# # display a new Figure object to force a redraw
# display(Immerse.Figure(fig.canvas, gplt))
Immerse.figure(fig.figno; displayfig = false)
display(gplt)
end
# -------------------------------
getGadflyContext(::ImmersePackage, plt::Plot) = plt.o[2]
getGadflyContext(::ImmersePackage, subplt::Subplot) = buildGadflySubplotContext(subplt)
function savepng(::ImmersePackage, plt::PlottingObject, fn::String;
w = 6 * Immerse.inch,
h = 4 * Immerse.inch)
gctx = getGadflyContext(plt.plotter, plt)
Gadfly.draw(Gadfly.PNG(fn, w, h), gctx)
nothing
function updatePlotItems(plt::Plot{ImmersePackage}, d::Dict)
updateGadflyGuides(plt.o[2], d)
end
# -------------------------------
# ----------------------------------------------------------------
function buildSubplotObject!(::ImmersePackage, subplt::Subplot)
function buildSubplotObject!(subplt::Subplot{ImmersePackage})
# create the Gtk window with vertical box vsep
d = subplt.initargs
d = subplt.initargs[1]
w,h = d[:size]
vsep = Gtk.GtkBoxLeaf(:v)
win = Gtk.GtkWindowLeaf(vsep, d[:windowtitle], w, h)
@@ -114,26 +91,49 @@ function buildSubplotObject!(::ImmersePackage, subplt::Subplot)
end
# destructor... clean up plots
Gtk.on_signal_destroy((x...) -> [Immerse.dropfig(_display,i) for i in figindices], win)
Gtk.on_signal_destroy((x...) -> [Immerse.dropfig(Immerse._display,i) for i in figindices], win)
subplt.o = win
end
# ----------------------------------------------------------------
# # create the underlying object
# function buildSubplotObject!(::ImmersePackage, subplt::Subplot)
# subplt.o = (nothing, nothing)
# end
getGadflyContext(::ImmersePackage, plt::Plot) = plt.o[2]
getGadflyContext(::ImmersePackage, subplt::Subplot) = buildGadflySubplotContext(subplt)
function Base.writemime(io::IO, ::MIME"image/png", plt::Plot{ImmersePackage})
gplt = getGadflyContext(plt.plotter, plt)
setGadflyDisplaySize(plt.initargs[:size]...)
Gadfly.draw(Gadfly.PNG(io, Compose.default_graphic_width, Compose.default_graphic_height), gplt)
end
function Base.display(::ImmersePackage, subplt::Subplot)
function Base.display(::PlotsDisplay, plt::Plot{ImmersePackage})
fig, gplt = plt.o
if fig == nothing
fig = createImmerseFigure(plt.initargs)
plt.o = (fig, gplt)
end
Immerse.figure(fig.figno; displayfig = false)
display(gplt)
end
function Base.writemime(io::IO, ::MIME"image/png", plt::Subplot{ImmersePackage})
gplt = getGadflyContext(plt.plotter, plt)
setGadflyDisplaySize(plt.initargs[1][:size]...)
Gadfly.draw(Gadfly.PNG(io, Compose.default_graphic_width, Compose.default_graphic_height), gplt)
end
function Base.display(::PlotsDisplay, subplt::Subplot{ImmersePackage})
# display the plots by creating a fresh Immerse.Figure object from the GtkCanvas and Gadfly.Plot
for plt in subplt.plts
fig, gplt = plt.o
Immerse.figure(fig.figno; displayfig = false)
display(gplt)
# display(Immerse.Figure(fig.canvas, gplt))
end
# o is the window... show it
+102 -59
View File
@@ -8,11 +8,11 @@ pyplot!() = plotter!(:pyplot)
# -------------------------------
supportedArgs(::PyPlotPackage) = setdiff(ARGS, [:reg, :heatmap_c, :fillto, :pos])
supportedAxes(::PyPlotPackage) = ALL_AXES
supportedTypes(::PyPlotPackage) = [:none, :line, :step, :stepinverted, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar]
supportedStyles(::PyPlotPackage) = setdiff(ALL_STYLES, [:dashdotdot])
supportedMarkers(::PyPlotPackage) = setdiff(ALL_MARKERS, [:star2])
supportedArgs(::PyPlotPackage) = setdiff(_allArgs, [:reg, :heatmap_c, :fillto, :pos, :xlims, :ylims, :xticks, :yticks])
supportedAxes(::PyPlotPackage) = _allAxes
supportedTypes(::PyPlotPackage) = [:none, :line, :path, :step, :stepinverted, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar]
supportedStyles(::PyPlotPackage) = [:auto, :solid, :dash, :dot, :dashdot]
supportedMarkers(::PyPlotPackage) = [:none, :auto, :rect, :ellipse, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :hexagon]
subplotSupported(::PyPlotPackage) = false
# convert colorant to 4-tuple RGBA
@@ -37,8 +37,8 @@ function getPyPlotMarker(marker::Symbol)
marker == :diamond && return "D"
marker == :utriangle && return "^"
marker == :dtriangle && return "v"
marker == :cross && return "x"
marker == :xcross && return "+"
marker == :cross && return "+"
marker == :xcross && return "x"
marker == :star1 && return "*"
# marker == :star2 && return "*"
marker == :hexagon && return "h"
@@ -47,7 +47,7 @@ function getPyPlotMarker(marker::Symbol)
end
# pass through
function getPyPlotMarker(marker::String)
function getPyPlotMarker(marker::AbstractString)
@assert length(marker) == 1
marker
end
@@ -67,7 +67,7 @@ function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol)
# in the 2-axis case we need to get: <rightaxis>[:<func>]
if axis == :right
ax = getRightAxis(plt.o)
ax = getRightAxis(plt.o[1])
ax[:set_ylabel](plt.initargs[:yrightlabel])
fmap = Dict(
:hist => :hist,
@@ -94,6 +94,29 @@ function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol)
# return linetype == :hist ? PyPlot.plt[:hist] : (linetype in (:sticks,:bar) ? PyPlot.bar : (linetype in (:heatmap,:hexbin) ? PyPlot.hexbin : PyPlot.plot))
end
function updateAxisColors(ax, fgcolor)
for loc in ("bottom", "top", "left", "right")
ax[:spines][loc][:set_color](fgcolor)
end
for axis in ("x", "y")
ax[:tick_params](axis=axis, colors=fgcolor, which="both")
end
for axis in (:yaxis, :xaxis)
ax[axis][:label][:set_color](fgcolor)
end
ax[:title][:set_color](fgcolor)
end
nop() = nothing
# makePyPlotCurrent(plt::Plot) = PyPlot.withfig(nop, plt.o[1])
makePyPlotCurrent(plt::Plot) = PyPlot.figure(plt.o[1].o[:number])
# makePyPlotCurrent(plt::Plot) = PyPlot.orig_figure(num = plt.o[1].o[:number])
function preparePlotUpdate(plt::Plot{PyPlotPackage})
makePyPlotCurrent(plt)
end
# ------------------------------------------------------------------
# TODO:
@@ -111,20 +134,24 @@ function plot(pkg::PyPlotPackage; kw...)
d = Dict(kw)
w,h = map(px2inch, d[:size])
bgcolor = getPyPlotColor(d[:background_color])
o = PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = 96)
fig = PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = 96)
PyPlot.title(d[:title])
PyPlot.xlabel(d[:xlabel])
PyPlot.ylabel(d[:ylabel])
plt = Plot(o, pkg, 0, d, Dict[])
num = fig.o[:number]
plt = Plot((fig, num), pkg, 0, d, Dict[])
plt
end
function plot!(::PyPlotPackage, plt::Plot; kw...)
function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
d = Dict(kw)
fig, num = plt.o
# PyPlot.figure(num) # makes this current
# makePyPlotCurrent(plt)
if !(d[:linetype] in supportedTypes(pkg))
error("linetype $(d[:linetype]) is unsupported in PyPlot. Choose from: $(supportedTypes(pkg))")
end
if d[:linetype] == :sticks
d,_ = sticksHack(;d...)
@@ -182,74 +209,90 @@ function plot!(::PyPlotPackage, plt::Plot; kw...)
extraargs[:label] = d[:label]
# do the plot
# @show lt
if lt == :hist
d[:serieshandle] = plotfunc(d[:y]; extraargs...)[1]
elseif lt in (:scatter, :heatmap, :hexbin)
d[:serieshandle] = plotfunc(d[:x], d[:y]; extraargs...)
else
d[:serieshandle] = plotfunc(d[:x], d[:y]; extraargs...)[1]
# retval = plotfunc(d[:x], d[:y]; extraargs...)
# @show retval
# d[:serieshandle] = retval
end
# this sets the bg color inside the grid (plt.o.o == matplotlib.Figure)
plt.o.o[:axes][1][:set_axis_bgcolor](getPyPlotColor(plt.initargs[:background_color]))
# this sets the bg color inside the grid
fig.o[:axes][1][:set_axis_bgcolor](getPyPlotColor(plt.initargs[:background_color]))
push!(plt.seriesargs, d)
plt
end
function addPyPlotLegend(plt::Plot)
# add a legend?
# try
if plt.initargs[:legend]
# gotta do this to ensure both axes are included
args = filter(x -> !(x[:linetype] in (:hist,:hexbin,:heatmap)), plt.seriesargs)
if length(args) > 0
PyPlot.legend([d[:serieshandle] for d in args], [d[:label] for d in args], loc="best")
end
end
# catch ex
# warn("Error adding PyPlot legend: ", ex)
# end
function updatePlotItems(plt::Plot{PyPlotPackage}, d::Dict)
# makePyPlotCurrent(plt)
haskey(d, :title) && PyPlot.title(d[:title])
haskey(d, :xlabel) && PyPlot.xlabel(d[:xlabel])
if haskey(d, :ylabel)
ax = getLeftAxis(plt.o[1])
ax[:set_ylabel](d[:ylabel])
end
if haskey(d, :yrightlabel)
ax = getRightAxis(plt.o[1])
ax[:set_ylabel](d[:yrightlabel])
end
end
function Base.display(::PyPlotPackage, plt::Plot)
addPyPlotLegend(plt)
display(plt.o)
end
# -------------------------------
function savepng(::PyPlotPackage, plt::PlottingObject, fn::String, args...)
addPyPlotLegend(plt)
f = open(fn, "w")
writemime(f, "image/png", plt.o)
close(f)
end
# function savepng(::PyPlotPackage, plt::PlottingObject, fn::AbstractString, args...)
# fig, num = plt.o
# addPyPlotLegend(plt)
# f = open(fn, "w")
# writemime(f, "image/png", fig)
# close(f)
# end
# -------------------------------
# -----------------------------------------------------------------
# create the underlying object (each backend will do this differently)
function buildSubplotObject!(::PyPlotPackage, subplt::Subplot)
# i = 0
# rows = []
# for rowcnt in subplt.layout.rowcounts
# push!(rows, Qwt.hsplitter([plt.o for plt in subplt.plts[(1:rowcnt) + i]]...))
# i += rowcnt
# end
# subplt.o = Qwt.vsplitter(rows...)
function buildSubplotObject!(subplt::Subplot{PyPlotPackage})
error("unsupported")
end
# -----------------------------------------------------------------
function Base.display(::PyPlotPackage, subplt::Subplot)
# for plt in subplt.plts
# Qwt.refresh(plt.o)
# end
# Qwt.showwidget(subplt.o)
function addPyPlotLegend(plt::Plot)
if plt.initargs[:legend]
# gotta do this to ensure both axes are included
args = filter(x -> !(x[:linetype] in (:hist,:hexbin,:heatmap)), plt.seriesargs)
if length(args) > 0
PyPlot.legend([d[:serieshandle] for d in args], [d[:label] for d in args], loc="best")
end
end
end
function Base.writemime(io::IO, m::MIME"image/png", plt::PlottingObject{PyPlotPackage})
fig, num = plt.o
# makePyPlotCurrent(plt)
addPyPlotLegend(plt)
ax = fig.o[:axes][1]
updateAxisColors(ax, getPyPlotColor(plt.initargs[:foreground_color]))
writemime(io, m, fig)
end
function Base.display(::PlotsDisplay, plt::Plot{PyPlotPackage})
fig, num = plt.o
# PyPlot.figure(num) # makes this current
# makePyPlotCurrent(plt)
addPyPlotLegend(plt)
ax = fig.o[:axes][1]
updateAxisColors(ax, getPyPlotColor(plt.initargs[:foreground_color]))
display(fig)
end
function Base.display(::PlotsDisplay, subplt::Subplot{PyPlotPackage})
display(subplt.o)
end

Some files were not shown because too many files have changed in this diff Show More