# How does Pluto decide what to show graphically?

**URL:** <https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033>\
**Category:** Pluto\
**Created:** [March 26, 2021, 5:37pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033 "2021-03-26T17:37:35Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 26, 2021, 5:37pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/1 "2021-03-26T17:37:35Z")

</div>

I’m having fun writing all my code in Pluto, and I’d like to add some graphical bells and whistles. [In Python/Jupyter](https://gist.github.com/rpmuller/5666810), I’ve done this by overloading repr\_html or repr\_svg. Is there something similar in Julia? I see `as_html` and `as_svg` in the [PlutoUI tutorial](https://blog.jcharistech.com/2020/11/17/pluto-jl-plutoui-tutorial/), and I also see a lot of references to overloading `show` with a specific MIME type in the PlutoUI/Images.jl module. Can someone give me pointers on where to start? If this is something where I should leverage existing code rather than writing this myself, please also let me know. I fear I’ve reached the end of my productive googling.

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 26, 2021, 5:59pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/2 "2021-03-26T17:59:43Z")

</div>

Discovered the following doctest in the PlutoUI source code:  
`Show(MIME"text/html"(), "I can be <b>rendered</b> as <em>HTML</em>!")`

Tried the analogous  
`Show(MIME"image/svg+xml"(), txtsvg)`

with `txtsvg` equal to a [simple SVG string](https://www.w3schools.com/graphics/tryit.asp?filename=trysvg_circle), but it didn’t work ☹ .

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 26, 2021, 6:32pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/3 "2021-03-26T18:32:02Z")

</div>

Also found [Compose.jl](https://giovineitalia.github.io/Compose.jl/latest/tutorial/#Tutorial), which looks great, but might be more complex than what I’m looking for.

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [March 26, 2021, 6:39pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/4 "2021-03-26T18:39:13Z")

</div>

cc @fonsp

---

<div class="post-metadata">

**Author:** ![rikh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rikh/32/204104_2.png) [@rikh](https://discourse.julialang.org/u/rikh)\
**Post date:** [March 26, 2021, 9:07pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/5 "2021-03-26T21:07:37Z")

</div>

If I understand correctly, this is a typical case where multiple dispatch is used. Basically, each library defines it’s own

```julia
function show(io::IO, m::MIME"some_mime", x::T)

```

where `some_mime` can be `MIME"text/html"` and the type `T` is some object defined by the library. Then, Pluto will just call

```julia
show(io, m, object)

```

and Julia figures out which `show` method needs to be called exactly. (Julia will try to do this by the most specific method possible or fall back to printing it as a string if no specific method for some type is known.)

For example, in [Gadfly](https://github.com/GiovineItalia/Gadfly.jl/blob/6123752e27aea77f86bcd683f833030909ae3566/src/Gadfly.jl#L941):

```julia
function show(io::IO, m::MIME"image/svg+xml", p::Plot)
    buf = IOBuffer()
    svg = SVG(buf, Compose.default_graphic_width,
              Compose.default_graphic_height, false)
    draw(svg, p)
    show(io, m, svg)
end

```

You can find many more examples in other libraries.

> [@rpmuller](#):
>
> with `txtsvg` equal to a [simple SVG string](https://www.w3schools.com/graphics/tryit.asp?filename=trysvg_circle), but it didn’t work ☹ .

Note that the type, here, is important. If you passed a simple SVG string as a literal `String`, then Julia will print it as a string.

> [@rpmuller](#):
>
> Can someone give me pointers on where to start?

To answer this question, what kind of objects do you want to show?

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 26, 2021, 11:08pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/6 "2021-03-26T23:08:04Z")

</div>

Thank you very much for your response. To answer what kind of objects I want to show, there are several, but I’m initially interested in being able to make graphical descriptions of quantum circuits, the kind of thing that Yao does [here](https://github.com/QuantumBFS/YaoPlots.jl). I realize this already exists, but I’m trying to understand Julia and Pluto a little bit more by rewriting some of the utilities I’ve written in python in the past, and I had a cute little [routine](https://github.com/rpmuller/PlotQCircuit/blob/master/PlotQCircuit.ipynb) that used matplotlib to plot out quantum circuits in just a few hundred loc.

Like I said, I did that one using matplotlib, but I could have just as easy done this in pure SVG. I had another [little python script here](https://gist.github.com/rpmuller/5666810) that overloaded repr\_svg to draw svg figures in Jupyter notebooks. I know that the ProfileSVG module uses SVG to visualize the FlameGraphs, so I thought that could be a good approach, but I got lost in looking through the source to see how they manage to display their SVG files.

I see that Yao uses Compose.jl, which looks beautiful, and may be the best way to go, but before I use someone else’s solution, I’d like to understand the mechanics a little bit better. It was a real lightbulb moment for me when I realized that all of those cool Jupyter notebook plugins just overloaded repr\_svg or repr\_html, and it was fun to have that kind of fluency with the Python/Jupyter code.

For the record, what I tried to do with the SVG string was to define the SVG string:

```julia
txtsvg = """<svg height="100" width="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>"""

```

and to then call

```julia
Show(MIME"image/svg+xml"(),txtsvg)

```

but that didn’t work. I also don’t understand why there are function parens after the `MIME"image/svg+xml"()` string literal.

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 26, 2021, 11:52pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/7 "2021-03-26T23:52:41Z")

</div>

…and after some more googling around, [this section of the manual on custom pretty printing](https://docs.julialang.org/en/v1/manual/types/#man-custom-pretty-printing) is what I needed to read.

What I hadn’t understood is that I need to define not only `show(io,obj)` but other show types as well, for example `show(io,::MIME"text/plain",obj)` and `show(io,::MIME"text/html",obj)`.

The latter appears to be called to display objects in Pluto notebooks. How do I control when the `MIME"image/svg+xml"` is displayed?

For example, does Pluto default by trying to show the object as an image, and then fall back to showing it as html?

For reasons I don’t yet understand, when my objects lacked a `MIME"text/html` method, Pluto didn’t call the normal `show(io,obj)`, but fell back to a 3-argument method of `AbstractArray`.

---

<div class="post-metadata">

**Author:** ![rikh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rikh/32/204104_2.png) [@rikh](https://discourse.julialang.org/u/rikh)\
**Post date:** [March 27, 2021, 8:49am UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/8 "2021-03-27T08:49:43Z")

</div>

> [@rpmuller](#):
>
> The latter appears to be called to display objects in Pluto notebooks. How do I control when the `MIME"image/svg+xml"` is displayed?

As far as I understand, the MIME types state how the browser shows the output data. So, for an object of type `T`, it doesn’t make sense to define two different output MIME types.

> [@rpmuller](#):
>
> For example, does Pluto default by trying to show the object as an image, and then fall back to showing it as html?

See the documentation of `show` via `?show`. It depends on the type of the third parameter (the object). The behavior is not really Pluto specific. Pluto just calls `show(io, mime, x)` and Julia calls the most applicable `show` method.

> [@rpmuller](#):
>
> For the record, what I tried to do with the SVG string was to define the SVG string:
> 
> ```julia
> txtsvg = """<svg height="100" width="100">
> <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
> </svg>"""
> 
> ```
> 
> and to then call
> 
> ```julia
> Show(MIME"image/svg+xml"(),txtsvg)
> 
> ```

The type of textsvg is a string, so `show(io, mime, obj::String)` will be called. Instead, you could define your own type

```julia
struct MySVG
   x::String
end

```

and your own `show` method

```julia
function show(io::IO, m::MIME"image/svg+xml", obj::MySVG)
    [...]
end

```

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 27, 2021, 4:53pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/9 "2021-03-27T16:53:08Z")

</div>

Thanks again for your responses. I think I have the basics now, and I’ll play around defining some types to see how to draw them. Thanks!

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 27, 2021, 7:28pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/10 "2021-03-27T19:28:11Z")

</div>

Sorry, I thought I had this, but I’m still being dense.

You say:

> [@rikh](#):
>
> The type of textsvg is a string, so `show(io, mime, obj::String)` will be called. Instead, you could define your own type
> 
> ```julia
> struct MySVG
> x::String
> end
> 
> ```
> 
> and your own `show` method
> 
> ```julia
> function show(io::IO, m::MIME"image/svg+xml", obj::MySVG)
> [...]
> end
> 
> ```

I’m just being stupid, but everything I put inside the show() block comes out as a string. I can write a proper svg xml file, and can test that the file is written correctly. But the only way I know how to include this is to cast it to a string and then write/show/print it as a string, which doesn’t work for the reasons you cite above the section I quoted.

E.g., if I have

```julia
function Base.show(io::IO, m::MIME"image/svg+xml", obj::MySVG)
    show(io,m,obj.x)
end

```

and

```julia
MySVG("""<?xml version="1.0" encoding="utf-8"?>
<svg width="40" height="40" xmlns="http://www.w3.org/2000/svg">
<g style="fill-opacity:1.0; stroke:black; stroke-width:1;">
  <line x1="5" y1="5" x2="25" y2="25"/>
</g>
</svg>
""")

```

it doesn’t work. Any hints as to what I’m doing wrong?

Thanks in advance for your help.

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 27, 2021, 7:36pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/11 "2021-03-27T19:36:06Z")

</div>

Nevermind. Turns out that

```julia
write(io,obj.x)

```

in the show() works. `print` also works here, but `show` doesn’t. I think the difference is that when I call `show()` I’m asking the interpreter to reinterpret this, and it sees and handles a string. Whereas if I just write the text to io, it ?? does the correct thing???

---

<div class="post-metadata">

**Author:** ![rikh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rikh/32/204104_2.png) [@rikh](https://discourse.julialang.org/u/rikh)\
**Post date:** [March 27, 2021, 8:40pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/12 "2021-03-27T20:40:52Z")

</div>

I’m happy to hear that you got further 🎉 Unfortunately, I’m unsure what is now the unexpected behavior with the `show`. Could you post a MWE ([Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757))?

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 28, 2021, 12:01am UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/13 "2021-03-28T00:01:34Z")

</div>

Sure thing. Following the code you posted…

```julia
struct MySVG
   x::String
end

function Base.show(io::IO, m::MIME"image/svg+xml", obj::MySVG)
    write(io,obj.x) # also works with print(io,obj.x), but not show(io,obj.x)
end

MySVG("""<?xml version="1.0" encoding="utf-8"?>
<svg width="40" height="40" xmlns="http://www.w3.org/2000/svg">
 <g style="fill-opacity:1.0; stroke:black; stroke-width:1;">
  <line x1="5" y1="5" x2="25" y2="25"/>
 </g>
</svg>
""")

```

See the comment after the write command on the 5th line of code: This displays an SVG image in Pluto if I use `write(io,obj.x)` or `print(io,obj.x)`, but not if I use `show(io,obj.x)`. The best guess I can make as to why this happens is that if I call `show`, the interpreter goes through the whole cycle again, decides it’s handling a string, and calls something else, whereas with `print/write` it just prints straight to `io`.

Does that make sense?

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [March 28, 2021, 12:19am UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/14 "2021-03-28T00:19:33Z")

</div>

```julia
julia>?show

show(io::IO, mime, x)
...
it is only necessary to define a new `show` method for T, via: 
`show(io, ::MIME"mime", x::T) = ...`, where `mime` is a MIME-type string and
 the function body calls `write` (or similar) ...

```

You could also make use of Compose’s types/functions. Note Compose will add it’s own svg header to the file.

```julia
using Compose
img = SVG(40mm, 40mm)
# img = SVG("test.svg", 40mm, 40mm)
write(img.out, """<g style="fill-opacity:1.0; stroke:black; stroke-width:1;">
  <line x1="0" y1="0" x2="40" y2="40"/></g></svg>""")
img

```

---

<div class="post-metadata">

**Author:** ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)\
**Post date:** [March 28, 2021, 1:02am UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/15 "2021-03-28T01:02:14Z")

</div>

Thanks!

---

<div class="post-metadata">

**Author:** ![L\_Adam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/l_adam/32/12086_2.png) [@L\_Adam](https://discourse.julialang.org/u/L_Adam)\
**Post date:** [August 29, 2021, 2:31pm UTC](https://discourse.julialang.org/t/how-does-pluto-decide-what-to-show-graphically/58033/18 "2021-08-29T14:31:25Z")

</div>

as you’ve figured it out, just implement `show(io::IO, m::MIME"image/svg+xml", c)` . It’s simpley

```julia
using Compose 

struct DrawConfig
	c::Compose.Context
	width
	height
end 

import Base

function Base.show(io::IO, m::MIME"image/svg+xml", d::DrawConfig)
	backend = SVG(io, d.width, d.height)
	draw(backend, d.c)
end 

DrawConfig(compose(compose(context(), rectangle()), fill("tomato")), 4cm, 4cm)

```

done, and pluto just call show for you

the good thing about that is you never needs to touch svg. Until you want native interaction from browser, that you have to inject some attributes and more likely, js code script element, this could be done by combining Compose, specically draw part, with some xml package, like [EzXML.jl](https://github.com/JuliaIO/EzXML.jl)
