Polar contour plot in Maxima - gnuplot

How can I make a polar contour plot in Maxima? Given an expression such as
exp(-r) * cos(phi)
I'd like to plot contours in the x-y plane which have the same value of the expression at all points along the contour.
I've tried
draw3d(cylindrical(exp(-r) * cos(phi), r, 0, 5, phi, 0, 2*%pi), contour=map))
but cylindrical plots r as a function of z and phi, not z as a function of r and phi. It would be nice to not have to convert manually to Cartesian coordinates.

contour_plot(exp(-r)*cos(phi), [r,0,2], [phi, 0, 2*%pi], [transform_xy, polar_to_xy],
[gnuplot_preamble, "set cntrparam levels 10;"]);
The polar_to_xy option interprets the first two variables as distance from the z axis and azimuthal angle.

What is the problem using something like
draw3d(explicit(20*exp(-x^2-y^2)-10,x,0,2,y,-3,3),
contour_levels = 15,
contour = map,
surface_hide = true) ;
I think that in that case is straigthforward to do it.

Related

How to invert Y axis of a ScatterPlotItem in PyQtGraph

I want to display points in a scatter plot with indices as if it were a matrix, origin top left inverting the Y axis:
0,0 1,0
0,1 1,1
instead of default where the origin is the lower left.
0,1 1,1
0,0 1,0
I tried:
plot = pg.ScatterPlotItem(...)
plot.getViewBox().invertY(True) # view box is NoneType
as suggested here Inverting the Y axis in PyQtGraph with no luck.
Referring to the official doc, when you have data displayed within axes, you end up (directly or indirectly) using a PlotItem object as a container, as shown in the figure.
Assuming you are plotting something like the following:
plot_widget = PlotWidget()
plot_item = plot_widget.plotItem
plot = pg.ScatterPlotItem(x=[0, 0, 1, 1], y=[0, 1, 0, 1], size=20.0)
plot_widget.addItem(plot) # Or equivalently, plot_item.addItem(plot)
You can simply do:
plot_item.invertY(True)
And here is the result:

create a 3d cylinder inside 3d volume

I have 3d volume. Which has shape of (399 x 512 x 512). And It has voxel spacing of 0.484704 x 0.484704 x 0.4847
Now, I want to define a cylinder inside this volume with length 5mm, diameter 1mm, intensity 1 inside, intensity 0 outside.
I saw an example to define a cylinder in internet like this code:
from mpl_toolkits.mplot3d import Axes3D
def data_for_cylinder_along_z(center_x,center_y,radius,height_z):
z = np.linspace(0, height_z, 50)
theta = np.linspace(0, 2*np.pi, 50)
theta_grid, z_grid=np.meshgrid(theta, z)
x_grid = radius*np.cos(theta_grid) + center_x
y_grid = radius*np.sin(theta_grid) + center_y
return x_grid,y_grid,z_grid
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
Xc,Yc,Zc = data_for_cylinder_along_z(0.2,0.2,0.05,0.1)
ax.plot_surface(Xc, Yc, Zc, alpha=0.5)
plt.show()
However, I don't know how to define the cylinder inside the 3d volume keeping all the conditions (length 5mm, diameter 1mm, intensity 1 inside, intensity 0 outside) true. I also want to define the center of cylinder automatically. So that I can define the cylinder at any place of inside the 3d volume keeping the other condition true. Can anyone show or provide any example?
Thanks a lot in advance.
One simple way of solving this would be to perform each of the checks individually and then just keep the voxels that satisfy all of your constraints.
If you build a grid with all of the centers of the voxels: P (399 x 512 x 512 x 3), each voxel at (i,j,k) will be associated with its real-world position (x,y,z).
That's a little tricky, but it should look something like this:
np.stack(np.meshgrid(np.arange(0, shape[0]),
np.arange(0, shape[1]),
np.arange(0, shape[2]), indexing='ij'), axis=3)
If you subtract the cylinder's center (center_x,center_y, center_z), you're left with the relative positions of each (i,j,k) voxel P_rel (399 x 512 x 512 x 3)
When you have that, you can apply each of your tests one after the other. For a Z-oriented cylinder with a radius and height_z it would look something like:
# constrain the Z-axis
not_too_high = P_rel[:,:,:,2]<= (0.5*height_z)
not_too_low = P_rel[:,:,:,2]>= (-0.5*height_z)
# constrain the radial direction
not_too_far = np.linalg.norm(P_rel[:,:,:,:2],axis=3)<=radius
voxels_in_cyl = not_too_high & not_too_low & not_too_far
I haven't tested the code, but you get the idea.
If you wanted to have an cylinder with an arbitrary orientation you would have to project P_rel into axial and radial components and then do an analogous check without "hard-coding" the indices as I did in this example

How to generate "triangles" parameter of Mayavi triangular_mesh using triangles which are known vertices coordinates

I have triangles which construct surface of sphere. I want to draw the surface using mayavi triangular_mesh function. The function has "triangles" parameter which is list of triplets (or an array) list the vertices in each triangle. I know vertices coordinate all of triangles. But I don't know how to generate this parameter.
I also tried to generate "triangles" parameter using matplotlib Triangulation function (triangles = matplotlib.tri.Triangulation(longitudes, latitudes).triangles). However, in some places of surface, the triangles are connected incorrectly (can be seen Figure 1).
Figure 1. Incorrect connection of triangles
How to generate "triangles" parameter of Mayavi triangular_mesh using triangles which are known vertices coordinates
Data Format
x, y and z are Cartesian coordinate of triangles. For example; (x[0], y[0], z[0]), (x[1], y[1], z[1]) and (x[2], y[2], z[2]) are vertices of a triangle. Next triangle has (x[3], y[3], z[3]), (x[4], y[4], z[4]) and (x[5], y[5], z[5]) vertices coordinate.
You just need to put it together using the indices.
Take a look at the shape of triangles.
It has three indices per triangle that is used
on x, y and z.
import numpy as np
import mayavi.mlab as mlab
x = np.random.rand(30)
y = np.random.rand(30)
z = np.random.rand(30)
s = np.random.rand(30)
triangles = np.random.randint(0, 30, size=(10, 3))
print(triangles)
mlab.triangular_mesh(x, y, z, triangles, scalars=s)
mlab.orientation_axes()
mlab.show()

