XPlot icon indicating copy to clipboard operation
XPlot copied to clipboard

Save chart to image

Open ArtemyB opened this issue 8 years ago • 14 comments

Would be nice to have capability of saving charts to images from code. For example, this will allow to create a couple of FsLab formatters as static image (could be especially useful for implementing LaTeX XPlot formatters). And it's no wonder that this feature is already supported by original libraries:

P.S.: Thanks so much for this library!

ArtemyB avatar Oct 24 '16 00:10 ArtemyB

Would love to see this too!

ndalchau avatar Jan 20 '17 09:01 ndalchau

Upvote

picolino avatar Dec 09 '19 10:12 picolino

We would be interested to offer a backend for Xploit for static charts. We've built Image-Charts just for this problem! We render charts world-wide (1 url = 1 chart) :)

Learn more here

FGRibreau avatar Dec 09 '19 15:12 FGRibreau

I want it too. Need this feature to use in chatbot

ivanmem avatar Feb 17 '20 15:02 ivanmem

essential feature for me

thomasd3 avatar Mar 28 '20 13:03 thomasd3

HighCharts makes use of a public server for rasterisation, but I haven't seen any similar service for Plotly. With kaleido image generation is lighter weight than Orca, but needs to be hosted as a service for this to work nicely.

malisimo avatar Sep 01 '20 21:09 malisimo

Plotly does have an API for saving charts as an image type, so it's just a matter of writing the API wire-up code to do that with a sensible default. Also worth noting that if you use XPlot as it exists today in a notebook, there is a button to just download the chart as an image already.

cartermp avatar Sep 01 '20 21:09 cartermp

Ah fantastic i wasn't aware, would be a nice addition. I'll try to take a look if nobody beats me to it 👍

malisimo avatar Sep 02 '20 20:09 malisimo

If we are in Javascript land then we can certainly call something like Plotly.toImage() but this requires adding to the JS stub and the plot actually being displayed in the browser.

However, the main benefit of saving to a static image (as far as I can imagine) would be to facilitate the generation of images without first having to display the image. For example, a frequent use-case for me personally when using Plotly from python is to use write_image within a loop to generate potentially hundreds of PNG's for later comparison, or even animation.

What is being proposed here (and please correct me if I'm wrong @artemyB @thomasd3 @cartermp) is to first require displaying the chart in the browser and then subsequently invoking the JS API to do the rasterisation, and would not facilitate the use case I described above.

Not to say this is not nonetheless useful, but I would really like to understand the exact use case before embarking on an actual implementation!

malisimo avatar Sep 06 '20 17:09 malisimo

Personally, I need rasterization on the server. To send an image using a chatbot.

ivanmem avatar Sep 07 '20 18:09 ivanmem

@malisimo the way this would get done to fit in with how XPlot works is just to build up the JS call programmatically via an F# API that would likely allow for different image types, since plotly supports PNG, SVG, and JPG.

but this requires adding to the JS stub and the plot actually being displayed in the browser.

I think it might require a slightly different stub, I guess it depends on what the ideal way to use the plotly API is. But fundamentally this would just be about adding the stub and wiring up an F# API to it to take a trace and produce a plot that gets saved as an image.

Ultimately since Plotly (and thus XPlot.Plotly) is about charting in the browser (or some hosted browser I suppose) this will just follow what it's meant for. Server-size image processing might be out of scope.

cartermp avatar Sep 09 '20 05:09 cartermp

I've published a package for Plotly.NET that uses PuppeteerSharp and Chromium to render charts. It uses a bit of HTML patching to call Plotly.toImage method that renders the chart in headless Chromium. Looks like the similar approach can be used for XPlot too.

ilyalatt avatar Apr 17 '21 12:04 ilyalatt

that's is great! thanks for doing this!

thomasd3 avatar Apr 17 '21 12:04 thomasd3

I've published a package that uses PuppeteerSharp and Chromium to render charts. It's called Plotly.NET.PuppeteerRenderer. The code is written in C# but it should not be a problem to use it in F#. Here's a snippet:

var chart = Chart.Line<int, int, int, int>(
    x: new[] { 1, 2, 3 },
    y: new[] { 4, 5, 6 }
);

await using var renderer = await PlotlyRenderer.FetchBrowserAndLaunch();
var png = await renderer.Render(1024, 768, chart.ToFullScreenHtml());
await File.WriteAllBytesAsync("chart.png", png);

Oh, I made a mistake. I had 2 tabs with XPlot and Plotly.NET issues and selected the wrong one :) However the approach for XPlot.Plotly is the same. Looks like only a small fix of HTML patching is needed. I'm sorry for this unwise situation :)

ilyalatt avatar Apr 17 '21 15:04 ilyalatt