# Unable to install GLMakie, StatsMakie... UndefVarError: AbstractBackend not defined

**URL:** https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434
**Category:** General Usage
**Created:** [December 7, 2018, 8:24pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434 "2018-12-07T20:24:28Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 7, 2018, 8:24pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/1 "2018-12-07T20:24:28Z")

</div>

Hello.

I’m trying to install StatsMakie on Windows 10 with Julia 1.0.2, but I’m getting errors:

```julia
Pkg.add(PackageSpec(url="https://github.com/JuliaPlots/GLMakie.jl.git")) 
Pkg.add(PackageSpec(url="https://github.com/JuliaPlots/Makie.jl.git")) 
Pkg.add(PackageSpec(url="https://github.com/JuliaPlots/AbstractPlotting.jl.git")) 
Pkg.add(PackageSpec(url="https://github.com/JuliaPlots/StatsMakie.jl.git")) 

```

and when I do  
using `GLMakie` I get this error:

```julia
using GLMakie
[Info: Precompiling GLMakie [e9467ef8-e4e7-5192-8a1a-b1aee30e663a]
ERROR: LoadError: UndefVarError: AbstractBackend not defined
Stacktrace:
 [1] getproperty(::Module, ::Symbol) at .\sysimg.jl:13
 [2] top-level scope at none:0
 [3] include at .\boot.jl:317 [inlined]
 [4] include_relative(::Module, ::String) at .\loading.jl:1044
 [5] include(::Module, ::String) at .\sysimg.jl:29
 [6] top-level scope at none:2
 [7] eval at .\boot.jl:319 [inlined]
 [8] eval(::Expr) at .\client.jl:393
 [9] top-level scope at .\none:3
in expression starting at C:\Users\joe\.julia\packages\GLMakie\30EXr\src\GLMakie.jl:21
ERROR: Failed to precompile GLMakie [e9467ef8-e4e7-5192-8a1a-b1aee30e663a] to C:\Users\joe\.julia\compiled\v1.0\GLMakie\nfnZR.ji.
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] macro expansion at .\logging.jl:311 [inlined]
 [3] compilecache(::Base.PkgId, ::String) at .\loading.jl:1190
 [4] macro expansion at .\logging.jl:309 [inlined]
 [5] _require(::Base.PkgId) at .\loading.jl:947
 [6] require(::Base.PkgId) at .\loading.jl:858
 [7] macro expansion at .\logging.jl:309 [inlined]
 [8] require(::Module, ::Symbol) at .\loading.jl:840

```

```julia
using Makie
WARNING: using Makie.AbstractPlotting in module Main conflicts with an existing identifier.

```

```julia
using StatsMakie
[Info: Precompiling StatsMakie [9d48ccf0-4268-5716-84ff-21228f561db3]
WARNING: could not import AbstractPlotting.used_attributes into StatsMakie
WARNING: could not import AbstractPlotting.combine into StatsMakie
WARNING: could not import AbstractPlotting.to_plotspec into StatsMakie
ERROR: LoadError: UndefVarError: PlotFunc not defined
Stacktrace:
 [1] include at .\boot.jl:317 [inlined]
 [2] include_relative(::Module, ::String) at .\loading.jl:1044
 [3] include(::Module, ::String) at .\sysimg.jl:29
 [4] top-level scope at none:2
 [5] eval at .\boot.jl:319 [inlined]
 [6] eval(::Expr) at .\client.jl:393
 [7] top-level scope at .\none:3
in expression starting at C:\Users\joe\.julia\packages\StatsMakie\UTjKs\src\StatsMakie.jl:6
ERROR: Failed to precompile StatsMakie [9d48ccf0-4268-5716-84ff-21228f561db3] to C:\Users\joe\.julia\compiled\v1.0\StatsMakie\FKwQI.ji.
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] macro expansion at .\logging.jl:311 [inlined]
 [3] compilecache(::Base.PkgId, ::String) at .\loading.jl:1190
 [4] macro expansion at .\logging.jl:309 [inlined]
 [5] _require(::Base.PkgId) at .\loading.jl:947
 [6] require(::Base.PkgId) at .\loading.jl:858
 [7] macro expansion at .\logging.jl:309 [inlined]
 [8] require(::Module, ::Symbol) at .\loading.jl:840

```

I’ve tried deleting uninstalling the packages and reinstalling again, also from the regular repository (instead of git) when available, the registry folder… with no luck.

---

<div class="post-metadata">

### Author: ![wsrinin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsrinin/32/7676_2.png) [@wsrinin](https://discourse.julialang.org/u/wsrinin)
#### Post date: [December 8, 2018, 7:40pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/2 "2018-12-08T19:40:36Z")

</div>

Try adding master version of the package. It is documented in this link

[https://nextjournal.com/sdanisch/makie-pkg3](https://nextjournal.com/sdanisch/makie-pkg3)

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 8, 2018, 8:33pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/3 "2018-12-08T20:33:56Z")

</div>

I tried this before specifying the “master” version but I have the same problem.

Anyway. If I just install from git doesn’t it automatically use the master version?

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [December 8, 2018, 8:40pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/4 "2018-12-08T20:40:35Z")

</div>

not sure, when in doubt, just check it 😉 those 3 packages need to be on master!

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 8, 2018, 8:42pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/5 "2018-12-08T20:42:56Z")

