plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
16.88k stars 1.85k forks source link

Improper stroke & arrow lines when exporting as vector graphic (PDF/SVG) - with solution #5081

Closed mherrmann3 closed 2 months ago

mherrmann3 commented 4 years ago

When figures are exported as PDF or SVG, I noticed that stroke lines (e.g., dashed or dotted) are accompanied by very thin lines. This is similar to this stackoverflow question (see this image on the right side). Since orca/kaleido make use of the Chromium library for static image export, it depends on how it renders the plots. The thin lines can be seen in Illustrator, Adobe Acrobat, Foxit, and Chrome(ium); in Firefox's PDF viewer and SumatraPDF they don't appear.

According to the answer on stackoverflow, the solution is adding the property "fill": "none". Indeed, when I patch plotly.min.js (.style in function .dashLine) accordingly, the thin lines disappear in the PDF using any viewer. Btw, this issue also affects arrow lines of the annotations as they also make use of "stroke-dasharray"; they can be patched likewise (.style in the arrowhead function).

I guess that also other elements with the "stroke-dasharray" property could be affected by this issue - of course, only relevant to fix if they are exportable (e.g., not the selection lines).

archmoj commented 4 years ago

@mherrmann3 thanks very much for the info. Would you be interested to submit a PR?

cc: @antoinerg

alexcjohnson commented 4 years ago

@mherrmann3 Can you elaborate about which lines show this effect? Data traces? (which trace types?) Shapes? Axis lines? Grid lines? Something else? I worry about a modification as general as dashLine deleting fills that we DO want, in which case we may need more selective fixes.

mherrmann3 commented 4 years ago

Very good point, Alex; I didn't thought about that. Possibly it needs a logic that only applies "fill": "none" if the fill property is not set yet; or making "none" the default fill. Dunno. I'm no JS programmer, so I leave the coding/testing it up to the experts. I was only happy that I could fix the improper stroke lines with my dirty patch and though I let you guys know... I think it's only relevant for people that want to generate publishable figures (e.g. in papers).

Keep up the good work! Plotly (via python) is my new plotting gem.

mherrmann3 commented 4 years ago

I now encountered the first side-effect of my patch: every shape with a fill had its fill removed.

@alexcjohnson: I see the improper PDF rendering only for shapes; traces with stroke lines were not affected. I don't know about other lines, but I saw that many calls to Drawing.dashLine() were already preceded by .style('fill', 'none'). So you are right: the fix cannot be generalized in the Drawing.dashLine() function; it should address line shapes in particular. I solved it by inserting the following snippet HERE

if(options.type === 'line') {
    path.style('fill', 'none');
}

Maybe there is a more elegant solution.

The 'fill': 'none' property should be fine in the arrowhead function, though, as a filling for arrows doesn't make sense, correct? This can be achieved by changing THIS line into:

el3.style({
    'stroke-dasharray': dashArray,
    'fill': 'none'
});

Could someone commit those adjustments?

gvwilson commented 2 months ago

Hi - we are trying to tidy up the stale issues and PRs in Plotly's public repositories so that we can focus on things that are still important to our community. Since this one has been sitting for several years, I'm going to close it; if it is still a concern, please add a comment letting us know what recent version of our software you've checked it with so that I can reopen it and add it to our backlog. Thanks for your help - @gvwilson