draw grid lines between same values in a matrix in python

Viewed 234

I have a np.array in python as below:

mat = np.array([[0.2, 0.2, 0.1, 0.1, 0.1],
      [0.2, 0.2, 0.1, 0.1, 0.0],
      [0.2, 0.2, 0.1, 0.1, 0.0],
      [0.2, 0.1, 0.1, 0.0, 0.0]])
mat

Output

I would like to draw lines between the same values in this array such that:

Output with grid line

And finally I would like to have a plot like this:

Grid Plot

I looked for a matplotlib and turtle library in python but could not find a way to plot this.

3 Answers

Using only matplotlib :

import matplotlib.pyplot as plt

mat = [[0.2, 0.2, 0.1, 0.1, 0.1],
      [0.2, 0.2, 0.1, 0.1, 0.0],
      [0.2, 0.2, 0.1, 0.1, 0.0],
      [0.2, 0.1, 0.1, 0.0, 0.0]]

def line(x,y):
     plt.plot(x,y,marker = 'o',color = 'red',
     markerfacecolor='black',markeredgecolor='black')

def draw(mat):
     for i in range(len(mat)):
          for k in range(len(mat[i])-1):
               if mat[i][k] == mat[i][k+1] :
                    line([k,k+1],[len(mat)-i,len(mat)-i])
     for i in range(len(mat)-1):
          for k in range(len(mat[i])):
               if mat[i][k] == mat[i+1][k]:
                    line([k,k],[len(mat)-i,len(mat)-i-1])

draw(mat)
plt.show()

This answer makes use of itertools.groupby. We start by flipping the array so when we iterate over it we go bottom to top, and for each row we use groupby to capture the continuous groups and their size. Based on that the first loop builds the dots and lines.

Then we transpose the array and iterate over the columns doing basically the same thing but swapping the x and y.

You could almost surely turn this into a function with a bit more thought, to basically handle rows and columns without almost duplicating the code.

import numpy as np
from itertools import groupby
import matplotlib.pyplot as plt

mat = np.array([[0.2, 0.2, 0.1, 0.1, 0.1],
      [0.2, 0.2, 0.1, 0.1, 0.0],
      [0.2, 0.2, 0.1, 0.1, 0.0],
      [0.2, 0.1, 0.1, 0.0, 0.0]])

mat = np.flip(mat,axis=0)

for r in range(mat.shape[0]-1,-1,-1):
    c = 0
    l = [(key, len(list(it))) for (key, it) in groupby(mat[r])]

    for p in l:
        if p[1]==1:

            plt.plot(c,r, color='red',
                     linestyle='solid',
                     marker='o',
                     markerfacecolor='black', 
                     markeredgecolor='black',
                     markersize=12)
            c+=1
        else:
            x = []
            y = []
            for i in range(p[1]):
                x.append(c)
                y.append(r)
                c+=1
            plt.plot(x, y, color='red',
                     linestyle='solid', 
                     marker='o',
                     markerfacecolor='black', 
                     markeredgecolor='black', 
                     markersize=12)
    r+=1
    
mat = np.transpose(mat)

for r in range(mat.shape[1],-1,-1):
    c = 0
    l = [(key, len(list(it))) for (key, it) in groupby(mat[r])]
    for p in l:
        if p[1]==1:
            plt.plot(r,c, 
                     color='red', 
                     linestyle='solid', 
                     marker='o',
                     markerfacecolor='black',
                     markeredgecolor='black',
                     markersize=12)
            c+=1
        else:
            x = []
            y = []
            for i in range(p[1]):
                x.append(c)
                y.append(r)
                c+=1
            plt.plot(y, x,
                     color='red', 
                     linestyle='solid', 
                     marker='o',
                     markerfacecolor='black', 
                     markeredgecolor='black', 
                     markersize=12)
    r+=1

Output

enter image description here

Using turtle graphics, we could approach the problem this way:

from turtle import Screen, Turtle
import numpy as np

NEIGHBORS = [(0, 1), (1, 0)]

matrix = np.array([
    [0.2, 0.2, 0.1, 0.1, 0.1],
    [0.2, 0.2, 0.1, 0.1, 0.0],
    [0.2, 0.2, 0.1, 0.1, 0.0],
    [0.2, 0.1, 0.1, 0.0, 0.0]
])

height, width = matrix.shape

screen = Screen()
screen.setup(width * 100, height * 100)
screen.setworldcoordinates(-0.5, height - 0.5, width - 0.5, -0.5)

turtle = Turtle()
turtle.hideturtle()
turtle.speed('fastest')  # there are ways to go even faster
turtle.color('red')
turtle.pensize(4)
turtle.penup()

for row in range(height):
    for col in range(width):
        for dx, dy in NEIGHBORS:
            try:
                if matrix[row, col] == matrix[row + dy, col + dx]:
                    turtle.goto(col, row)
                    turtle.pendown()
                    turtle.goto(col + dx, row + dy)
                    turtle.penup()
            except IndexError:
                pass

        turtle.goto(col, row)
        turtle.dot(15, 'black')

screen.exitonclick()

enter image description here

Related