Glowing (neon) effect in gnuplot

I want to reproduce this effect in gnuplot:
How can I achive it? If it can't be done, what software can I use to reproduce it?
Using a 2d kernel for every pixel can be done inside gnuplot. That way, more dense accumulations get brighter than single pixels. Check show palette rgbformulae and the respective chapter in the help to change the colours.
set term wxt size 300,300 background rgb 0
set view map
set samp 140
set dgrid3d 180,180, gauss kdensity2d 0.2,0.2
set palette rgbform 4,4,3
splot "+" us 1:(sin($1/3)**2*20):(1) with pm3d notitle
Disclaimer: It can be done with gnuplot as instructed in this answer but you should probably consider a different tool to draw this particular type of plot.
There is at least one way to do it, with preprocessing of the data. The idea is to mimic the glow effect by using a Gaussian kernel to smear the data points. Consider the following data, contained in a file called data:
1 2
1 2.1
1.1 2.2
2 3
3 4
I have purposely placed the first 3 points close to each other to be able to observe the intensified glow of neighboring points. These data look like this:
Now we smear the data points using a 2D Gaussian kernel. I have written the following python code to help with this. The code has a cutoff of 4 standard deviations (sx and sy) around each point. If you want the glow to be a circle, you should choose the standard deviations so that the sx / sy ratio is the same as the ratio of the x/y axes lengths in gnuplot. Otherwise the points will look like ellipses. This is the code:
import numpy as np
import sys
filename = str(sys.argv[1])
sx = float(sys.argv[2])
sy = float(sys.argv[3])
def f(x,y,x0,y0,sx,sy):
return np.exp(-(x-x0)**2/2./sx**2 -(y-y0)**2/2./sy**2)
datafile = open(filename, 'r')
data = []
for datapoint in datafile:
a, b = datapoint.split()
data.append([float(a),float(b)])
xmin = data[0][0]
xmax = data[0][0]
ymin = data[0][1]
ymax = data[0][1]
for i in range(1, len(data)):
if(data[i][0] < xmin):
xmin = data[i][0]
if(data[i][0] > xmax):
xmax = data[i][0]
if(data[i][1] < ymin):
ymin = data[i][1]
if(data[i][1] > ymax):
ymax = data[i][1]
xmin -= 4.*sx
xmax += 4.*sx
ymin -= 4.*sy
ymax += 4.*sy
dx = (xmax - xmin) / 250.
dy = (ymax - ymin) / 250.
for i in np.arange(xmin,xmax+dx, dx):
for j in np.arange(ymin,ymax+dy, dy):
s = 0.
for k in range(0, len(data)):
d2 = (i - data[k][0])**2 + (j - data[k][1])**2
if( d2 < (4.*sx)**2 + (4.*sy)**2):
s += f(i,j,data[k][0],data[k][1],sx,sy)
print i, j, s
It is used as follows:
python script.py data sx sy
where script.py is the name of the file where the code is located, data is the name of the data file, and sx and sy are the standard deviations.
Now, back to gnuplot, we define a palette that mimics a glowing pattern. For isolated points, the summed Gaussians yield 1 at the position of the point; for overlapping points it yields values higher than 1. You must consider that when defining the palette. The following is just an example:
set cbrange [0:3]
unset colorbox
set palette defined (0 "black", 0.5 "blue", 0.75 "cyan", 1 "white", 3 "white")
plot "< python script.py data 0.05 0.05" w image
You can see that the points are actually ellipses, because the ratio of the axes lengths is not the same as that of the standard deviations along the different directions. This can be easily fixed:
plot "< python script.py data 0.05 0.06" w image
Set a black background, and then plot your dataset several time in different colours with decreasing pointsize.
set term wxt backgr rgb "black"
plot sin(x) w p pt 7 ps 2 lc rgb 0x00003f not, \
sin(x) w p pt 7 ps 1.5 lc rgb 0x00007f not, \
sin(x) w p pt 7 ps 1 lc rgb 0x0000af not, \
sin(x) w p pt 7 ps .5 lc rgb 0x0000ff
Alternatively, some combination of splot with pm3d,set dgrid3d gauss kdensity2d, and set view map, combined with a suitable palette, can be used, see my other answer.

Mixed Scaled and ordinary coordinates in Mathematica?

Is it possible to specify a position in terms of Scaled coordinates in one direction and use the ordinary coordinates from my data points in the other direction on the plot? In other words, I want to specify a position, where the x coordinate is an ordinary coordinate and will change position in the plot if the plot range is changed, but the y coordinate is Scaled coordinate and will remain at a fixed height relative to the plot.
It is a bit late in coming, but is this what you are looking for?
data = {{1, 0.5}, {2, 0.7}, {3, 0.4}, {4, 0.2}};
Graphics[
Line[data /. {x_, y_} :> Scaled[{0, y}, {x, 0}]],
Axes -> True,
PlotRange -> {Automatic, {0, 100}},
AspectRatio -> Full
]

Resources