不改变相对位置的前提下把点散开2

之前的方法只适合数据点只有一个中心的情况,有多个中心的数据可能会有反效果。
思路2:不考虑中心,按点和下一个点的距离进行判断和调整。
最终呈现的结果中相邻的两个点之间的距离占坐标轴总长度的1/25。依次排查各个点,如果和下一个点的距离小于这个最小值,就进行调整。

import math
from matplotlib import pyplot as plt

def find_min_dis(xdata):
    """找两点间允许的最小距离"""
    return (max(xdata) - min(xdata))/25

def adjust_x(order_num, n, xdis):
    """以该点和下一个点连线的法线为参照,向两边分离上下的点
    :param order_num: 数据列表, [序号, x坐标, y坐标];
    :param n: 点的索引, 该点和下一个点距离需要加大;
    :param xdis: 和允许的最小距离相差的值;
    :return: 调整过点后的数据列表;
    """
    for i in range(len(order_num)):
        if i <= n:
            # 调整比例应该为1/2,但是变化过大
            order_num[i][1] -= xdis/20
        elif i > n:
            order_num[i][1] += xdis/20
    return order_num

def adjacent_scatter(xdata):
    """某一个循环内的扩散"""
    order_num = []
    for i in range(len(xdata)):
        order_num.append([i, xdata[i]])
    
    order_num.sort(key=lambda x: x[1])
    min_xdis = find_min_dis(xdata)
    for i in range(len(xdata) - 1):
        xdis = order_num[i+1][1] - order_num[i][1]
        if xdis < min_xdis:		# 坐标1的距离小于最小值
            order_num = adjust_x(order_num, i, min_xdis-xdis)
    order_num.sort(key=lambda x: x[0])
    return [x[1] for x in order_num]

def main():
    colors = ['#{0:0>2}{0:0>2}{0:0>2}'.format(i) for i in range(95)]
    cycles = 0
    while cycles < 20:
        plt.scatter(xdata, ydata, c=colors)
        plt.savefig(f'ok{cycles}.png')
        plt.clf()
        
        xdata, ydata = adjacent_scatter(xdata, ydata)
        ydata, xdata = adjacent_scatter(ydata, xdata)
        cycles += 1

初始点分布
扩散2次点分布
扩散9次点分布
上面三个图依次是初始点图、扩散2次后的点图和扩散9次后的点图。从结果能看到,这次的思路扩散很少的次数就能基本满足需求,扩散次数多了反而不是太好。对存在多个中心的数据点能较好地分散开,对于不要求精确度的分散已经能使用了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值