Python vtkInterface0.9.3 library examples not working - python

I found out about vtkInterface, a python vtk wrapper that facilitates vtk plotting.
Trying to run their first example, under Initialize from Numpy Arrays in this page: vtkInterface.PolyData, by simply running the code as is, and it results in a gray render window with nothing in it.
Some of the other examples do work but this is exactly the thing that I need at the moment and was wondering if anybody has tried it and knows what might be wrong.
Example Code:
import numpy as np
import vtkInterface
# mesh points
vertices = np.array([[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0]])
# mesh faces
faces = np.hstack([[4, 0, 1, 2, 3], # square
[3, 0, 1, 4], # triangle
[3, 1, 2, 4]]) # triangle
surf = vtkInterface.PolyData(vertices, faces)
# plot each face with a different color
surf.Plot(scalars=np.arange(3))

The example is wrong. It lacks a fifth point. For example this will work.
vertices = np.array([[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0],
[0.5, 0.5, -1]])
Explanation: In VTK, faces are encoded in the following way:
face_j = [ n, i_0, i_1, ..., i_n ]
Here, n is the number of points per face, and i_k are the indices of the points in the vertex-array. The face is formed by connecting the points vertices[i_k] with k in range(0,n). A list of faces is created by simply concatenating the single face specifications:
np.hstack([face_0, face_1, ..., face_j, ...])
The advantage of this encoding is that the number of points used per face, n, can vary. So a mesh can consist of lines, triangles, quads, etc.
In the example, the vertex with id 4 is used in the second and third face. So vertices is required to consist of at least five entries. Surprisingly, the sample doesn't crash, as VTK almost certainly would if some faces were accessing non-existing points.

Related

How to make adjacency matrix for sub-graphs detected by leidenalg

I need to make adjacency matrix for each community(sub-graph) detected by leidenalg; but the problem is the output of find_partition() is just showing the nodes in each sub-graph. Is there any way to convert the output to something like np.array with edge information of each sub-graph??
import leidenalg
import igraph as ig
G = ig.Graph.Erdos_Renyi(10, 0.1);
partitions = leidenalg.find_partition(G, leidenalg.ModularityVertexPartition)
print(partitions)
output:
Clustering with 10 elements and 3 clusters
[0] 2, 5, 8, 9
[1] 3, 4, 6
[2] 0, 1, 7
You can do this by simply constructing the subgraph and the computing the adjacency matrix. Your example is not quite reproducible because ig.Graph.Erdos_Renyi uses the random number generator. Therefore, I added a little code to set the random seed and generate a graph like yours, except reproducible. I simply get the adjacency matrix for the first partition, but of course, you can just loop through the partitions and get all of the matrices.
import igraph as ig
import leidenalg
import random
random.seed(a=321)
G = ig.Graph.Erdos_Renyi(10, 0.28);
partitions = leidenalg.find_partition(G, leidenalg.ModularityVertexPartition)
print(partitions)
P0 = G.subgraph(partitions[0])
P0.get_adjacency()
Out[15]: Matrix([[0, 1, 1, 0], [1, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]])

Numpy "Place Object" in Array

I have a program where I am trying to generate outputs based on a few IO's--like these two IOs.
The program recognizes objects in the grids, and it represents the grids as numpy arrays. Is there a built in numpy function, or elegant solution, to 'inserting' an object into a numpy array?
Ex: if it recognizes a square object, like [[1, 1], [1, 1]], and I have a grid [[0, 0, 0], [0, 0, 0], [0, 0, 0]], how can I insert the object into the grid so it becomes [[0, 1, 1], [0, 1, 1], [0, 0, 0]] (but for any object inserted at any index)?
There is no way other than knowing the indices at which to change the value of your 2-D numpy array.
So if your grid is a 2-D array of zeros like:
grid = np.zeros((10, 10))
Then you can use a tuple of indices tuples (x, y), each identifying a cell of your grid at which you want to change the grid value:
indices = ((x1, y1), (x2, y2), ..., (xn, yn))
then you can use it to assign values in your 2-D numpy array like so:
grid[indices] = 1

Trying to extract a patch given 8 points from NumPy array

