Can I use vtkCellLocator to find intersected cells by line - c++

I have mesh grid and there is a line passing through several cells. I want to get all the cells which are intersected by line.
I have start and end points of line and I have mesh vertexes coordinates.
What is the fastest way to compute this condition, is there any way, I could use vtk class ?

You can check the vtk class vtkOBBTree, and the method IntersectWithLine. This is python, but you get the idea of how it works here
from vedo import dataurl, Mesh, Line, show
m = Mesh(dataurl+'bunny.obj')
l = Line([-0.15,0.1,0], [0.1,0.1,0], c='k', lw=3)
pts_cellids = m.intersectWithLine(l, returnIds=True)
print(pts_cellids)
show(m, l, axes=1)
You should get cells ids: [3245 1364]

Related

How to put parameters obtained through "pandas.describe" in a plot in one go?

Like if i have a data frame with four columns and i want to plot any two columns of it just to visualize my data. And we can find the value of all the parameters by using this
pd.describe()
count 332.000000
mean 5645.999337
std 391.081389
min 4952.290000
25% 5294.402500
50% 5647.905000
75% 6028.805000
max 6290.980000
Now, how can we put the information that we get with this function ('pandas.describe') into the plot in just one go. Instead of using the usual 'label' function from matplotlib.
Matplotlib has the option ax.text. So you need to convert this info into text.
Here comes an example:
import pandas as pd
df=pd.DataFrame({'A':[1,2,3]})
desc=df.describe()
Describe is also a DataFrame, you can turn every column into a string list:
data1=[i for i in desc.index]
data2=[str(i) for i in desc.A]
Now you can join both with a colon in between:
text= ('\n'.join([ a +':'+ b for a,b in zip(data1,data2)]))
Then in your graph, you can input:
ax.text(pos1, pos2, text , fontsize=15)
Where pos1 and pos2are numbers for the position of your text.
Does that help?
Tell me!

Python:How to do operations on a grid

For a word game(something similar to image provided),where inside a grid various letters are entered on different tile,enter image description here I had to create a 6*6 grid and then do operations on it like:
a)place the tile on a specific location in the grid and
b)return the location of any tile on the grid
c)determining the top scoring words in the grid
Till now I have managed to create the grid but i have no clue of how to place a tile on a specific grid or fetch the location of a tile on the grid.I have created the following grid:
grid = [[" _" for x in range(6)]]
for y in range(6):
list1 = []
for x in range(13):
if x%2 == 0:
list1.append("|")
else:
list1.append("_")
grid.append(list1)
for row in grid:
print("".join(row))
I am new to python and any help would be appreciated.
Did you try to run this piece of code? I don't think so because the indentation here is bad, so it won't work.
You should rename your variable list1 to row for comprehension
purpose : your variable names should always be as descriptive as
possible.
Here to initialize in a more compact way your grid you could do:
grid = [["_" if x%2==0 else "|" for x in range(13)] for x in range(6)]
To access a specific tile you can do:
grid[y][x]
In example, the following command would print the cell on the third row second column:
print(grid[3][2])
To set the value you can do:
grid[y][x] = value
But I think that you should see a course about learning Python before trying to do these things.
Google it and good luck!

numpy.interpd -returning only the last value after interpolation

