我尝试将marker参数设置为列表或者和数据等长的列表也无济于事(官方也没有提供)。
用到数据:
# 这是用到的数据
# 分别是X[:, 0],X[:, 1], y
"""
(array([ 9.96346605, 11.0329545 , 11.54155807, 8.69289001, 8.1062269 ,
8.30988863, 11.93027136, 9.67284681, 8.34810316, 8.67494727,
9.17748385, 10.24028948, 8.68937095, 8.92229526, 9.49123469,
9.25694192, 7.99815287, 8.18378052, 8.7337095 , 9.32298256,
10.06393839, 9.50048972, 8.34468785, 9.50169345, 9.15072323,
11.563957 ]),
array([ 4.59676542, -0.16816717, 5.21116083, 1.54322016, 4.28695977,
4.80623966, 4.64866327, -0.20283165, 5.13415623, 4.47573059,
5.09283177, 2.45544401, 1.48709629, -0.63993225, 4.33224792,
5.13284858, 4.8525051 , 1.29564214, 2.49162431, 5.09840649,
0.99078055, -0.26430318, 1.63824349, 1.93824624, 5.49832246,
1.3389402 ]),
array([1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0,
0, 0, 1, 0]))
"""
下面是我的改善方法:
# 实现一种算法,解决scatter函数不可以一图多种形状的问题
import matplotlib.pyplot as plt
import numpy
import pandas
from typing import Any
# 思路: 分类点,然后分类画
def scatterDing(X : list or tuple or numpy.ndarray,
y : list or tuple or numpy.ndarray,
aim : list or tuple or numpy.ndarray,
markers : dict,
func : Any,
**kwargs):
"""
:param X: 横坐标集
:param y: 纵坐标集
:param markers: 对于某一符合集样式,markers是这些不同符合集的组成的字典,如{1 : '>', 0: '*'}
:param aim: 决定性标签,比如对这类数据的分类
:param func: 你所规定的算法,该函数返回值必须是字典组成的列表,因为要用来充当scatter参数
:param kwargs: scatter接口参数
:return:
"""
assert set(aim).issubset(set(list(markers.keys()))) == True
# 开始分类
# 按照你设计的算法返回
marker_s :list = func(X, y, aim, markers)
for i in marker_s:
plt.scatter(**i, **kwargs)
def apiFunc(X, y, aim, markers):
a = numpy.c_[X, y, aim]
df = pandas.DataFrame(a)
reli = []
for i in list(set(markers.keys())):
index = numpy.where(df[2] == i)[0]
x_ = [X[ii] for ii in index]
y_ = [y[ii] for ii in index]
dict_s = dict(x=x_, y=y_, marker=markers[i])
reli.append(dict_s)
return reli
scatterDing(X[:, 0], X[:, 1], y, {1 : 'o', 0: '*'}, apiFunc, s=105)
注: 这里scatterDing是实现函数,他的参数实质是继承了scatter原有参数,只不过通过调用func参数来实现scatter几个常用的参数。因此,func必须是一个返回字典组成列表的函数,你可以通过设计自己的分类方法,来决定新的画图方式,这里我的思路是将某一类的点赋予一种点状,以此类推,因此使用了:assert set(aim).issubset(set(list(markers.keys()))) == True断言——你分的类需要的种类是否是提供每种类对应点状集合的子集
效果展示:
下面来尝试一下三类点,从创建一个新类2开始。(这样属于对应值0、1、2三种类):
# 先创建更多数据并且合并
newS = numpy.random.rand(8) + numpy.random.randint(7, 13, 8)
newy = numpy.random.rand(8) + numpy.random.randint(-1, 6, 8)
newaim = numpy.ones(8, dtype=numpy.uint8) * 2
x1 = numpy.r_[X[:, 0], newS]
x2 = numpy.r_[X[:, 1], newy]
aiim = numpy.r_[y, newaim]
# 试效果
scatterDing(x1, x2, aiim, {1 : 'o', 0: '*', 2: 's'}, apiFunc, s=105)
效果很让我满意!
这里注意一个问题:由于scatter本来参数c可以根据不同目标类设置不同颜色(也只是颜色),但是我这个新方法是不能写入c参数的,这并不是一个缺陷,反而,scatter本就可以根据不同组点自动划分颜色,恰好我的这个新函数正符合这一特性(从上面两个图就可以看到)。(对于其他参数,不幸的是,我并没有测试是否有缺陷,不过目前这个方法对我来说刚好够用@_@。)