Related
I'm plotting a 3D network using Mayavi,
edge_size = 0.2
pts = mlab.points3d(x, y, z,
scale_mode='none',
scale_factor=0.1)
pts.mlab_source.dataset.lines = np.array(graph.edges())
tube = mlab.pipeline.tube(pts, tube_radius=edge_size)
I want to change edge/tube radius. So I tried
tube = mlab.pipeline.tube(pts, tube_radius=listofedgeradius)
I get an error that says,
traits.trait_errors.TraitError: The 'tube_radius' trait of a TubeFactory instance must be a float
From the error, I understand a list cannot be assigned to tube_radius. In this case, I am not sure how to assign a different radius to each edge.
Any suggestions on how to assign edge weights/edge radius will be helpful.
EDIT: Complete working example
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
from mayavi import mlab
def main(edge_color=(0.8, 0.8, 0.8), edge_size=0.02):
t = [1, 2, 3, 4, 5]
h = [2, 3, 4, 5, 6]
ed_ls = [(x, y) for x, y in zip(t, h)]
G = nx.OrderedGraph()
G.add_edges_from(ed_ls)
nx.draw(G)
plt.show()
graph_pos = nx.spring_layout(G, dim=3)
# numpy array of x,y,z positions in sorted node order
xyz = np.array([graph_pos[v] for v in sorted(G)])
mlab.figure(1)
mlab.clf()
pts = mlab.points3d(xyz[:, 0], xyz[:, 1], xyz[:, 2])
pts.mlab_source.dataset.lines = np.array(G.edges())
tube = mlab.pipeline.tube(pts, tube_radius=edge_size)
mlab.pipeline.surface(tube, color=edge_color)
mlab.show() # interactive window
main()
New edge weights to be added in the expected output:
listofedgeradius = [1, 2, 3, 4, 5]
tube = mlab.pipeline.tube(pts, tube_radius=listofedgeradius)
Is seems to me that you can't plot multiple tubes with different diameter at once.
So one solution is to plot them one after another:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
from mayavi import mlab
def main(edge_color=(0.8, 0.8, 0.8)):
t = [1, 2, 4, 4, 5, 3, 5]
h = [2, 3, 6, 5, 6, 4, 1]
ed_ls = [(x, y) for x, y in zip(t, h)]
G = nx.OrderedGraph()
G.add_edges_from(ed_ls)
graph_pos = nx.spring_layout(G, dim=3)
print(graph_pos)
# numpy array of x,y,z positions in sorted node order
xyz = np.array([graph_pos[v] for v in sorted(G)])
listofedgeradius = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]) * 0.1
for i, e in enumerate(G.edges()):
# node number of the edge
i1, i2 = e
# graph_pos is a dictionary
c1 = graph_pos[i1]
c2 = graph_pos[i2]
edge_xyz = np.vstack((c1, c2))
pts = mlab.points3d(edge_xyz[:, 0], edge_xyz[:, 1], edge_xyz[:, 2])
#pts.mlab_source.dataset.lines = np.array(G.edges())
# always first and second point
pts.mlab_source.dataset.lines = np.array([[0, 1]])
tube = mlab.pipeline.tube(pts, tube_radius=listofedgeradius[i])
mlab.pipeline.surface(tube, color=edge_color)
mlab.gcf().scene.parallel_projection = True
mlab.show() # interactive window
main()
Here is a larger example with 100 edges (image below) and one caveat of this solution becomes obvious: the for loop is slow.
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
from mayavi import mlab
def main(edge_color=(0.8, 0.8, 0.8)):
n = 100
t = np.random.randint(100, size=n)
h = np.random.randint(100, size=n)
ed_ls = [(x, y) for x, y in zip(t, h)]
G = nx.OrderedGraph()
G.add_edges_from(ed_ls)
graph_pos = nx.spring_layout(G, dim=3)
print(graph_pos)
# numpy array of x,y,z positions in sorted node order
xyz = np.array([graph_pos[v] for v in sorted(G)])
listofedgeradius = np.random.rand(n) * 0.01
for i, e in enumerate(G.edges()):
print(i)
# node number of the edge
i1, i2 = e
# graph_pos is a dictionary
c1 = graph_pos[i1]
c2 = graph_pos[i2]
edge_xyz = np.vstack((c1, c2))
pts = mlab.points3d(edge_xyz[:, 0], edge_xyz[:, 1], edge_xyz[:, 2])
#pts.mlab_source.dataset.lines = np.array(G.edges())
# always first and second point
pts.mlab_source.dataset.lines = np.array([[0, 1]])
tube = mlab.pipeline.tube(pts, tube_radius=listofedgeradius[i])
mlab.pipeline.surface(tube, color=edge_color)
mlab.gcf().scene.parallel_projection = True
mlab.show() # interactive window
main()
Inspired by this, this and this I put together a first example that works well for large graphs (I tried up to 5000 edges). There is still a for loop, but it is not used for plotting, only for gathering the data in numpy arrays, so it's not that bad.
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
from mayavi import mlab
def main(edge_color=(0.8, 0.8, 0.8)):
n = 5000
t = np.random.randint(100, size=n)
h = np.random.randint(100, size=n)
ed_ls = [(x, y) for x, y in zip(t, h)]
G = nx.OrderedGraph()
G.add_edges_from(ed_ls)
graph_pos = nx.spring_layout(G, dim=3)
print(graph_pos)
listofedgeradius = np.random.rand(n) * 0.01
# We create a list of positions and connections, each describing a line.
# We will collapse them in one array before plotting.
x = list()
y = list()
z = list()
s = list()
connections = list()
N = 2 # every edge brings two nodes
# The index of the current point in the total amount of points
index = 0
for i, e in enumerate(G.edges()):
# node number of the edge
i1, i2 = e
# graph_pos is a dictionary
c1 = graph_pos[i1]
c2 = graph_pos[i2]
edge_xyz = np.vstack((c1, c2))
x.append(edge_xyz[:, 0])
y.append(edge_xyz[:, 1])
z.append(edge_xyz[:, 2])
s.append(listofedgeradius[i])
s.append(listofedgeradius[i])
# This is the tricky part: in a line, each point is connected
# to the one following it. We have to express this with the indices
# of the final set of points once all lines have been combined
# together, this is why we need to keep track of the total number of
# points already created (index)
ics = np.vstack(
[np.arange(index, index + N - 1.5),
np.arange(index + 1, index + N - .5)]
).T
#print(ics)
connections.append(ics)
index += N
# Now collapse all positions, scalars and connections in big arrays
x = np.hstack(x)
y = np.hstack(y)
z = np.hstack(z)
s = np.hstack(s)
# print(x.shape)
# print(y.shape)
# print(z.shape)
# print(s.shape)
connections = np.vstack(connections)
# # graph_pos is a dictionary
# c1 = graph_pos[i1]
# c2 = graph_pos[i2]
# edge_xyz = np.vstack((c1, c2))
#src = mlab.points3d(x, y, z, s)
#src = mlab.pipeline.scalar_scatter(x, y, z, s)
src = mlab.plot3d(x, y, z, s)
print(src)
print(src.parent)
print(src.parent.parent)
#src.parent.parent.filter.vary_radius = 'vary_radius_by_scalar'
src.parent.parent.filter.vary_radius = 'vary_radius_by_absolute_scalar'
# Connect them
src.mlab_source.dataset.lines = connections
#src.update()
# The stripper filter cleans up connected lines
lines = mlab.pipeline.stripper(src)
# Finally, display the set of lines
#mlab.pipeline.surface(lines, colormap='Accent', line_width=1, opacity=.4)
#tube = mlab.pipeline.tube(src, tube_radius=0.01)
#tube.filter.radius_factor = 1
#tube.filter.vary_radius = 'vary_radius_by_scalar'
#surf = mlab.pipeline.surface(tube, opacity=0.6, color=(0.8,0.8,0))
#t = mlab.plot3d(x, y, z, s, tube_radius=10)
#t.parent.parent.filter.vary_radius = 'vary_radius_by_scalar'
#pts.mlab_source.dataset.lines = np.array(G.edges())
# always first and second point
#pts.mlab_source.dataset.lines = np.array([[0, 1]])
#tube = mlab.pipeline.tube(src, tube_radius=listofedgeradius[i])
#mlab.pipeline.surface(tube, color=edge_color)
# pts = self.scene.mlab.quiver3d(x, y, z, atomsScales, v, w,
# scalars=scalars, mode='sphere', vmin=0.0, vmax=1.0, figure = scene)
# pts.mlab_source.dataset.lines = bonds
# tube = scene.mlab.pipeline.tube(pts, tube_radius=0.01)
# tube.filter.radius_factor = 1
# tube.filter.vary_radius = 'vary_radius_by_scalar'
# surf = scene.mlab.pipeline.surface(tube, opacity=0.6, color=(0.8,0.8,0))
# t = mlab.plot3d(x, y, z, s, tube_radius=10)
#t.parent.parent.filter.vary_radius = 'vary_radius_by_scalar'
# self.plot = self.scene.mlab.plot3d(x, y, z, t,
# tube_radius=self.radius, colormap='Spectral')
# else:
# self.plot.parent.parent.filter.radius = self.radius
mlab.gcf().scene.parallel_projection = True
# And choose a nice view
mlab.view(33.6, 106, 5.5, [0, 0, .05])
mlab.roll(125)
mlab.show()
main()
I'm trying to animate projectile motion with the help of matplotlib.animation but I've been facing a few errors. Please help me with this.
Thank you so much
I've tried searching through the internet and I did implement solutions of a few similar problems but the code still gives an error
import matplotlib as mat
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as mat_anim
u = 5
g = 9.8
theta_degree = np.rad2deg([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
theta_rad = [0, np.pi/6, np.pi/4, np.pi/3, np.pi/2]
fr = 100
print(1)
def projectile_range():
# calculate projectile range
rng = ((u**2)*(np.sin(np.multiply(2.0, theta_rad))))/g
return rng
def max_height():
# calculate maximum height of projectile
max_ht = ((u*np.sin(theta_rad))**2)/(2*g)
return max_ht
def projectile():
# calculating projectile path
r = projectile_range()
for j in range(len(r)):
x = np.linspace(0, r[j], 100)
y.append(x*(np.tan(theta_rad[j])) - ((0.5*g*(x**2))/(u*np.cos(theta_rad[j]))**2))
return y
fig1, ax1 = plt.subplots(1,1)
fig1.suptitle("Projectile Motion Range", fontsize = 10)
ax1.set_xlim([0, round(max(projectile_range()))+1])
ax1.set_ylim([0, round(max(max_height()))+1])
# ax_range, = ax1.plot([], [])
dots, = ax1.plot([], [], 'o')
lines, = ax1.plot([], [], lw = 2)
plot_colour = ["black", "red", "green", "yellow", "blue"]
line_list = []
dot_list = []
print(2)
for index in range(len(theta_rad)):
line_obj = ax1.plot([], [], lw = 2, color = plot_colour[index])[0]
dot_obj = ax1.plot([], [], 'o', color = plot_colour[len(theta_rad)-index-1])[0]
line_list.append(line_obj)
dot_list.append(dot_obj)
print(3)
def initialize():
# initializing projectile range plot
print(4)
for line in line_list:
line.set_data([], [])
for dot in dot_list:
dot.set_data([], [])
print(5)
return dot_list, line_list,
print(6)
def proj_animation(i):
# animation function
print(7)
n = 100
# fr = n
y = np.empty([len(theta_rad), n], dtype = float)
x = np.empty([len(theta_rad), n], dtype = float)
r = projectile_range()
for j in range(len(r)):
x[j] = np.linspace(0, r[j], n)
y[j] = np.multiply(x[j], np.tan(theta_rad[j])) - ((0.5*g*(np.square(x[j])))/(u*np.cos(theta_rad[j]))**2)
for count, element in enumerate(line_list):
element.set_data(x[count][:i], y[count][:i])
for count, element in enumerate(dot_list):
element.set_data(x[count][i], y[count][i])
print(8)
return dot_list,line_list,
proj_anim = mat_anim.FuncAnimation(fig1, proj_animation, frames = fr,
interval = 20, blit = True)
proj_anim.save("projectile_range.mp4", fps = 20, extra_args = ['-vcodec', 'libx264'])
plt.show()
key=lambda x: x.get_zorder())
AttributeError: 'list' object has no attribute 'get_zorder'
I believe the issue is that in proj_animation() you are returning a tuple of two lists, but FuncAnimation() is looking for an iterable of drawn objects directly. The quickest fix for this is to concatenate dot_list with line_list and return the concatenated list. Nb This should also be done in your initialization function.
I was trying to plot sensor data using subplots and was getting the same error. The way I fixed it was to return just a variable or a list. In the animation function I was returning a list of lists, I just flattened this list of lists and the code works. The solution adapted to your code is the following:
import matplotlib as mat
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as mat_anim
u = 5
g = 9.8
theta_degree = np.rad2deg([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
theta_rad = [0, np.pi/6, np.pi/4, np.pi/3, np.pi/2]
fr = 100
print(1)
def projectile_range():
# calculate projectile range
rng = ((u**2)*(np.sin(np.multiply(2.0, theta_rad))))/g
return rng
def max_height():
# calculate maximum height of projectile
max_ht = ((u*np.sin(theta_rad))**2)/(2*g)
return max_ht
def projectile():
# calculating projectile path
r = projectile_range()
for j in range(len(r)):
x = np.linspace(0, r[j], 100)
y.append(x*(np.tan(theta_rad[j])) - ((0.5*g*(x**2))/(u*np.cos(theta_rad[j]))**2))
return y
fig1, ax1 = plt.subplots(1,1)
fig1.suptitle("Projectile Motion Range", fontsize = 10)
ax1.set_xlim([0, round(max(projectile_range()))+1])
ax1.set_ylim([0, round(max(max_height()))+1])
# ax_range, = ax1.plot([], [])
dots, = ax1.plot([], [], 'o')
lines, = ax1.plot([], [], lw = 2)
plot_colour = ["black", "red", "green", "yellow", "blue"]
line_list = []
dot_list = []
print(2)
for index in range(len(theta_rad)):
line_obj = ax1.plot([], [], lw = 2, color = plot_colour[index])[0]
dot_obj = ax1.plot([], [], 'o', color = plot_colour[len(theta_rad)-index-1])[0]
line_list.append(line_obj)
dot_list.append(dot_obj)
print(3)
def initialize():
# initializing projectile range plot
print(4)
for line in line_list:
line.set_data([], [])
for dot in dot_list:
dot.set_data([], [])
print(5)
return dot_list, line_list,
print(6)
def proj_animation(i):
# animation function
print(7)
n = 100
# fr = n
y = np.empty([len(theta_rad), n], dtype = float)
x = np.empty([len(theta_rad), n], dtype = float)
r = projectile_range()
graph_list = []
for j in range(len(r)):
x[j] = np.linspace(0, r[j], n)
y[j] = np.multiply(x[j], np.tan(theta_rad[j])) - ((0.5*g*(np.square(x[j])))/(u*np.cos(theta_rad[j]))**2)
for count, element in enumerate(line_list):
element.set_data(x[count][:i], y[count][:i])
for count, element in enumerate(dot_list):
element.set_data(x[count][i], y[count][i])
graph_list.append(dot_list)
graph_list.append(line_list)
graph_list = [item for sublist in graph_list for item in sublist]
print(8)
return graph_list
proj_anim = mat_anim.FuncAnimation(fig1, proj_animation, frames = fr,
interval = 20, blit = True)
proj_anim.save("projectile_range.mp4", fps = 20, extra_args = ['-vcodec', 'libx264'])
plt.show()
I test the code and it works.
I have a pickle file which contains 300 coordinates of my subject's location in time. There are some missing values in the middle of it for which I am using a particle filter to estimate those missing values. At the end, I am getting some predictions (not completely accurate) but in a bit drifted form.
So the position of my subject is, in fact, the position of my subject's nose. I take a total of 300 frames and each frame consists of a coordinate for nose in it. There are some frames which have the value of (0,0) meaning the values are missing. So in order to find them, I am implementing the particle filter. I am a newbie for particle filter so there are possibilities that I may have messed up the code. The results that I get, gives me the prediction for 300 frames with drifted values. You can get a clear idea form the image.
My measurement value is distance from four landmarks and I provide orientation angle to next point and distance to next point as additional measurements.
from filterpy.monte_carlo import systematic_resample
import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import norm
from numpy.random import randn
import scipy.stats
from numpy.random import uniform
import pickle
from math import *
#####################################################
def create_uniform_particles(x_range, y_range, hdg_range, N):
particles = np.empty((N, 3))
particles[:, 0] = uniform(x_range[0], x_range[1], size=N)
particles[:, 1] = uniform(y_range[0], y_range[1], size=N)
particles[:, 2] = uniform(hdg_range[0], hdg_range[1], size=N)
particles[:, 2] %= 2 * np.pi
return particles
def create_gaussian_particles(mean, std, N):
particles = np.empty((N, 3))
particles[:, 0] = mean[0] + (randn(N) * std[0])
particles[:, 1] = mean[1] + (randn(N) * std[1])
particles[:, 2] = mean[2] + (randn(N) * std[2])
particles[:, 2] %= 2 * np.pi
return particles
#####################################################
def predict(particles, u, std):
# move according to control input u (heading change, velocity)
#with noise Q (std heading change, std velocity)`
N = len(particles)
# update heading
#particles[:, 2] += u[0] + (randn(N) * std[0])
#particles[:, 2] %= 2 * np.pi
#u[0] += (randn(N) * std[0])
u[0] %= 2 * np.pi
# move in the (noisy) commanded direction
dist = (u[1]) #+ (randn(N) * std[1])
particles[:, 0] += np.cos(u[0]) * dist
particles[:, 1] += np.sin(u[0]) * dist
#####################################################
def update(particles, weights, z, R, landmarks):
for i, landmark in enumerate(landmarks):
distance = np.linalg.norm(particles[:, 0:2] - landmark, axis=1)
weights *= scipy.stats.norm(distance, R).pdf(z[i])
weights += 1.e-300 # avoid round-off to zero
weights /= sum(weights) # normalize
#####################################################
def estimate(particles, weights):
#returns mean and variance of the weighted particles
pos = particles[:, 0:2]
mean = np.average(pos, weights=weights, axis=0)
var = np.average((pos - mean)**2, weights=weights, axis=0)
return mean, var
#####################################################
def simple_resample(particles, weights):
N = len(particles)
cumulative_sum = np.cumsum(weights)
cumulative_sum[-1] = 1. # avoid round-off error
indexes = np.searchsorted(cumulative_sum, random(N))
# resample according to indexes
particles[:] = particles[indexes]
weights.fill(1.0 / N)
#####################################################
def neff(weights):
return 1. / np.sum(np.square(weights))
#####################################################
def resample_from_index(particles, weights, indexes):
particles[:] = particles[indexes]
weights[:] = weights[indexes]
weights.fill(1.0 / len(weights))
#####################################################
def read_pickle(pkl_file, f,j):
with open(pkl_file, 'rb') as res:
dets = pickle.load(res, encoding = 'latin1')
all_keyps = dets['all_keyps']
keyps_t = np.array(all_keyps[1])
keyps = np.zeros((keyps_t.shape[0], 4, 17))
for k in range(keyps.shape[0]):
if keyps_t[k]!=[]:
keyps[k] = keyps_t[k][0]
keyps = keyps[:,:2,:]
for i in range(keyps.shape[0]):
keyps[i][0] = keyps[i][0]/480*256
keyps[i][1] = keyps[i][1]/640*256
x0=keyps[f][0][j]
y0=keyps[f][1][j]
x1=keyps[f+1][0][j]
y1=keyps[f+1][1][j]
cord = np.array([x0,y0])
orientation = atan2((y1 - y0),(x1 - x0))
dist= sqrt((x1-x0) ** 2 + (y1-y0) ** 2)
u = np.array([orientation,dist])
return (cord, u)
#####################################################
def run_pf1(N, iters=298, sensor_std_err=.1,
do_plot=True, plot_particles=False,
xlim=(-256, 256), ylim=(-256, 256),
initial_x=None):
landmarks = np.array([[0, 0], [0, 256], [256,0], [256,256]])
NL = len(landmarks)
plt.figure()
# create particles and weights
if initial_x is not None:
particles = create_gaussian_particles(
mean=initial_x, std=(5, 5, np.pi/4), N=N)
else:
particles = create_uniform_particles((0,20), (0,20), (0, 6.28), N)
weights = np.ones(N) / N
if plot_particles:
alpha = .20
if N > 5000:
alpha *= np.sqrt(5000)/np.sqrt(N)
plt.scatter(particles[:, 0], particles[:, 1],
alpha=alpha, color='g')
xs = []
#robot_pos, u = read_pickle('.pkl',1,0)
for x in range(iters):
robot_pos, uv = read_pickle('.pkl',x,0)
print("orignal: ", robot_pos,)
# distance from robot to each landmark
zs = (norm(landmarks - robot_pos, axis=1) +
(randn(NL) * sensor_std_err))
# move diagonally forward to (x+1, x+1)
predict(particles, u=uv, std=(0, .0))
# incorporate measurements
update(particles, weights, z=zs, R=sensor_std_err,
landmarks=landmarks)
# resample if too few effective particles
if neff(weights) < N/2:
indexes = systematic_resample(weights)
resample_from_index(particles, weights, indexes)
assert np.allclose(weights, 1/N)
mu, var = estimate(particles, weights)
#mu +=(120,10)
xs.append(mu)
print("expected: ",mu)
if plot_particles:
plt.scatter(particles[:, 0], particles[:, 1],
color='k', marker=',', s=1)
p1 = plt.scatter(robot_pos[0], robot_pos[1], marker='+',
color='k', s=180, lw=3)
p2 = plt.scatter(mu[0], mu[1], marker='s', color='r')
print(p2)
xs = np.array(xs)
#plt.plot(xs[:, 0], xs[:, 1])
plt.legend([p1, p2], ['Actual', 'PF'], loc=4, numpoints=1)
plt.xlim(*xlim)
plt.ylim(*ylim)
print('final position error, variance:\n\t', mu - np.array([iters, iters]), var)
plt.show()
return(p2)
###############################
run_pf1(N=5000)
I expect a set of 300 coordinate values (estimated) as a result of the particle filter so I can replace my missing values in original files with this predicted ones.
How to plot a graph with x and y labels in networkx ?
def particles_visualization(self,neighbour_listx,particles):
G=nx.Graph()
print(particles)
print(neighbour_listx)
for i in range(len(particles)):
G.add_node(particles[i][0], pos=(particles[i][1], particles[i[2]))
for i in range(len(neighbour_listx)):
G.add_edge(neighbour_listx[i][0], neighbour_listx[i][1])
pos = nx.get_node_attributes(G, 'pos')
#nx.draw_networkx_labels(G, pos)
plt.title("CLUSTERING NETWORK'S")
# Limits for the Y axis
plt.ylim(0, 100)
# Create names
plt.xlim(0,100)
plt.xlabel('X-AXIS')
plt.ylabel('Y-AXIS')
nx.draw(G, pos, with_labels=True)
plt.draw()
plt.show()
IMAGE URL: https://cdn-images-1.medium.com/max/1600/0*Jwm3mV92c3qRhqEl.
i want output with grid x and y labels as shown in the picture visit IMAGE URL
import sys
import os
import time
import random
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
class wireless_sensor_networks:
def __init__(self):
self.user_input()
def user_input(self):
print("ENTER THE DIMENSION OF THE FIELD AS (Length Breadth [as Int]) : ")
length,breadth=list(map(int,input().split(" ")))
print("ENTER THE NUMBER OF NODES THAT IS NEEDED TO BE DEPLOYED [as INT] :")
nodes=int(input())
print(length,breadth,nodes)
self.cluster_creation(length,breadth,nodes)
def cluster_creation(self,length,breadth,nodes):
print("""ENTER TYPE OF CLUSTER CREATION:
1. AREA WISE CLUSTER CREATION
2. DEFAULT (NOT KNOWS AS OF NOW) :""")
cluster_option=int(input())
if cluster_option==1:
self.cluster_area_wise(length,breadth,nodes)
elif cluster_option==2:
pass
else:
pass
def cluster_area_wise(self,length,breadth,nodes):
print("ENTER THE NUMBER OF CLUSTERS YOU WANT TO CREATE :")
number_of_clusters=int(input()) #can be changed to user input later on
x=length//(number_of_clusters**0.5)
y=breadth//(number_of_clusters**0.5)
cluster_list=[]
cluster_count=1
x=int(x)
y=int(y)
print(length,breadth,x,y)
#THE CLUSTERING ASSIGNMENT CAUSES ERROR DURING UNEVEN LENGTH AND BREADTH ASSIGNMENT
for x_axis in range(0,length,x):
for y_axis in range(0,breadth,y):
cluster_number="CLUSTER "+str(cluster_count)
cluster_count+=1
cluster_list.append([cluster_number,[],[[x_axis,x_axis+x],[y_axis,y_axis+y]]])
#print(cluster_list)
self.deployment(length,breadth,nodes,cluster_list)
def sergation_of_nodes_in_cluster(self,length,breadth,nodes,cluster_list,particles):
for each_partilcle in particles:
for node_cluster in cluster_list:
if ((each_partilcle[1][0]>=node_cluster[2][0][0] and each_partilcle[1][0]<node_cluster[2][0][1]) and (each_partilcle[1][1]>=node_cluster[2][1][0] and each_partilcle[1][1]<node_cluster[2][1][1])):
node_cluster[1].append(each_partilcle)
break
#print(cluster_list)
for each in cluster_list:
print(each[0],each[1],len(each[1])/nodes)
print(cluster_list)
self.visualization(length,breadth,cluster_list,particles)
def deployment(self,length,breadth,nodes,cluster_list):
print("""CHOOSE A DEPLOYMENT TYPE AS OPTIONS -
1. RANDOM DEPLOYMENT
2. SPIRAL DEPPLYMENT
3. SQUARE DEPLYMENT
4. DEFAULT DEPLOYMENT""")
deployment_option=int(input())
print(deployment_option)
if deployment_option==1:
self.random_deployment(length,breadth,nodes,cluster_list)
elif deployment_option==2:
self.spiral_deployment(length,breadth,nodes,cluster_list)
elif deployment_option==3:
self.square_deployment(length,breadth,nodes,cluster_list)
else:
self.default_deployment(length,breadth,nodes,cluster_list)
def random_deployment(self,length,breadth,nodes,cluster_list):
no_of_particles = nodes
particles = []
for i in range(no_of_particles):
id = i+1 # creates a id of the particles
x_cordinate = round(random.randrange(0,length),2)+round(random.random(),2)# creates the x cordinate of the particle in the range 0-100 units
y_cordinate = round(random.randrange(0,breadth),2)+round(random.random(),2) # creates the y cordinate of the particles in the range 0-100 units
# print(x_cordinate,y_cordinate)
battery=0 #change it later on
particles.append([id,[x_cordinate,y_cordinate],[battery]])
print(particles)
self.sergation_of_nodes_in_cluster(length,breadth,nodes,cluster_list,particles)
def spiral_deployment(self,length,breadth,nodes,cluster_list):
listx = []
particles=[]
def spiralPrint(m, n):
k = 0
l = 0
''' k - starting row index
m - ending row index
l - starting column index
n - ending column index
i - iterator '''
while (k < m and l < n):
# Print the first row from
# the remaining rows
for i in range(l, n):
particles.append([k, i])
#print("({},{})".format(k + 0.5, i + 0.5), end=" ")
k += 1
# Print the last column from
# the remaining columns
for i in range(k, m):
particles.append([i, n - 1])
#print("({},{})".format(i + 0.5, n - 1 + 0.5), end=" ")
n -= 1
# Print the last row from
# the remaining rows
if (k < m):
for i in range(n - 1, (l - 1), -1):
#print("({},{})".format(m - 1 + 0.5, i + 0.5), end=" ")
particles.append([m - 1, i])
m -= 1
# Print the first column from
# the remaining columns
if (l < n):
for i in range(m - 1, k - 1, -1):
#print("({},{})".format(i + 0.5, l + 0.5), end=" ")
particles.append([i, l])
l += 1
spiralPrint(length, breadth)
listx=particles
print("""ENTER THE TIME INTERVAL IN UNITS""")
time_interval=int(input())
time_interval=time_interval/nodes
node_interval=len(listx)//nodes
time=0
id=1
particles=[]
battery=0
for i in range(0,len(listx),node_interval):
particles.append([id,[listx[i][0],listx[i][1]],[battery],time])
time+=time_interval
id+=1
print(particles)
self.sergation_of_nodes_in_cluster(length, breadth, nodes, cluster_list, particles)
def square_deployment(self,length,breadth,nodes,cluster_list):
print("""ENTER THE TIME INTERVAL IN UNITS""")
time_interval = int(input())
time_interval=time_interval/nodes
no_of_particles = nodes
particles = []
timex=0
breadth_sqr=breadth
no_of_clusters=len(cluster_list)
breadth_start=int(breadth_sqr-((breadth_sqr//(no_of_clusters**0.5))//2))
breadth_incx=int(breadth_sqr//(no_of_clusters**0.5))
id=0
flx=0
while(breadth_start>0):
y_cordinate=breadth_start
flx+=1
temp=[]
battery=0 #change it later on
for i in range(0, int(no_of_particles // (no_of_clusters ** 0.5))):
temp.append(random.randrange(0, length))
if (flx % 2 != 0):
temp = sorted(temp)
else:
temp = sorted(temp, reverse=True)
for x_cordinate in temp:
id += 1
timex+=time_interval
particles.append([id, [x_cordinate, y_cordinate], [battery], timex])
breadth_start = breadth_start - breadth_incx
print(particles)
self.sergation_of_nodes_in_cluster(length, breadth, nodes, cluster_list, particles)
def default_deployment(self,length,breadth,nodes,cluster_list):
pass
def visualization(self,length,breadth,cluster_list,particles):
G=nx.Graph()
for each in particles:
G.add_node(each[0],pos=(each[1][0],each[1][1]))
#pos = nx.get_node_attributes(G, 'pos')
pos = {}
for each in particles:
pos[each[0]] = (each[1][0], each[1][1])
#nx.draw_networkx_labels(G, pos)
nx.draw_networkx(G,pos=pos)
plt.title("CLUSTERING NETWORK'S")
plt.xlabel('X-AXIS')
plt.ylabel('Y-AXIS')
# Limits for the Y and Yaxis
incx=(len(cluster_list)**0.5)
#plt.ylim(0, breadth)
#plt.xlim(0, length)
plt.xticks(np.arange(0, length+1, length//incx))
plt.yticks(np.arange(0, breadth+1, breadth//incx))
#plt.plot([lambda x: x[1][0] for x in particles],[lambda y: y[1][1] for y in particles[1][1]],'ro')
plt.grid()
plt.savefig("WSN_labels.png")
plt.show()
for each in cluster_list:
for i in range(0, len(each[1])-1):
for j in range(i + 1, len((each[1]))):
G.add_edge(each[1][i][0], each[1][j][0])
#nx.draw(G,pos, with_labels=True)
nx.draw_networkx(G, pos=pos,with_labels=True)
plt.xticks(np.arange(0, length + 1, length // incx))
plt.yticks(np.arange(0, breadth + 1, breadth // incx))
plt.grid()
plt.savefig("WSN_CLUSTER.png")
plt.show()
obj1=wireless_sensor_networks()
I've got the problem with repeating the animation. I want to use matplotlib in order to visualise each simulation on the matrix. Here is the code for simulation:
import numpy as np
from matplotlib import pyplot as plt
s = np.array([[1,1,1], [1,10,1], [1,1,1]], dtype=np.int8) #Matrix of wages
e = np.zeros((19,), dtype=np.int8) # Vector of rules
e[3]=1
e[12]=1
e[13]=1
mama = np.array([[1, 0, 1], [0, 1, 0], [0, 0, 1]], dtype=np.int8) #The matrix to be tested
def simulation(ma): #Simulation on a given matrix
n, m = ma.shape
p = np.zeros((n+2, m+2), dtype=np.int8) #Creates an extended matrix, avoiding conflicts at the edges of the initial matrix. Here I construct a torus
p[1:-1, 1:-1] = ma #middle
p[0, 1:-1] = ma[n-1] #the first row of p, the last of ma
p[-1, 1:-1] = ma[0] #the last row of p, the first of ma
p[1:-1, 0] = ma[0:, -1] #left col p, right of ma
p[1:-1, -1] = ma[0:, 0] #right col of p, left of ma
p[-1, 0] = ma[0, -1] #left bottom corner
p[-1, -1] = ma[0, 0] #right bottom corner
p[0, 0] = ma[-1, -1] #left upper corner
p[0, -1] = ma[-1, 0] #right upper corner
new = np.zeros(ma.shape, dtype=np.int8)
v, c = p.shape #verses and columns
for i in range(1, v):
for j in range(1, c):
if p[i-1:i+2, j-1:j+2].shape == (3, 3):
new[i-1, j-1] = e[np.sum(p[i-1:i+2,j-1:j+2]*s)]
return new
However, I want to run simulation over the specified number of repetitions and visualise each step of the simulation, so I have tried the code:
def rep(fun, mac, ti): #function, matrix, repetitions (time)
if ti == 1:
plt.imshow(fun(mac))
plt.title("Celllar automaton")
plt.show()
else:
f = fun(rep(fun, mac, ti-1))
plt.imshow(f)
plt.title("Cellular automaton")
plt.show()
I get an error:
n, m = ma.shape
AttributeError: 'NoneType' object has no attribute 'shape'
Please, could you help me? I got really tired of my unability to visualise my work.
ADDITIONALLY:
I have substituted with rep with:
def shoow(fig):
plt.imshow(fig)
plt.title("Cellular automaton")
plt.show()
def repet(fun, mac, ti):
c1 = mac
for i in range(ti):
f = fun(c1)
shoow(f)
c1 = f
However, it creates each time a new figure. How can I get a continuous simulation?