I have a set of data points in pressure(p) and vmr.
I want to find the vmr values for another pressure grid(pressure_grid).I used np.interp,
for lines in itertools.islice(input_file, i, l):
lines=lines.split()
p.append(float(lines[0]))
vmr.append(float(lines[3]))
x = np.array(p)
y = np.array(vmr)
yi=np.interp(pressure_grid,x,y)
But when I tried to print "yi" it is printing only the value(i.e.,vmr value) corresponding to the last value of "pressure_grid".For all iterations it is printing the same value
I tried to print p and vmr ,Everything seems to be fine till there.I'm not able to understand why this is happening...
I'm new to this........Please Help
This is how my file looks like,first column-p and second column-vmr.
and this is my pressure grid
https://1drv.ms/t/s!AmPNuP3pNnN8g35NPwIfzSl-VBeO
https://1drv.ms/f/s!AmPNuP3pNnN8hAx3opovgipabSjJ
There are two issues with your code. First x and y are being overwritten for each iteration of the for loop, which means, x and y contain just a single element for the interpolation. To fix this, you could define x and y list outside the loop and append in the for loop, or more simply, just use numpy.loadtxt():
import numpy as np
data = np.loadtxt('demo.txt',comments='<',usecols=[0,2])
Here, I have specified to skip rows beginning with a less than sign, so we only get the actual data.
Second, for numpy.interp to actually work, you need the x-coordinate to be an increasing sequence. (check the notes). For your data, x is a decreasing sequence, so you should flip the data after loading it:
x = data[::-1,0]
y = data[::-1,1]
interpolation = np.interp(grid,x,y)
Alternatively, you could just use the scipy.interpolate package on the original, unflipped data. This has the added advantage of allowing you to extrapolate data that isn't enclosed by your input domain:
from scipy import interpolate
interpolation = interpolate.interp1d(x,y,fill_value='extrapolate')
Note: your input file appears to have more than one <Matrix> </Matrix> set. To get all this to work, I trimmed the file so it only contained one dataset. Otherwise, your x input data will not be strictly increasing, even after flipping, and you will have to sort.

igraph invalid vertex Id

I'm trying to run igraph's fast greedy community detection algorithm using the following code:
G = Graph()
L = []
V = []
for row in cr:
try:
l = []
source = int((row[0]).strip())
target = int((row[1]).strip())
weight = int((row[2]).strip())
l.append(source)
l.append(target)
if l not in L:
L.append(l)
if source not in V:
V.append(source)
if target not in V:
V.append(target)
except ValueError:
print "Value Error"
continue
if weight == 1:
continue
G.add_vertices(max(V))
G.add_edges(L)
cl = G.community_fastgreedy(weights=weight).as_clustering(10);
But this is the error I'm getting:
igraph._igraph.InternalError: Error at type_indexededgelist.c:272: cannot add edges, Invalid vertex id
I found this: Cannot add edges, Invalid vertex ID in IGraph so I tried adding all the vertices and then all the edges but I still get an error.
Does the above code do the same thing as:
tupleMapping = []
for row in cr:
if int(row[2]) < 10:
continue
l = [row[0], row[1], row[2]]
tupleMapping.append(tuple(l))
g = Graph.TupleList(tupleMapping)
cl = g.community_fastgreedy().as_clustering(20)
I dont have to explicitly say the G.community_fastgreedy(weights=weight) right?
Also another problem I was having; when I try to add more clusters in the following way:
cl = g.community_fastgreedy().as_clustering(10)
cl = g.community_fastgreedy().as_clustering(20)
I get two large clusters and the rest of the clusters compose of one element. This happens when I try to make the cluster size 5/10/20, is there any way for me to make the clusters more equally divided? I need more than 2 clusters for my dataset.
This is a small snippet of the data I'm trying to read from the csv file so that I can generate a graph and then run the community detection algorithm:
202,580,11
87,153,7
227,459,6
263,524,11
Thanks.
That's right, the second code does the same. In the first example, the problem is that when you add edges, you refer to igraph's internal vertex IDs, which always start from 0, and go until N-1. Does not matter your own vertex names are integers, you need to translate them to igraph vertex IDs.
The igraph.Graph.TupleList() method is much more convenient here. However, you need to specify that the third element of the tuple is the weight. You can do it either by weights = True or edge_attrs = ['weight'] arguments:
import igraph
data = '''1;2;34
1;3;41
1;4;87
2;4;12
4;5;22
5;6;33'''
L = set([])
for row in data.split('\n'):
row = row.split(';')
L.add(
(row[0].strip(), row[1].strip(), int(row[2].strip()))
)
G = igraph.Graph.TupleList(L, edge_attrs = ['weight'])
You can then create dictionaries to translate between igraph vertex IDs and your original names:
vid2name = dict(zip(xrange(G.vcount()), G.vs['name']))
name2vid = dict((name, vid) for vid, name in vid2name.iteritems())
However, the first is not so much needed, as you can always use G.vs[vid]['name'].
For fastgreedy, I think you should specify the weights, at least the documentation does not tell if it automatically considers the attribute named weight if such attribute exists.
fg = G.community_fastgreedy(weights = 'weight')
fg_clust_10 = fg.as_clustering(10)
fg_clust_20 = fg.as_clustering(20)
If fastgreedy gives you only 2 large clusters, I can only recommend to try other community detection methods. Actually you could try all of them which run within reasonable time (it depends on the size of your graph), and then compare their results. Also because you have a weighted graph, you could take a look at moduland method family, which is not implemented in igraph, but has good documentation, and you can set quite sophisticated settings.
Edit: The comments from OP suggest that the original data describes a directed graph. The fastgreedy algorithm is unable to consider directions, and gives error if called on a directed graph. That's why in my example I created an undirected igraph.Graph() object. If you want to run other methods, some of those might able to deal with directed networks, you should create first a directed graph:
G = igraph.Graph.TupleList(L, directed = True, edge_attrs = ['weight'])
G.is_directed()
# returns True
To run fastgreedy, convert the graph to undirected. As you have a weight attribute for the edges, you need to specify what igraph should do when 2 edges of opposit direction between the same pair of vertices being collapsed to one undirected edge. You can do many things with the weights, like taking the mean, the larger, or the smaller one, etc. For example, to make the combined edges have a mean weight of the original edges:
uG = G.as_undirected(combine_edges = 'mean')
fg = uG.community_fastgreedy(weights = 'weight')
Important: be aware that at this operation, and also when you add or remove vertices or edges, igraph reindexes the vertices and edges, so if you know that vertex id x corresponds to your original id y, after reindexing this won't be valid anymore, you need to recreate the name2vid and vid2name dictionaries.

