Issue
The question is not the clearest, but I am basically getting this error when I try to plot different colors vi a colormap on a scatter plot. I have two 2d arrays (x and y) and they are both a size of 42,100. I would like to plot the color but based on a 1D array and the size of 42. However I get a recurrent error:
Please note that this is just an example for reproducibility!
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
# test
x = np.random.rand(42,100)
y = np.random.rand(42,100)
color = np.arange(0,42,1)
# scatter plot of x and y with no colormap!
plt.scatter(x,y,s=5)
plt.show()
# error occurs when trying to plot the 1D array as the color
plt.scatter(x,y,s=5,c=color,cmap='jet')
plt.show()
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/axes/_axes.py in _parse_scatter_color_args(c, edgecolors, kwargs, xsize, get_next_color_func)
4349 try: # Is 'c' acceptable as PathCollection facecolors?
-> 4350 colors = mcolors.to_rgba_array(c)
4351 except (TypeError, ValueError) as err:
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/colors.py in to_rgba_array(c, alpha)
384 else:
--> 385 rgba = np.array([to_rgba(cc) for cc in c])
386
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/colors.py in <listcomp>(.0)
384 else:
--> 385 rgba = np.array([to_rgba(cc) for cc in c])
386
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/colors.py in to_rgba(c, alpha)
205 if rgba is None: # Suppress exception chaining of cache lookup failure.
--> 206 rgba = _to_rgba_no_colorcycle(c, alpha)
207 try:
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/colors.py in _to_rgba_no_colorcycle(c, alpha)
283 if not np.iterable(c):
--> 284 raise ValueError(f"Invalid RGBA argument: {orig_c!r}")
285 if len(c) not in [3, 4]:
ValueError: Invalid RGBA argument: 0.0
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
/tmp/ipykernel_2811997/1837670260.py in <module>
----> 1 plt.scatter(x,y,s=5,c=color,cmap='jet')
2 plt.show()
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/pyplot.py in scatter(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, data, **kwargs)
3066 vmin=None, vmax=None, alpha=None, linewidths=None, *,
3067 edgecolors=None, plotnonfinite=False, data=None, **kwargs):
-> 3068 __ret = gca().scatter(
3069 x, y, s=s, c=c, marker=marker, cmap=cmap, norm=norm,
3070 vmin=vmin, vmax=vmax, alpha=alpha, linewidths=linewidths,
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
1359 def inner(ax, *args, data=None, **kwargs):
1360 if data is None:
-> 1361 return func(ax, *map(sanitize_sequence, args), **kwargs)
1362
1363 bound = new_sig.bind(ax, *args, **kwargs)
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/axes/_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, **kwargs)
4514 orig_edgecolor = kwargs.get('edgecolor', None)
4515 c, colors, edgecolors = \
-> 4516 self._parse_scatter_color_args(
4517 c, edgecolors, kwargs, x.size,
4518 get_next_color_func=self._get_patches_for_fill.get_next_color)
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/matplotlib/axes/_axes.py in _parse_scatter_color_args(c, edgecolors, kwargs, xsize, get_next_color_func)
4354 else:
4355 if not valid_shape:
-> 4356 raise invalid_shape_exception(c.size, xsize) from err
4357 # Both the mapping *and* the RGBA conversion failed: pretty
4358 # severe failure => one may appreciate a verbose feedback.
ValueError: 'c' argument has 42 elements, which is inconsistent with 'x' and 'y' with size 4200.
It looks like the error has something to do with the shape of the 2d array (reshaped it to 4200...).
The error goes away if you change the color array to match the shape of 4200:
color_but_not_accurate = np.linspace(0,42,4200)
plt.scatter(x,y,s=5,c=color_but_not_accurate,cmap='jet')
plt.show()
But in my real program, I sort of need to retain the color array to be a shape of 42 for the colorbar to make sense. Is there a workaround to this problem? Goal is to plot the scatter plot of x and y (two-d arrays of size 42,100) and then plot the color based on the size of 42? Thanks!
Solution
You could use color = np.repeat(np.arange(42), 100)
, repeating each color value as many times as there are columns in the data.
Here is an example. The number of rows is reduced to 4 and columns to 10 for easier debugging:
import matplotlib.pyplot as plt
import numpy as np
x = np.tile(np.arange(10), 4).reshape(4, 10)
y = (np.random.randn(4, 10) + 0.1).cumsum(axis=1) + np.arange(0, 40, 10)[:, np.newaxis]
color = np.repeat(np.arange(x.shape[0]), x.shape[1])
plt.scatter(x, y, s=50, c=color, cmap='plasma')
plt.colorbar(ticks=np.arange(x.shape[0]))
plt.show()
With the original size of the data, the example would look like:
import matplotlib.pyplot as plt
import numpy as np
x = np.tile(np.arange(100), 42).reshape(42, 100)
y = (np.random.randn(42, 100) + 0.01).cumsum(axis=1) + np.arange(0, 420, 10)[:, np.newaxis]
color = np.repeat(np.arange(x.shape[0]), x.shape[1])
plt.scatter(x, y, s=5, c=color, cmap='plasma')
plt.colorbar(ticks=np.arange(x.shape[0]))
plt.show()
Answered By - JohanC
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.