如何使一维数组成为散点图中两个二维数组的颜色

How to make a 1d array be the color of two 2d arrays in a scatter plot

这个问题不是最清楚的,但是当我尝试在散点图上通过颜色图绘制不同的颜色时,我基本上遇到了这个错误。 我有两个二维数组(x 和 y),它们的大小都是 42,100。 我想绘制颜色,但基于一维数组和 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?
-> 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.

看起来错误与二维数组的形状有关(将其重塑为 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? 的大小绘制颜色?谢谢!

您可以使用 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()