Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/hvband #1264

Merged
merged 1 commit into from
Nov 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ Each release typically has a number of minor bug fixes beyond what is listed her
# Version 1.x
* Add `Geom.blank` (#1345)
* Support DataFrames.jl 0.19 changes in indexing (#1318)
* Add `Geom.hband` and `Geom.vband` geometries (#1264)
* Allow elements of type `Measure` to pass through `coord.jl` and `statistics.jl` (#1264)



# Version 1.1.0
* Add `alpha` aesthetic, `Scale.alpha_continuous` and `Scale.alpha_discrete` (#1252)
* Add `limits=(min= , max= )` to `Stat.histogram` (#1249)
* Add dodged boxplots (#1246)
* Add `Stat.dodge` (#1240)
* Add `Stat.dodge` (#1240)
* `Stat.smooth(method=:lm)` confidence bands (#1231)
* Support AbstractVectors everywhere (e.g. `Guide.xticks(ticks=1:10)`) (#1293)

Expand All @@ -24,7 +26,7 @@ Each release typically has a number of minor bug fixes beyond what is listed her
# Version 0.8.0
* Add `linestyle` aesthetic (#1181)
* Add `Guide.shapekey` (#1156)
* `Geom.contour`: add support for `DataFrame` (#1150)
* `Geom.contour`: add support for `DataFrame` (#1150)

# Version 0.7.0

Expand All @@ -43,7 +45,7 @@ Each release typically has a number of minor bug fixes beyond what is listed her
# Version 0.6.4

* Regression testing tools (#1020)

# Version 0.6.3

* Wide format data (#1013)
Expand Down Expand Up @@ -234,5 +236,3 @@ Each release typically has a number of minor bug fixes beyond what is listed her
keys are wrapped automatically.

* Default Theme changes.


43 changes: 30 additions & 13 deletions docs/src/gallery/geometries.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,30 @@ p1 = plot(dataset("ggplot2", "mpg"),
Guide.annotation(compose(context(), text(6,4, "y=x", hleft, vtop), fill("red"))))

x = [20*rand(20); exp(-3)]
D = DataFrame(x=x, y= exp.(-0.5*asinh.(x).+5) .+ 2*randn(length(x)))
D = DataFrame(x=x, y= exp.(-0.5*asinh.(x).+5) .+ 2*randn(length(x)))
abline = Geom.abline(color="red", style=:dash)
p2 = plot(D, x=:x, y=:y, Geom.point, Scale.x_asinh, Scale.y_log,
intercept=[148], slope=[-0.5], abline)
hstack(p1, p2)
```

## [`Geom.band`](@ref), [`Geom.hband`](@ref), [`Geom.vband`](@ref)


```@example
using Colors, Dates, Gadfly, RDatasets

Dp = dataset("ggplot2","presidential")[3:end,:]
De = dataset("ggplot2","economics")
De.Unemploy /= 10^3

plot(De, x=:Date, y=:Unemploy, Geom.line,
layer(Dp, xmin=:Start, xmax=:End, Geom.vband, color=:Party),
Scale.color_discrete_manual("deepskyblue", "lightcoral"),
Coord.cartesian(xmin=Date("1965-01-01"), ymax=12),
Guide.xlabel("Time"), Guide.ylabel("Unemployment (x10³)"), Guide.colorkey(title=""),
Theme(default_color="black", key_position=:top))
```

## [`Geom.bar`](@ref)

Expand Down Expand Up @@ -75,7 +92,7 @@ set_default_plot_size(21cm, 8cm)
singers, salaries = dataset("lattice", "singer"), dataset("car","Salaries")
salaries.Salary /= 1000.0
salaries.Discipline = ["Discipline $(x)" for x in salaries.Discipline]
p1 = plot(singers, x=:VoicePart, y=:Height, Geom.boxplot,
p1 = plot(singers, x=:VoicePart, y=:Height, Geom.boxplot,
Theme(default_color="MidnightBlue"))
p2 = plot(salaries, x=:Discipline, y=:Salary, color=:Rank,
Scale.x_discrete(levels=["Discipline A", "Discipline B"]),
Expand Down Expand Up @@ -128,7 +145,7 @@ using Gadfly, RDatasets, Distributions
set_default_plot_size(14cm, 8cm)
dist = MixtureModel(Normal, [(0.5, 0.2), (1, 0.1)])
xs = rand(dist, 10^5)
plot(layer(x=xs, Geom.density, Theme(default_color="orange")),
plot(layer(x=xs, Geom.density, Theme(default_color="orange")),
layer(x=xs, Geom.density(bandwidth=0.0003), Theme(default_color="green")),
layer(x=xs, Geom.density(bandwidth=0.25), Theme(default_color="purple")),
Guide.manual_color_key("bandwidth", ["auto", "bw=0.0003", "bw=0.25"],
Expand Down Expand Up @@ -185,9 +202,9 @@ ys = mean.(rand.(Normal.(0, sds), n))
df = DataFrame(x=1:length(sds), y=ys,
mins=ys.-(1.96*sds/sqrt(n)), maxs=ys.+(1.96*sds/sqrt(n)),
g=repeat(["a","b"], inner=3))
p1 = plot(df, x=1:length(sds), y=:y, ymin=:mins, ymax=:maxs, color=:g,
p1 = plot(df, x=1:length(sds), y=:y, ymin=:mins, ymax=:maxs, color=:g,
Geom.point, Geom.errorbar)
p2 = plot(df, y=1:length(sds), x=:y, xmin=:mins, xmax=:maxs, color=:g,
p2 = plot(df, y=1:length(sds), x=:y, xmin=:mins, xmax=:maxs, color=:g,
Geom.point, Geom.errorbar)
hstack(p1, p2)
```
Expand All @@ -202,18 +219,18 @@ df = by(salaries, [:Rank,:Discipline], :Salary=>mean, :Salary=>std)
df.ymin, df.ymax = df.Salary_mean.-df.Salary_std, df.Salary_mean.+df.Salary_std
df.label = string.(round.(Int, df.Salary_mean))

p1 = plot(df, x=:Discipline, y=:Salary_mean, color=:Rank,
p1 = plot(df, x=:Discipline, y=:Salary_mean, color=:Rank,
Scale.x_discrete(levels=["Discipline A", "Discipline B"]),
ymin=:ymin, ymax=:ymax, Geom.errorbar, Stat.dodge,
Geom.bar(position=:dodge),
Geom.bar(position=:dodge),
Scale.color_discrete(levels=["Prof", "AssocProf", "AsstProf"]),
Guide.colorkey(title="", pos=[0.76w, -0.38h]),
Theme(bar_spacing=0mm, stroke_color=c->"black")
)
p2 = plot(df, y=:Discipline, x=:Salary_mean, color=:Rank,
p2 = plot(df, y=:Discipline, x=:Salary_mean, color=:Rank,
Coord.cartesian(yflip=true), Scale.y_discrete,
xmin=:ymin, xmax=:ymax, Geom.errorbar, Stat.dodge(axis=:y),
Geom.bar(position=:dodge, orientation=:horizontal),
Geom.bar(position=:dodge, orientation=:horizontal),
Scale.color_discrete(levels=["Prof", "AssocProf", "AsstProf"]),
Guide.yticks(orientation=:vertical), Guide.ylabel(nothing),
Theme(bar_spacing=0mm, stroke_color=c->"gray")
Expand Down Expand Up @@ -440,7 +457,7 @@ x, y = cumsum(randn(n)), cumsum(randn(n))
D = DataFrame(x1=x[1:end-1], y1=y[1:end-1], x2=x[2:end], y2=y[2:end], colv=1:n-1)
palettef(c::Float64) = get(ColorSchemes.viridis, c)

plot(D, x=:x1, y=:y1, xend=:x2, yend=:y2,
plot(D, x=:x1, y=:y1, xend=:x2, yend=:y2,
color = :colv, Geom.segment, Coord.cartesian(aspect_ratio=1.0),
Scale.color_continuous(colormap=palettef, minvalue=0, maxvalue=1000)
)
Expand Down Expand Up @@ -557,16 +574,16 @@ using Gadfly, RDatasets
set_default_plot_size(21cm, 8cm)

coord = Coord.cartesian(xmin=-2, xmax=2, ymin=-2, ymax=2)
p1 = plot(coord, z=(x,y)->x*exp(-(x^2+y^2)),
xmin=[-2], xmax=[2], ymin=[-2], ymax=[2],
p1 = plot(coord, z=(x,y)->x*exp(-(x^2+y^2)),
xmin=[-2], xmax=[2], ymin=[-2], ymax=[2],
# or: x=-2:0.25:2.0, y=-2:0.25:2.0,
Geom.vectorfield(scale=0.4, samples=17), Geom.contour(levels=6),
Scale.x_continuous(minvalue=-2.0, maxvalue=2.0),
Scale.y_continuous(minvalue=-2.0, maxvalue=2.0),
Guide.xlabel("x"), Guide.ylabel("y"), Guide.colorkey(title="z"))

volcano = Matrix{Float64}(dataset("datasets", "volcano"))
volc = volcano[1:4:end, 1:4:end]
volc = volcano[1:4:end, 1:4:end]
coord = Coord.cartesian(xmin=1, xmax=22, ymin=1, ymax=16)
p2 = plot(coord, z=volc, x=1.0:22, y=1.0:16,
Geom.vectorfield(scale=0.05), Geom.contour(levels=7),
Expand Down
8 changes: 4 additions & 4 deletions src/coord.jl
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ function apply_coordinate(coord::Cartesian, aess::Vector{Gadfly.Aesthetics},
for var in coord.xvars
for aes in aess
vals = getfield(aes, var)
vals === nothing && continue
(vals === nothing || eltype(vals) <: Measure) && continue
bjarthur marked this conversation as resolved.
Show resolved Hide resolved

if !isa(vals, AbstractArray)
vals = [vals]
Expand All @@ -172,7 +172,7 @@ function apply_coordinate(coord::Cartesian, aess::Vector{Gadfly.Aesthetics},
for var in coord.yvars
for aes in aess
vals = getfield(aes, var)
vals === nothing && continue
(vals === nothing || eltype(vals) <: Measure) && continue

# Outliers is an odd aesthetic that needs special treatment.
if var == :outliers
Expand Down Expand Up @@ -223,12 +223,12 @@ function apply_coordinate(coord::Cartesian, aess::Vector{Gadfly.Aesthetics},
ymin = coord.ymin === nothing ? ymin : coord.ymin
ymax = coord.ymax === nothing ? ymax : coord.ymax

if xmin === nothing || !isfinite(xmin)
if xmin === nothing || isa(xmin, Measure) || !isfinite(xmin)
xmin = 0.0
xmax = 1.0
end

if ymin === nothing || !isfinite(ymin)
if ymin === nothing || isa(ymin, Measure) || !isfinite(ymin)
ymin = 0.0
ymax = 1.0
end
Expand Down
28 changes: 28 additions & 0 deletions src/geom/hvband.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
Geom.band[(; orientation=:vertical)]

Draw bands across the plot canvas with a horizontal span specifed by `xmin` and `xmax` if `orientation` is `:vertical`, or a vertical span specified by `ymin` and `ymax` if the `orientation` is `:horizontal`.

This geometry is equivalent to [`Geom.rect`](@ref) with [`Stat.band`](@ref).
"""
band(; orientation=:vertical) = RectangularBinGeometry(Stat.band(orientation)) #TODO: use RectangularGeometry when it becomes available.


"""
Geom.hband[()]

Draw horizontal bands across the plot canvas with a vertical span specified by `ymin` and `ymax` aesthetics.

This geometry is equivalent to [`Geom.band`](@ref) with `orientation` set to `:vertical`.
"""
hband() = band(orientation = :horizontal)


"""
Geom.vband[()]

Draw vertical bands across the plot canvas with a horizontal span specified by `xmin` and `xmax` aesthetics.

This geometry is equivalent to [`Geom.band`](@ref).
"""
const vband = band
1 change: 1 addition & 0 deletions src/geometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ include("geom/boxplot.jl")
include("geom/errorbar.jl")
include("geom/hexbin.jl")
include("geom/hvabline.jl")
include("geom/hvband.jl")
include("geom/label.jl")
include("geom/line.jl")
include("geom/point.jl")
Expand Down
45 changes: 44 additions & 1 deletion src/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,49 @@ apply_statistic(stat::Identity,
"""
const identity = Identity

struct BandStatistic <: Gadfly.StatisticElement
orientation::Symbol # :horizontal or :vertical
end

function BandStatistic(; orientation=:vertical)
return BandStatistic(orientation)
end

input_aesthetics(stat::BandStatistic) = [:xmin, :xmax, :ymin, :ymax]
output_aesthetics(stat::BandStatistic) = [:xmin, :xmax, :ymin, :ymax]
default_scales(stat::BandStatistic) = [Scale.x_continuous(), Scale.y_continuous()]

"""
Stat.band[(; orientation=:vertical)]

Transform points in $(aes2str(input_aesthetics(band()))) into rectangles in
$(aes2str(output_aesthetics(band()))). Used by [`Geom.band`](@ref Gadfly.Geom.band).
"""
const band = BandStatistic

function apply_statistic(stat::BandStatistic,
scales::Dict{Symbol, Gadfly.ScaleElement},
coord::Gadfly.CoordinateElement,
aes::Gadfly.Aesthetics)

if stat.orientation == :horizontal

n = max(length(aes.ymin)) #Note: already passed check for equal lengths.

aes.xmin = fill(0w, n)
aes.xmax = fill(1w, n)

elseif stat.orientation == :vertical

n = max(length(aes.xmin)) #Note: already passed check for equal lengths.

aes.ymin = fill(0h, n)
aes.ymax = fill(1h, n)

else
error("Orientation must be :horizontal or :vertical")
end
end

# Determine bounds of bars positioned at the given values.
function barminmax(vals, iscontinuous::Bool)
Expand Down Expand Up @@ -779,7 +822,7 @@ function apply_statistic(stat::TickStatistic,
for var in in_vars
categorical && !in(var,[:x,:y]) && continue
vals = getfield(aes, var)
if vals != nothing && eltype(vals) != Function
if vals != nothing && eltype(vals) != Function && !(eltype(vals) <: Measure)
if minval == nothing
minval = first(vals)
end
Expand Down
8 changes: 8 additions & 0 deletions test/testscripts/hvband.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Gadfly
set_default_plot_size(21cm, 8cm)

p1 = plot(xmin=[1.0, 5.0, 7.0], xmax=[2.0, 6.5, 8.0] , Geom.vband, Theme(default_color="green"));

p2 = plot(ymin=[2.5], ymax=[7.5], Geom.hband, Theme(default_color="red"));

hstack(p1, p2)