Certain plots (like scatter plots with many points or 2D plots with many bins) are huge (in MB) in SVG, so the file size of Jupyter notebook explodes. Such notebooks get really sluggish, and GitHub Gists even crashes when trying to upload them.
For PyPlot, using
PyPlot.svg(false)
does work with Plots.jl, but only _after_
[Plots.jl] Initializing backend: pyplot
i.e. after the first Plot or after a manual Plots.backend(). It would be nice if the default output type could be set in a user-friendly way, e.g. with Plots.pyplot(svg = true|false) or even backend-independent with something like Plots.default_output(:svg | :png | ...) or so.
Correction: I must have mixed something up: PyPlot.svg(false) does _not_ work with Plots.jl.
I think there's open issue regarding Jupyter output (if there's not, it's certainly on my own wishlist).
e.g. with Plots.pyplot(svg = true|false) or even backend-independent with something like
Just a quick note... Plots.pyplot is still a backend generic method for settings. Its just a convenience that passes the arguments to the default method before changing the backend.
I have the same problem with IJulia and PyPlot Plots. Related issue: https://github.com/tbreloff/Plots.jl/issues/157
Thanks for finding the issue @diegozea
Since the PyPlot svg isn't interactive on the notebook, making png the default on IJulia for the PyPlot backend could be the best option. Is that possible @tbreloff ?
Since the PyPlot svg isn't interactive on the notebook, making png the default on IJulia for the PyPlot backend could be the best option.
On the other hand, SVG is a better default if someone plans to export the notebook to PDF. Ok, that doesn't work with Plots.jl plots at the moment, but I hope it will in the future. PDF is kind of a central document format in science, after all (and still looks best when there's a lot of LaTeX/Math in the notebook).
I think I just figured out a solution to the png issue. It looks something like this:
function html_output_format(fmt)
if fmt == "png"
@eval function Base.writemime(io::IO, ::MIME"text/html", plt::Plot)
print(io, "<img src=\"data:image/png;base64,", base64(writemime, MIME("image/png"), plt), "\" />")
end
elseif fmt == "svg"
@eval function Base.writemime(io::IO, ::MIME"text/html", plt::Plot)
writemime(io, MIME("image/svg+xml"), plt)
end
else
error("only png or svg allowed. got: $fmt")
end
end
html_output_format("svg")
I just need to figure out the best interface for that, and how it gets set. I might store a dict mapping backend to svg/png so each backend can have its own default, and it's updated on a call to pyplot() for example. Comments welcome.
@oschulz I rather prefer a lower quality in the PDF to an unexpected break in the notebook. The actual behavior (crashing) is really annoying.
Can you use a function like default_format(...backend...) = "..." instead of a Dict? A format keyword argument to change the default would be great ;)
My suspicion about the PDF issue is that I don't have PDF output in the IJulia.display_dict return. I don't know enough about IJulia to say for sure.
Can you use a function like default_format(...backend...) = "..." instead of a Dict?
The user would probably never access the dict directly... just a way to keep per-backend defaults.
Maybe the constant value function (that dispatchs on backend) will be inlined avoiding the Dict look up... (?)
Pretty sure a Dict look up will be negligble compared to how many Dict lookups plots already do,
Yes beyond negligible. I'm not worried about speed... Just gotta settle on
interface. I expect one would do 'pyplot(fmt = :png)' just like any other
setting.
On Thursday, May 26, 2016, Kristoffer Carlsson [email protected]
wrote:
Pretty sure a Dict look up will be negligble compared to how many Dict
lookups plots already do,—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/tbreloff/Plots.jl/issues/275#issuecomment-222001992
A Dict is fine ;) I prefer the explicit format to fmt.
I settled on something that I like more... I added the arg :html_output_format with aliases: add_aliases(:html_output_format, :format, :fmt, :html_format) and default value :auto. When it's auto, it takes a value from:
const _best_html_output_type = KW(
:pyplot => :png,
)
and uses svg when the backend's not in the dict. This way you can set a default just like any other arg (pyplot(fmt = :svg)) or you could set it on a per-plot basis:
heatmap(rand(10000,2000), fmt=:png)

Let me know how this works.
A 17186x103 matrix doesn't break the notebook now :D
I rather prefer a lower quality in the PDF to an unexpected break in the notebook. The actual behavior (crashing) is really annoying.
@diegozea: Sure, I fully agree - some plots need to be PNG. But my feeling is that for the average user, most plots will be fine in SVG (with the advantage of not being pixelized). That's why I think SVG should stay the default.
@diegozea: Sorry, maybe I'm misunderstanding the whole PDF output issue - maybe SVG isn't involved there at all? If so, I'm fine with PNG as default.
Most helpful comment
I settled on something that I like more... I added the arg
:html_output_formatwith aliases:add_aliases(:html_output_format, :format, :fmt, :html_format)and default value:auto. When it's auto, it takes a value from:and uses svg when the backend's not in the dict. This way you can set a default just like any other arg (
pyplot(fmt = :svg)) or you could set it on a per-plot basis:Let me know how this works.