391 lines
16 KiB
Julia
391 lines
16 KiB
Julia
|
|
module PlotExamples
|
|
|
|
using Plots
|
|
using Colors
|
|
using Compat
|
|
|
|
const DOCDIR = Pkg.dir("Plots") * "/docs"
|
|
const IMGDIR = Pkg.dir("Plots") * "/img"
|
|
|
|
"""
|
|
Holds all data needed for a documentation example... header, description, and plotting expression (Expr)
|
|
"""
|
|
type PlotExample
|
|
header::@compat(AbstractString)
|
|
desc::@compat(AbstractString)
|
|
exprs::Vector{Expr}
|
|
end
|
|
|
|
|
|
|
|
# the examples we'll run for each
|
|
const examples = PlotExample[
|
|
PlotExample("Lines",
|
|
"A simple line plot of the columns.",
|
|
[
|
|
:(plot(Plots.fakedata(50,5), w=3))
|
|
]),
|
|
PlotExample("Functions, adding data, and animations",
|
|
"Plot multiple functions. You can also put the function first, or use the form `plot(f, xmin, xmax)` where f is a Function or AbstractVector{Function}.\n\nGet series data: `x, y = plt[i]`. Set series data: `plt[i] = (x,y)`. Add to the series with `push!`/`append!`.\n\nEasily build animations. (`convert` or `ffmpeg` must be available to generate the animation.) Use command `gif(anim, filename, fps=15)` to save the animation.",
|
|
[
|
|
:(p = plot([sin,cos], zeros(0), leg=false)),
|
|
:(anim = Animation()),
|
|
:(for x in linspace(0, 10π, 100)
|
|
push!(p, x, Float64[sin(x), cos(x)])
|
|
frame(anim)
|
|
end)
|
|
]),
|
|
PlotExample("Parametric plots",
|
|
"Plot function pair (x(u), y(u)).",
|
|
[
|
|
:(plot(sin, x->sin(2x), 0, 2π, line=4, leg=false, fill=(0,:orange)))
|
|
]),
|
|
PlotExample("Colors",
|
|
"Access predefined palettes (or build your own with the `colorscheme` method). Line/marker colors are auto-generated from the plot's palette, unless overridden. Set the `z` argument to turn on series gradients.",
|
|
[
|
|
:(y = rand(100)),
|
|
:(plot(0:10:100,rand(11,4),lab="lines",w=3, palette=:grays, fill=(0.5,:auto))),
|
|
:(scatter!(y, zcolor=abs(y-.5), m=(:heat,0.8,stroke(3,:green)), ms=10*abs(y-0.5)+3, lab="grad"))
|
|
]),
|
|
PlotExample("Global",
|
|
"Change the guides/background/limits/ticks. Convenience args `xaxis` and `yaxis` allow you to pass a tuple or value which will be mapped to the relevant args automatically. The `xaxis` below will be replaced with `xlabel` and `xlims` args automatically during the preprocessing step. You can also use shorthand functions: `title!`, `xaxis!`, `yaxis!`, `xlabel!`, `ylabel!`, `xlims!`, `ylims!`, `xticks!`, `yticks!`",
|
|
[
|
|
:(y = rand(20,3)),
|
|
:(plot(y, xaxis=("XLABEL",(-5,30),0:2:20,:flip), background_color = RGB(0.2,0.2,0.2), leg=false)),
|
|
:(hline!(mean(y,1)+rand(1,3), line=(4,:dash,0.6,[:lightgreen :green :darkgreen]))),
|
|
:(vline!([5,10])),
|
|
:(title!("TITLE")),
|
|
:(yaxis!("YLABEL", :log10))
|
|
]),
|
|
PlotExample("Two-axis",
|
|
"Use the `axis` arguments.\n\nNote: Currently only supported with Qwt and PyPlot",
|
|
[
|
|
:(plot(Vector[randn(100), randn(100)*100], axis = [:l :r], ylabel="LEFT", yrightlabel="RIGHT"))
|
|
]),
|
|
PlotExample("Arguments",
|
|
"Plot multiple series with different numbers of points. Mix arguments that apply to all series (marker/markersize) with arguments unique to each series (colors). Special arguments `line`, `marker`, and `fill` will automatically figure out what arguments to set (for example, we are setting the `linestyle`, `linewidth`, and `color` arguments with `line`.) Note that we pass a matrix of colors, and this applies the colors to each series.",
|
|
[
|
|
:(ys = Vector[rand(10), rand(20)]),
|
|
:(plot(ys, line=(:dot,4,[:black :orange]), marker=([:hex :d],12,0.8,stroke(3,:gray))))
|
|
]),
|
|
PlotExample("Build plot in pieces",
|
|
"Start with a base plot...",
|
|
[
|
|
:(plot(rand(100)/3, reg=true, fill=(0,:green)))
|
|
]),
|
|
PlotExample("",
|
|
"and add to it later.",
|
|
[
|
|
:(scatter!(rand(100), markersize=6, c=:orange))
|
|
]),
|
|
PlotExample("Heatmaps",
|
|
"",
|
|
[
|
|
:(heatmap(randn(10000),randn(10000), nbins=20))
|
|
]),
|
|
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, line=(types,3), lab=map(string,types), ms=15))
|
|
]),
|
|
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,Shape])'),
|
|
:(n = length(markers)),
|
|
:(x = linspace(0,10,n+2)[2:end-1]),
|
|
:(y = repmat(reverse(x)', n, 1)),
|
|
:(scatter(x, y, m=(8,:auto), lab=map(string,markers), bg=:linen))
|
|
]),
|
|
PlotExample("Bar",
|
|
"x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)",
|
|
[
|
|
:(bar(randn(999)))
|
|
]),
|
|
PlotExample("Histogram",
|
|
"",
|
|
[
|
|
:(histogram(randn(1000), nbins=20))
|
|
]),
|
|
PlotExample("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`.
|
|
""",
|
|
[
|
|
:(subplot(randn(100,5), layout=[1,1,3], t=[:line :hist :scatter :step :bar], nbins=10, leg=false))
|
|
]),
|
|
PlotExample("Adding to subplots",
|
|
"Note here the automatic grid layout, as well as the order in which new series are added to the plots.",
|
|
[
|
|
:(subplot(Plots.fakedata(100,10), n=4, palette=[:grays :blues :heat :lightrainbow], bg=[:orange :pink :darkblue :black]))
|
|
]),
|
|
PlotExample("",
|
|
"",
|
|
[
|
|
:(subplot!(Plots.fakedata(100,10)))
|
|
]),
|
|
PlotExample("Open/High/Low/Close",
|
|
"Create an OHLC chart. Pass in a vector of OHLC objects 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))
|
|
]),
|
|
PlotExample("Annotations",
|
|
"Currently only text annotations are supported. Pass in a tuple or vector-of-tuples: (x,y,text). `annotate!(ann)` is shorthand for `plot!(; annotation=ann)`",
|
|
[
|
|
:(y = rand(10)),
|
|
:(plot(y, ann=(3,y[3],text("this is #3",:left)))),
|
|
:(annotate!([(5,y[5],text("this is #5",16,:red,:center)),
|
|
(10,y[10],text("this is #10",:right,20,"courier"))]))
|
|
]),
|
|
PlotExample("Custom Markers",
|
|
"A `Plots.Shape` is a light wrapper around vertices of a polygon. For supported backends, pass arbitrary polygons as the marker shapes. Note: The center is (0,0) and the size is expected to be rougly the area of the unit circle.",
|
|
[
|
|
:(verts = [(-1.0,1.0),(-1.28,0.6),(-0.2,-1.4),(0.2,-1.4),(1.28,0.6),(1.0,1.0),
|
|
(-1.0,1.0),(-0.2,-0.6),(0.0,-0.2),(-0.4,0.6),(1.28,0.6),(0.2,-1.4),
|
|
(-0.2,-1.4),(0.6,0.2),(-0.2,0.2),(0.0,-0.2),(0.2,0.2),(-0.2,-0.6)])
|
|
:(plot(0.1:0.2:0.9, 0.7rand(5)+0.15,
|
|
l=(3,:dash,:lightblue),
|
|
m=(Shape(verts),30,RGBA(0,0,0,0.2)),
|
|
bg=:pink, fg=:darkblue,
|
|
xlim = (0,1), ylim=(0,1), leg=false))
|
|
])
|
|
|
|
]
|
|
|
|
|
|
function createStringOfMarkDownCodeValues(arr, prefix = "")
|
|
string("`", prefix, join(sort(map(string, arr)), "`, `$prefix"), "`")
|
|
end
|
|
createStringOfMarkDownSymbols(arr) = isempty(arr) ? "" : createStringOfMarkDownCodeValues(arr, ":")
|
|
|
|
|
|
function generate_markdown(pkgname::Symbol)
|
|
|
|
# set up the backend, and don't show the plots by default
|
|
pkg = backend(pkgname)
|
|
# default(:show, false)
|
|
|
|
# mkdir if necessary
|
|
try
|
|
mkdir("$IMGDIR/$pkgname")
|
|
end
|
|
|
|
# open the markdown file
|
|
md = open("$DOCDIR/$(pkgname)_examples.md", "w")
|
|
|
|
write(md, "## Examples for backend: $pkgname\n\n")
|
|
|
|
write(md, "### Initialize\n\n```julia\nusing Plots\n$(pkgname)()\n```\n\n")
|
|
|
|
|
|
for (i,example) in enumerate(examples)
|
|
|
|
try
|
|
|
|
# we want to always produce consistent results
|
|
srand(1234)
|
|
|
|
# run the code
|
|
map(eval, example.exprs)
|
|
|
|
# # save the png
|
|
# imgname = "$(pkgname)_example_$i.png"
|
|
|
|
# NOTE: uncomment this to overwrite the images as well
|
|
if i == 2
|
|
imgname = "$(pkgname)_example_$i.gif"
|
|
gif(anim, "$IMGDIR/$pkgname/$imgname", fps=15)
|
|
else
|
|
imgname = "$(pkgname)_example_$i.png"
|
|
png("$IMGDIR/$pkgname/$imgname")
|
|
end
|
|
|
|
# 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, "\n\n")
|
|
|
|
catch ex
|
|
# TODO: put error info into markdown?
|
|
warn("Example $pkgname:$i failed with: $ex")
|
|
end
|
|
|
|
#
|
|
end
|
|
|
|
write(md, "- Supported arguments: $(createStringOfMarkDownCodeValues(supportedArgs(pkg)))\n")
|
|
write(md, "- Supported values for axis: $(createStringOfMarkDownSymbols(supportedAxes(pkg)))\n")
|
|
write(md, "- Supported values for linetype: $(createStringOfMarkDownSymbols(supportedTypes(pkg)))\n")
|
|
write(md, "- Supported values for linestyle: $(createStringOfMarkDownSymbols(supportedStyles(pkg)))\n")
|
|
write(md, "- Supported values for marker: $(createStringOfMarkDownSymbols(supportedMarkers(pkg)))\n")
|
|
write(md, "- Is `subplot`/`subplot!` supported? $(subplotSupported(pkg) ? "Yes" : "No")\n\n")
|
|
|
|
write(md, "(Automatically generated: $(now()))")
|
|
close(md)
|
|
|
|
end
|
|
|
|
|
|
# make and display one plot
|
|
function test_examples(pkgname::Symbol, idx::Int; debug = true)
|
|
Plots._debugMode.on = debug
|
|
println("Testing plot: $pkgname:$idx:$(examples[idx].header)")
|
|
backend(pkgname)
|
|
backend()
|
|
map(eval, examples[idx].exprs)
|
|
plt = current()
|
|
gui(plt)
|
|
plt
|
|
end
|
|
|
|
# generate all plots and create a dict mapping idx --> plt
|
|
function test_examples(pkgname::Symbol; debug = false)
|
|
Plots._debugMode.on = debug
|
|
plts = Dict()
|
|
for i in 1:length(examples)
|
|
# if examples[i].header == "Subplots" && !subplotSupported()
|
|
# break
|
|
# end
|
|
|
|
try
|
|
plt = test_examples(pkgname, i, debug=debug)
|
|
plts[i] = plt
|
|
catch ex
|
|
# TODO: put error info into markdown?
|
|
warn("Example $pkgname:$i:$(examples[i].header) failed with: $ex")
|
|
end
|
|
end
|
|
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
|
|
# fill # fill 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)
|
|
|
|
|
|
|
|
@compat const _ltdesc = Dict(
|
|
:none => "No line",
|
|
:line => "Lines with sorted x-axis",
|
|
:path => "Lines",
|
|
:steppre => "Step plot (vertical then horizontal)",
|
|
:steppost => "Step plot (horizontal then vertical)",
|
|
:sticks => "Vertical lines",
|
|
:scatter => "Points, no lines",
|
|
:heatmap => "Colored regions by density",
|
|
:hexbin => "Similar to heatmap",
|
|
:hist => "Histogram (doesn't use x)",
|
|
:bar => "Bar plot (centered on x values)",
|
|
:hline => "Horizontal line (doesn't use x)",
|
|
:vline => "Vertical line (doesn't use x)",
|
|
:ohlc => "Open/High/Low/Close chart (expects y is AbstractVector{Plots.OHLC})",
|
|
:contour => "Contour lines (uses z)",
|
|
:path3d => "3D path (uses z)",
|
|
:scatter3d => "3D scatter plot (uses z)",
|
|
)
|
|
|
|
function buildReadme()
|
|
readme = readall("$DOCDIR/readme_template.md")
|
|
|
|
# build keyword arg table
|
|
table = "Keyword | Default | Type | Aliases \n---- | ---- | ---- | ----\n"
|
|
allseries = merge(Plots._seriesDefaults, @compat(Dict(:line=>nothing, :marker=>nothing, :fill=>nothing)))
|
|
allplots = merge(Plots._plotDefaults, @compat(Dict(:xaxis=>nothing, :yaxis=>nothing)))
|
|
alldefs = merge(allseries, allplots)
|
|
for k in Plots.sortedkeys(alldefs)
|
|
# for d in (Plots._seriesDefaults, Plots._plotDefaults)
|
|
# for k in Plots.sortedkeys(d)
|
|
aliasstr = createStringOfMarkDownSymbols(aliases(Plots._keyAliases, k))
|
|
table = string(table, "`:$k` | `$(alldefs[k])` | $(haskey(allseries,k) ? "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)
|
|
|
|
gadfly()
|
|
Plots.dumpSupportGraphs()
|
|
end
|
|
|
|
default(size=(500,300))
|
|
|
|
# run it!
|
|
# note: generate separately so it's easy to comment out
|
|
# @osx_only generate_markdown(:unicodeplots)
|
|
# generate_markdown(:qwt)
|
|
# generate_markdown(:gadfly)
|
|
# generate_markdown(:pyplot)
|
|
# generate_markdown(:immerse)
|
|
# generate_markdown(:winston)
|
|
|
|
|
|
end # module
|
|
|