TidierOrg / TidierPlots.jl

Tidier data visualization in Julia, modeled after the ggplot2 R package.
MIT License
196 stars 7 forks source link

`geom_line` and `geom_step` not matching ggplot2 behavior #91

Closed adknudson closed 2 months ago

adknudson commented 2 months ago

Describe the bug Right now there is no functional difference between geom_line and geom_path

To Reproduce In R:

xs <- runif(100, 0, 2*pi)
df <- data.frame(x = xs, y = sin(xs))
ggplot(df, aes(x, y)) + geom_line() # produces a nice sin graph
ggplot(df, aes(x, y)) + geom_path() # should produce a web-looking sin graph

In Julia

xs = collect(rand(100) * 2pi
df = DataFrame(x = xs, y = sin.(xs))
ggplot(df, @aes(x = x, y = y)) + geom_line() # produces a web-looking sin graph
ggplot(df, @aes(x = x, y = y)) + geom_path() # produces a web-looking sin graph

Expected behavior geom_line should "connect [the observations] in order of the variable on the x axis"

Solution Instead of plotting (x, y) as given, geom_line should first compute the sort permutation of x and plot (x[sp], y[sp]).

xs = collect(rand(100) * 2pi
df = DataFrame(x = xs, y = sin.(xs))
sp = sortperm(df.x)
df.xs = df.x[sp]
df.ys = df.y[sp]

ggplot(df, @aes(x = xs, y = ys)) + geom_line() # produces the sin graph

The same comments apply to geom_step which also sorts observations according to the x-axis

rdboyes commented 2 months ago

Fixed! There's a new column transform sort_by:

geom_line = geom_template("geom_line", ["x", "y"], :Lines; 
    column_transformations = Dict{Symbol, Pair{Vector{Symbol}, AesTransform}}(
        :y => [:y, :x]=>sort_by,
        :x => [:x, :x]=>sort_by
    )
)
ggplot(df, @aes(x = x, y = y)) + geom_path() 

image

ggplot(df, @aes(x = x, y = y)) + geom_line()

image