plotly/Plotly.NET

Option to set DPI for static image export

nhirschey opened this issue · 8 comments

Description

I want to use Chart.savePNG to save plots so that I can include them in latex documents. The default 600x600 size results in blurry images, so I need to increase the dots per inch (dpi). But when I increase size using Chart.savePNG(height=1000,width=1000), the text and markers look too small because their size is still the same number of pixels. As a result, I have to manually change image size, marker size, and text size whenever I want to increase resolution.

It would be nice if a dpi option increased resolution while keeping apparent marker, text, etc. size constant.

Repro steps

Please provide the steps required to reproduce the problem

let exampleChart =
    Chart.Point([ 1.; 2.; 2.; 4.; 5. ], [ 1.; 2.; 2.; 4.; 5. ])

// blurry
exampleChart
|> Chart.savePNG ("blurry", Width = 300, Height = 300)

// Clear but text and markers appear much smaller
exampleChart
|> Chart.savePNG ("clear-but-small", Width = 900, Height = 900)

Expected behavior

I'd like the "clear-but-small" image to be the same proportions as "blurry", just clearer due to higher dpi.

See for example dpi options for ggsave in R.

I have done some digging in the docs of the function that is used in the browser to generate these images, and it sadly seems like there is no direct option for this. Other rendering engines for plotly.py support a scale parameter, but that does not seem to be an option for plotly.toImage, which is used in the PuppeteerSharpRenderer.

This thread goes a bit into details on a workaround: plotly/dash-core-components#403 (comment) . It involves using the ToImageButtons, which can be used on a plot displayed in the browser to offer a button to download a plot as image. On that button, you can set the scale (see here).

However, this is a manual process and therefore no real solution for static image export. I'd suggest going the route of the issue i mentioned - exporting to svg and using another program to export the svg to a correctly scaled image format (this is also how i usually make figures publication-ready).

I see, thank you for the svg tip @kMutagene, I understand now why your publication example charts use svg. Time to learn inkscape...

There is a scale parameter in Plotly.toImage in the PuppeteerSharpRenderer here.

+ $".then(x => Plotly.toImage(x, {{ format: '{StyleParam.ImageFormat.toString format}', scale: 1, width: {width}, height: {height} }}))"

It's just that we don't allow it to surface in the API, but I don't see what would prevent us from doing that...

There is a scale parameter in Plotly.toImage in the PuppeteerSharpRenderer here

Hmm weird, that parameter is not documented on the plotly.js function reference. Anyways, i'll try it and check whether it has the expected results.

Hmm weird, that parameter is not documented on the plotly.js function reference. Anyways, i'll try it and check whether it has the expected results.

This had an effect back when I first contributed to Plotly.NET :) #179

Just played around and can confirm that scale works (kinda). The image has a larger size with the same DPI (instead of increasing the dpi on the same size), so i guess increasing the scale and then downsizing the image should have the intended effect right?

Still, very weird to not document this at the js docs. I'll prepare an update to the whole render engine thing soon.

would this achieve what you need @nhirschey ?

closing this, it will be available with the next major version release