gopherdata / gophernotes

The Go kernel for Jupyter notebooks and nteract.
MIT License
3.82k stars 265 forks source link

Display should have an option to use WriterTo #121

Closed btracey closed 5 years ago

btracey commented 6 years ago

As far as I can tell, this is currently the easiest way to display a gonum/plot

p, _ := plot.New()
p.Add(scat)
w, err := p.WriterTo(8*vg.Inch, 8*vg.Inch, "jpg")
if err != nil{
    panic(err)
}
var b bytes.Buffer
writer := bufio.NewWriter(&b)
w.WriteTo(writer)
display.JPEG(b.Bytes())

This is a lot of effort. It would be really nice if this could somehow be display.JPEGTo(p.WriterTo(8*vg.Inch, 8*vg.Inch, "jpg"))

At the very least, it seems like display should be using the io interfaces instead of taking in a []byte directly

cosmos72 commented 6 years ago

Hi @btracey, I agree, displaying a gonum/plot is cumbersome with the current API. It would be nice to have something like

p, _ := plot.New()
// ...
img, err := p.Image(8*vg.Inch, 8*vg.Inch)
display.Image(img)

but I guess it will happen only if somebody implements that and gets it merged into gonum/plot.

I am not very fond of duplicating the whole display API and add a bunch of functions

func JPEGTo(io.WriterTo) Data
func PNGTo(io.WriterTo) Data
func SVGTo(io.WriterTo) Data
func PDFTo(io.WriterTo) Data
// ...

also because they invite to add as well

func JPEGRead(io.Reader) Data
func PNGRead(io.Reader) Data
func SVGRead(io.Reader) Data
func PDFRead(io.Reader) Data
// ...

What about adding instead only the following two functions?

func WriterTo(mimeType string, to io.WriterTo) Data
func Reader(mimeType string, r io.Reader) Data

Your example would become:

p, _ := plot.New()
p.Add(scat)
w, err := p.WriterTo(8*vg.Inch, 8*vg.Inch, "jpg")
if err != nil {
    panic(err)
}
display.WriterTo("image/jpeg", w)
sbinet commented 6 years ago

FYI, I introduced hplot.Show to achieve the same thing with the neugram jupyter kernel: https://godoc.org/go-hep.org/x/hep/hplot#Show

so one would just have to run:

hplot.Show(p, width, height, "png")

at the jupyter prompt.

cosmos72 commented 6 years ago

Thanks @sbinet, you read my mind: I was thinking about a function

display.Plot(p *plot.Plot, width vg.Length, height vg.Length)

although it has the unfortunate side effect that gonum.org/plot becomes a compile-time dependency of gophernotes

sbinet commented 6 years ago

it doesn't have to:

also, note that the display implementation of neugram is using net/http.DetectContentType to avoid having all the display.JPEG, display.PNG, ... methods.

cosmos72 commented 5 years ago

I have added

func WriterTo(mimeType string, to io.WriterTo) Data
func Reader(mimeType string, r io.Reader) Data

to the package display, with mimeType autodetection as you suggested.