</div>

> [@Juan](#):
>
> Pkg.add(PackageSpec(url=“[GitHub - JuliaPlots/StatsMakie.jl: Statistical visualizations based on high performance plotting package Makie](https://github.com/JuliaPlots/StatsMakie.jl.git)”))

Unfortunatelly I’m still getting this error:

```julia

WARNING: could not import AbstractPlotting.used_attributes into StatsMakie
WARNING: could not import AbstractPlotting.combine into StatsMakie
WARNING: could not import AbstractPlotting.to_plotspec into StatsMakie
ERROR: LoadError: UndefVarError: PlotFunc not defined
Stacktrace:
 [1] include at .\boot.jl:317 [inlined]
 [2] include_relative(::Module, ::String) at .\loading.jl:1044
 [3] include(::Module, ::String) at .\sysimg.jl:29
 [4] top-level scope at none:2
 [5] eval at .\boot.jl:319 [inlined]
 [6] eval(::Expr) at .\client.jl:393
 [7] top-level scope at .\none:3
in expression starting at C:\Users\joe\.julia\packages\StatsMakie\UTjKs\src\StatsMakie.jl:6
ERROR: Failed to precompile StatsMakie [9d48ccf0-4268-5716-84ff-21228f561db3] to C:\Users\joe\.julia\compiled\v1.0\StatsMakie\FKwQI.ji.
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] macro expansion at .\logging.jl:311 [inlined]
 [3] compilecache(::Base.PkgId, ::String) at .\loading.jl:1190
 [4] macro expansion at .\logging.jl:309 [inlined]
 [5] _require(::Base.PkgId) at .\loading.jl:947
 [6] require(::Base.PkgId) at .\loading.jl:858
 [7] macro expansion at .\logging.jl:309 [inlined]
 [8] require(::Module, ::Symbol) at .\loading.jl:840

```

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [December 8, 2018, 9:08pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/6 "2018-12-08T21:08:18Z")

</div>

If you don’t follow the recommended commands to install the master version, there is no surprise that you still get different results 😉  
That’s what you should call:

```nohighlight
pkg"up; add AbstractPlotting#master GLMakie#master Makie#master https://github.com/JuliaPlots/StatsMakie.jl.git"

```

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 9, 2018, 12:04am UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/7 "2018-12-09T00:04:59Z")

</div>

> [@sdanisch](#):
>
> pkg"up; add AbstractPlotting#master GLMakie#master Makie#master [GitHub - JuliaPlots/StatsMakie.jl: Statistical visualizations based on high performance plotting package Makie](https://github.com/JuliaPlots/StatsMakie.jl.git)"

but I do follow these commands:

```julia
julia> using Pkg
julia> pkg"up; add AbstractPlotting#master GLMakie#master Makie#master https://github.com/JuliaPlots/StatsMakie.jl.git"
  Updating registry at `C:\Users\joe\.julia\registries\General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
  Updating git-repo `https://github.com/JuliaPlots/StatsMakie.jl.git`
  Updating git-repo `https://github.com/JuliaData/DataFrames.jl.git`
  Updating git-repo `https://github.com/JuliaPlots/Makie.jl.git`
  Updating git-repo `https://github.com/JuliaPlots/AbstractPlotting.jl.git`
  Updating git-repo `https://github.com/JuliaPlots/GLMakie.jl.git`
  Updating git-repo `https://github.com/JuliaLang/IJulia.jl.git`
  Updating git-repo `https://github.com/JuliaStats/GLM.jl.git`
  Updating git-repo `https://github.com/m-j-w/CpuId.jl.git`
 Resolving package versions...
  Updating `C:\Users\joe\.julia\environments\v1.0\Project.toml`
 [no changes]
  Updating `C:\Users\joe\.julia\environments\v1.0\Manifest.toml`
 [no changes]
  Updating git-repo `https://github.com/JuliaPlots/AbstractPlotting.jl.git`
  Updating git-repo `https://github.com/JuliaPlots/GLMakie.jl.git`
  Updating git-repo `https://github.com/JuliaPlots/Makie.jl.git`
  Updating git-repo `https://github.com/JuliaPlots/StatsMakie.jl.git`
[ Info: Assigning UUID 9d48ccf0-4268-5716-84ff-21228f561db3 to StatsMakie
 Resolving package versions...
  Updating `C:\Users\joe\.julia\environments\v1.0\Project.toml`
 [no changes]
  Updating `C:\Users\joe\.julia\environments\v1.0\Manifest.toml`
 [no changes]

julia> using Makie
julia> using AbstractPlotting
julia> using GLMakie
[Info: Precompiling GLMakie [e9467ef8-e4e7-5192-8a1a-b1aee30e663a]
ERROR: LoadError: UndefVarError: AbstractBackend not defined
Stacktrace:
 [1] getproperty(::Module, ::Symbol) at .\sysimg.jl:13
 [2] top-level scope at none:0
 [3] include at .\boot.jl:317 [inlined]
 [4] include_relative(::Module, ::String) at .\loading.jl:1044
 [5] include(::Module, ::String) at .\sysimg.jl:29
 [6] top-level scope at none:2
 [7] eval at .\boot.jl:319 [inlined]
 [8] eval(::Expr) at .\client.jl:393
 [9] top-level scope at .\none:3
in expression starting at C:\Users\joe\.julia\packages\GLMakie\30EXr\src\GLMakie.jl:21
ERROR: Failed to precompile GLMakie [e9467ef8-e4e7-5192-8a1a-b1aee30e663a] to C:\Users\joe\.julia\compiled\v1.0\GLMakie\nfnZR.ji.
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] macro expansion at .\logging.jl:311 [inlined]
 [3] compilecache(::Base.PkgId, ::String) at .\loading.jl:1190
 [4] macro expansion at .\logging.jl:309 [inlined]
 [5] _require(::Base.PkgId) at .\loading.jl:947
 [6] require(::Base.PkgId) at .\loading.jl:858
 [7] macro expansion at .\logging.jl:309 [inlined]
 [8] require(::Module, ::Symbol) at .\loading.jl:840

julia> using StatsMakie
[Info: Precompiling StatsMakie [9d48ccf0-4268-5716-84ff-21228f561db3]
WARNING: could not import AbstractPlotting.used_attributes into StatsMakie
WARNING: could not import AbstractPlotting.combine into StatsMakie
WARNING: could not import AbstractPlotting.to_plotspec into StatsMakie
ERROR: LoadError: UndefVarError: PlotFunc not defined
Stacktrace:
 [1] include at .\boot.jl:317 [inlined]
 [2] include_relative(::Module, ::String) at .\loading.jl:1044
 [3] include(::Module, ::String) at .\sysimg.jl:29
 [4] top-level scope at none:2
 [5] eval at .\boot.jl:319 [inlined]
 [6] eval(::Expr) at .\client.jl:393
 [7] top-level scope at .\none:3
in expression starting at C:\Users\joe\.julia\packages\StatsMakie\UTjKs\src\StatsMakie.jl:6
ERROR: Failed to precompile StatsMakie [9d48ccf0-4268-5716-84ff-21228f561db3] to C:\Users\joe\.julia\compiled\v1.0\StatsMakie\FKwQI.ji.
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] macro expansion at .\logging.jl:311 [inlined]
 [3] compilecache(::Base.PkgId, ::String) at .\loading.jl:1190
 [4] macro expansion at .\logging.jl:309 [inlined]
 [5] _require(::Base.PkgId) at .\loading.jl:947
 [6] require(::Base.PkgId) at .\loading.jl:858
 [7] macro expansion at .\logging.jl:309 [inlined]
 [8] require(::Module, ::Symbol) at .\loading.jl:840

```

What am I doing wrong?

---

<div class="post-metadata">

### Author: ![wsrinin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsrinin/32/7676_2.png) [@wsrinin](https://discourse.julialang.org/u/wsrinin)
#### Post date: [December 9, 2018, 3:58pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/8 "2018-12-09T15:58:15Z")

</div>

Hi Juan,

I don’t understand why you typing in `using Pkg` should not pressing `]` in the REPL enough? Once I am in that mode I am typing exactly what you have done above, which works for me after fixing some issues specific to MacOSX platform.

From the logging the error starts from line 21 in GLMakie.jl which is

```julia
struct GLBackend <: AbstractPlotting.AbstractBackend
end

```

The errors say that AbstractBackend is not defined. Can you try something like `pkg" build AbstractPlotting` and type something like

```julia
using AbstractPlotting

AbstractPlotting.AbstractBackend

```

and see what happens.

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 9, 2018, 4:46pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/9 "2018-12-09T16:46:10Z")

</div>

I also tried with ] instead, it’s the same, but I get the same message in two computers, one with Windows 10 and another one with Window 7.  
The installation itself doesn’t produce any error, but when I do “using” the compilation fails.

---

<div class="post-metadata">

### Author: ![wsrinin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsrinin/32/7676_2.png) [@wsrinin](https://discourse.julialang.org/u/wsrinin)
#### Post date: [December 9, 2018, 4:48pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/10 "2018-12-09T16:48:39Z")

</div>

Did you try

```julia
using AbstractPlotting

AbstractPlotting.AbstractBackend

```

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 9, 2018, 4:51pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/11 "2018-12-09T16:51:19Z")

</div>

> [@wsrinin](#):
>
> AbstractPlotting.AbstractBackend

```julia
julia> using AbstractPlotting

julia> AbstractPlotting.AbstractBackend
ERROR: UndefVarError: AbstractBackend not defined

```

---

<div class="post-metadata">

### Author: ![wsrinin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsrinin/32/7676_2.png) [@wsrinin](https://discourse.julialang.org/u/wsrinin)
#### Post date: [December 9, 2018, 4:57pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/12 "2018-12-09T16:57:58Z")

</div>

This means that the problem is that somehow AbstractBackend is not defined in AbstractPlotting which is really bizarre because clearly in the package AbstractPlotting AbstractBackend is defined. You can actually go in the AbstractPlotting package and see for yourself. In `display.jl`

```julia
struct PlotDisplay <: AbstractDisplay end

abstract type AbstractBackend end
function backend_display end

```

what version of Julia are you using?

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 9, 2018, 5:01pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/13 "2018-12-09T17:01:28Z")

</div>

More people have the same problem:  
[https://github.com/JuliaPlots/Makie.jl/issues/218](https://github.com/JuliaPlots/Makie.jl/issues/218)

I’m using Julia 1.0.2 on Windows. (Today Windows 10, but I have the same problema at work with Windows 7).

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 9, 2018, 5:05pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/14 "2018-12-09T17:05:51Z")

</div>

I can find a AbstractPlotting folder with several subfolders containing a display.jl file. I guess they have been created after each installation.

The content of the newest one is:

```julia
struct PlotDisplay <: AbstractDisplay end

abstract type AbstractBackend end
function backend_display end

"""
Currently available displays by backend
"""
const available_backends = AbstractBackend[]
const current_backend = Ref{Union{Missing,AbstractBackend}}(missing)
const use_display = Ref{Bool}(true)

function inline!(inline = true)
    use_display[] = !inline
end

function register_backend!(backend::AbstractBackend)
    push!(available_backends, backend)
    if(length(available_backends) == 1)
        current_backend[] = backend
    end
    nothing
end

const has_ffmpeg = Ref(false)

function __init__ ()
    pushdisplay(PlotDisplay())
    has_ffmpeg[] = try
        success(`ffmpeg -h`)
    catch
        false
    end
end

function Base.display(d::PlotDisplay, scene::Scene)
    use_display[] || throw(MethodError(display, (d, scene)))
    try
        return backend_display(current_backend[], scene)
    catch ex
        if ex isa MethodError && ex.f in (backend_display, backend_show)
            throw(MethodError(display, (d, scene)))
        else
            rethrow()
        end
    end
end

Base.showable(mime::MIME, scene::Scene) = backend_showable(current_backend[], mime, scene)

# have to be explicit with mimetypes to avoid ambiguity

function backend_show end
for M in (MIME"text/plain", MIME)
    @eval function Base.show(io::IO, m::$M, scene::Scene)
        res = get(io, :juno_plotsize, size(scene))
        resize!(scene, res...)
        update!(scene)
        return AbstractPlotting.backend_show(current_backend[], io, m, scene)
    end
end

function backend_showable(backend, m::MIME, scene::Scene)
    hasmethod(backend_show, Tuple{typeof(backend), IO, typeof(m), typeof(scene)})
end

# fallback show when no backend is selected
function backend_show(backend, io::IO, ::MIME"text/plain", scene::Scene)
    println(io, "Scene ($(size(scene, 1))px, $(size(scene, 2))px):")
    println(io, "events:")
    for field in fieldnames(Events)
        println(io, " ", field, ": ", to_value(getfield(scene.events, field)))
    end
    println(io, "plots:")
    for plot in scene.plots
        println(io, " *", typeof(plot))
    end
    print(io, "subscenes:")
    for subscene in scene.children
        print(io, "\n *scene($(size(subscene, 1))px, $(size(subscene, 2))px)")
    end
    return
end

function backend_show(backend, io::IO, ::MIME"text/plain", plot::Combined)
    println(io, typeof(plot))
    println(io, "plots:")
    for p in plot.plots
        println(io, " *", typeof(p))
    end
    print(io, "attributes:")
    for (k, v) in theme(plot)
        print(io, "\n $k : $(typeof(v))")
    end
end

function Base.show(io::IO, ::MIME"text/plain", plot::Atomic)
    println(io, typeof(plot))
    print(io, "attributes:")
    for (k, v) in theme(plot)
        print(io, "\n $k : $(typeof(to_value(v)))")
    end
end

# Stepper for generating progressive plot examples
mutable struct Stepper
    scene::Scene
    folder::String
    step::Int
end

function Stepper(scene, path)
    ispath(path) || mkpath(path)
    Stepper(scene, path, 1)
end

function FileIO.save(filename::String, scene::Scene)
    open(filename, "w") do s
        show(IOContext(s, :full_fidelity => true), MIME"image/png"(), scene)
    end
end
"""
    step!(s::Stepper)
steps through a `Makie.Stepper` and outputs a file with filename `filename-step.jpg`.
This is useful for generating progressive plot examples.
"""
function step!(s::Stepper)
    FileIO.save(joinpath(s.folder, basename(s.folder) * "-$(s.step).jpg"), s.scene)
    s.step += 1
    return s
end

"""
Record all window events that happen while executing function `f`
for `scene` and serializes them to `path`.
"""
function record_events(f, scene::Scene, path::String)
    display(scene)
    result = Vector{Pair{Float64, Pair{Symbol, Any}}}()
    for field in fieldnames(Events)
        on(getfield(scene.events, field)) do value
            value = isa(value, Set) ? copy(value) : value
            push!(result, time() => (field => value))
        end
    end
    f()
    open(path, "w") do io
        serialize(io, result)
    end
end

"""
Replays the serialized events recorded with `record_events` in `path` in `scene`.
"""
replay_events(scene::Scene, path::String) = replay_events(()-> nothing, scene, path)
function replay_events(f, scene::Scene, path::String)
    display(scene)
    events = open(io-> deserialize(io), path)
    sort!(events, by = first)
    for i in 1:length(events)
        t1, (field, value) = events[i]
        field == :mousedrag && continue
        if field == :mousebuttons
            Base.invokelatest() do
                getfield(scene.events, field)[] = value
            end
        else
            Base.invokelatest() do
                getfield(scene.events, field)[] = value
            end
        end
        f()
        yield()
        if i < length(events)
            t2, (field, value) = events[i + 1]
            # min sleep time 0.001
            (t2 - t1 > 0.001) && sleep(t2 - t1)
        end
    end
end

struct RecordEvents
    scene::Scene
    path::String
end

function Base.display(d::PlotDisplay, re::RecordEvents)
    display(d, re.scene)
end

struct VideoStream
    io
    process
    screen
    path::String
end

"""
    VideoStream(scene::Scene, dir = mktempdir(), name = "video")

returns a stream and a buffer that you can use to not allocate for new frames.
Use `add_frame!(stream, window, buffer)` to add new video frames to the stream.
Use `save(stream)` to save the video to 'dir/name.mkv'. You can also call
`save(stream, "mkv")`, `save(stream, "mp4")`, `save(stream, "gif")` or `save(stream, "webm")` to convert the stream to those formats.
"""
function VideoStream(scene::Scene)
    if !has_ffmpeg[]
        error("You can't create a video stream without ffmpeg installed.
         Please install ffmpeg, e.g. via https://ffmpeg.org/download.html.
         When you download the binaries, please make sure that you add the path to your PATH
         environment variable.
         On unix you can install ffmpeg with `sudo apt-get install ffmpeg`.
        ")
    end
    #codec = `-codec:v libvpx -quality good -cpu-used 0 -b:v 500k -qmin 10 -qmax 42 -maxrate 500k -bufsize 1000k -threads 8`
    dir = mktempdir()
    path = joinpath(dir, "$(gensym(:video)).mkv")
    screen = backend_display(current_backend[], scene)
    AbstractPlotting.update!(scene)
    _xdim, _ydim = widths(pixelarea(scene)[])
    xdim = _xdim % 2 == 0 ? _xdim : _xdim + 1
    ydim = _ydim % 2 == 0 ? _ydim : _ydim + 1
    process = open(`ffmpeg -loglevel quiet -f rawvideo -pixel_format rgb24 -r 24 -s:v $(xdim)x$(ydim) -i pipe:0 -vf vflip -y $path`, "w")
    VideoStream(process.in, process, screen, abspath(path))
end

function colorbuffer(x)
    error("colorbuffer not implemented for screen $(typeof(x))")
end

"""
Adds a video frame to the VideoStream
"""
function recordframe!(io::VideoStream)
    #codec = `-codec:v libvpx -quality good -cpu-used 0 -b:v 500k -qmin 10 -qmax 42 -maxrate 500k -bufsize 1000k -threads 8`
    frame = colorbuffer(io.screen)
    _xdim, _ydim = size(frame)
    xdim = _xdim % 2 == 0 ? _xdim : _xdim + 1
    ydim = _ydim % 2 == 0 ? _ydim : _ydim + 1
    frame_out = fill(RGB{N0f8}(1, 1, 1), ydim, xdim)
    for x in 1:_xdim, y in 1:_ydim
        c = frame[(_xdim + 1) - x, y]
        frame_out[y, x] = RGB{N0f8}(c)
    end
    write(io.io, frame_out)
    return
end

"""
    save(path::String, io::VideoStream)

Flushes the video stream and converts the file to the extension found in `path` which can
be `mkv` is default and doesn't need convert, `gif`, `mp4` and `webm`.
`mp4` is recommended for the internet, since it's the most supported format.
`webm` yields the smallest file size, `mp4` and `mk4` are marginally bigger and `gif`s are up to
6 times bigger with same quality!
"""
function save(path::String, io::VideoStream)
    close(io.process)
    wait(io.process)
    p, typ = splitext(path)
    if typ == ".mkv"
        cp(io.path, out)
    elseif typ == ".mp4"
        run(`ffmpeg -loglevel quiet -i $(io.path) -c:v libx264 -preset slow -crf 24 -pix_fmt yuv420p -c:a libvo_aacenc -b:a 128k -y $path`)
    elseif typ == ".webm"
        run(`ffmpeg -loglevel quiet -i $(io.path) -c:v libvpx-vp9 -threads 16 -b:v 2000k -c:a libvorbis -threads 16 -vf scale=iw:ih -y $path`)
    elseif typ == ".gif"
        filters = "fps=15,scale=iw:ih:flags=lanczos"
        palette_path = dirname(io.path)
        pname = joinpath(palette_path, "palette.bmp")
        isfile(pname) && rm(pname, force = true)
        run(`ffmpeg -loglevel quiet -i $(io.path) -vf "$filters,palettegen" -y $pname`)
        run(`ffmpeg -loglevel quiet -i $(io.path) -i $pname -lavfi "$filters [x]; [x][1:v] paletteuse" -y $path`)
        rm(pname, force = true)
    else
        rm(io.path)
        error("Video type $typ not known")
    end
    rm(io.path)
    return path
end

"""
    record(func, scene, path)
usage:
"example
    record(scene, "test.gif") do io
        for i = 1:100
            scene.plots[:color] = ...# animate scene
            recordframe!(io) # record a new frame
        end
    end
"
"""
function record(func, scene, path)
    io = VideoStream(scene)
    func(io)
    save(path, io)
end

"""
    record(func, scene, path, iter)
usage:
"example
    record(scene, "test.gif", 1:100) do i
        scene.plots[:color] = ...# animate scene
    end
"
"""
function record(func, scene, path, iter)
    io = VideoStream(scene)
    for i in iter
        t1 = time()
        func(i)
        recordframe!(io)
        diff = (1/24) - (time() - t1)
        if diff > 0.0
            sleep(diff)
        else
            yield()
        end
    end
    save(path, io)
end

function Base.show(io::IO, mime::MIME"text/html", vs::VideoStream)
    mktempdir() do dir
        path = finish(vs, joinpath(dir, "video.mp4"))
        print(
            io,
            """<video autoplay controls><source src="data:video/x-m4v;base64,""",
            base64encode(open(read, path)),
            """" type="video/mp4"></video>"""
        )
    end
end

```

---

<div class="post-metadata">

### Author: ![wsrinin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsrinin/32/7676_2.png) [@wsrinin](https://discourse.julialang.org/u/wsrinin)
#### Post date: [December 9, 2018, 5:37pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/15 "2018-12-09T17:37:09Z")

</div>

Alright, I have one last suggestion. This suggestion is similar to the last post in

[https://github.com/JuliaPlots/Makie.jl/issues/244](https://github.com/JuliaPlots/Makie.jl/issues/244)

Remove all the package so that you only have display.jl file.

```julia
pkg" rm Makie AbstractPlotting GLMakie; gc 
pkg" add Makie#master AbstractPlotting#master GLMakie#master 

```

If this fail, then I am run out of idea :(. T

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 9, 2018, 7:18pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/16 "2018-12-09T19:18:49Z")

</div>

OK, I’ going to try again. Thanks.

Anyway I’m confused because you insist in that syntax.

Don’t this two lines produce the same result?  
`pkg" add Makie#master`  
and  
`Pkg.add(PackageSpec(name="Makie", rev="master"))`

The second way is just the new syntax. Isn’t it?

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [December 9, 2018, 9:26pm UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/17 "2018-12-09T21:26:46Z")

</div>

> The second way is just the new syntax. Isn’t it?

I don’t think you would say, that it’s the new syntax - `] add Makie#master` is definitely the official way - I think the `PlotSpec` is pretty much just the lower level version of this.  
If you execute exactly those commands and abstractbackend isn’t defined, it’s 99% sure that you’re not on master of AbstractPlotting - for whatever reason 😉 Not sure what Pkg3 is doing in your case… But I guess rm + gc + add could help

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [December 10, 2018, 12:17am UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/18 "2018-12-10T00:17:05Z")

</div>

Look at  
[https://docs.julialang.org/en/v1/stdlib/Pkg/index.html#Pkg.add](https://docs.julialang.org/en/v1/stdlib/Pkg/index.html#Pkg.add)

```julia
Pkg.add("Example") # Add a package from registry
Pkg.add(PackageSpec(name="Example", version="0.3")) # Specify version
Pkg.add(PackageSpec(url="https://github.com/JuliaLang/Example.jl", rev="master")) # From url
Pkg.add(PackageSpec(url="/remote/mycompany/juliapackages/OurPackage"))` # From path (has to be a gitrepo)

```

I think I will wait some weeks for a new version or changes.  
I’ve already tried rm, gc and adding several times, with no luck.  
The add process doesn’t produce any error, the problem comes when I use “using”.

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [December 10, 2018, 8:53am UTC](https://discourse.julialang.org/t/unable-to-install-glmakie-statsmakie-undefvarerror-abstractbackend-not-defined/18434/19 "2018-12-10T08:53:30Z")

</div>

yes, it is a documented function! Still, it’s rather for CI - locally the preferred way is `]add Package#master`.  
If your Pkg refuses to install the version you ask it to, i have little hope that this will be solved by a new version 😉  
What’s the output of `]st`?
