Compare commits

...

23 Commits

Author SHA1 Message Date
Thomas Breloff 9ea98bcb56 readme 2015-09-12 22:54:16 -04:00
Thomas Breloff 4f9804d24e readme 2015-09-12 22:48:07 -04:00
Thomas Breloff 0a88518188 readme 2015-09-12 22:38:56 -04:00
Thomas Breloff ccae6373be readme 2015-09-12 22:31:05 -04:00
Thomas Breloff 31e5d07a45 readme 2015-09-12 22:24:44 -04:00
Thomas Breloff 056fee4b28 added parametric plot with example 2015-09-12 22:02:17 -04:00
Thomas Breloff 5a47864d73 readme 2015-09-12 21:46:30 -04:00
Thomas Breloff 1c7da432f1 readme 2015-09-12 21:40:25 -04:00
Thomas Breloff 3d3ceacaab pickDefaultBackend with warning; readme improvements 2015-09-12 21:33:38 -04:00
Thomas Breloff 35df39a44b readme and shorthands for switching plotters 2015-09-12 21:12:18 -04:00
Thomas Breloff c23d6d62e7 examples, fixes, and reorg img dir 2015-09-12 20:47:09 -04:00
Thomas Breloff 243d4a7ac3 working on unicodeplots savepng and examples 2015-09-12 20:28:40 -04:00
Thomas Breloff 50254d06d7 working on unicodeplots savepng and examples 2015-09-12 20:23:36 -04:00
Thomas Breloff 475b46f516 working on unicodeplots 2015-09-12 16:49:02 -04:00
Thomas Breloff f4573f7e87 added unicodeplots to examples 2015-09-12 16:37:34 -04:00
Thomas Breloff 7fb1a4ec0f better error when importing a package that is not installed; xmin/xmax functions example 2015-09-12 16:10:42 -04:00
Thomas Breloff 4299aa0ff8 more ways to plot Funtions 2015-09-12 15:59:45 -04:00
Thomas Breloff 4eb7e3810e unicodeplots 2015-09-12 14:58:15 -04:00
Thomas Breloff 3e7e7e9ac0 working on unicodeplots 2015-09-12 00:57:58 -04:00
Thomas Breloff 9e1058ec0a working on unicodeplots 2015-09-12 00:54:41 -04:00
Thomas Breloff 426a9eb6d3 working on unicodeplots 2015-09-12 00:31:48 -04:00
Thomas Breloff f322b9ac1c working on unicodeplots; added args to Plot; some reorg 2015-09-12 00:24:35 -04:00
Thomas Breloff e13fec08ca readme 2015-09-11 22:12:33 -04:00
92 changed files with 716 additions and 317 deletions
+163 -121
View File
@@ -2,39 +2,49 @@
[![Build Status](https://travis-ci.org/tbreloff/Plots.jl.svg?branch=master)](https://travis-ci.org/tbreloff/Plots.jl)
#### Author: Thomas Breloff (@tbreloff)
Plotting interface and wrapper for several plotting packages.
Please add wishlist items, bugs, or any other comments/questions to the issues list.
## Examples
## Examples for each implemented backend:
- [Qwt.jl](docs/qwt_examples.md)
- [Gadfly.jl](docs/gadfly_examples.md)
- [UnicodePlots.jl](docs/unicodeplots_examples.md)
## Installation
First, clone the package, and get any plotting packages you need:
First, clone the package
```
```julia
Pkg.clone("https://github.com/tbreloff/Plots.jl.git")
```
then get any plotting packages you need (obviously, you should get at least one backend):
```julia
Pkg.add("Gadfly") # [optional]
Pkg.clone("https://github.com/tbreloff/Qwt.jl.git") # [optional] requires pyqt and pyqwt
Pkg.add("UnicodePlots") # [optional]
```
## Use
Load it in. The underlying plotting backends are not imported until `plotter()` is called (which happens
on your first call to `plot`). This means that you don't need any backends to be installed when you call `using Plots`.
For now, the default backend is Gadfly.
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:
```
plot(rand(10,2); marker = :rect)
```julia
gadfly!()
plot(rand(10,2); marker = :rect) # this will bring up a browser window with the plot, set show=false if you don't want that
savepng(Plots.IMG_DIR * "gadfly1.png")
```
@@ -42,153 +52,188 @@ which saves:
![gadfly_plt](img/gadfly1.png)
See the examples pages for lots of ways to plot in every supported backend.
Do a plot in Qwt, then save a png:
## API
```
plotter!(:qwt) # switches the backend to Qwt
plot(rand(10,2); marker = :rect)
savepng(Plots.IMG_DIR * "qwt1.png")
```
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:
which saves:
![qwt_plt](img/qwt1.png)
## plot and plotter! interface (WIP)
The main plot command. Call `plotter!(:module)` to set the current plotting backend.
Commands are converted into the relevant plotting commands for that package:
```
plotter!(:gadfly)
plot(1:10) # this effectively calls `y = 1:10; Gadfly.plot(x=1:length(y), y=y)`
plotter!(:qwt)
plot(1:10) # this effectively calls `Qwt.plot(1:10)`
```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:
```
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`
```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.
Here are some various args to supply, and the implicit mapping (AVec == AbstractVector and AMat == AbstractMatrix):
```
plot(y::AVec; kw...) # one line... x = 1:length(y)
plot(x::AVec, y::AVec; kw...) # one line (will assert length(x) == length(y))
plot(y::AMat; kw...) # multiple lines (one per column of x), all sharing x = 1:size(y,1)
plot(x::AVec, y::AMat; kw...) # multiple lines (one per column of x), all sharing x (will assert length(x) == size(y,1))
plot(x::AMat, y::AMat; kw...) # multiple lines (one per column of x/y... will assert size(x) == size(y))
plot(x::AVec, f::Function; kw...) # one line, y = f(x)
plot(x::AMat, f::Function; kw...) # multiple lines, yᵢⱼ = f(xᵢⱼ)
plot(x::AVec, fs::AVec{Function}; kw...) # multiple lines, yᵢⱼ = fⱼ(xᵢ)
plot(y::AVec{AVec}; kw...) # multiple lines, each with x = 1:length(y[i])
plot(x::AVec, y::AVec{AVec}; kw...) # multiple lines, will assert length(x) == length(y[i])
plot(x::AVec{AVec}, y::AVec{AVec}; kw...) # multiple lines, will assert length(x[i]) == length(y[i])
plot(n::Integer; kw...) # n lines, all empty (for updating plots)
```julia
# one line... x = 1:length(y)
plot(y::AVec; kw...)
# TODO: how do we handle NA values in dataframes?
plot(df::DataFrame; kw...) # one line per DataFrame column, labels == names(df)
plot(df::DataFrame, columns; kw...) # one line per column, but on a subset of column names
# one line (will assert length(x) == length(y))
plot(x::AVec, y::AVec; kw...)
# 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
```
[TODO] You can swap out `plot` for `subplot`. Each line will go into a separate plot. Use the layout keyword:
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
```
y = rand(100,3)
subplot(y; layout=(2,2), kw...) # creates 3 lines going into 3 separate plots, laid out on a 2x2 grid (last row is filled with plot #3)
subplot(y; layout=(1,3), kw...) # again 3 plots, all in the same row
subplot(y; layout=[1,[2,3]]) # pass a nested Array to fully specify the layout. here the first plot will take up the first row,
# and the others will share the second 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:
```
scatter(args...; kw...) = plot(args...; kw..., linetype = :none, marker = :hexagon)
scatter!(args...; kw...) = plot!(args...; kw..., linetype = :none, marker = :hexagon)
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)
```julia
scatter(args...; kw...) = plot(args...; kw..., linetype = :none, marker = :hexagon)
scatter!(args...; kw...) = plot!(args...; kw..., linetype = :none, marker = :hexagon)
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)
```
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, :dots, :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)
show # true or false, show the plot (in case you don't want the window to pop up right away)
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, :dots, :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)
show # true or false, show the plot (in case you don't want the window to pop up right away)
```
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 = (800,600)
pos = (0,0)
windowtitle = ""
screen = 1
show = true
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 = (800,600)
pos = (0,0)
windowtitle = ""
screen = 1
show = true
```
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__: You can see the default value for a given argument with `plotDefault(arg::Symbol)`, and set the default value with `plotDefault!(arg::Symbol, value)`
```
plot(rand(100,2); colors = [:red, RGB(.5,.5,0)], axiss = [:left, :right], width = 5) # note the width=5 is applied to both lines
__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)
```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)
```
# TODO
- [x] Plot vectors/matrices/functions
- [ ] Plot DataFrames
- [ ] Subplots
- [ ] Histograms
- [ ] 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
@@ -207,18 +252,15 @@ When plotting multiple lines, you can give every line the same trait by using th
- [ ] TextPlots.jl
- [ ] ASCIIPlots.jl
- [ ] Sparklines.jl
- [ ] UnicodePlots.jl
- [x] UnicodePlots.jl
- [ ] Hinton.jl
- [ ] ImageTerm.jl
- [ ] GraphViz.jl
- [ ] TikzGraphs.jl
- [ ] GraphLayout.jl
# Backends
# More information on backends (both supported and unsupported)
See the wiki at: https://github.com/JuliaPlot/juliaplot_docs/wiki
# Author
Thomas Breloff (@tbreloff)
+19 -5
View File
@@ -23,8 +23,14 @@ const examples = PlotExample[
"A simple line plot of the 3 columns.",
[:(plot(rand(100,3)))]),
PlotExample("Functions",
"Plot multiple functions",
"Plot multiple functions.",
[:(plot(0:0.01:4π, [sin,cos]))]),
PlotExample("",
"You can also call it with plot(f, xmin, xmax).",
[:(plot([sin,cos], 0, 4π))]),
PlotExample("",
"Or make a parametric plot with plot(fx, fy, umin, umax).",
[:(plot(sin, x->sin(2x), 0, 2π))]),
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)))]),
@@ -45,7 +51,7 @@ const examples = PlotExample[
[:(heatmap(randn(10000),randn(10000); nbins=200))]),
PlotExample("Lots of line types",
"Options: (:line, :step, :stepinverted, :sticks, :dots, :none, :heatmap, :hexbin, :hist, :bar) \nNote: some may not work with all backends",
[:(plot(rand(20,4); linetypes=[:line, :step, :sticks, :dots]))]),
[:(plot(rand(20,4); linetypes=[:line, :step, :sticks, :dots], labels=["line","step","sticks","dots"]))]),
PlotExample("Bar",
"x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)",
[:(bar(randn(1000)))]),
@@ -78,6 +84,11 @@ function generate_markdown(pkgname::Symbol)
plotter!(pkgname)
plotDefault!(:show, false)
# mkdir if necessary
try
mkdir("$IMGDIR/$pkgname")
end
# open the markdown file
md = open("$DOCDIR/$(pkgname)_examples.md", "w")
@@ -90,13 +101,13 @@ function generate_markdown(pkgname::Symbol)
# save the png
imgname = "$(pkgname)_example_$i.png"
savepng("$IMGDIR/$imgname")
savepng("$IMGDIR/$pkgname/$imgname")
# write out the header, description, code block, and image link
write(md, "### $(example.header)\n\n")
write(md, "$(example.desc)\n\n")
write(md, "```julia\n$(join(map(string, example.exprs), "\n"))\n```\n\n")
write(md, "![](../img/$imgname)\n\n")
write(md, "![](../img/$pkgname/$imgname)\n\n")
catch ex
# TODO: put error info into markdown?
@@ -111,7 +122,10 @@ function generate_markdown(pkgname::Symbol)
end
# run it!
map(generate_markdown, (:qwt, :gadfly))
# note: generate separately so it's easy to comment out
generate_markdown(:qwt)
generate_markdown(:gadfly)
generate_markdown(:unicodeplots)
end # module
+38 -16
View File
@@ -6,17 +6,39 @@ A simple line plot of the 3 columns.
plot(rand(100,3))
```
![](../img/gadfly_example_1.png)
![](../img/gadfly/gadfly_example_1.png)
### Functions
Plot multiple functions
Plot multiple functions.
```julia
plot(0:0.01:4π,[sin,cos])
```
![](../img/gadfly_example_2.png)
![](../img/gadfly/gadfly_example_2.png)
###
You can also call it with plot(f, xmin, xmax).
```julia
plot([sin,cos],0,4π)
```
![](../img/gadfly/gadfly_example_3.png)
###
Or make a parametric plot with plot(fx, fy, umin, umax).
```julia
plot(sin,(x->begin # /Users/tom/.julia/v0.4/Plots/docs/example_generation.jl, line 33:
sin(2x)
end),0,2π)
```
![](../img/gadfly/gadfly_example_4.png)
### Global
@@ -26,7 +48,7 @@ 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))
```
![](../img/gadfly_example_3.png)
![](../img/gadfly/gadfly_example_5.png)
### Two-axis
@@ -38,7 +60,7 @@ Note: This is only supported with Qwt right now
plot(Vector[randn(100),randn(100) * 100]; axiss=[:left,:right])
```
![](../img/gadfly_example_4.png)
![](../img/gadfly/gadfly_example_6.png)
### Vectors w/ pluralized args
@@ -48,7 +70,7 @@ Plot multiple series with different numbers of points. Mix arguments that apply
plot(Vector[rand(10),rand(20)]; marker=:ellipse,markersize=8,colors=[:red,:blue])
```
![](../img/gadfly_example_5.png)
![](../img/gadfly/gadfly_example_7.png)
### Build plot in pieces
@@ -58,7 +80,7 @@ Start with a base plot...
plot(rand(100) / 3; reg=true,fillto=0)
```
![](../img/gadfly_example_6.png)
![](../img/gadfly/gadfly_example_8.png)
###
@@ -68,7 +90,7 @@ and add to it later.
scatter!(rand(100); markersize=6,color=:blue)
```
![](../img/gadfly_example_7.png)
![](../img/gadfly/gadfly_example_9.png)
### Heatmaps
@@ -78,7 +100,7 @@ scatter!(rand(100); markersize=6,color=:blue)
heatmap(randn(10000),randn(10000); nbins=200)
```
![](../img/gadfly_example_8.png)
![](../img/gadfly/gadfly_example_10.png)
### Lots of line types
@@ -86,10 +108,10 @@ Options: (:line, :step, :stepinverted, :sticks, :dots, :none, :heatmap, :hexbin,
Note: some may not work with all backends
```julia
plot(rand(20,4); linetypes=[:line,:step,:sticks,:dots])
plot(rand(20,4); linetypes=[:line,:step,:sticks,:dots],labels=["line","step","sticks","dots"])
```
![](../img/gadfly_example_9.png)
![](../img/gadfly/gadfly_example_11.png)
### Bar
@@ -99,7 +121,7 @@ x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints
bar(randn(1000))
```
![](../img/gadfly_example_10.png)
![](../img/gadfly/gadfly_example_12.png)
### Histogram
@@ -109,7 +131,7 @@ note: fillto isn't supported on all backends
histogram(randn(1000); nbins=50,fillto=20)
```
![](../img/gadfly_example_11.png)
![](../img/gadfly/gadfly_example_13.png)
### Subplots
@@ -124,7 +146,7 @@ histogram(randn(1000); nbins=50,fillto=20)
subplot(randn(100,5); layout=[1,1,3],linetypes=[:line,:hist,:dots,:step,:bar],nbins=10,legend=false)
```
![](../img/gadfly_example_12.png)
![](../img/gadfly/gadfly_example_14.png)
### Adding to subplots
@@ -134,7 +156,7 @@ Note here the automatic grid layout, as well as the order in which new series ar
subplot(randn(100,5); n=4)
```
![](../img/gadfly_example_13.png)
![](../img/gadfly/gadfly_example_15.png)
###
@@ -144,5 +166,5 @@ subplot(randn(100,5); n=4)
subplot!(randn(100,3))
```
![](../img/gadfly_example_14.png)
![](../img/gadfly/gadfly_example_16.png)
+38 -16
View File
@@ -6,17 +6,39 @@ A simple line plot of the 3 columns.
plot(rand(100,3))
```
![](../img/qwt_example_1.png)
![](../img/qwt/qwt_example_1.png)
### Functions
Plot multiple functions
Plot multiple functions.
```julia
plot(0:0.01:4π,[sin,cos])
```
![](../img/qwt_example_2.png)
![](../img/qwt/qwt_example_2.png)
###
You can also call it with plot(f, xmin, xmax).
```julia
plot([sin,cos],0,4π)
```
![](../img/qwt/qwt_example_3.png)
###
Or make a parametric plot with plot(fx, fy, umin, umax).
```julia
plot(sin,(x->begin # /Users/tom/.julia/v0.4/Plots/docs/example_generation.jl, line 33:
sin(2x)
end),0,2π)
```
![](../img/qwt/qwt_example_4.png)
### Global
@@ -26,7 +48,7 @@ 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))
```
![](../img/qwt_example_3.png)
![](../img/qwt/qwt_example_5.png)
### Two-axis
@@ -38,7 +60,7 @@ Note: This is only supported with Qwt right now
plot(Vector[randn(100),randn(100) * 100]; axiss=[:left,:right])
```
![](../img/qwt_example_4.png)
![](../img/qwt/qwt_example_6.png)
### Vectors w/ pluralized args
@@ -48,7 +70,7 @@ Plot multiple series with different numbers of points. Mix arguments that apply
plot(Vector[rand(10),rand(20)]; marker=:ellipse,markersize=8,colors=[:red,:blue])
```
![](../img/qwt_example_5.png)
![](../img/qwt/qwt_example_7.png)
### Build plot in pieces
@@ -58,7 +80,7 @@ Start with a base plot...
plot(rand(100) / 3; reg=true,fillto=0)
```
![](../img/qwt_example_6.png)
![](../img/qwt/qwt_example_8.png)
###
@@ -68,7 +90,7 @@ and add to it later.
scatter!(rand(100); markersize=6,color=:blue)
```
![](../img/qwt_example_7.png)
![](../img/qwt/qwt_example_9.png)
### Heatmaps
@@ -78,7 +100,7 @@ scatter!(rand(100); markersize=6,color=:blue)
heatmap(randn(10000),randn(10000); nbins=200)
```
![](../img/qwt_example_8.png)
![](../img/qwt/qwt_example_10.png)
### Lots of line types
@@ -86,10 +108,10 @@ Options: (:line, :step, :stepinverted, :sticks, :dots, :none, :heatmap, :hexbin,
Note: some may not work with all backends
```julia
plot(rand(20,4); linetypes=[:line,:step,:sticks,:dots])
plot(rand(20,4); linetypes=[:line,:step,:sticks,:dots],labels=["line","step","sticks","dots"])
```
![](../img/qwt_example_9.png)
![](../img/qwt/qwt_example_11.png)
### Bar
@@ -99,7 +121,7 @@ x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints
bar(randn(1000))
```
![](../img/qwt_example_10.png)
![](../img/qwt/qwt_example_12.png)
### Histogram
@@ -109,7 +131,7 @@ note: fillto isn't supported on all backends
histogram(randn(1000); nbins=50,fillto=20)
```
![](../img/qwt_example_11.png)
![](../img/qwt/qwt_example_13.png)
### Subplots
@@ -124,7 +146,7 @@ histogram(randn(1000); nbins=50,fillto=20)
subplot(randn(100,5); layout=[1,1,3],linetypes=[:line,:hist,:dots,:step,:bar],nbins=10,legend=false)
```
![](../img/qwt_example_12.png)
![](../img/qwt/qwt_example_14.png)
### Adding to subplots
@@ -134,7 +156,7 @@ Note here the automatic grid layout, as well as the order in which new series ar
subplot(randn(100,5); n=4)
```
![](../img/qwt_example_13.png)
![](../img/qwt/qwt_example_15.png)
###
@@ -144,5 +166,5 @@ subplot(randn(100,5); n=4)
subplot!(randn(100,3))
```
![](../img/qwt_example_14.png)
![](../img/qwt/qwt_example_16.png)
+160
View File
@@ -0,0 +1,160 @@
### Lines
A simple line plot of the 3 columns.
```julia
plot(rand(100,3))
```
![](../img/unicodeplots/unicodeplots_example_1.png)
### Functions
Plot multiple functions.
```julia
plot(0:0.01:4π,[sin,cos])
```
![](../img/unicodeplots/unicodeplots_example_2.png)
###
You can also call it with plot(f, xmin, xmax).
```julia
plot([sin,cos],0,4π)
```
![](../img/unicodeplots/unicodeplots_example_3.png)
###
Or make a parametric plot with plot(fx, fy, umin, umax).
```julia
plot(sin,(x->begin # /Users/tom/.julia/v0.4/Plots/docs/example_generation.jl, line 33:
sin(2x)
end),0,2π)
```
![](../img/unicodeplots/unicodeplots_example_4.png)
### Global
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))
```
![](../img/unicodeplots/unicodeplots_example_5.png)
### Two-axis
Use the `axis` or `axiss` arguments.
Note: This is only supported with Qwt right now
```julia
plot(Vector[randn(100),randn(100) * 100]; axiss=[:left,:right])
```
![](../img/unicodeplots/unicodeplots_example_6.png)
### 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`).
```julia
plot(Vector[rand(10),rand(20)]; marker=:ellipse,markersize=8,colors=[:red,:blue])
```
![](../img/unicodeplots/unicodeplots_example_7.png)
### Build plot in pieces
Start with a base plot...
```julia
plot(rand(100) / 3; reg=true,fillto=0)
```
![](../img/unicodeplots/unicodeplots_example_8.png)
###
and add to it later.
```julia
scatter!(rand(100); markersize=6,color=:blue)
```
![](../img/unicodeplots/unicodeplots_example_9.png)
### Lots of line types
Options: (:line, :step, :stepinverted, :sticks, :dots, :none, :heatmap, :hexbin, :hist, :bar)
Note: some may not work with all backends
```julia
plot(rand(20,4); linetypes=[:line,:step,:sticks,:dots],labels=["line","step","sticks","dots"])
```
![](../img/unicodeplots/unicodeplots_example_11.png)
### Bar
x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)
```julia
bar(randn(1000))
```
![](../img/unicodeplots/unicodeplots_example_12.png)
### Histogram
note: fillto isn't supported on all backends
```julia
histogram(randn(1000); nbins=50,fillto=20)
```
![](../img/unicodeplots/unicodeplots_example_13.png)
### Subplots
subplot and subplot! are distinct commands which create many plots and add series to them in a circular fashion.
You can define the layout with keyword params... either set the number of plots `n` (and optionally number of rows `nr` or
number of columns `nc`), or you can set the layout directly with `layout`.
Note: Gadfly is not very friendly here, and although you can create a plot and save a PNG, I haven't been able to actually display it.
```julia
subplot(randn(100,5); layout=[1,1,3],linetypes=[:line,:hist,:dots,:step,:bar],nbins=10,legend=false)
```
![](../img/unicodeplots/unicodeplots_example_14.png)
### Adding to subplots
Note here the automatic grid layout, as well as the order in which new series are added to the plots.
```julia
subplot(randn(100,5); n=4)
```
![](../img/unicodeplots/unicodeplots_example_15.png)
###
```julia
subplot!(randn(100,3))
```
![](../img/unicodeplots/unicodeplots_example_16.png)
Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