Error "'Quiver' object has no attribute 'shape'"

I am using the Python Quiver function to combine u-velocity and v-velocity values into a vector map. I have semi-successfully combined the two arrays by using the quiver function within the colormesh() function, and my code returns a B&W plot of the data, but I get an error message "'Quiver' object has no attribute 'shape'". The data plot also seems to not allow the landmass/ocean commands to plot (or if I put those commands before the colormesh() command, then the quiver() command doesn't work). Also, I can't seem to add color or size to the quiver arrows. Why am I still getting sort of successful plotting, if I'm getting this error message? How can I fix it? I tried making a quiver array and then just plotting the name of that in the colormesh(), but that didn't work, either.
Thank you!!
m = Basemap(llcrnrlon=-120,llcrnrlat=32,urcrnrlon=-116,urcrnrlat=35,
resolution='l',projection='stere',
lat_0=32.5,lon_0=-117.)
fig = plt.figure(figsize=(10,10))
plt.figtext(.45,.15,'Figure 1. Avg. velocity from CORDC HF Radar avg. June 1, 2013',fontsize=12,ha='center')
x, y = m(lon,lat)# define color map
cmap = plt.cm.hsv
cs = m.pcolormesh(x,y,quiver(lon[0:230],lat[0:230],u_nanmean_mask,v_nanmean_mask),shading='gouraud',cmap=cm.RdYlBu,vmin=-0.10,vmax=0.12)
m.drawcoastlines()
m.fillcontinents(color='#989865',lake_color='w')
m.drawmapboundary(fill_color='w')
m.drawparallels(np.arange(-80.,81.,5.),labels=[0,1,1,0])
m.drawmeridians(np.arange(-180.,180.,5.),labels=[1,0,0,1])