3

I just need to draw scatter plot in 3D.

from mpl_toolkits import mplot3d
from matplotlib import pyplot as plt
ax = plt.axes(projection="3d")
ax.scatter(dots_x, dots_y, dots_z, c='red')
plt.show()

There dots_x, dots_y, dots_z are coordinates (python lists). Every time I running program I get ValueError: Invalid RGBA argument: (1.0, 0.0, 0.0, 0.300088123161615)

I don't know anything about this tuple. BUT if i use plot3D instead of scatter3D i get perfect curve.

Full error message:

Traceback (most recent call last):
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\colors.py", line 166, in to_rgba
    rgba = _colors_full_map.cache[c, alpha]
KeyError: ((1.0, 0.0, 0.0, 0.300088123161615), None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backends\backend_qt5.py", line 519, in _draw_idle
    self.draw()
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backends\backend_agg.py", line 437, in draw
    self.figure.draw(self.renderer)
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\artist.py", line 55, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\figure.py", line 1493, in draw
    renderer, self, artists, self.suppressComposite)
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\image.py", line 141, in _draw_list_compositing_images
    a.draw(renderer)
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 281, in draw
    reverse=True)):
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 280, in <lambda>
    key=lambda col: col.do_3d_projection(renderer),
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\mpl_toolkits\mplot3d\art3d.py", line 459, in do_3d_projection
    fcs = mcolors.to_rgba_array(fcs, self._alpha)
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\colors.py", line 267, in to_rgba_array
    result[i] = to_rgba(cc, alpha)
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\colors.py", line 168, in to_rgba
    rgba = _to_rgba_no_colorcycle(c, alpha)
  File "C:\Users\bozzy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\colors.py", line 219, in _to_rgba_no_colorcycle
    raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))
ValueError: Invalid RGBA argument: (1.0, 0.0, 0.0, 0.300088123161615)

Sorry for my english :)

UPD: There is entire code of my program

from sympy import *
from mpl_toolkits import mplot3d
from matplotlib import pyplot as plt
import pdb

"""
"""

print ("""dx/dt = f(t,x,y,z)
 dy/dt = g(t,x,y,z)
 dz/dt = r(t,x,y,z)""")

x,y,z,t = symbols('x y z t')

f = eval(input("dx/dt = "))
g = eval(input("dy/dt = "))
k = eval(input("dz/dt = "))

n = int(input("Input number of dots: "))
delta_t = eval(input("Input time 'step': "))

t0, x0,y0,z0 = eval(input("Input initial conditions t0, x0, y0, z0: "))


dots_x = [x0]
dots_y = [y0]
dots_z = [z0]
current_t = t0

k1,k2,k3,k4 = None, None, None, None
m1,m2,m3,m4 = None, None, None, None
j1,j2,j3,j4 = None, None, None, None

for i in range(1,n+1):
    k1 = f.evalf(subs={x: dots_x[i-1], y: dots_y[i-1], z: dots_z[i-1], t:current_t})*delta_t
    m1 = g.evalf(subs={x: dots_x[i-1], y: dots_y[i-1], z: dots_z[i-1], t:current_t})*delta_t
    j1 = k.evalf(subs={x: dots_x[i-1], y: dots_y[i-1], z: dots_z[i-1], t:current_t})*delta_t

    k2 = f.evalf(subs={x: dots_x[i-1]+k1/2, y: dots_y[i-1]+m1/2, z: dots_z[i-1]+j1/2, t:current_t+delta_t/2})*delta_t
    m2 = g.evalf(subs={x: dots_x[i-1]+k1/2, y: dots_y[i-1]+m1/2, z: dots_z[i-1]+j1/2, t:current_t+delta_t/2})*delta_t
    j2 = k.evalf(subs={x: dots_x[i-1]+k1/2, y: dots_y[i-1]+m1/2, z: dots_z[i-1]+j1/2, t:current_t+delta_t/2})*delta_t

    k3 = f.evalf(subs={x: dots_x[i-1]+k2/2, y: dots_y[i-1]+m2/2, z: dots_z[i-1]+j1/2, t:current_t+delta_t/2})*delta_t
    m3 = g.evalf(subs={x: dots_x[i-1]+k2/2, y: dots_y[i-1]+m2/2, z: dots_z[i-1]+j1/2, t:current_t+delta_t/2})*delta_t
    j3 = g.evalf(subs={x: dots_x[i-1]+k2/2, y: dots_y[i-1]+m2/2, z: dots_z[i-1]+j2/2, t:current_t+delta_t/2})*delta_t

    k4 = f.evalf(subs={x: dots_x[i-1]+k3/2, y: dots_y[i-1]+m3/2, z: dots_z[i-1]+j1/2, t:current_t+delta_t/2})*delta_t
    m4 = g.evalf(subs={x: dots_x[i-1]+k3/2, y: dots_y[i-1]+m3/2, z: dots_z[i-1]+j1/2, t:current_t+delta_t/2})*delta_t
    j4 = g.evalf(subs={x: dots_x[i-1]+k3/2, y: dots_y[i-1]+m3/2, z: dots_z[i-1]+j3/2, t:current_t+delta_t/2})*delta_t

    dots_x.append(dots_x[i-1]+(1/6)*(k1+2*k2+2*k3+k4))
    dots_y.append(dots_y[i-1]+(1/6)*(m1+2*m2+2*m3+m4))
    dots_z.append(dots_z[i-1]+(1/6)*(j1+2*j2+2*j3+j4))
    current_t += delta_t

