# Plots in the terminal (with sixel)

**URL:** <https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503>\
**Category:** Visualization\
**Tags:** plotting, repl\
**Created:** [March 29, 2019, 2:58pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503 "2019-03-29T14:58:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alexander-Barth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander-barth/32/3692_2.png) [@Alexander-Barth](https://discourse.julialang.org/u/Alexander-Barth)\
**Post date:** [March 29, 2019, 2:58pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/1 "2019-03-29T14:58:45Z")

</div>

I just came across “sixel” which allows to show graphics in the terminal (while reading this [GitHub - csdvrx/sixel-gnuplot: GNUplot with sixel support](https://github.com/csdvrx/sixel-gnuplot) )

Unfortunately, gnome-terminal does not support this ([Bug 729204 – sixel support](https://bugzilla.gnome.org/show_bug.cgi?id=729204)), but xterm (run as `xterm -ti vt340`) does.

In fact it does not take much to use this with julia and PyPlot (or any other plotting package), just the `convert` tool from ImageMagic.

I started Julia with `unset DISPLAY` (on Linux)

```julia
using PyPlot
plt.style.use("dark_background")
function show()
   fname = tempname() * ".png";
   savefig(fname)
   run(`convert $fname -geometry 800x480 sixel:-`)
   return nothing
end
x = 1:0.1:10;
pcolor(sin.(x) * sin.(x)');
show()

```

 ![Bildschirmfoto%20von%202019-03-29%2015-50-34](https://global.discourse-cdn.com/julialang/original/3X/d/5/d5d354f9f5be095022eaa6fb22d751edd204ab24.png)

Off-topic, but also useful is `lsix`: “ls” for images ([GitHub - hackerb9/lsix: Like "ls", but for images. Shows thumbnails in terminal using sixel graphics.](https://github.com/hackerb9/lsix))

---

<div class="post-metadata">

**Author:** ![tshort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tshort/32/43_2.png) [@tshort](https://discourse.julialang.org/u/tshort)\
**Post date:** [March 29, 2019, 7:38pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/2 "2019-03-29T19:38:14Z")

</div>

You could also try the unregistered [https://github.com/tshort/SixelTerm.jl](https://github.com/tshort/SixelTerm.jl). It uses ImageMagick.

---

<div class="post-metadata">

**Author:** ![Alexander-Barth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander-barth/32/3692_2.png) [@Alexander-Barth](https://discourse.julialang.org/u/Alexander-Barth)\
**Post date:** [March 29, 2019, 8:08pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/3 "2019-03-29T20:08:38Z")

</div>

SixelTerm.jl is really nice! Thanks for sharing! It is quite impressive what you can do with 30 lines of code in SixelTerm.jl.

---

<div class="post-metadata">

**Author:** ![jheinen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jheinen/32/2787_2.png) [@jheinen](https://discourse.julialang.org/u/jheinen)\
**Post date:** [March 29, 2019, 8:47pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/4 "2019-03-29T20:47:54Z")

</div>

GR has builtin sixel support:

```julia
using GR
inline("iterm")
contourf(peaks())

```

 ![59](https://global.discourse-cdn.com/julialang/original/3X/1/a/1a308de74090f5fa34b01eb6b75fd2b02fb80279.jpeg)

Could also be integrated into `Plots` `gr()` backend - just let me know …

---

<div class="post-metadata">

**Author:** ![Alexander-Barth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexander-barth/32/3692_2.png) [@Alexander-Barth](https://discourse.julialang.org/u/Alexander-Barth)\
**Post date:** [March 29, 2019, 9:08pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/5 "2019-03-29T21:08:43Z")

</div>

It could also be useful to overload the display function to make a plot for long vector and a heatmap for large matrices. I think I will use the feature at lot more!

```julia
ENV["GKSwstype"] = "nul" # needed for the GR backend on headless servers
using Plots
using SixelTerm
using NCDatasets

function Base.display(x::Matrix{T}) where T <: Union{Number,Union{Missing,Number}}
    if length(x) < 300
        invoke(display, Tuple{AbstractMatrix}, x)
    else
        display(heatmap(coalesce.(x,NaN)', color=:lightrainbow))
    end
end

ds = Dataset("/home/abarth/Data/DivaData/Global/gebco_30sec_16.nc");
bathymetry = ds["bat"][:,:] # returns a Array{Union{Missing, Float32},2}

```

 ![Screenshot_sixel](https://global.discourse-cdn.com/julialang/original/3X/3/4/3457322857a598711dfa01c0038ecf0c7ac686fb.png)

---

<div class="post-metadata">

**Author:** ![jheinen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jheinen/32/2787_2.png) [@jheinen](https://discourse.julialang.org/u/jheinen)\
**Post date:** [March 29, 2019, 9:34pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/6 "2019-03-29T21:34:00Z")

</div>

… no need to overload `display` in GR: 😀

 ![14](https://global.discourse-cdn.com/julialang/original/3X/b/d/bd52d275aaed1d71bf7ad470735bda244510a2cf.jpeg)

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [March 30, 2019, 12:03am UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/7 "2019-03-30T00:03:24Z")

</div>

Not in the REPL but I still prefer

```julia
using GMT
grdimage("@earth_relief_05m.grd", proj=:Winkel, fmt=:png, show=true)

```

 ![wrld](https://global.discourse-cdn.com/julialang/original/3X/9/0/90f12eab3858222e87d5c9d8aed444d8493e2d17.png)

---

<div class="post-metadata">

**Author:** ![simonschoelly](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonschoelly/32/21606_2.png) [@simonschoelly](https://discourse.julialang.org/u/simonschoelly)\
**Post date:** [March 30, 2019, 8:09am UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/8 "2019-03-30T08:09:40Z")

</div>

But if I see that correctly, this means, that `GR.jl` can only plot using terminals that are hard coded in `GR.jl`, right`

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 30, 2019, 9:35am UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/9 "2019-03-30T09:35:42Z")

</div>

I ran into some pages in Japanese when looking for the details of the sixel generation algorithm so I cannot judge how complex it is, but I am wondering if it would make sense to have a native Julia implementation. It would have obvious advantages for all packages using this functionality, and could also serve as a nice reference.

---

<div class="post-metadata">

**Author:** ![jheinen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jheinen/32/2787_2.png) [@jheinen](https://discourse.julialang.org/u/jheinen)\
**Post date:** [March 30, 2019, 4:50pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/10 "2019-03-30T16:50:09Z")

</div>

GR.jl is only a wrapper for the GR framework. Any software that uses GR.jl can produce sixel graphics. It’s just about converting an internally rendered image to sixels …

Thus, it can be used from Julia, Python C, or whatever.

---

<div class="post-metadata">

**Author:** ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)\
**Post date:** [April 1, 2019, 8:50pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/11 "2019-04-01T20:50:02Z")

</div>

The latest release of [Gaston](https://github.com/mbaz/Gaston.jl) also supports sixel:

 ![sixel](https://global.discourse-cdn.com/julialang/original/3X/0/a/0af9820eebb19c1d5fd9a3779d5a646573e700c9.png)

I had had experimental support for a while, but this thread motivated me to finish it up. Also, since gnuplot has native sixel support, no external libraries or converters are needed.

---

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [April 30, 2019, 11:05pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/12 "2019-04-30T23:05:49Z")

</div>

This really seems like the minimum time to first plot after UnicodePlots! GR doesn’t appear to have a `spy()` for sparse matrices. I put this together quickly to plot sparsity patterns in iTerm2 and it’s great:

```julia
function spy(A::AbstractSparseMatrix)
  nrows, ncols = size(A)
  rows, cols, vals = findnz(A)
  avals = abs.(vals)
  scatter(cols, rows, 50 * ones(length(rows)), 255 * avals ./ maximum(avals), xlim=(1, ncols), ylim=(1, nrows), yflip=true)
end

```

This could be a great alias for `show()` for sparse matrices in terminals that support it.  
However, I’m not finding a convenient reference for keyword arguments accepted by GR. How do I

- adjust the aspect ratio to match the matrix?
- choose my own x and y ticks?
- remove the background grid?

![56](https://global.discourse-cdn.com/julialang/original/3X/9/f/9fed34f3fe097adf22b913d141c9ca3ce66311dc.png)

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [May 4, 2019, 11:07am UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/13 "2019-05-04T11:07:33Z")

</div>

I would like to be able to set an environment variable that makes the sixel terminal display default for all plotting packages, so that when I load any plotting package I don’t need to configure.

---

<div class="post-metadata">

**Author:** ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)\
**Post date:** [May 5, 2019, 1:20am UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/14 "2019-05-05T01:20:33Z")

</div>

In the meantime, remember that you can add configuration commands to your `~/.juliarc` file.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [May 5, 2019, 1:35am UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/15 "2019-05-05T01:35:53Z")

</div>

That would require loading a plotting package each time I launch Julia, which I definitely don’t want in my startup file.

Currently, enabling sixel requires setting an option after loading the package.

The point of having an environment variable is to pre-set the option before any plotting package is loaded, so that I can choose to load plotting whenever I need it, without worrying about enabling sixel.

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [May 5, 2019, 2:18am UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/16 "2019-05-05T02:18:48Z")

</div>

What’s an environment variable plotting could agree on? `ENV["SIXEL"]` perhaps?

---

<div class="post-metadata">

**Author:** ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)\
**Post date:** [May 5, 2019, 3:03pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/17 "2019-05-05T15:03:17Z")

</div>

You could add this function to your `.juliarc`:

```julia
function plot_with_gaston()
    @eval using Gaston
    @eval set(terminal="sixelgd")
end

```

and just call it when you’re ready to plot.

---

<div class="post-metadata">

**Author:** ![isentropic](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/isentropic/32/11894_2.png) [@isentropic](https://discourse.julialang.org/u/isentropic)\
**Post date:** [November 24, 2021, 1:12pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/18 "2021-11-24T13:12:04Z")

</div>

Although this is late, would you please let me how to achieve this with plots? I’d like to get this to work in Plots

---

<div class="post-metadata">

**Author:** ![jheinen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jheinen/32/2787_2.png) [@jheinen](https://discourse.julialang.org/u/jheinen)\
**Post date:** [November 24, 2021, 1:27pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/19 "2021-11-24T13:27:56Z")

</div>

```julia
env GKSwstype=iterm julia
...
julia> using Plots
julia> plot(randn(10))

```

 ![Plots-iterm](https://global.discourse-cdn.com/julialang/original/3X/2/6/26c82821246b9d48d4c1a09310e04e12ee04a976.png)

For any reason, in `Plots.jl` the resulting plot is not HiDPI, but at least it works …

---

<div class="post-metadata">

**Author:** ![piechologist](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piechologist/32/27662_2.png) [@piechologist](https://discourse.julialang.org/u/piechologist)\
**Post date:** [November 15, 2022, 9:48pm UTC](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/20 "2022-11-15T21:48:16Z")

</div>

This is an old thread but if some desperate soul is still looking for a solution I want to share my accidental discovery:

# How to plot inside iTerm on macOS

This produces sharp plots even on Retina displays. Adjust the size and scaling to your liking.

```julia
using Plots
theme(:dark) # for dark terminal backgrounds
default(display_type=:inline, size=(1500,800), thickness_scaling=1.5)
plot(rand(20))

```

~~(Minor) caveats: - The GKS QT terminal starts in the background (it doesn't open a window). - You can even ssh into a headless remote machine and initiate the plot there. Some QT related error messages do appear though.~~

Set the the environment variable `GKSwstype=nul` before starting julia to suppress the launching of `gksqt`.

You can even ssh into a headless remote machine and initiate the plot there.

EDIT: How to avoid GKSQT. Thanks to [Plots in the terminal (with sixel) - #31 by jheinen](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503/31).

[Next page](https://discourse.julialang.org/t/plots-in-the-terminal-with-sixel/22503.md?page=2)
