plotly / plotly.py

The interactive graphing library for Python :sparkles: This project now includes Plotly Express!
https://plotly.com/python/
MIT License
16.06k stars 2.54k forks source link

Bug in streamline? #2021

Closed rafa-guedes closed 2 months ago

rafa-guedes commented 4 years ago

create_streamline breaks with the test example below. This seems to fix it:

- if ((x[index + 1] - x[index]) - (x[1] - x[0])) > 0.0001:
+ if any(((x[index + 1] - x[index]) - (x[1] - x[0])) > 0.0001):
import plotly.figure_factory as ff
import numpy as np

x,y = np.meshgrid(np.arange(0, 2, .2), np.arange(0, 2, .2))
u = np.cos(x)*y
v = np.sin(x)*y

fig = ff.create_streamline(x, y, u, v, arrow_scale=.1)

~/.virtualenvs/onbeach/local/lib/python3.7/site-packages/plotly/figure_factory/_streamline.py in create_streamline(x, y, u, v, density, angle, arrow_scale, **kwargs)
    112     utils.validate_equal_length(x, y)
    113     utils.validate_equal_length(u, v)
--> 114     validate_streamline(x, y)
    115     utils.validate_positive_scalars(density=density, arrow_scale=arrow_scale)
    116 

~/.virtualenvs/onbeach/local/lib/python3.7/site-packages/plotly/figure_factory/_streamline.py in validate_streamline(x, y)
     26         raise ImportError("FigureFactory.create_streamline requires numpy")
     27     for index in range(len(x) - 1):