+6 -9
View File
@@ -27,7 +27,12 @@ export
histogram!,
heatmap!,
savepng
savepng,
backends,
qwt!,
gadfly!,
unicodeplots!
# ---------------------------------------------------------
@@ -39,15 +44,7 @@ const IMG_DIR = Pkg.dir("Plots") * "/img/"
include("types.jl")
include("utils.jl")
# ---------------------------------------------------------
include("qwt.jl")
include("gadfly.jl")
include("plotter.jl")
# ---------------------------------------------------------
include("args.jl")
include("plot.jl")
include("subplot.jl")
+5 -3
View File
@@ -96,8 +96,6 @@ function getPlotKeywordArgs(kw, idx::Int, n::Int)
# fill in d with either 1) plural value, 2) value, 3) default
for k in keys(PLOT_DEFAULTS)
plural = makeplural(k)
# if haskey(d, plural)
# d[k] = d[plural][idx]
if !haskey(d, k)
if n == 0 || k != :size
d[k] = haskey(d, plural) ? d[plural][idx] : PLOT_DEFAULTS[k]
@@ -125,7 +123,11 @@ function getPlotKeywordArgs(kw, idx::Int, n::Int)
# set label
label = d[:label]
d[:label] = string(label == "AUTO" ? "y_$n" : label, d[:axis] == :left ? "" : " (R)")
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
end
d
+7 -4
View File
@@ -3,6 +3,8 @@
immutable GadflyPackage <: PlottingPackage end
gadfly!() = plotter!(:gadfly)
# create a blank Gadfly.Plot object
function plot(pkg::GadflyPackage; kw...)
@@ -27,7 +29,7 @@ function plot(pkg::GadflyPackage; kw...)
plt.theme = Gadfly.Theme(background_color = (haskey(d, :background_color) ? d[:background_color] : colorant"white"))
Plot(plt, pkg, 0)
Plot(plt, pkg, 0, d, Dict[])
end
function getGeomFromLineType(linetype::Symbol, nbins::Int)
@@ -95,6 +97,9 @@ function plot!(::GadflyPackage, plt::Plot; kw...)
warn("Gadly only supports one y axis")
end
# save the kw args
push!(plt.seriesargs, d)
# add the layer to the Gadfly.Plot
prepend!(plt.o.layers, Gadfly.layer(unique(gfargs)...; x = x, y = d[:y]))
plt
@@ -115,9 +120,7 @@ end
# -------------------------------
# # create the underlying object (each backend will do this differently)
# o = buildSubplotObject(plts, pkg, layout)
# create the underlying object (each backend will do this differently)
function buildSubplotObject!(::GadflyPackage, subplt::Subplot)
i = 0
rows = []
+7 -4
View File
@@ -3,6 +3,8 @@
immutable QwtPackage <: PlottingPackage end
qwt!() = plotter!(:qwt)
# -------------------------------
function adjustQwtKeywords(iscreating::Bool; kw...)
@@ -24,13 +26,16 @@ end
function plot(pkg::QwtPackage; kw...)
kw = adjustQwtKeywords(true; kw...)
plt = Plot(Qwt.plot(zeros(0,0); kw..., show=false), pkg, 0)
o = Qwt.plot(zeros(0,0); kw..., show=false)
plt = Plot(o, pkg, 0, kw, Dict[])
plt
end
function plot!(::QwtPackage, plt::Plot; kw...)
kw = adjustQwtKeywords(false; kw...)
Qwt.oplot(plt.o; kw...)
push!(plt.seriesargs, kw)
plt
end
function Base.display(::QwtPackage, plt::Plot)
@@ -44,9 +49,7 @@ savepng(::QwtPackage, plt::PlottingObject, fn::String, args...) = Qwt.savepng(pl
# -------------------------------
# # create the underlying object (each backend will do this differently)
# o = buildSubplotObject(plts, pkg, layout)
# create the underlying object (each backend will do this differently)
function buildSubplotObject!(::QwtPackage, subplt::Subplot)
i = 0
rows = []
+161
View File
@@ -0,0 +1,161 @@
# https://github.com/Evizero/UnicodePlots.jl
immutable UnicodePlotsPackage <: PlottingPackage end
unicodeplots!() = plotter!(:unicodeplots)
# -------------------------------
function expandLimits!(lims, x)
e1, e2 = extrema(x)
lims[1] = min(lims[1], e1)
lims[2] = max(lims[2], e2)
nothing
end
# do all the magic here... build it all at once, since we need to know about all the series at the very beginning
function rebuildUnicodePlot!(plt::Plot)
# figure out the plotting area xlim = [xmin, xmax] and ylim = [ymin, ymax]
sargs = plt.seriesargs
xlim = [Inf, -Inf]
ylim = [Inf, -Inf]
for d in sargs
expandLimits!(xlim, d[:x])
expandLimits!(ylim, d[:y])
end
x = Float64[xlim[1]]
y = Float64[ylim[1]]
# create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds
iargs = plt.initargs
width, height = iargs[:size]
o = UnicodePlots.createPlotWindow(x, y; width = width,
height = height,
title = iargs[:title],
# labels = iargs[:legend],
xlim = xlim,
ylim = ylim)
# set the axis labels
UnicodePlots.xlabel!(o, iargs[:xlabel])
UnicodePlots.ylabel!(o, iargs[:ylabel])
# now use the ! functions to add to the plot
for d in sargs
addUnicodeSeries!(o, d, iargs[:legend])
end
# save the object
plt.o = o
end
# add a single series
function addUnicodeSeries!(o, d::Dict, addlegend::Bool)
# get the function, or special handling for step/bar/hist
lt = d[:linetype]
stepstyle = :post
if lt == :line
func = UnicodePlots.lineplot!
elseif lt == :dots || d[:marker] != :none
func = UnicodePlots.scatterplot!
elseif lt == :step
func = UnicodePlots.stairs!
elseif lt == :stepinverted
func = UnicodePlots.stairs!
stepstyle = :pre
else
error("Linestyle $lt not supported by UnicodePlots")
end
# get the series data and label
x, y = [collect(float(d[s])) for s in (:x, :y)]
label = addlegend ? d[:label] : ""
# if we happen to pass in allowed color symbols, great... otherwise let UnicodePlots decide
color = d[:color] in UnicodePlots.autoColors ? d[:color] : :auto
# add the series
func(o, x, y; color = color, name = label, style = stepstyle)
end
# -------------------------------
function plot(pkg::UnicodePlotsPackage; kw...)
plt = Plot(nothing, pkg, 0, Dict(kw), Dict[])
# do we want to give a new default size?
if !haskey(plt.initargs, :size) || plt.initargs[:size] == PLOT_DEFAULTS[:size]
plt.initargs[:size] = (60,20)
end
plt
end
function plot!(::UnicodePlotsPackage, plt::Plot; kw...)
d = Dict(kw)
if d[:linetype] in (:sticks, :bar)
d = barHack(; d...)
elseif d[:linetype] == :hist
d = barHack(; histogramHack(; d...)...)
end
push!(plt.seriesargs, d)
plt
end
function Base.display(::UnicodePlotsPackage, plt::Plot)
rebuildUnicodePlot!(plt)
show(plt.o)
end
# -------------------------------
function savepng(::UnicodePlotsPackage, plt::PlottingObject, fn::String, args...)
# make some whitespace and show the plot
println("\n\n\n\n\n\n")
display(plt)
@osx_only begin
# BEGIN HACK
# wait while the plot gets drawn
sleep(0.5)
# use osx screen capture when my terminal is maximized and cursor starts at the bottom (I know, right?)
# TODO: compute size of plot to adjust these numbers (or maybe implement something good??)
run(`screencapture -R50,600,700,420 $fn`)
# # some other attempts:
# run(`screencapture -w $fn`)
# using PyCall
# @pyimport pyscreenshot as pss
# END HACK (phew)
return
end
error("Can only savepng on osx with UnicodePlots (though even then I wouldn't do it)")
end
# -------------------------------
# we don't do very much for subplots... just stack them vertically
function buildSubplotObject!(::UnicodePlotsPackage, subplt::Subplot)
nothing
end
function Base.display(::UnicodePlotsPackage, subplt::Subplot)
for plt in subplt.plts
display(UnicodePlotsPackage(), plt)
end
end
+53 -128
View File
@@ -104,14 +104,6 @@ end
# this adds to a specific plot... most plot commands will flow through here
function plot!(plt::Plot, args...; kw...)
# # increment n if we're going directly to the package's plot method
# if length(args) == 0
# plt.n += 1
# end
# plot!(plt.plotter, plt, args...; kw...)
kwList = createKWargsList(plt, args...; kw...)
for (i,d) in enumerate(kwList)
plt.n += 1
@@ -150,6 +142,12 @@ function createKWargsList(plt::PlottingObject; kw...)
[getPlotKeywordArgs(d, 1, plt.n + 1)]
end
# ----------------------------------------------------------------------------
# Arrays of numbers
# ----------------------------------------------------------------------------
# create one series where y is vectors of numbers
function createKWargsList{T<:Real}(plt::PlottingObject, y::AVec{T}; kw...)
d = getPlotKeywordArgs(kw, 1, plt.n + 1)
@@ -208,6 +206,45 @@ function createKWargsList(plt::PlottingObject, x::AMat, y::AMat; kw...)
ret
end
# ----------------------------------------------------------------------------
# Functions
# ----------------------------------------------------------------------------
# create 1 series, y = f(x), x ∈ [xmin, xmax]
function createKWargsList(plt::PlottingObject, f::Function, xmin::Real, xmax::Real; kw...)
d = getPlotKeywordArgs(kw, 1, plt.n + 1)
width = plt.initargs[:size][1]
d[:x] = collect(linspace(xmin, xmax, width)) # we don't need more than the width
d[:y] = map(f, d[:x])
[d]
end
# create m series, yᵢ = fᵢ(x), x ∈ [xmin, xmax]
function createKWargsList(plt::PlottingObject, fs::Vector{Function}, xmin::Real, xmax::Real; kw...)
m = length(fs)
ret = []
width = plt.initargs[:size][1]
x = collect(linspace(xmin, xmax, width)) # we don't need more than the width
for i in 1:m
d = getPlotKeywordArgs(kw, i, plt.n + i)
d[:x] = x
d[:y] = map(fs[i], x)
push!(ret, d)
end
ret
end
# create 1 series, x = fx(u), y = fy(u); u ∈ [umin, umax]
function createKWargsList(plt::PlottingObject, fx::Function, fy::Function, umin::Real, umax::Real; kw...)
d = getPlotKeywordArgs(kw, 1, plt.n + 1)
width = plt.initargs[:size][1]
u = collect(linspace(umin, umax, width)) # we don't need more than the width
d[:x] = map(fx, u)
d[:y] = map(fy, u)
[d]
end
# create 1 series, y = f(x)
function createKWargsList(plt::PlottingObject, x::AVec, f::Function; kw...)
d = getPlotKeywordArgs(kw, 1, plt.n + 1)
@@ -215,6 +252,7 @@ function createKWargsList(plt::PlottingObject, x::AVec, f::Function; kw...)
d[:y] = map(f, x)
[d]
end
createKWargsList(plt::PlottingObject, f::Function, x::AVec; kw...) = createKWargsList(plt, x, f; kw...)
# create m series, y = f(x), 1 for each column of x
function createKWargsList(plt::PlottingObject, x::AMat, f::Function; kw...)
@@ -228,6 +266,13 @@ function createKWargsList(plt::PlottingObject, x::AMat, f::Function; kw...)
end
ret
end
createKWargsList(plt::PlottingObject, f::Function, x::AMat; kw...) = createKWargsList(plt, x, f; kw...)
# ----------------------------------------------------------------------------
# Other combinations... lists of vectors, etc
# ----------------------------------------------------------------------------
# create m series, 1 for each item in y (assumes vectors of something other than numbers... functions? vectors?)
function createKWargsList(plt::PlottingObject, y::AVec; kw...)
@@ -292,123 +337,3 @@ end
# -------------------------
# # most calls should flow through here now... we create a Dict with the keyword args for each series, and plot them
# function plot!(pkg::PlottingPackage, plt::Plot, args...; kw...)
# kwList = createKWargsList(plt, args...; kw...)
# for (i,d) in enumerate(kwList)
# plt.n += 1
# plot!(pkg, plt; d...)
# end
# plt
# end
# -------------------------
# # These methods are various ways to add to an existing plot
# function plot!{T<:Real}(pkg::PlottingPackage, plt::Plot, y::AVec{T}; kw...)
# plt.n += 1
# # plot!(pkg, plt; x = 1:length(y), y = y, getPlotKeywordArgs(kw, 1, plt)...)
# end
# function plot!{T<:Real,S<:Real}(pkg::PlottingPackage, plt::Plot, x::AVec{T}, y::AVec{S}; kw...) # one line (will assert length(x) == length(y))
# @assert length(x) == length(y)
# plt.n += 1
# plot!(pkg, plt; x=x, y=y, getPlotKeywordArgs(kw, 1, plt)...)
# end
# function plot!(pkg::PlottingPackage, plt::Plot, y::AMat; kw...) # multiple lines (one per column of x), all sharing x = 1:size(y,1)
# n,m = size(y)
# for i in 1:m
# plt.n += 1
# plot!(pkg, plt; x = 1:n, y = y[:,i], getPlotKeywordArgs(kw, i, plt)...)
# end
# plt
# end
# function plot!(pkg::PlottingPackage, plt::Plot, x::AVec, y::AMat; kw...) # multiple lines (one per column of x), all sharing x (will assert length(x) == size(y,1))
# n,m = size(y)
# for i in 1:m
# @assert length(x) == n
# plt.n += 1
# plot!(pkg, plt; x = x, y = y[:,i], getPlotKeywordArgs(kw, i, plt)...)
# end
# plt
# end
# function plot!(pkg::PlottingPackage, plt::Plot, x::AMat, y::AMat; kw...) # multiple lines (one per column of x/y... will assert size(x) == size(y))
# @assert size(x) == size(y)
# for i in 1:size(x,2)
# plt.n += 1
# plot!(pkg, plt; x = x[:,i], y = y[:,i], getPlotKeywordArgs(kw, i, plt)...)
# end
# plt
# end
# function plot!(pkg::PlottingPackage, plt::Plot, x::AVec, f::Function; kw...) # one line, y = f(x)
# plt.n += 1
# plot!(pkg, plt; x = x, y = map(f,x), getPlotKeywordArgs(kw, 1, plt)...)
# end
# function plot!(pkg::PlottingPackage, plt::Plot, x::AMat, f::Function; kw...) # multiple lines, yᵢⱼ = f(xᵢⱼ)
# for i in 1:size(x,2)
# xi = x[:,i]
# plt.n += 1
# plot!(pkg, plt; x = xi, y = map(f, xi), getPlotKeywordArgs(kw, i, plt)...)
# end
# plt
# end
# # function plot!(pkg::PlottingPackage, plt::Plot, x::AVec, fs::AVec{Function}; kw...) # multiple lines, yᵢⱼ = fⱼ(xᵢ)
# # for i in 1:length(fs)
# # plt.n += 1
# # plot!(pkg, plt; x = x, y = map(fs[i], x), getPlotKeywordArgs(kw, i, plt)...)
# # end
# # plt
# # end
# function plot!(pkg::PlottingPackage, plt::Plot, y::AVec; kw...) # multiple lines, each with x = 1:length(y[i])
# for i in 1:length(y)
# plt.n += 1
# plot!(pkg, plt; x = 1:length(y[i]), y = y[i], getPlotKeywordArgs(kw, i, plt)...)
# end
# plt
# end
# function plot!{T<:Real}(pkg::PlottingPackage, plt::Plot, x::AVec{T}, y::AVec; kw...) # multiple lines, will assert length(x) == length(y[i])
# for i in 1:length(y)
# if typeof(y[i]) <: AbstractVector
# @assert length(x) == length(y[i])
# plt.n += 1
# plot!(pkg, plt; x = x, y = y[i], getPlotKeywordArgs(kw, i, plt)...)
# elseif typeof(y[i]) == Function
# plt.n += 1
# plot!(pkg, plt; x = x, y = map(y[i], x), getPlotKeywordArgs(kw, 1, plt)...)
# end
# end
# plt
# end
# function plot!(pkg::PlottingPackage, plt::Plot, x::AVec, y::AVec; kw...) # multiple lines, will assert length(x[i]) == length(y[i])
# @assert length(x) == length(y)
# for i in 1:length(x)
# @assert length(x[i]) == length(y[i])
# plt.n += 1
# plot!(pkg, plt; x = x[i], y = y[i], getPlotKeywordArgs(kw, i, plt)...)
# end
# plt
# end
# function plot!(pkg::PlottingPackage, plt::Plot, n::Integer; kw...) # n lines, all empty (for updating plots)
# for i in 1:n
# plt.n += 1
# plot(pkg, plt, x = zeros(0), y = zeros(0), getPlotKeywordArgs(kw, i, plt)...)
# end
# end
# -------------------------
# # this is the core method... add to a plot object using kwargs, with args already converted into kwargs
# function plot!(pkg::PlottingPackage, plt::Plot; kw...)
# plot!(pl, plt; kw...)
# end
+52 -8
View File
@@ -1,5 +1,13 @@
include("backends/qwt.jl")
include("backends/gadfly.jl")
include("backends/unicodeplots.jl")
# ---------------------------------------------------------
plot(pkg::PlottingPackage; kw...) = error("plot($pkg; kw...) is not implemented")
plot!(pkg::PlottingPackage, plt::Plot; kw...) = error("plot!($pkg, plt; kw...) is not implemented")
Base.display(pkg::PlottingPackage, plt::Plot) = error("display($pkg, plt) is not implemented")
@@ -7,15 +15,35 @@ Base.display(pkg::PlottingPackage, plt::Plot) = error("display($pkg, plt) is not
# ---------------------------------------------------------
const AVAILABLE_PACKAGES = [:qwt, :gadfly]
const AVAILABLE_PACKAGES = [:qwt, :gadfly, :unicodeplots]
const INITIALIZED_PACKAGES = Set{Symbol}()
backends() = AVAILABLE_PACKAGES
type CurrentPackage
sym::Symbol
pkg::PlottingPackage
end
# const CURRENT_PACKAGE = CurrentPackage(:qwt, QwtPackage())
const CURRENT_PACKAGE = CurrentPackage(:gadfly, GadflyPackage())
function pickDefaultBackend()
try
Pkg.installed("Qwt")
return CurrentPackage(:qwt, QwtPackage())
end
try
Pkg.installed("Gadfly")
return CurrentPackage(:gadfly, GadflyPackage())
end
try
Pkg.installed("UnicodePlots")
return CurrentPackage(:unicodeplots, UnicodePlotsPackage())
end
warn("You don't have any of the supported backends installed! Chose from ", backends())
return CurrentPackage(:gadfly, GadflyPackage())
end
const CURRENT_PACKAGE = pickDefaultBackend()
println("[Plots.jl] Default backend: ", CURRENT_PACKAGE.sym)
# const CURRENT_PACKAGE = CurrentPackage(:gadfly, GadflyPackage())
doc"""
@@ -27,23 +55,37 @@ function plotter()
if !(currentPackageSymbol in INITIALIZED_PACKAGES)
# initialize
print("[Plots.jl] Initializing package: $CURRENT_PACKAGE... ")
println("[Plots.jl] Initializing package: ", CURRENT_PACKAGE.sym)
if currentPackageSymbol == :qwt
@eval import Qwt
try
@eval import Qwt
catch
error("Couldn't import Qwt. Install it with: Pkg.clone(\"https://github.com/tbreloff/Qwt.jl.git\")\n (Note: also requires pyqt and pyqwt)")
end
elseif currentPackageSymbol == :gadfly
@eval import Gadfly
try
@eval import Gadfly
catch
error("Couldn't import Gadfly. Install it with: Pkg.add(\"Gadfly\")")
end
elseif currentPackageSymbol == :unicodeplots
try
@eval import UnicodePlots
catch
error("Couldn't import UnicodePlots. Install it with: Pkg.add(\"UnicodePlots\")")
end
else
error("Unknown plotter $currentPackageSymbol. Choose from: $AVAILABLE_PACKAGES")
end
push!(INITIALIZED_PACKAGES, currentPackageSymbol)
println("done.")
println("[Plots.jl] done.")
end
CURRENT_PACKAGE.pkg
end
doc"""
Set the plot backend. Choose from: :qwt, :gadfly
Set the plot backend. Choose from: :qwt, :gadfly, :unicodeplots
"""
function plotter!(modname)
@@ -52,6 +94,8 @@ function plotter!(modname)
CURRENT_PACKAGE.pkg = QwtPackage()
elseif modname == :gadfly
CURRENT_PACKAGE.pkg = GadflyPackage()
elseif modname == :unicodeplots
CURRENT_PACKAGE.pkg = UnicodePlotsPackage()
else
error("Unknown plotter $modname. Choose from: $AVAILABLE_PACKAGES")
end
+5 -1
View File
@@ -8,7 +8,11 @@ abstract PlottingPackage
type Plot <: PlottingObject
o # the underlying object
plotter::PlottingPackage
n::Int # number of series
n::Int # number of series
# store these just in case
initargs::Dict
seriesargs::Vector{Dict} # args for each series
end
+2 -2
View File
@@ -13,7 +13,7 @@ try
facts("Gadfly") do
@fact plotter!(:gadfly) --> Plots.GadflyPackage()
@fact plotter() --> Plots.GadflyPackage()
@fact typeof(plot(1:10)) --> Plot
@fact typeof(plot(1:10)) --> Plots.Plot
# plot(x::AVec, y::AVec; kw...) # one line (will assert length(x) == length(y))
@@ -43,7 +43,7 @@ try
facts("Qwt") do
@fact plotter!(:qwt) --> Plots.QwtPackage()
@fact plotter() --> Plots.QwtPackage()
@fact typeof(plot(1:10)) --> Plot
@fact typeof(plot(1:10)) --> Plots.Plot
# plot(y::AVec; kw...) # one line... x = 1:length(y)
@fact plot(1:10) --> not(nothing)