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
I would like to draw lines between the same values in this array such that:
And finally I would like to have a plot like this:
I looked for a matplotlib and turtle library in python but could not find a way to plot this.
CodePudding user response:
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()
CodePudding user response:
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
CodePudding user response:
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()