print (dots_x)
print (dots_y)
print (dots_z)

plt.switch_backend(u"qt5agg")
ax = plt.axes(projection="3d")
# pdb.set_trace()
ax.scatter(dots_x, dots_y, dots_z, c='red')
plt.show()

Sample input:

dx/dt = y - x 
dy/dt = x*(28-z) - y 
dz/dt = x*y - z 
number of dots: 500 
time step: 0.1 
initials: 0, 1, 1, 1 
Mr. T
  • 11,960
  • 10
  • 32
  • 54
  • 1
    "if i use plot3D instead of scatter3D" -- you're not using scatter3D, you're using scatter, which only takes 2 data arguments, and so it thinks the third is colour information. – Denziloe Sep 03 '18 at 19:24
  • 2
    @Denziloe If `ax` is a mplot3d axes, [`ax.scatter` is the same as `scatter3D`](https://github.com/matplotlib/matplotlib/blob/7c0e7601911b166c42c4034d8a5393d71b2e32d3/lib/mpl_toolkits/mplot3d/axes3d.py#L2309). This function takes 3 input arguments x,y,z, hence "so it thinks the third is colour information" is wrong. – ImportanceOfBeingErnest Sep 03 '18 at 19:36
  • @ImportanceOfBeingErnest Thank you for correcting me, my apologies. – Denziloe Sep 03 '18 at 19:38
  • I am stumped in that case. This code works fine for me and plots red dots. I can only recommend restarting the kernel and updating the matplotlib package. – Denziloe Sep 03 '18 at 19:40
  • 2
    Indeed it would be helpful to see a [mcve], i.e. a code where all input variables are defined and that can be run. Also, which version matplotlib version is used here? – ImportanceOfBeingErnest Sep 03 '18 at 19:45
  • @ImportanceOfBeingErnest 2.2.3 – Yaroslav Bondarev Sep 04 '18 at 06:29
  • What would be a sample input in your script that reproduces you error? P.S.: Are you aware of the [dangers of using `eval` in a script](https://stackoverflow.com/questions/15197673/using-pythons-eval-vs-ast-literal-eval)? – Mr. T Sep 04 '18 at 07:11
  • @Mr.T it's small script for data visualization and i don't worry about it. So, example: dx/dt = y - x dy/dt = x*(28-z) - y dz/dt = x*y - z number of dots: 500 time step: 0.1 initials: 0, 1, 1, 1 – Yaroslav Bondarev Sep 04 '18 at 07:29
  • 1
    Please always edit your question if you have new information. Most people do not carefully read the comments (or the question, but this is another problem). – Mr. T Sep 04 '18 at 07:47

1 Answers1

5

The problem seems to be that matplotlib in my (Windows 10, Python 3.6.5, matplotlib 2.2.3, sympy 1.1.1, Eclipse/PyDev) and your environment can't handle properly sympy.core.floats. Your lists like x_dots do not contain normal Python float values, but the sympy data format. I do not know sympy well, so I am not sure, how to handle properly this problem, but you can confirm that this is the problem by converting the values before plotting:

fx = [float(i) for i in dots_x]
fy = [float(i) for i in dots_y]
fz = [float(i) for i in dots_z]
ax.scatter(fx, fy, fz, c='red')

Alternatively, you can use numpy for the conversion:

ax.scatter(np.asarray(dots_x, dtype = "float"), np.asarray(dots_y, dtype = "float"), np.asarray(dots_z, dtype = "float"), c='red')

Sample output:

enter image description here

P.S.: Just tested it also on Ubuntu 18.04, Python 3.6.5, matplotlib 2.2.3, sympy 1.2, Eclipse/PyDev and the error is reproducible there as well. The error is also independent of the backend - my first suspicion. No difference when tested with Qt5 and TkAgg.

Mr. T
  • 11,960
  • 10
  • 32
  • 54
  • 1
    Mind you that this is a suboptimal workaround. I tagged in `sympy` so maybe somebody with better knowledge of this library can give an answer that addresses the core problem. – Mr. T Sep 04 '18 at 09:37
  • 1
    The original question has been updated to specify the data -- I simply tested with lists of ints. (Python 3.5, Windows 10, can't get matplotlib version at the moment -- but it's clear sympy is the issue). – Denziloe Sep 04 '18 at 09:39
  • @Denziloe Me too. Since I was able to use the code with lists, it was obvious that something is different with those lists like `dots_x`. A stark reminder that people always should include an MCVE in their question. – Mr. T Sep 04 '18 at 09:42