Comments (10)
If I'm understanding what's happening in https://github.com/JuliaPlots/PlotlyJS.jl/blob/562082f9a584a22bd9bda42dc0402640b5e8f611/src/kaleido.jl#L86-L97, it should be possible to define a generic
savefig
function (in a new package) such that we wouldn't need to depend on it. At its core, Kaleido just needs a JSON-formatted string?
Seems like it.
The following code works to save figures from PlotlyLight.
import PlotlyJS
import JSON
using Base64
function savefig(
p;
width::Union{Nothing,Int}=nothing,
height::Union{Nothing,Int}=nothing,
scale::Union{Nothing,Real}=nothing,
format::String="png"
)::Vector{UInt8}
# construct payload
_get(x, def) = x === nothing ? def : x
payload = Dict(
:width => _get(width, 700),
:height => _get(height, 500),
:scale => _get(scale, 1),
:format => format,
:data => p
)
PlotlyJS._ensure_kaleido_running()
# convert payload to vector of bytes
bytes = transcode(UInt8, JSON.json(payload))
write(PlotlyJS.P.stdin, bytes)
write(PlotlyJS.P.stdin, transcode(UInt8, "\n"))
flush(PlotlyJS.P.stdin)
# read stdout and parse to json
res = readline(PlotlyJS.P.stdout)
js = JSON.parse(res)
# check error code
code = get(js, "code", 0)
if code != 0
msg = get(js, "message", nothing)
error("Transform failed with error code $code: $msg")
end
# get raw image
img = String(js["result"])
# base64 decode if needed, otherwise transcode to vector of byte
return base64decode(img)
end
function savefig(
p, fn::AbstractString;
format::Union{Nothing,String}=nothing,
width::Union{Nothing,Int}=nothing,
height::Union{Nothing,Int}=nothing,
scale::Union{Nothing,Real}=nothing,
)
ext = split(fn, ".")[end]
if format === nothing
format = String(ext)
end
open(fn, "w") do f
savefig(f, p; format=format, scale=scale, width=width, height=height)
end
return fn
end
function savefig(io::IO,
p;
width::Union{Nothing,Int}=nothing,
height::Union{Nothing,Int}=nothing,
scale::Union{Nothing,Real}=nothing,
format::String="png")
bytes = savefig(p, width=width, height=height, scale=scale, format=format)
write(io, bytes)
end
This is basically just a copy&pase of PlotlyJS
s savefig
method and uses their kaleido pipeline.
If their savefig
method wouldn't restrict itself to plots of type PlotlyBase.Plot
one could directly use their method to save plots from PlottlyLight.Plot
.
Maybe one could just ask PlotlyJS
if they could change their methods to accept any plot object, or whether one could extract their kaleido pipeline into an extra package.
from plotlylight.jl.
This will be solved by a package in the near future! JuliaRegistries/General#67704
from plotlylight.jl.
Given the "light" aspect of PlotlyLight, I'd like to avoid a binary dependency like Kaleido if I can. I'll need to think through how to make this possible, and I'm happy to take a co-author credit in exchange for implementing it 😄
from plotlylight.jl.
We are trying to publish a bioinformatics software called GSEA. We binarize the final product. PlotlyLight has been a great alternative for PlotlyJS.jl. However, we need the ability to save a figure to publications. Our users should be able to run this software, save high-quality figures, and use them for their papers. I was wondering if it is possible to add the ability to export static images from PlotlyLight.jl. It would be amazing. Also, if you'd like, I can talk to my team about including you as a co-author :)
from plotlylight.jl.
There must be a JavaScript lib that saves static image. Hopefully.
I'll talk to my boss 👍
from plotlylight.jl.
If you are actually displaying the Plot inside on a browser (like in Pluto for example) I believe you can directly used the plotly downloadImage
function: https://plotly.com/javascript/plotlyjs-function-reference/#plotlydownloadimage
You can create png, jpg webp and svg, which I think would suffice most outputs requirements (you could have conversion from svg to pdf outside of the plotlylight package).
from plotlylight.jl.
Thank you @disberd . This is great.
from plotlylight.jl.
Thanks to disberds comment I use this snipped as a workaround:
using HypertextLiteral
function saveplot(p, path, format="png")
htl"<script>Plotly.downloadImage($(p.id), {format: $, width: 800, height: 600, filename: $path});</script>"
end
The drawbacks:
- the result of the function has to be "displayed" by Pluto for the download to be executed
- you can only save to you download folder
So, this is far from great, but still better than using the snapshot functionality.
from plotlylight.jl.
Both issues are a result of saving the function from the javascript
side. I think the easiest to use solution would be Kaleido but as @joshday pointed out that is quite a dependency for the lightness of the package (Kaleido was also removed from PlotlyBase and moved to PlotlyJS partly also because of the burden on the loading time of the package).
For the second drawback of only being able to save within the download folder, I did use some workaround in Pluto before where I had an async julia function waiting for the file to appear in downloads before moving it to a target directory.
You can find an example within this code https://github.com/disberd/PlutoUtils.jl/blob/273e080b03074d181371a2066636571bfb06f08a/src/html2canvas_savediv.jl#L29-L71.
The code here was using html2canvas
to save a generic div element rather than a Plotly plot, but the underlying concept is the same, and the julia function try_moveimage
would basically be the same.
from plotlylight.jl.
If I'm understanding what's happening in https://github.com/JuliaPlots/PlotlyJS.jl/blob/562082f9a584a22bd9bda42dc0402640b5e8f611/src/kaleido.jl#L86-L97, it should be possible to define a generic savefig
function (in a new package) such that we wouldn't need to depend on it. At its core, Kaleido just needs a JSON-formatted string?
from plotlylight.jl.
Related Issues (20)
- Use latest release of plotly.js HOT 3
- Unicode text isn't shown correctly with long series HOT 1
- Is there some way to do animation a la `react!` of PlotlyJS? HOT 1
- UndefVarError: `Plot` not defined HOT 3
- Option to specify default browser to display PlotlyLight.Plot() output HOT 17
- VSCode Notebook - opens browser instead of cell rendering HOT 7
- Usage of "legendgroup" inside PlotlyLight HOT 12
- Cannot display output file "index.html" on Ubuntu 22.04 HOT 3
- feature: legendgrouptitle_text / legendgrouptitle.text not working HOT 3
- Downloading Plotly.js error HOT 3
- fail to precompile on 1.6 HOT 1
- stacked displays HOT 1
- Plots in VSCode Jupyter notebook opens in browser instead of below cell HOT 13
- Missing NaN support HOT 3
- `SETTINGS.layout` gets mutated during plotting HOT 1
- calling `JSON.json` on a PlotlyLight Plot causes stackoverflow HOT 1
- Can't generate plot in Documenter.jl HOT 3
- Support nested NamedTuple HOT 1
- Add Introductory resources to README
- Documenter Docs
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from plotlylight.jl.