plotly / Kaleido

Fast static image export for web-based visualization libraries with zero dependencies
MIT License
378 stars 38 forks source link

Noise produced in region of negative infinity, doesn't happen with orca #106

Open paddyroddy opened 3 years ago

paddyroddy commented 3 years ago

I've recently realised that plotly no longer supports orca and seen I should be using kaleido. I'm using Surface and Mesh3d and in both I'm doing something similar, but I only get this problem with Mesh3d. Essentially, I create some field on the surface/mesh, and then I set the value outside some region to a large negative number so that the region can be seen easily. In both cases I export as png as well as pdf and the problem is the same for both, and I do not get it in the browser.

This is an example of what I mean with the Surface example. Here I have the topography of the Earth and then the region outside South America is set to a large negative value, and it appears white as desired. earth_2smoothed_L128_res512_real slepian_south_america_2smoothed_L128_res512_real

Now if I do the same for some mesh, instead of the white I'm expecting I get noise. Here is a field on a Mesh3d of Homer, then I isolate the head as the region and I get the noise. If I use the orca engine, I do not get this issue. homer_field slepian_homer_field

Is there a way to fix this, or is it a bug? I'll have to revert to orca in the meantime.

jonmmease commented 3 years ago

Hi @paddyroddy, thanks for the report. Would you be able to provide full code for a simple example that reproduces this behavior?

paddyroddy commented 3 years ago

Here's some code which reads a mesh of homer from this repo. The library I'm using to read the mesh is igl which can be installed via: conda install -c conda-forge igl.

import numpy as np
import plotly.offline as py
from igl import read_triangle_mesh
from plotly.graph_objs import Figure, Mesh3d

def kaledio_bug(
    engine: str,
    mesh: str = "homer.off",
    large_negative_value: float = -1.56e30,
    region_ymin: float = 0.15,
) -> None:
    """
    minimal working example to reproduce the Kaleido bug
    """
    # read in mesh
    vertices, faces = read_triangle_mesh(mesh)

    # create some region
    region = vertices[:, 1] >= region_ymin

    # create dummy field
    function_on_mesh = np.ones(vertices.shape[0])

    # set value outside region to negative infinity
    masked_region = np.where(region, function_on_mesh, large_negative_value)

    # create plot
    data = [
        Mesh3d(
            x=vertices[:, 0],
            y=vertices[:, 2],
            z=vertices[:, 1],
            i=faces[:, 0],
            j=faces[:, 1],
            k=faces[:, 2],
            intensity=masked_region,
            cmin=-1,
            cmax=1,
        )
    ]
    fig = Figure(data=data)
    py.plot(fig)

    # bug happens kaledio but not orca
    for file_type in {"png", "pdf"}:
        fig.write_image(f"homer_{engine}.{file_type}", engine=engine)

if __name__ == "__main__":
    for engine in {"kaleido", "orca"}:
        kaledio_bug(engine)

The resulting plots look like: Kaleido homer_kaleido Orca homer_orca

paddyroddy commented 2 years ago

I've found if I set large_negative_value to some less small number, i.e. -1e5 then it's okay. However, when I don't normalise the dataset sometimes this wouldn't be a small enough value, so not ideal.