diff --git a/docs/example_generation.jl b/docs/example_generation.jl index b0d74216..60df484b 100644 --- a/docs/example_generation.jl +++ b/docs/example_generation.jl @@ -43,6 +43,12 @@ const examples = PlotExample[ 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]))]), + 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))]), ] diff --git a/docs/gadfly_examples.md b/docs/gadfly_examples.md index 4513ec62..5efbf340 100644 --- a/docs/gadfly_examples.md +++ b/docs/gadfly_examples.md @@ -80,3 +80,23 @@ plot(rand(20,4); linetypes=[:line,:step,:sticks,:dots]) ![](../img/gadfly_example_8.png) +### Bar + +x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints) + +```julia +bar(randn(1000)) +``` + +![](../img/gadfly_example_9.png) + +### Histogram + +note: fillto isn't supported on all backends + +```julia +histogram(randn(1000); nbins=50,fillto=20) +``` + +![](../img/gadfly_example_10.png) + diff --git a/docs/qwt_examples.md b/docs/qwt_examples.md index d7910732..41d6b221 100644 --- a/docs/qwt_examples.md +++ b/docs/qwt_examples.md @@ -80,3 +80,23 @@ plot(rand(20,4); linetypes=[:line,:step,:sticks,:dots]) ![](../img/qwt_example_8.png) +### Bar + +x is the midpoint of the bar. (todo: allow passing of edges instead of midpoints) + +```julia +bar(randn(1000)) +``` + +![](../img/qwt_example_9.png) + +### Histogram + +note: fillto isn't supported on all backends + +```julia +histogram(randn(1000); nbins=50,fillto=20) +``` + +![](../img/qwt_example_10.png) + diff --git a/img/gadfly_example_1.png b/img/gadfly_example_1.png index 66abdf17..5f3ff3ac 100644 Binary files a/img/gadfly_example_1.png and b/img/gadfly_example_1.png differ diff --git a/img/gadfly_example_10.png b/img/gadfly_example_10.png new file mode 100644 index 00000000..6ef8b8fa Binary files /dev/null and b/img/gadfly_example_10.png differ diff --git a/img/gadfly_example_2.png b/img/gadfly_example_2.png index 85562f21..02320106 100644 Binary files a/img/gadfly_example_2.png and b/img/gadfly_example_2.png differ diff --git a/img/gadfly_example_3.png b/img/gadfly_example_3.png index 0c95c530..9c391552 100644 Binary files a/img/gadfly_example_3.png and b/img/gadfly_example_3.png differ diff --git a/img/gadfly_example_4.png b/img/gadfly_example_4.png index 418d9c92..734ed1e9 100644 Binary files a/img/gadfly_example_4.png and b/img/gadfly_example_4.png differ diff --git a/img/gadfly_example_5.png b/img/gadfly_example_5.png index 5216a218..51d0907f 100644 Binary files a/img/gadfly_example_5.png and b/img/gadfly_example_5.png differ diff --git a/img/gadfly_example_6.png b/img/gadfly_example_6.png index 2daf4ec2..48d09e3d 100644 Binary files a/img/gadfly_example_6.png and b/img/gadfly_example_6.png differ diff --git a/img/gadfly_example_7.png b/img/gadfly_example_7.png index bb65d4f6..aa7b6a1a 100644 Binary files a/img/gadfly_example_7.png and b/img/gadfly_example_7.png differ diff --git a/img/gadfly_example_8.png b/img/gadfly_example_8.png index 2dd3e944..40d215b3 100644 Binary files a/img/gadfly_example_8.png and b/img/gadfly_example_8.png differ diff --git a/img/gadfly_example_9.png b/img/gadfly_example_9.png new file mode 100644 index 00000000..317531b3 Binary files /dev/null and b/img/gadfly_example_9.png differ diff --git a/img/qwt_example_1.png b/img/qwt_example_1.png index 4c5838d1..06c9e4a8 100644 Binary files a/img/qwt_example_1.png and b/img/qwt_example_1.png differ diff --git a/img/qwt_example_10.png b/img/qwt_example_10.png new file mode 100644 index 00000000..f54f48eb Binary files /dev/null and b/img/qwt_example_10.png differ diff --git a/img/qwt_example_3.png b/img/qwt_example_3.png index 671e7b7e..1699bd45 100644 Binary files a/img/qwt_example_3.png and b/img/qwt_example_3.png differ diff --git a/img/qwt_example_4.png b/img/qwt_example_4.png index bc1463d5..fe17d098 100644 Binary files a/img/qwt_example_4.png and b/img/qwt_example_4.png differ diff --git a/img/qwt_example_5.png b/img/qwt_example_5.png index a778b9d6..f21b1c3c 100644 Binary files a/img/qwt_example_5.png and b/img/qwt_example_5.png differ diff --git a/img/qwt_example_6.png b/img/qwt_example_6.png index ce484d30..bba40e75 100644 Binary files a/img/qwt_example_6.png and b/img/qwt_example_6.png differ diff --git a/img/qwt_example_7.png b/img/qwt_example_7.png index 3e5c5880..ef4d3de2 100644 Binary files a/img/qwt_example_7.png and b/img/qwt_example_7.png differ diff --git a/img/qwt_example_8.png b/img/qwt_example_8.png index 02ea7786..348cfa50 100644 Binary files a/img/qwt_example_8.png and b/img/qwt_example_8.png differ diff --git a/img/qwt_example_9.png b/img/qwt_example_9.png new file mode 100644 index 00000000..81c01cb4 Binary files /dev/null and b/img/qwt_example_9.png differ diff --git a/src/Plots.jl b/src/Plots.jl index 75483eca..1eb2e166 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -74,6 +74,7 @@ include("plotter.jl") # --------------------------------------------------------- +include("utils.jl") include("args.jl") include("plot.jl") diff --git a/src/gadfly.jl b/src/gadfly.jl index a0684b1b..655fad78 100644 --- a/src/gadfly.jl +++ b/src/gadfly.jl @@ -30,12 +30,12 @@ function plot(pkg::GadflyPackage; kw...) Plot(plt, pkg, 0) end -function getGeomFromLineType(linetype::Symbol) +function getGeomFromLineType(linetype::Symbol, nbins::Int) linetype == :line && return Gadfly.Geom.line linetype == :dots && return Gadfly.Geom.point linetype == :bar && return Gadfly.Geom.bar linetype == :step && return Gadfly.Geom.step - linetype == :hist && return Gadfly.Geom.hist + linetype == :hist && return Gadfly.Geom.histogram(bincount=nbins) linetype == :none && return Gadfly.Geom.point # change this? are we usually pairing no line with scatterplots? linetype == :sticks && return Gadfly.Geom.bar error("linetype $linetype not currently supported with Gadfly") @@ -50,7 +50,7 @@ function getGeoms(linetype::Symbol, marker::Symbol, nbins::Int) else # for other linetypes, get the correct Geom - push!(geoms, getGeomFromLineType(linetype)) + push!(geoms, getGeomFromLineType(linetype, nbins)) # for any marker, add Geom.point if marker != :none @@ -96,7 +96,7 @@ function plot!(::GadflyPackage, plt::Plot; kw...) end # add the layer to the Gadfly.Plot - append!(plt.o.layers, Gadfly.layer(unique(gfargs)...; x = x, y = d[:y])) + prepend!(plt.o.layers, Gadfly.layer(unique(gfargs)...; x = x, y = d[:y])) plt end diff --git a/src/qwt.jl b/src/qwt.jl index 900e7baf..07ee29e9 100644 --- a/src/qwt.jl +++ b/src/qwt.jl @@ -3,26 +3,31 @@ immutable QwtPackage <: PlottingPackage end -function adjustQwtKeywords(; kw...) +function adjustQwtKeywords(iscreating::Bool; kw...) d = Dict(kw) + d[:heatmap_n] = d[:nbins] + if d[:linetype] == :hexbin d[:linetype] = :heatmap elseif d[:linetype] == :dots d[:linetype] = :none d[:marker] = :hexagon + elseif !iscreating && d[:linetype] == :bar + return barHack(; kw...) + elseif !iscreating && d[:linetype] == :hist + return barHack(; histogramHack(; kw...)...) end - d[:heatmap_n] = d[:nbins] d end function plot(pkg::QwtPackage; kw...) - kw = adjustQwtKeywords(;kw...) + kw = adjustQwtKeywords(true; kw...) plt = Plot(Qwt.plot(zeros(0,0); kw..., show=false), pkg, 0) plt end function plot!(::QwtPackage, plt::Plot; kw...) - kw = adjustQwtKeywords(;kw...) + kw = adjustQwtKeywords(false; kw...) Qwt.oplot(plt.o; kw...) end diff --git a/src/utils.jl b/src/utils.jl new file mode 100644 index 00000000..5a167a23 --- /dev/null +++ b/src/utils.jl @@ -0,0 +1,71 @@ + +calcMidpoints(edges::AbstractVector) = Float64[0.5 * (edges[i] + edges[i+1]) for i in 1:length(edges)-1] + +doc"Make histogram-like bins of data" +function binData(data, nbins) + lo, hi = extrema(data) + edges = collect(linspace(lo, hi, nbins+1)) + midpoints = calcMidpoints(edges) + buckets = Int[max(2, min(searchsortedfirst(edges, x), length(edges)))-1 for x in data] + counts = zeros(Int, length(midpoints)) + for b in buckets + counts[b] += 1 + end + edges, midpoints, buckets, counts +end + +doc""" +A hacky replacement for a histogram when the backend doesn't support histograms directly. +Convert it into a bar chart with the appropriate x/y values. +""" +function histogramHack(; kw...) + d = Dict(kw) + + # we assume that the y kwarg is set with the data to be binned, and nbins is also defined + edges, midpoints, buckets, counts = binData(d[:y], d[:nbins]) + d[:x] = midpoints + d[:y] = float(counts) + d[:linetype] = :bar + d[:fillto] = d[:fillto] == nothing ? 0.0 : d[:fillto] + d +end + +doc""" +A hacky replacement for a bar graph when the backend doesn't support bars directly. +Convert it into a line chart with fillto set. +""" +function barHack(; kw...) + d = Dict(kw) + midpoints = d[:x] + heights = d[:y] + fillto = d[:fillto] == nothing ? 0.0 : d[:fillto] + + # estimate the edges + dists = diff(midpoints) * 0.5 + edges = zeros(length(midpoints)+1) + for i in 1:length(edges) + if i == 1 + edge = midpoints[1] - dists[1] + elseif i == length(edges) + edge = midpoints[i-1] + dists[i-2] + else + edge = midpoints[i-1] + dists[i-1] + end + edges[i] = edge + end + + x = Float64[] + y = Float64[] + for i in 1:length(heights) + e1, e2 = edges[i:i+1] + append!(x, [e1, e1, e2, e2]) + append!(y, [fillto, heights[i], heights[i], fillto]) + end + + d[:x] = x + d[:y] = y + d[:linetype] = :line + d[:fillto] = fillto + d +end +