#python #numpy #matplotlib #jupyter #scatter-plot
Вопрос:
Вопрос не самый ясный, но я в основном получаю эту ошибку, когда пытаюсь отобразить разные цвета на цветовой карте на точечной диаграмме. У меня есть два 2d массива (x и y), и оба они имеют размер 42 100. Я хотел бы отобразить цвет, но на основе массива 1D и размера 42. Однако я получаю повторяющуюся ошибку:
Пожалуйста, обратите внимание, что это всего лишь пример воспроизводимости!
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? -gt; 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: --gt; 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 lt;listcompgt;(.0) 384 else: --gt; 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. --gt; 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): --gt; 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 lt;modulegt; ----gt; 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): -gt; 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: -gt; 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 = -gt; 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: -gt; 4356 raise invalid_shape_exception(c.size, xsize) from err 4357 # Both the mapping *and* the RGBA conversion failed: pretty 4358 # severe failure =gt; 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…).
Ошибка исчезнет, если вы измените цветовой массив в соответствии с формой 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()
Но в моей реальной программе мне нужно сохранить цветовой массив в форме 42, чтобы цветовая панель имела смысл. Есть ли обходной путь для решения этой проблемы? Цель состоит в том, чтобы построить диаграмму рассеяния x и y (двухмерные массивы размером 42 100), а затем построить цвет на основе размера 42? Спасибо!
Ответ №1:
Вы можете использовать color = np.repeat(np.arange(42), 100)
повторение каждого значения цвета столько раз , сколько столбцов в данных.
Вот пример. Количество строк сокращено до 4, а столбцов-до 10 для упрощения отладки:
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()
При исходном размере данных пример будет выглядеть следующим образом:
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()
Комментарии:
1. Спасибо! Последний вопрос заключается в том, можно ли сделать то же самое , но с цветом, имеющим форму 100, что-то вроде
color = np.repeat(np.arange(100), 42)
, но это не дает правильных значений тиков цветовой шкалы… большое спасибо!2. Если 100 тиков не подходят, вы могли
plt.colorbar(ticks=np.arange(0, x.shape[0], 2))
бы показать только четные тики. Или вы можете увеличить размер рисунка. Кроме того, в зависимости от того, как организованы ваши данные , вам может потребоватьсяnp.tile
вместоnp.repeat
, напримерcolor=np.tile(np.arange(100), 42)