I'm trying to fill in a structured grid with an analytical field, but despite reading the vtk docs, I haven't found out how to actually set scalar values at the grid points or the set the spacing/origin info of the grid. Starting from the code below, how do I
associate spatial information with the grid (ie cell 0,0,0 is at coordinates 0,0,0, the spacing is dx in every direction)
associate scalar values with each grid point. To start, I just need one, but eventually I'd like to store 3 pieces of data at each point (not a vector, 3 distinct scalars).
grid = vtk.vtkStructuredGrid()
numPoints = int((maxGrid - minGrid)/dx)
grid.SetDimensions(numPoints, numPoints, numPoints)
In VTK there are 3 types of "structured" grids, vtkImageData (vtkUniformGrid derives from this), vtkRectilinearGrid, and vtkStructuredGrid. They are all structured in the sense that the topology is set. vtkImageData has constant spacing between points and is axis aligned, vtkRectilinearGrid is axis aligned but can vary the spacing in each axis direction, and vtkStructuredGrid has arbitrarily located points (cells may not be valid though).
For what you want to do you should do:
from vtk import *
dx = 2.0
grid = vtkImageData()
grid.SetOrigin(0, 0, 0) # default values
grid.SetSpacing(dx, dx, dx)
grid.SetDimensions(5, 8, 10) # number of points in each direction
# print grid.GetNumberOfPoints()
# print grid.GetNumberOfCells()
array = vtkDoubleArray()
array.SetNumberOfComponents(1) # this is 3 for a vector
array.SetNumberOfTuples(grid.GetNumberOfPoints())
for i in range(grid.GetNumberOfPoints()):
array.SetValue(i, 1)
grid.GetPointData().AddArray(array)
# print grid.GetPointData().GetNumberOfArrays()
array.SetName("unit array")
Related
I have a dataframe with time-series data on two variables Reported_Cases and Horizontal_Threshold, here is my graph code:
def time_series_graph_horizontal_threshold(df, x_var, y_var):
plt.figure(figsize=(10, 6))
plt.grid(True)
df.plot(x='Year_Week', y=['Reported_Cases', 'Horizontal_Threshold'])
plt.show()
Which generates this graph
How can I add positive signals on the graph such that when the Reported_Cases is higher than the Horizontal_Threshold, it will show green signal dots across the graph? We can assume I have another column named Positive_Signal which is binary (0, 1=above).
First draw your image, but saving the result (axes object):
ax = df.plot(x='Year_Week', y=['Reported_Cases', 'Horizontal_Threshold'], grid=True, rot=45)
No need to call plt.grid(True) separately, maybe you should add parameters
concerning the image size.
Then impose green points on it:
ht = df.iloc[0].Horizontal_Threshold
dotY = 280 # Y coordinate of green points
hDist = 2 # Number of weeks between green points
for idx, rc in df.Reported_Cases.items():
if idx % hDist == 0 and rc > ht:
ax.plot(idx, dotY, '.g')
Writing the above code I assumed that your DataFrame has the index composed of consecutive integers.
Maybe you should set other values of dotY and hDist. Actually hDist depends
on the number of source rows and how is the desired "density" of these points.
For my test data containing 40 rows (weeks) I got:
I am trying to plot a bunch of particles in a box. I want the partile sizes to be scaled according to the axes length. If the particles have a radius of 1 and the box of length of 100, how do I draw this using matplotlib.pyplot.scatter()
Attempt:
I have intialised the positions of the particles, such that none overlap each other.
When I try to plot these using pyplot.scatter(), I find that the particle sizes(radius)are not 0.01 times the box dimesions.
How do I do this?
I have attached a picture here.
If I change the box length from 100 to 1000, I expect to see the markers get their radius decrease by a factor of 10.
I'm using:
import matplotlib.pyplot
pyplot.scatter(particles_np[:,0],particles_np[:,1])
pyplot.show()`
particles_np is a numpy array which has the x and y positions of the particles.
given an array of points my program should in theory, Find the two furthest points from each other. Then calculate the angle that those two points make with the x axis. Then in rotate all the points in the array around the averaged center of all the points by that angle. For some reason my translation function to rotate all the points around the center is not working it is giving me unexpected values. I am fairly sure the math I am using to do this is accurate since I tested the formula I am using using wolfram alpha and plotted the points on desmos. I am not sure what's wrong with my code because it keeps giving me unexpected output. Any help would greatly be appreciated.
This is the code to translate the array:
def translation(array,centerArray):
array1=array
maxDistance=0
point1=[]
point2=[]
global angle
for i in range(len(array1)):
for idx in range(len(array1)):
if(maxDistance<math.sqrt(((array1[i][0]-array1[idx][0])**2)+((array1[i][1]-array1[idx][1])**2)+((array1[i][2]-array1[idx][2])**2))):
maxDistance=math.sqrt(((array1[i][0]-array1[idx][0])**2)+((array1[i][1]-array1[idx][1])**2)+((array1[i][2]-array1[idx][2])**2))
point1 = array1[i]
point2 = array1[idx]
angle=math.atan2(point1[1]-point2[1],point1[0]-point2[0]) #gets the angle between two furthest points and xaxis
for i in range(len(array1)): #this is the problem here
array1[i][0]=((array[i][0]-centerArray[0])*math.cos(angle)-(array[i][1]-centerArray[1])*math.sin(angle))+centerArray[0] #rotate x cordiate around center of all points
array1[i][1]=((array[i][1]-centerArray[1])*math.cos(angle)+(array[i][0]-centerArray[0])*math.sin(angle))+centerArray[1] #rotate y cordiate around center of all points
return array1
This is the code I am using to test it. tortose is what I set turtle graphics name as
tortose.color("violet")
testarray=[[200,400,9],[200,-100,9]] #array of 2 3d points but don't worry about z axis it will not be used for in function translation
print("testsarray",testarray)
for i in range(len(testarray)): #graph points in testarray
tortose.setposition(testarray[i][0],testarray[i][1])
tortose.dot()
testcenter=findCenter(testarray) # array of 1 point in the center of all the points format center=[x,y,z] but again don't worry about z
print("center",testcenter)
translatedTest=translation(testarray,testcenter) # array of points after they have been translated same format and size of testarray
print("translatedarray",translatedTest) #should give the output [[-50,150,9]] as first point but instead give output of [-50,-99.999999997,9] not sure why
tortose.color("green")
for i in range(len(testarray)): #graphs rotated points
tortose.setposition(translatedTest[i][0],translatedTest[i][1])
tortose.dot()
print(angle*180/3.14) #checks to make sure angle is 90 degrees because it should be in this case this is working fine
tortose.color("red")
tortose.setposition(testcenter[0],testcenter[1])
tortose.dot()
find center code finds the center of all points in array don't worry about z axis since it is not used in translation:
def findCenter(array):
sumX = 0
sumY = 0
sumZ = 0
for i in range(len(array)):
sumX += array[i][0]
sumY += array[i][1]
sumZ += array[i][2]
centerX= sumX/len(array)
centerY= sumY/len(array)
centerZ= sumZ/len(array)
#print(centerX)
#print(centerY)
#print(centerZ)
centerArray=[centerX,centerY,centerZ]
return centerArray
import math
import turtle
tortose = turtle.Turtle()
tortose.penup()
my expected output should be a point at (-50,150) but it is giving me a point at (-50,-99.99999999999997)
This is a common mistake when doing in-place rotations:
array1[i][0]= ...
array1[i][1]= ... array[i][0] ...
First you update array1[i][0]. Then you update array1[i][1], but you use the new value when you should use the old value. Instead, temporarily store the old value:
x = array1[i][0]
array1[i][0]=((array[i][0]-centerArray[0])*math.cos(angle)-(array[i][1]-centerArray[1])*math.sin(angle))+centerArray[0] #rotate x cordiate around center of all points
array1[i][1]=((array[i][1]-centerArray[1])*math.cos(angle)+(x-centerArray[0])*math.sin(angle))+centerArray[1] #rotate y cordiate around center of all points
I am trying various visualizations for an Igraph in R (version.3.3.1).
Currently my visualizing is as shown as below, 2 nodes (blue and green) in circular layout.
Circular Layout
visNetwork(data$nodes,data$edges) %>% visIgraphLayout(layout="layout_in_circle")
Now I want to have a semicircle structure instead of a full circle as in the pic. All blue nodes form a semicircle, green nodes another semicircle. Each semicircle separated by a small distance as well. How can i achieve this. I found grid package has an option for semicircle, but i couldnt make it work with igraph. Please provide some pointers.
The layout argument accepts an arbitrary matrix with two columns and N rows if your graph has N vertices; all you need to do is to create a list of coordinates that correspond to a semicircle. You can make use of the fact that a vertex at angle alpha around a circle with radius r centered at (0, 0) is to be found at (r * cos(alpha), r * sin(alpha)). Since you are using R, alpha should be specified in radians, spaced evenly between 0 and pi (which corresponds to 180 degrees).
My dataset consists of three vectors (x,y and z). I plot these values as dots in a 3d-plot with plot3(x,y,z), which is fine. I also want to show a plane in the same plot. To get the data of this plot I use linear regression on x and y to get a new z.
This is how it looks:
(source: bildr.no)
I want the surf to be filled with only one color (say light blue or gray) and set the opacity, to make it see-through. How can I do this?
The easiest way to create a surface that has just 1 color and a given transparency value is to set the 'FaceColor' and 'FaceAlpha' properties of the surface object:
hSurface = surf(...your arguments to create the surface object...);
set(hSurface,'FaceColor',[1 0 0],'FaceAlpha',0.5);
This example sets the surface color to be red and the transparency to 0.5. You can also set the edge properties too (with 'EdgeColor' and 'EdgeAlpha').
It is not clear to me what you want to do. When you say one color for the surf, do you mean exactly one color, or do you mean you want shades of gray?
Here is some code that will do a variety of things, you can choose which lines to use:
x = rand(1,20);
y = rand(1,20);
z = rand(1,20);
[X,Y] = meshgrid(linspace(0,1,10),linspace(0,1,10));
Z = rand(10)*0.1;
clf
plot3(x,y,z,'.');
hold on
h = surf(X,Y,Z)
hold off
%% This will change the color
colormap(copper)
%% This will remove colordata
set(h, 'cdata',zeros(10))
%% This will make transparent
alpha(0.5)
Completing the answer from gnovice, an extra ingredient in set(hsurface...) may be required (Matlab R2010b 64):
hSurface = surf(...your arguments to create the surface object...);
set(hSurface, 'FaceColor',[1 0 0], 'FaceAlpha',0.5, 'EdgeAlpha', 0);
to make invisible the point-to-point edges of the plotted surface
#matlabDoug has what you need, I think. The property cdata holds color data that gets a color map applied to it. Setting it to an array the same size as your surface data, with each element in that array having the same value, will make your surface one color. With the default color map, setting everything in cdata to zero will make your surface blue, and setting everything to 1 will make the surface red. Then you can play with the alpha to make it transparent.