---> 28         if ((x[index + 1] - x[index]) - (x[1] - x[0])) > 0.0001:
     29             raise exceptions.PlotlyError(
     30                 "x must be a 1 dimensional, " "evenly spaced array"

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
emmanuelle commented 4 years ago

Thank you @rafa-guedes for the bug report. I tried the fix you proposed and then I got a ValueError later in the code (see below). Were you able to make the example execute correctly with just the fix above? Thanks again.

import plotly.figure_factory as ff
import numpy as np

x, y = np.meshgrid(np.arange(0, 2, .2), np.arange(0, 2, .2))
u = np.cos(x)*y
v = np.sin(x)*y

fig = ff.create_streamline(x, y, u, v)
fig.show()

Error after adding the any

------------------------------------------------------
ValueError           Traceback (most recent call last)
<ipython-input-1-4ea6a12e8cbb> in <module>
      6 v = np.sin(x)*y
      7 
----> 8 fig = ff.create_streamline(x, y, u, v)
      9 fig.show()

~/code/plotly.py/packages/python/plotly/plotly/figure_factory/_streamline.py in create_streamline(x, y, u, v, density, angle, arrow_scale, **kwargs)
    116 
    117     streamline_x, streamline_y = _Streamline(
--> 118         x, y, u, v, density, angle, arrow_scale
    119     ).sum_streamlines()
    120     arrow_x, arrow_y = _Streamline(

~/code/plotly.py/packages/python/plotly/plotly/figure_factory/_streamline.py in __init__(self, x, y, u, v, density, angle, arrow_scale, **kwargs)
    166         self.st_x = []
    167         self.st_y = []
--> 168         self.get_streamlines()
    169         streamline_x, streamline_y = self.sum_streamlines()
    170         arrows_x, arrows_y = self.get_streamline_arrows()

~/code/plotly.py/packages/python/plotly/plotly/figure_factory/_streamline.py in get_streamlines(self)
    297         for indent in range(self.density // 2):
    298             for xi in range(self.density - 2 * indent):
--> 299                 self.traj(xi + indent, indent)
    300                 self.traj(xi + indent, self.density - 1 - indent)
    301                 self.traj(indent, xi + indent)

~/code/plotly.py/packages/python/plotly/plotly/figure_factory/_streamline.py in traj(self, xb, yb)
    287             return
    288         if self.blank[yb, xb] == 0:
--> 289             t = self.rk4_integrate(xb * self.spacing_x, yb * self.spacing_y)
    290             if t is not None:
    291                 self.trajectories.append(t)

~/code/plotly.py/packages/python/plotly/plotly/figure_factory/_streamline.py in rk4_integrate(self, x0, y0)
    257             return stotal, xf_traj, yf_traj
    258 
--> 259         sf, xf_traj, yf_traj = rk4(x0, y0, f)
    260         sb, xb_traj, yb_traj = rk4(x0, y0, g)
    261         stotal = sf + sb

~/code/plotly.py/packages/python/plotly/plotly/figure_factory/_streamline.py in rk4(x0, y0, f)
    233                 try:
    234                     k1x, k1y = f(xi, yi)
--> 235                     k2x, k2y = f(xi + 0.5 * ds * k1x, yi + 0.5 * ds * k1y)
    236                     k3x, k3y = f(xi + 0.5 * ds * k2x, yi + 0.5 * ds * k2y)
    237                     k4x, k4y = f(xi + ds * k3x, yi + ds * k3y)

~/code/plotly.py/packages/python/plotly/plotly/figure_factory/_streamline.py in f(xi, yi)
    205 
    206         def f(xi, yi):
--> 207             dt_ds = 1.0 / self.value_at(self.speed, xi, yi)
    208             ui = self.value_at(self.u, xi, yi)
    209             vi = self.value_at(self.v, xi, yi)

~/code/plotly.py/packages/python/plotly/plotly/figure_factory/_streamline.py in value_at(self, a, xi, yi)
    184             self.y = yi.astype(np.int)
    185         else:
--> 186             self.val_x = np.int(xi)
    187             self.val_y = np.int(yi)
    188         a00 = a[self.val_y, self.val_x]

ValueError: cannot convert float NaN to integer
rafa-guedes commented 4 years ago

@emmanuelle no sorry, I didn't try running the full code with that fix applied..

emmanuelle commented 4 years ago

ok so we have more work to do here, thanks for bringing this to our attention,

Ziaeemehr commented 3 years ago

I still have the same error. I am using plotly python '4.7.1' on ubuntu 20.04 machine.

fig = create_streamline(r, v, dr, dv)

shape each input is e.g 20 by 20

fig = create_streamline(r, v, dr, dv)
  File "/home/ziaee/git/Dashboards/dash_ve/lib/python3.8/site-packages/plotly/figure_factory/_streamline.py", line 114, in create_streamline
    validate_streamline(x, y)
  File "/home/ziaee/git/Dashboards/dash_ve/lib/python3.8/site-packages/plotly/figure_factory/_streamline.py", line 28, in validate_streamline
    if ((x[index + 1] - x[index]) - (x[1] - x[0])) > 0.0001:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

any solution?

jordanlorenzatto commented 7 months ago

Any updates on the solution to this? I'm running plotly python '5.11.0' on Windows 10 machine.

Coding-with-Adam commented 7 months ago

Unfortunately, we're limited with resources currently. I'd encourage the community to try to fix the bug and write a test if possible. We would make sure to review that PR.

TillerBurr commented 6 months ago

I don't think this is an actual bug. The docs say that x and y values are supposed to be a 1D object. In this case, x and y are 2D. You can get the streamlines for the above example if you do the following.

import plotly.figure_factory as ff
import numpy as np

x = y = np.arange(0, 2, .2)
x1, y1 = np.meshgrid(x,y)
u = np.cos(x1)*y1
v = np.sin(x1)*y1

fig = ff.create_streamline(x, y, u, v)
fig.show()

Not super pretty, but that is probably a byproduct of the coarse grid.

image

The streamline are calculated using the 4th order Runge-Kutta method, which (as far as I know) can only be done in one-dimension. The x and y are done somewhat separately.

I'd be willing to take a look at it further if there is another example that uses 1d x and y.

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 a while, 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. Alternatively, if it's a request for tech support, please post in our community forum. Thank you - @gvwilson