How to create a graph(ANN) with blender 2.9+
Blockquote

I used Animation nodes to do something like this
my result:

first of all this is not a fast way to do this so I unchecked Always and set it to change if AN graph changed

so I made a grid to have some points and used noise and offset matrix nodes like this

then using those matrix transforms instance and placed spheres

so now its time for splines between them
there is a node(find close point) which gets a list of points and makes some edges based on distance or amount of edges you like to make for each point
but the problem is in your picture there is no intersected lines so we have to remove them by masking that edge list I learned this here
so for finding those intersected lines we need some values like starting and end points of each line I also got length just in case(later I use it for deleting the longer edge for each two intersecting edges not the little one)

properties we need to do this:

maybe there is a better solution (rather than two nested for loops) but I looped through lines and using this method found intersected lines and then changed corresponding index in result array to False so it wont be in edge list connected to spline making nodes
here is the code:
def orientation(p1, p2, p3): 
      
    # to find the orientation of  
    # an ordered triplet (p1,p2,p3) 
    # function returns the following values: 
    # 0 : Colinear points 
    # 1 : Clockwise points 
    # 2 : Counterclockwise 
    val = (float(p2.y - p1.y) * (p3.x - p2.x)) - (float(p2.x - p1.x) * (p3.y - p2.y)) 
    if (val &gt; 0): 
          
        # Clockwise orientation 
        return 1
    elif (val &lt; 0): 
          
        # Counterclockwise orientation 
        return 2
    else: 
          
        # Colinear orientation 
        return 0

def doIntersect(p1,q1,p2,q2): 
      
    # Find the 4 orientations required for  
    # the general and special cases 
    o1 = orientation(p1, q1, p2) 
    o2 = orientation(p1, q1, q2) 
    o3 = orientation(p2, q2, p1) 
    o4 = orientation(p2, q2, q1) 
    
    if (o1*o2*o3*o4 == 0 ):
        return False
    
    if ((o1 != o2) and (o3 != o4)): 
        return True
  
    return False



results=[True]*edge_size


for i in range (edge_size):
    for j in range (edge_size):
        if  i == j :
           break
       
        if (results[i]==False):
            break       
       
        if(doIntersect(starts[i],ends[i],starts[j],ends[j])):
            if (lenghts[i]&gt;lenghts[j]):
                results[i] = False
            else:        
                results[j] = False