How to resolve visualization errors when using the networkx library? - networkx

The visualization works fine, but there is an error in which the order of the variables x, y, and v in the Top_Edge_list does not match with [G_top[u][v]['weight']]. As a result, the edges are not displayed correctly. Is there anyone who can help me fix this error?
def make_Co_Keyword(Text):
Co_Keyword = list(itertools.combinations(Text,2))
Co_Keyword = [(x,y) for (x,y) in Co_Keyword if x != y]
return Co_Keyword
def make_Edgelist(Token):
Co_Keyword = [make_Co_Keyword(text) for text in Token]
Co_Keyword = list(itertools.chain(*Co_Keyword))
Edge_list = list((x, y, v) for (x,y), v in Counter(Co_Keyword).items())
Edge_list.sort(key=lambda x:-x[2])
return Edge_list
Edge_list_2023 = make_Edgelist(Token)
def Top_Keyword_Edgelist(Token, Edge_list, N, year='2023', font_name='NanumGothic'):
if not os.path.exists('./Graph'):
os.makedirs('./Graph')
filename = 'Graph/Keyword_Network_' + year + '.png'
flatten_tokens = list(itertools.chain(*Token))
All_words = Counter(flatten_tokens)
Top_words = All_words.most_common(N)
Top_words = [word for (word, count) in Top_words]
Top_Edge_list = [(x, y, v) for (x, y, v) in Edge_list if (x in Top_words and y in Top_words)]
Top_Edge_list.sort(key=lambda x: -x[2])
print(Top_Edge_list)
G_top = nx.Graph()
# Add edges with weights
for A, B, weight in Top_Edge_list:
G_top.add_edge(A, B, weight=weight)
# Get node degree and edge weights
degree = [All_words[node] for node in list(G_top.nodes)]
edge_weights = [G_top[u][v]['weight'] / 10 for u, v in G_top.edges()]
# Define the layout and draw the graph
pos = nx.spring_layout(G_top, k=0.5)
plt.figure(figsize=(15, 15))
nx.draw_networkx_nodes(G_top, pos, node_color='yellow', node_size=degree)
nx.draw_networkx_edges(G_top, pos, width=edge_weights, edge_color='red')
nx.draw_networkx_labels(G_top, pos, font_size=12, font_family=font_name, font_color='black')
plt.axis('off')
plt.savefig(filename)
plt.show()```
The visualization works fine, but there is an error in which the order of the variables x, y, and v in the Top_Edge_list does not match with [G_top[u][v]['weight']]. As a result, the edges are not displayed correctly. Is there anyone who can help me fix this error?

Related

Global fit coupled odes system lmfit

I'm trying to get the global fit of multiple set of data considering a system of 4 coupled ODEs.
I have the working code that solves the system of 4 coupled ODEs for a single set of data, and I have the working code that do the global fit with an arbitrary function (but not using odeint).
My problem is that I'm not able to merge the two codes...
Code for coupled ODEs
t =
data=
def gauss(x, amp, sigma, center):
"""Gaussian lineshape."""
return amp * np.exp(-(x-center)**2 / (2.*sigma**2))
def f(xs, t, ps):
"""Lotka-Volterra predator-prey model."""
try:
amp = ps['amp'].value
center = ps['center'].value
sigma = ps['sigma'].value
T1 = ps['T1'].value
Teq = ps['Teq'].value
except Exception:
amp, center, sigma, T1, Teq = ps
s0,s1,s2,s3 = xs
return [- gauss(t,amp,sigma,center) * (s0-s1),\
gauss(t,amp,sigma,center) * (s0-s1) - s1/T1,\
(s1/T1 - s2/Teq),\
(s2/Teq)]
def g(t, x0, ps):
x = odeint(f, x0, t, args=(ps,))
return x
def residual(ps, ts, data):
x0 = ps['s0'].value, ps['s1'].value, ps['s2'].value, ps['s3'].value
b = ps['b'].value
model = (((g(ts, x0, ps)[:,0]-g(ts, x0, ps)[:,1]+g(ts, x0, ps)[:,2]+b*g(ts, x0, ps)[:,3]))**2)/((g(ts, x0, ps)[0,0]))**2
return (model - data).ravel()
# set parameters incluing bounds
params = Parameters()
params.add('s0', value=1, vary=False)
params.add('s1', value=0, vary=False)
params.add('s2', value=0, vary=False)
params.add('s3', value=0, vary=False)
params.add('amp', value=0.02)
params.add('center', value=5)
params.add('sigma', value=0.1)
params.add('T1', value=0.3)
params.add('Teq', value=0.7)
params.add('b', value=-1)
# fit model and find predicted values
result = minimize(residual, params, args=(t, data), method='leastsq')
final = data + result.residual.reshape(data.shape)
Considering the code here: https://lmfit.github.io/lmfit-py/examples/example_fit_multi_datasets.html
I've tried to do by myself the code for global fit in this case
def gauss(x, amp, sigma, center):
"""Gaussian lineshape."""
return amp * np.exp(-(x-center)**2 / (2.*sigma**2))
def f(xs, t, ps):
"""Lotka-Volterra predator-prey model."""
try:
amp = ps['amp'].value
center = ps['center'].value
sigma = ps['sigma'].value
T1 = ps['T1'].value
Teq = ps['Teq'].value
except Exception:
amp, center, sigma, T1, Teq = ps
s0,s1,s2,s3 = xs
return [- gauss(t,amp,sigma,center) * (s0-s1),\
gauss(t,amp,sigma,center) * (s0-s1) - s1/T1,\
(s1/T1 - s2/Teq),\
(s2/Teq)]
def g(t, x0, params):
"""
Solution to the ODE x'(t) = f(t,x,k) with initial condition x(0) = x0
"""
x = odeint(f, x0, t, args=(params,))
return x
def testmodel(params, ts, data):
x0 = params['s0'].value, params['s1'].value, params['s2'].value, params['s3'].value
b = params['b'].value
model = (((g(ts, x0, params)[:,0]-g(ts, x0, params)[:,1]+g(ts, x0, params)[:,2]+b*g(ts, x0, params)[:,3]))**2)/((g(ts, x0, params)[0,0]))**2
return model
def testmodel_dataset(params, i, x):
"""Calculate Gaussian lineshape from parameters for data set."""
x0 = params[f's0_{i+1}'], params[f's1_{i+1}'], params[f's2_{i+1}'], params[f's3_{i+1}']
amp = params[f'amp_{i+1}']
center = params[f'center_{i+1}']
sigma = params[f'sigma_{i+1}']
T1 = params[f'T1_{i+1}']
Teq = params[f'Teq_{i+1}']
b = params[f'b_{i+1}']
return testmodel(params, x, data)
def objective(params, x, data):
"""Calculate total residual for fits of Gaussians to several data sets."""
ndata, _ = data.shape
resid = 0.0*data[:]
# make residual per data set
for i in range(ndata):
resid[i, :] = data[i, :] - testmodel_dataset(params, i, x)
# now flatten this to a 1D array, as minimize() needs
return resid.flatten()
fit_params = Parameters()
for iy, y in enumerate(data):
fit_params.add(f's0_{iy+1}', value=1)
fit_params.add(f's1_{iy+1}', value=0)
fit_params.add(f's2_{iy+1}', value=0)
fit_params.add(f's3_{iy+1}', value=0)
fit_params.add(f'amp_{iy+1}', value=0.5)
fit_params.add(f'center_{iy+1}', value=0.5)
fit_params.add(f'sigma_{iy+1}', value=0.5)
fit_params.add(f'T1_{iy+1}', value=0.5)
fit_params.add(f'Teq_{iy+1}', value=0.4)
fit_params.add(f'b_{iy+1}', value=0.3)
for iy in (2, 3, 4, 5, 6):
fit_params[f'sigma_{iy}'].expr = 'sigma_1'
out = minimize(objective, fit_params, args=(x, data))
report_fit(out.params)
Result -> KeyError: 's0'
There is a problem with x0 and s0,s1,s2,s3, population of the four states.
I'm sorry if the question may be very naive...
Thank you for your help.

How to convert a location on football pitch to coordinates on rectangle?

I have 4 points of football pitch (corner points):
P1(lat, lon, alt), P2(lat, lon, alt), P3(lat, lon, alt), P4(lat, lon, alt).
and a location on the pitch:
L(lat, lon, alt)
I want to convert L(lat, lon, alt) to L(x, y) on a rectangle with size of (W, H).
How to implement this conversion function? (I preferred C# language but implementation language is not important)
The following image describes my problem (I don't know how to implement the Function box):
First off, because output coordinates are 2D, I'm going to assume that we can get rid of altitude information from input coordinates. So input data consist of four points defining the input rectangle:
P1(lat, lon), P2(lat, lon), P3(lat, lon), P4(lat, lon)
and dimensions of the output rectangle: w, h.
I'm also going to ignore the curvature of the Earth (football pitch is small enough). With those assumptions we can implement the conversion function, by performing affine transformation. It would be wasteful to create transformation matrix each time we want to perform a transformation. For that reason we need two functions: first one to create the transformation matrix (called only once), and the second one that will use that matrix to perform transformation itself (called possibly many times, one time for each point we want to transform), something like:
tm = createTransformationMatrix(P1, P2, P4, w, h)
inPoint = (200, 50)
outPoint = transform(inPoint, tm)
Note that we only need three of four input points to unambiguously define a rotated rectangle in 2D euclidean space.
Here is the implementation of createTransformationMatrix and transform functions:
const run = function() {
// Creates transformation matrix to transform
// from rectangle somewhere in 2D space with coordinates p0, px, pi, py
// to rectangle with coordinates (x=0, y=0), (x=w, y=0), (x=w, y=h), (x=0, y=h).
// Note that: p0 is mapped to (x=0, y=0)
// px is mapped to (x=w, y=0)
// py is mapped to (x=0, y=h)
const createTransformationMatrix = function(p0, px, py, w, h) {
// Translate px and py by p0 - pxt and pyt are px and py vectors in coordinate system in which p0 is at the origin
const pxt = {
x: px.x - p0.x,
y: px.y - p0.y,
};
const pyt = {
x: py.x - p0.x,
y: py.y - p0.y,
};
// Create transformation matrix, which is inverse of transformation matrix that:
// 1. Transforms (x=0, y=0) to (x=p0.x, y=p0.y)
// 2. Transforms (x=1, y=0) to (x=p0.x + pxt.x / w, y=p0.y + pxt.y / w)
// 3. Transforms (x=0, y=1) to (x=p0.x + pyt.x / h, y=p0.y + pyt.y / h)
return Matrix.invert3([
[pxt.x / w, pyt.x / h, p0.x],
[pxt.y / w, pyt.y / h, p0.y],
[0 , 0 , 1 ],
]);
};
const transform = function(point, transformationMatrix) {
// Convert point to homogeneous coordinates
const inputVector = [
[point.x],
[point.y],
[1],
];
// Transform inputVector
const outputVector = Matrix.multiply(transformationMatrix, inputVector);
// Convert outputVector back to cartesian coordinates and return
return {
x: outputVector[0][0] / outputVector[2][0],
y: outputVector[1][0] / outputVector[2][0],
};
};
const w = 220;
const h = 115;
const p1 = {x:-79, y:80 };
const p2 = {x:9, y:-96};
const p3 = {x:55, y:-72};
const p4 = {x:-34, y:105};
const tm = createTransformationMatrix(p1, p2, p4, w, h);
const inPoint = {x: 200, y: 50};
const outPoint = transform(inPoint, tm);
console.log(`(${inPoint.x}, ${inPoint.y}) --[transform]--> (${outPoint.x}, ${outPoint.y})`);
}
//// Matrix ////
const Matrix = {};
Matrix.scale = (s, m) => m.map(x => Array.isArray(x) ? Matrix.scale(s, x) : s * x);
Matrix.multiply = function(a, b) {
const aNumRows = a.length, aNumCols = a[0].length;
const bNumRows = b.length, bNumCols = b[0].length;
const m = new Array(aNumRows);
for (let r = 0; r < aNumRows; ++r) {
m[r] = new Array(bNumCols);
for (let c = 0; c < bNumCols; ++c) {
m[r][c] = 0;
for (let i = 0; i < aNumCols; ++i)
m[r][c] += a[r][i] * b[i][c];
}
}
return m;
};
Matrix.invert3 = function(m) {
const [[a, b, c],
[d, e, f],
[g, h, i]] = m;
const det = a*(e*i - f*h) - b*(d*i - f*g) + c*(d*h - e*g);
return Matrix.scale(1/det, [
[e*i - f*h, c*h - b*i, b*f - c*e],
[f*g - d*i, a*i - c*g, c*d - a*f],
[d*h - e*g, b*g - a*h, a*e - b*d],
]);
};
//////////////
run();
I've included all the matrix processing logic, so that this code snippet is self contained, but I would suggest you to instead use some linear algebra library for matrix processing.
I've also made a more visual demo.

Local Binary Patterns features

I have a dataset of images that differ in sizes, and when I extract the local binary pattern (uniform local binary 59 feature) from them I get several features as zeros, is it acceptable as features, if not, and how to deal with it
You can use this solution: https://github.com/arsho/local_binary_patterns
def get_pixel(img, center, x, y):
new_value = 0
try:
if img[x][y] >= center:
new_value = 1
except:
pass
return new_value
def lbp_calculated_pixel(img, x, y):
center = img[x][y]
val_ar = []
val_ar.append(get_pixel(img, center, x-1, y+1)) # top_right
val_ar.append(get_pixel(img, center, x, y+1)) # right
val_ar.append(get_pixel(img, center, x+1, y+1)) # bottom_right
val_ar.append(get_pixel(img, center, x+1, y)) # bottom
val_ar.append(get_pixel(img, center, x+1, y-1)) # bottom_left
val_ar.append(get_pixel(img, center, x, y-1)) # left
val_ar.append(get_pixel(img, center, x-1, y-1)) # top_left
val_ar.append(get_pixel(img, center, x-1, y)) # top
power_val = [1, 2, 4, 8, 16, 32, 64, 128]
val = 0
for i in range(len(val_ar)):
val += val_ar[i] * power_val[i]
return val
# Function to generate horizontal projection profile
def getHorizontalProjectionProfile(image):
# Convert black spots to ones
image[image == 0] = 1
# Convert white spots to zeros
image[image == 255] = 0
horizontal_projection = np.sum(image, axis = 1)
return horizontal_projection
# Function to generate vertical projection profile
def getVerticalProjectionProfile(image):
# Convert black spots to ones
image[image == 0] = 1
# Convert white spots to zeros
image[image == 255] = 0
vertical_projection = np.sum(image, axis = 0)
return vertical_projection
lenx = x_train.shape[0]
x_train_lbp = np.zeros((lenx, 32,32))
for NUM in range(lenx):
gray = rgb2gray(x_train[NUM])
for i in range(0, 32):
for j in range(0, 32):
x_train_lbp[NUM][i][j] = lbp_calculated_pixel(gray, i, j)
lenx = x_test.shape[0]
x_test_lbp = np.zeros((lenx, 32,32))
for NUM in range(lenx):
gray = rgb2gray(x_test[NUM])
for i in range(0, 32):
for j in range(0, 32):
x_test_lbp[NUM][i][j] = lbp_calculated_pixel(gray, i, j)
from sklearn import preprocessing
lenx = x_train.shape[0]
x_train_lbp_vector = np.zeros((lenx, 64))
for NUM in range(lenx):
horizontal_projection = getHorizontalProjectionProfile(x_train_lbp[NUM])
vertical_projection = getVerticalProjectionProfile(x_train_lbp[NUM])
x_train_lbp_vector[NUM] = np.concatenate((horizontal_projection, vertical_projection), axis=0)
x_train_lbp_vector[NUM] = normalize(x_train_lbp_vector[NUM].reshape(1, -1))
lenx = x_test.shape[0]
x_test_lbp_vector = np.zeros((lenx, 64))
for NUM in range(lenx):
horizontal_projection = getHorizontalProjectionProfile(x_test_lbp[NUM])
vertical_projection = getVerticalProjectionProfile(x_test_lbp[NUM])
x_test_lbp_vector[NUM] = np.concatenate((horizontal_projection, vertical_projection), axis=0)
x_test_lbp_vector[NUM] = normalize(x_test_lbp_vector[NUM].reshape(1, -1))

How to get the points (coordinates) on 2D Line?

When I plot point1(p1) and point2(p2), the line between p1 and p2 is drawn. I wanna know a set of the points making the line.
For example, I wanna get x, y coordinates (as array type: x[], y[]). Is there any algorithms or code?
Here's what I have come up with:
It is fair to say that we need to use the slope formula, y = m*x + b to find the slope so we can plot our points along that line. We need the following:
(x1, y1)
(x2, y2)
to find the following:
m = (y2 - y1) / (x2 - x1)
b = y1 - (m * x1)
minX = min(x1, x2) used for limiting our lower bound
maxX = max(x1, x2) used for limiting our upper bound
Now that everything is set, we can plot our line pixel by pixel and obtain all (x,y) coordinates we need. The logic is simple:
let x loop from minX to maxX and plug it in y = m*x + b (we already have all the variables except y). Then, store the (x,y) pair.
I have used Java for coding this logically and visually. Also, I used LinkedList instead of arrays (because I we can't know the number of points we will obtain).
I have also drawn what Java would draw (in blue) and my approach (in red). They are almost perfectly the exact output and coordinates. The image below is zoomed 5x the original size.
Note! The above explanation is what you would use if the line is not vertical (because the slope would be undefined, division by zero). If it is, then you will plug y (instead of x) values and find the x (instead of y) value from the following formula x = (y - b) / m (instead of y = m*x + b). Though, the code takes care of vertical lines.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.LinkedList;
import javax.swing.JFrame;
public class LineDrawing extends Canvas {
int x1 = 5;
int y1 = 10;
int x2 = 105;
int y2 = 100;
double m = ((double) (y2 - y1)) / ((double) (x2 - x1));//slope
double b = y1 - (m * ((double) x1));//vertical shift
//Takes care of the domain we will loop between.
//min and max will be assigned minX and maxX if the line is not vertical.
//minY and maxY are assigned to min and max otherwise.
int minX = Math.min(x1, x2);//minimum x value we should consider
int maxX = Math.max(x1, x2);//maximum x value we should consider
int minY = Math.min(y1, y2);//minimum y value we should consider
int maxY = Math.max(y1, y2);//maximum y value we should consider
int min = 0;
int max = 0;
boolean plugX = true;//if true, the line is not vertical.
LinkedList<Point> points = new LinkedList<>();//Store all points here
public LineDrawing() {
if (x1 == x2) {//plug the y value instead the x, this is a vertical line.
plugX = false;
min = minY;
max = maxY;
} else {//dont change and plug x values.
min = minX;
max = maxX;
}
}
#Override
public void paint(Graphics g) {
super.paint(g);
//Draw the line, using default java drawLine in blue.
g.setColor(Color.BLUE);
g.drawLine(x1, y1, x2, y2);
//change the color to red, it will draw our verison.
g.setColor(Color.RED);
//Draw the points, point by point on screen.
//Plug m, x, and b in the formula y = m*x + b
//to obtain the y value.
//OR
//Plug m, y, and b in the formula x = (y - b) / m
//to obtain the x value if vertical line.
//Then plot (x,y) coordinate on screen and add the point to our linkedList.
for (int i = min; i <= max; i++) {
int obtained = 0;
if (plugX) {//not a vertical line
obtained = (int) Math.round((m * i + b));
System.out.println("x = " + i + " , y = " + obtained);
points.add(new Point(i, obtained));
//Uncomment to see the full blue line.
g.drawLine(i, obtained, i, obtained);
} else {//vertical line
obtained = (int) Math.round((double) (i - b) / (double) m);
System.out.println("x = " + x1 + " , y = " + i);
g.drawLine(x1, i, x1, i);//Uncomment to see the full blue line.
points.add(new Point(x1, i));
}
}
//Print out the number of points as well as the coordinates themselves.
System.out.println("Total points: " + points.size());
for (int i = 0; i < points.size(); i++) {
System.out.println(i + " ( " + points.get(i).x
+ ", " + points.get(i).y + " )");
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(120, 150);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LineDrawing());
frame.setVisible(true);
}
}

How to find the third coordinate of an equilateral triangle?

If I have two points say A(x,y) & B(p,q), how can I find the coordinates of the third point on both sides of AB?
I have the formula for one side, but that cannot give the other one..
Need the formula for coordinates of third point on each sides.
Since you have the result on one side then it's easy to find the symmetrical point.
Let's say your result for the third point is C(r, s). You need to find D(t, w), the symmetrical point of C, with respect to the segment AB.
For this we consider the middle of AB: M(u, v) = (A(x, y) + B(p, q)) / 2;
We have the following equation: M(u, v) = (D(t, w) + C(r, s))/2.
We get D(t, w) = 2 * M(u, v) - C(r, s).
We further get: D(t, w) = A(x, y) + B(p, q) - C(r, s).
A possible solution, based on a rotation matrix R is:
A = [0 0];
B = [0 1];
AB = B-A;
theta = deg2rad(60);
R = [cos(theta) -sin(theta); sin(theta) cos(theta)];
C = A + AB*R';
X = [A;B;C; A];
plot(X(:, 1), X(:, 2));
axis equal