I have an array which looks like this
boxes = [268,885,426,865,406,707,248,727]
It's a collection of (x,y) points. If I plot this using this function:
def draw_boxes_on_image_mod(image, boxes):
image_copy = image.copy()
image_copy = np.array(image_copy)
cv2.line(image_copy, (boxes[0],boxes[1]),(boxes[2],boxes[3]),(0,255,255),2)
cv2.line(image_copy, (boxes[4], boxes[5]),(boxes[6],boxes[7]),(0,255,255),2)
cv2.line(image_copy, (boxes[0],boxes[1]),(boxes[6],boxes[7]),(0,255,255),2)
cv2.line(image_copy, (boxes[4], boxes[5]),(boxes[2],boxes[3]),(0,255,255),2)
scipy. misc.imsave('/home/ryan/TEST.png', image_copy)
return image_copy
I get an image with a rectangle drawn on the part of the image I'm interested in, But what I want is to extract that portion and convert it into an image.
I was thinking of using NumPy indexing to achieve this but
image = image[268:426]
I am finding it difficult to understand how to index the (x,y) values together.
Any suggestions would be really helpful.Thanks in advance.
When you just call A[1:3] all you are asking for are the rows 1 and 2, the rows including 1 and stopping before 3, so you must take into account columns as well to get the exact subsection you need.
You can do this in numpy by stating the range of the rows and columns, the subsection of the array you want will start at a row and end at row + m as well as starting at a column and ending at column + n
For example take
A = np.array([[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]])
We want just the values in the middle set to 1, so we select them with
Asub = A[1:3,1:3]
To get
[[1 1]
[1 1]]

Create matrix with same in and out degree for all nodes

I've stated this question in graph theory terms, but that conceptualization isn't necessary.
What I'm trying to do, using Python, is produce a matrix of zeros and ones, where every row has the same number of ones and every column has the same number of ones. The number for rows will not be the same as the number for columns when the number of rows (sending nodes) does not equal the number of columns (receiving nodes) -- which is something I'm allowing.
It makes sense to me to do this in numpy, but there may be other packages (like networkx?) that would help.
Here's the function I'm looking to write with the desired inputs and outputs:
n_pre = 4 # number of nodes available to send a connection
n_post = 4 # number of nodes available to receive a connection
p = 0.5 # proportion of all possible connections that exist
mat = generate_mat(n_pre, n_post, p)
print mat
The output would be, for example:
[[0, 1, 0, 1],
[1, 0, 1, 0],
[1, 1, 0, 0],
[0, 0, 1, 1]]
Notice, every column and every row has two ones in it. Aside from this constraint, the positions of the ones should be random (and vary from call to call of this function).
In graph theory terms, this means every node has an in-degree of 2 and an out-degree of 2 (50% of all possible connections, as specified with p = 0.5).
For a square matrix, what you describe is the adjacency matrix of a random k-regular directed graph, and there are known algorithms to generate such graphs. igraph implements one:
# I think this is how you call it - it's an instance method for some reason.
igraph.Graph().K_Regular(n, k, directed=True)
networkx has a function for random k-regular undirected graphs:
networkx.random_regular_graph(k, n)
For a non-square matrix, what you describe is isomorphic to a random biregular graph. I have found no convenient existing implementation for random biregular graphs, but the term should be a good starting point for searching for known algorithms.
First, do the pre-work so that we have available the size of the square matrix and the population pop of each row and column. Now, initialize a matrix with pop ones on the diagonal. For n = 6 and pop = 3, you'd have
[[1, 1, 1, 0, 0, 0]
[0, 1, 1, 1, 0, 0]
[0, 0, 1, 1, 1, 0]
[0, 0, 0, 1, 1, 1]
[1, 0, 0, 0, 1, 1]
[1, 1, 0, 0, 0, 1]]
Now, apply your friendly neighborhood random shuffle operation to the columns, then the rows (or in the other order). There's your matrix. A shuffle of rows-only or columns-only does not change the population on either axis.

Replace numpy cell with values from second array based on a condition

I have two images, img1 and img2. I'm trying to find everywhere in img1 that the color [0,204,204] occurs and replace it with whatever is in img2 in the same place. I can use np.where() to find the places where that color occurs and replace it with a different color directly:
img1[np.where((img1==[0,204,204]).all(axis=2))] = [255,255,0]
I'm unsure how to grab the indices of these cells as the shape of the images are 5070000 with 3 dimensions, so, I can't display the array's effectively. Looking over the numpy documentation, I think I can do something like:
img2[img1[img1==[0,204,204]]]
to get the indices of img1 where that color occurs and then call the same array position from img2, but, I can't seem to get this syntax correct. Help?
If I understand correctly, you can use the following:
img1[np.where((img1==[0,204,204]).all(axis=2))] = img2[np.where((img1==[0,204,204]).all(axis=2))]
This works because the syntax you had originally (np.where((img1==[0,204,204]).all(axis=2))) already returns the indices you are looking for
Example (on a small array):
img1 = np.array([[[0,204,204],[0,0,0],[1,2,3]]])
array([[[ 0, 204, 204],
[ 0, 0, 0],
[ 1, 2, 3]]])
img2 = np.array([[[0,1,2],[1,1,1],[2,7,3]]])
array([[[0, 1, 2],
[1, 1, 1],
[2, 7, 3]]])
img1[np.where((img1==[0,204,204]).all(axis=2))] = img2[np.where((img1==[0,204,204]).all(axis=2))]
>>> img1
array([[[0, 1, 2],
[0, 0, 0],
[1, 2, 3]]])

Categories